mcstas-readout-master 0.3.3__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 (127) hide show
  1. mcstas_readout_master-0.3.3/.github/workflows/docs.yml +49 -0
  2. mcstas_readout_master-0.3.3/.github/workflows/main.yml +112 -0
  3. mcstas_readout_master-0.3.3/.github/workflows/wheels.yml +68 -0
  4. mcstas_readout_master-0.3.3/.gitignore +64 -0
  5. mcstas_readout_master-0.3.3/AGENT.md +44 -0
  6. mcstas_readout_master-0.3.3/CLAUDE.md +52 -0
  7. mcstas_readout_master-0.3.3/CMakeLists.txt +119 -0
  8. mcstas_readout_master-0.3.3/DEVELOPMENT.md +73 -0
  9. mcstas_readout_master-0.3.3/LICENSE +11 -0
  10. mcstas_readout_master-0.3.3/PKG-INFO +123 -0
  11. mcstas_readout_master-0.3.3/PLAN.md +215 -0
  12. mcstas_readout_master-0.3.3/ParameterPublisher.md +94 -0
  13. mcstas_readout_master-0.3.3/README.md +105 -0
  14. mcstas_readout_master-0.3.3/VERSION +1 -0
  15. mcstas_readout_master-0.3.3/cmake/check.cmake +55 -0
  16. mcstas_readout_master-0.3.3/cmake/conan_provider.cmake +675 -0
  17. mcstas_readout_master-0.3.3/cmake/fetcher.cmake +17 -0
  18. mcstas_readout_master-0.3.3/cmake/readout-hdf5.cmake +39 -0
  19. mcstas_readout_master-0.3.3/cmake/version.py +102 -0
  20. mcstas_readout_master-0.3.3/conanfile.py +115 -0
  21. mcstas_readout_master-0.3.3/devel/check_install.sh +68 -0
  22. mcstas_readout_master-0.3.3/docs/Doxyfile.in +52 -0
  23. mcstas_readout_master-0.3.3/docs/architecture.md +69 -0
  24. mcstas_readout_master-0.3.3/docs/cli.md +91 -0
  25. mcstas_readout_master-0.3.3/docs/collector-files.md +66 -0
  26. mcstas_readout_master-0.3.3/docs/examples.md +94 -0
  27. mcstas_readout_master-0.3.3/docs/extract_comp_docs.py +194 -0
  28. mcstas_readout_master-0.3.3/docs/index.md +29 -0
  29. mcstas_readout_master-0.3.3/docs/install.md +43 -0
  30. mcstas_readout_master-0.3.3/docs/integration.md +47 -0
  31. mcstas_readout_master-0.3.3/docs/theme/LICENSE +21 -0
  32. mcstas_readout_master-0.3.3/docs/theme/doxygen-awesome-sidebar-only.css +116 -0
  33. mcstas_readout_master-0.3.3/docs/theme/doxygen-awesome.css +2681 -0
  34. mcstas_readout_master-0.3.3/examples/readout_example.instr +76 -0
  35. mcstas_readout_master-0.3.3/examples/run_example.sh +36 -0
  36. mcstas_readout_master-0.3.3/layout_plan.md +201 -0
  37. mcstas_readout_master-0.3.3/pyproject.toml +63 -0
  38. mcstas_readout_master-0.3.3/python/_readout_core/__init__.py +59 -0
  39. mcstas_readout_master-0.3.3/readout_core/CMakeLists.txt +210 -0
  40. mcstas_readout_master-0.3.3/readout_core/app_combine/main.cpp +155 -0
  41. mcstas_readout_master-0.3.3/readout_core/app_common/args.hxx +4594 -0
  42. mcstas_readout_master-0.3.3/readout_core/app_config/helper.cpp +45 -0
  43. mcstas_readout_master-0.3.3/readout_core/app_config/helper.h +34 -0
  44. mcstas_readout_master-0.3.3/readout_core/app_config/main.cpp +139 -0
  45. mcstas_readout_master-0.3.3/readout_core/app_replay/main.cpp +97 -0
  46. mcstas_readout_master-0.3.3/readout_core/cmake/ReadoutConfig.cmake.in +21 -0
  47. mcstas_readout_master-0.3.3/readout_core/cmake/readout_config.h.in +20 -0
  48. mcstas_readout_master-0.3.3/readout_core/components/CollectorBM0.comp +276 -0
  49. mcstas_readout_master-0.3.3/readout_core/components/CollectorBM2.comp +298 -0
  50. mcstas_readout_master-0.3.3/readout_core/components/CollectorBMI.comp +297 -0
  51. mcstas_readout_master-0.3.3/readout_core/components/CollectorCAEN.comp +344 -0
  52. mcstas_readout_master-0.3.3/readout_core/components/CollectorCDT.comp +298 -0
  53. mcstas_readout_master-0.3.3/readout_core/components/CollectorTTLMonitor.comp +301 -0
  54. mcstas_readout_master-0.3.3/readout_core/components/CollectorVMM3.comp +336 -0
  55. mcstas_readout_master-0.3.3/readout_core/components/ReadoutCAEN.comp +293 -0
  56. mcstas_readout_master-0.3.3/readout_core/components/ReadoutDiscreteCAEN.comp +271 -0
  57. mcstas_readout_master-0.3.3/readout_core/components/ReadoutTTLMonitor.comp +274 -0
  58. mcstas_readout_master-0.3.3/readout_core/components/lib-readout.c +55 -0
  59. mcstas_readout_master-0.3.3/readout_core/components/lib-readout.h +36 -0
  60. mcstas_readout_master-0.3.3/readout_core/include/CollectorClass.h +546 -0
  61. mcstas_readout_master-0.3.3/readout_core/include/Readout.h +13 -0
  62. mcstas_readout_master-0.3.3/readout_core/include/ReadoutClass.h +178 -0
  63. mcstas_readout_master-0.3.3/readout_core/include/Sender.h +166 -0
  64. mcstas_readout_master-0.3.3/readout_core/include/SenderConfigs.h +62 -0
  65. mcstas_readout_master-0.3.3/readout_core/include/Structs.h +142 -0
  66. mcstas_readout_master-0.3.3/readout_core/include/TypeDescriptionParser.h +82 -0
  67. mcstas_readout_master-0.3.3/readout_core/include/cluon-complete.hpp +18808 -0
  68. mcstas_readout_master-0.3.3/readout_core/include/efu_time.h +151 -0
  69. mcstas_readout_master-0.3.3/readout_core/include/enums.h +91 -0
  70. mcstas_readout_master-0.3.3/readout_core/include/hdf_interface.h +301 -0
  71. mcstas_readout_master-0.3.3/readout_core/include/reader.h +682 -0
  72. mcstas_readout_master-0.3.3/readout_core/include/readout_collector.h +149 -0
  73. mcstas_readout_master-0.3.3/readout_core/include/readout_discrete.h +146 -0
  74. mcstas_readout_master-0.3.3/readout_core/include/readout_orig.h +85 -0
  75. mcstas_readout_master-0.3.3/readout_core/include/readout_structs.h +94 -0
  76. mcstas_readout_master-0.3.3/readout_core/include/readout_type_descriptions.h +39 -0
  77. mcstas_readout_master-0.3.3/readout_core/include/replay.h +117 -0
  78. mcstas_readout_master-0.3.3/readout_core/include/writer.h +120 -0
  79. mcstas_readout_master-0.3.3/readout_core/src/Array.cpp +36 -0
  80. mcstas_readout_master-0.3.3/readout_core/src/Array.h +67 -0
  81. mcstas_readout_master-0.3.3/readout_core/src/CollectorClass.cpp +1238 -0
  82. mcstas_readout_master-0.3.3/readout_core/src/DiscreteAfter.h +107 -0
  83. mcstas_readout_master-0.3.3/readout_core/src/DiscreteWhile.h +86 -0
  84. mcstas_readout_master-0.3.3/readout_core/src/IndexSampler.h +59 -0
  85. mcstas_readout_master-0.3.3/readout_core/src/ReadoutClass.cpp +281 -0
  86. mcstas_readout_master-0.3.3/readout_core/src/Readout_merge.cpp +62 -0
  87. mcstas_readout_master-0.3.3/readout_core/src/RecordBuffer.h +69 -0
  88. mcstas_readout_master-0.3.3/readout_core/src/Sender.cpp +312 -0
  89. mcstas_readout_master-0.3.3/readout_core/src/SenderConfigs.cpp +184 -0
  90. mcstas_readout_master-0.3.3/readout_core/src/TypeDescriptionParser.cpp +273 -0
  91. mcstas_readout_master-0.3.3/readout_core/src/ctream/algorithms.hpp +920 -0
  92. mcstas_readout_master-0.3.3/readout_core/src/ctream/ctream.hpp +12 -0
  93. mcstas_readout_master-0.3.3/readout_core/src/ctream/rng.hpp +50 -0
  94. mcstas_readout_master-0.3.3/readout_core/src/ctream/sampler.hpp +98 -0
  95. mcstas_readout_master-0.3.3/readout_core/src/ctream/utilities.hpp +225 -0
  96. mcstas_readout_master-0.3.3/readout_core/src/enums.cpp +132 -0
  97. mcstas_readout_master-0.3.3/readout_core/src/hdf_interface.cpp +2 -0
  98. mcstas_readout_master-0.3.3/readout_core/src/main.cpp +155 -0
  99. mcstas_readout_master-0.3.3/readout_core/src/readout_collector.cpp +191 -0
  100. mcstas_readout_master-0.3.3/readout_core/src/readout_discrete.cpp +210 -0
  101. mcstas_readout_master-0.3.3/readout_core/src/readout_orig.cpp +162 -0
  102. mcstas_readout_master-0.3.3/readout_core/src/readout_type_descriptions.cpp +24 -0
  103. mcstas_readout_master-0.3.3/readout_core/src/replay.cpp +245 -0
  104. mcstas_readout_master-0.3.3/readout_core/src/tester.cpp +44 -0
  105. mcstas_readout_master-0.3.3/test/CMakeLists.txt +40 -0
  106. mcstas_readout_master-0.3.3/test/array_test.cpp +87 -0
  107. mcstas_readout_master-0.3.3/test/collector_test.cpp +333 -0
  108. mcstas_readout_master-0.3.3/test/combine_test.cpp +170 -0
  109. mcstas_readout_master-0.3.3/test/discrete_test.cpp +202 -0
  110. mcstas_readout_master-0.3.3/test/enums_test.cpp +112 -0
  111. mcstas_readout_master-0.3.3/test/readout_all_types_test.cpp +210 -0
  112. mcstas_readout_master-0.3.3/test/readout_test.cpp +206 -0
  113. mcstas_readout_master-0.3.3/test/replay_test.cpp +720 -0
  114. mcstas_readout_master-0.3.3/test/sender_configs_test.cpp +179 -0
  115. mcstas_readout_master-0.3.3/test/star_collector_test.cpp +214 -0
  116. mcstas_readout_master-0.3.3/test/test_integration.sh +144 -0
  117. mcstas_readout_master-0.3.3/test/test_utils.h +20 -0
  118. mcstas_readout_master-0.3.3/test/type_description_test.cpp +142 -0
  119. mcstas_readout_master-0.3.3/test/weight_to_event_test.cpp +157 -0
  120. mcstas_readout_master-0.3.3/test_package/CMakeLists.txt +7 -0
  121. mcstas_readout_master-0.3.3/test_package/CMakeUserPresets.json +9 -0
  122. mcstas_readout_master-0.3.3/test_package/conanfile.py +30 -0
  123. mcstas_readout_master-0.3.3/test_package/src/main.c +9 -0
  124. mcstas_readout_master-0.3.3/tests/conftest.py +308 -0
  125. mcstas_readout_master-0.3.3/tests/test_compile_components.py +172 -0
  126. mcstas_readout_master-0.3.3/tests/test_mpi_collect.py +324 -0
  127. mcstas_readout_master-0.3.3/tests/test_run_components.py +559 -0
@@ -0,0 +1,49 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+ pages: write
12
+ id-token: write
13
+
14
+ concurrency:
15
+ group: "docs-${{ github.ref }}"
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ build:
20
+ name: Build static docs
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+
25
+ - name: Install Doxygen
26
+ run: sudo apt-get update && sudo apt-get install -y doxygen
27
+
28
+ - name: Configure
29
+ run: cmake -S . -B build -DREADOUT_DOCS_ONLY=ON
30
+
31
+ - name: Generate docs
32
+ run: cmake --build build --target docs -j2
33
+
34
+ - name: Upload Pages artifact
35
+ uses: actions/upload-pages-artifact@v4
36
+ with:
37
+ path: build/docs/html
38
+
39
+ deploy:
40
+ name: Deploy to GitHub Pages
41
+ if: github.event_name != 'pull_request'
42
+ needs: build
43
+ runs-on: ubuntu-latest
44
+ environment:
45
+ name: github-pages
46
+ url: ${{ steps.deployment.outputs.page_url }}
47
+ steps:
48
+ - id: deployment
49
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,112 @@
1
+ name: Main
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ concurrency:
8
+ group: "${{ github.workflow }}-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}"
9
+ # supersede in-flight runs on branches/PRs, but let every main run finish
10
+ cancel-in-progress: ${{ github.ref_name != 'main' }}
11
+
12
+ jobs:
13
+ cmake_and_ctest:
14
+ name: "CMake & CTest, ${{ matrix.cmake-type }} ${{ matrix.variant.os }}, py${{ matrix.python-version }}"
15
+ runs-on: ${{ matrix.variant.os }}
16
+ defaults:
17
+ run:
18
+ shell: bash -l {0}
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ variant:
23
+ - { os: ubuntu-latest}
24
+ - { os: macos-26-intel}
25
+ - { os: macos-26}
26
+ - { os: windows-latest}
27
+ python-version: ["3.12"]
28
+ cmake-type: ["Debug", "Release"]
29
+
30
+ steps:
31
+ - name: Setup Python
32
+ uses: actions/setup-python@v6
33
+ with:
34
+ python-version: ${{ matrix.python-version }}
35
+
36
+ - name: Install Python-based dependencies
37
+ run: |
38
+ python -m pip install conan numpy mccode-antlr
39
+ echo "pythonInterpreter=`which python`" >> $GITHUB_ENV
40
+
41
+ - name: Cache conan setup
42
+ id: conan-cache-key
43
+ run: |
44
+ echo "key=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
45
+ echo "path=$(conan config home)" >> $GITHUB_OUTPUT
46
+
47
+ - name: Cache conan
48
+ uses: actions/cache@v6
49
+ with:
50
+ path: ${{ steps.conan-cache-key.outputs.path }}
51
+ key: conan-${{ matrix.variant.os }}-${{ steps.conan-cache-key.outputs.key }}
52
+
53
+ - uses: actions/checkout@v6
54
+ with:
55
+ fetch-depth: 0
56
+ fetch-tags: true
57
+
58
+ - name: configure
59
+ run: cmake -S . -B build -D CMAKE_BUILD_TYPE=${{ matrix.cmake-type }} -D Python3_EXECUTABLE=${{ env.pythonInterpreter }}
60
+
61
+ - name: build
62
+ run: cmake --build build --config ${{ matrix.cmake-type }} -j
63
+
64
+ - name: test
65
+ working-directory: build
66
+ run: ctest -C ${{ matrix.cmake-type }} --verbose -j
67
+
68
+ integration_tests:
69
+ name: "Python integration tests, ${{ matrix.variant.os }} ${{ matrix.mpi }}"
70
+ runs-on: ${{ matrix.variant.os }}
71
+ needs: cmake_and_ctest
72
+ defaults:
73
+ run:
74
+ shell: bash -l {0}
75
+ strategy:
76
+ fail-fast: false
77
+ matrix:
78
+ variant:
79
+ - { os: ubuntu-latest }
80
+ mpi: [ 'mpich', 'openmpi', 'intelmpi']
81
+ python-version: ["3.12"]
82
+
83
+ steps:
84
+ - name: Setup Python
85
+ uses: actions/setup-python@v6
86
+ with:
87
+ python-version: ${{ matrix.python-version }}
88
+
89
+ - name: Setup MPI
90
+ uses: mpi4py/setup-mpi@v1
91
+ with:
92
+ mpi: ${{ matrix.mpi }}
93
+
94
+ - name: Install system dependencies
95
+ run: sudo apt-get update && sudo apt-get install -y libhdf5-dev
96
+
97
+ - name: Install Python-based dependencies
98
+ run: |
99
+ python -m pip install conan numpy mccode-antlr pytest h5py
100
+
101
+ - uses: actions/checkout@v6
102
+ with:
103
+ fetch-depth: 0
104
+ fetch-tags: true
105
+
106
+ - name: Build with development mode
107
+ run: |
108
+ cmake -S . -B build-dev
109
+ cmake --build build-dev -j
110
+
111
+ - name: Run integration tests
112
+ run: python -m pytest tests/ -v --tb=short
@@ -0,0 +1,68 @@
1
+ name: Wheels
2
+
3
+ on:
4
+ pull_request:
5
+ release:
6
+ types: [created, edited, published]
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: ${{ github.event.action == 'published' }}
12
+
13
+ jobs:
14
+ source:
15
+ name: Build source distribution
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+ with:
20
+ fetch-depth: 0
21
+ - run: pipx run build --sdist
22
+ - run: pipx run twine check dist/*
23
+ - uses: actions/upload-artifact@v4
24
+ with:
25
+ name: dist-sdist
26
+ path: dist/*.tar.gz
27
+
28
+ cibuildwheel:
29
+ name: "Wheels for ${{ matrix.variant.platform }} on ${{ matrix.variant.os }}"
30
+ runs-on: ${{ matrix.variant.os }}
31
+ strategy:
32
+ fail-fast: false
33
+ matrix:
34
+ variant:
35
+ - { os: ubuntu-latest, platform: 'manylinux' }
36
+ - { os: macos-15-intel, platform: 'macosx' }
37
+ - { os: macos-15, platform: 'macosx' }
38
+ steps:
39
+ - uses: actions/checkout@v6
40
+ with:
41
+ fetch-depth: 0
42
+ - uses: pypa/cibuildwheel@v3.1.4
43
+ env:
44
+ CIBW_BUILD: "*-${{ matrix.variant.platform }}*"
45
+ MACOSX_DEPLOYMENT_TARGET: "14"
46
+ - name: Verify clean directory
47
+ run: git diff --exit-code
48
+ shell: bash
49
+ - uses: actions/upload-artifact@v4
50
+ with:
51
+ name: dist-${{ matrix.variant.os }}
52
+ path: wheelhouse/*.whl
53
+
54
+ publish:
55
+ name: Publish to PyPI
56
+ needs: [source, cibuildwheel]
57
+ if: github.event_name == 'release' && github.event.action == 'published'
58
+ runs-on: ubuntu-latest
59
+ environment: pypi
60
+ permissions:
61
+ id-token: write
62
+ steps:
63
+ - uses: actions/download-artifact@v4
64
+ with:
65
+ pattern: dist-*
66
+ merge-multiple: true
67
+ path: dist
68
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,64 @@
1
+ *.py[cod]
2
+ *~
3
+ MANIFEST
4
+
5
+ # C extensions
6
+ *.so
7
+ *.so.*
8
+ *.lo
9
+ *.o
10
+ python/src
11
+
12
+ # Packages
13
+ *.egg
14
+ *.egg-info
15
+
16
+ # Installer logs
17
+ pip-log.txt
18
+
19
+ # Unit test / coverage reports
20
+ .coverage
21
+ .tox
22
+ nosetests.xml
23
+
24
+ # Translations
25
+ *.mo
26
+
27
+ # Mr Developer
28
+ .mr.developer.cfg
29
+ .project
30
+ .pydevproject
31
+
32
+ # Doc
33
+ .buildinfo
34
+ .doctrees
35
+ *.db
36
+ api/
37
+ .doctree
38
+ pages/
39
+
40
+ # Various build directories
41
+ *build
42
+ *dist
43
+ cmake-build*
44
+
45
+ # Built version header
46
+ */version.hpp
47
+
48
+ # Pipenv environment files
49
+ Pipfile
50
+ Pipfile.lock
51
+ .snakemake
52
+ .status_flag*
53
+
54
+ # CLion
55
+ .idea/
56
+
57
+ # devtools generated directories
58
+ devtools/conan
59
+ devtools/wheelhouse
60
+ *.comp.json
61
+ *build-dev
62
+ *tmp
63
+ test_*.c
64
+ references/
@@ -0,0 +1,44 @@
1
+ # Description
2
+ This repository contains library functionality for collecting simulated readouts from a McStas
3
+ neutron raytracing runtime and replaying them, statistically correctly, to ESS Event Formation
4
+ Units (EFUs) after the fact — decoupling the simulation runtime from the data-acquisition
5
+ pipeline.
6
+
7
+ Collection happens through the `Collector{ReadoutType}.comp` component family (CAEN, TTLMonitor,
8
+ CDT, VMM3, BM0, BM2, BMI in share/Readout/). Each component stores whole records through the
9
+ description-based collector engine: the C-struct layout of one record is described by a canonical
10
+ string (lib/readout_type_descriptions.h) parsed at runtime into an HDF5 compound datatype.
11
+ Multiple components write independent named groups into one file, each with the cue-based layout
12
+ `readouts`, `cues`, `weights`, `normalizations`, managed by the singleton CollectorSink
13
+ (lib/CollectorClass.h), which also records instrument parameters. Routing information lives as
14
+ group attributes: the detector identity (from the component's ess_type — it becomes the ESS
15
+ packet-type byte that EFUs filter on at replay) and optional EFU address/port. The record layout
16
+ itself carries no attributes: it is the dataset's own compound datatype.
17
+
18
+ Users can collect arbitrary additional data by passing their own struct-description string to the
19
+ same engine (`Collector(filename, name, description)` in C++, `collector_star_new` from C); such
20
+ groups are readable and combinable but not EFU-sendable. EFU-sendability is decided by exact
21
+ datatype comparison against the registry (`hdf_compound_type`), never by attributes — an
22
+ attribute cannot lie about the record layout, and an anti-drift unit test pins the canonical
23
+ description strings to the C++ event structs.
24
+
25
+ Files from repeated or scanned simulation points are combined with the `readout-combine` CLI
26
+ (validate / append / concatenate) into one multi-point file. The Reader/ReaderSource classes
27
+ (lib/reader.h) provide access to points, records, weights, and parameters. `readout-replay`
28
+ (lib/replay.h) steps through the points in a file, publishes each point's parameters through the
29
+ ParameterPublisher interface (EPICS transport plugs in from outside the library), draws
30
+ `n ~ Poisson(w * counting_time)` events per stored readout, and routes them to per-(detector,
31
+ readout) EFU endpoints resolved from explicit configuration, file-embedded attributes, or
32
+ defaults — in that precedence order.
33
+
34
+ # Current state
35
+ All of the above is implemented and tested (ctest plus mccode-antlr run tests per component).
36
+ The legacy per-ray Readout broadcasting components (ReadoutCAEN, ReadoutTTLMonitor,
37
+ ReadoutDiscreteCAEN) remain for in-simulation streaming use cases.
38
+
39
+ # Remaining work
40
+ 1. EPICS implementation of ParameterPublisher (lives outside this repository; mccode-plumber).
41
+ The interface contract and implementation requirements are written down in
42
+ ParameterPublisher.md.
43
+ 2. Consider a fixed-count replay mode ("exactly N events") using the retained WRSWR reservoir
44
+ sampler (lib/IndexSampler.h, lib/ctream).
@@ -0,0 +1,52 @@
1
+ # 2026-07-04 Status
2
+
3
+ This project is the interface between the simulation world (McStas based) and the ESS data
4
+ acquisition world (EPICS, Kafka and the EFU). The redevelopment from runtime event streaming
5
+ to decoupled collect → combine → replay is **complete**; see AGENT.md for the architecture
6
+ and PLAN.md for how it got here.
7
+
8
+ In one paragraph: `Collector{ReadoutType}.comp` components (readout_core/components/) store
9
+ weighted-ray records into cue-based multi-point HDF5 files through a description-based engine
10
+ (a C-struct description string parsed to an HDF5 compound datatype at runtime; canonical
11
+ strings in readout_core/include/readout_type_descriptions.h). Files are combined with the
12
+ `readout-combine` CLI (validate/append/concatenate) and replayed with `readout-replay`, which
13
+ steps through points, publishes each point's parameters through the ParameterPublisher
14
+ interface (EPICS transport is external — see ParameterPublisher.md), draws
15
+ `n ~ Poisson(w * counting_time)` events per stored readout, and routes them to EFUs resolved
16
+ from explicit config > file-embedded attributes > defaults. EFU-sendability of a collector
17
+ group is decided by exact datatype comparison against the registry (`hdf_compound_type`),
18
+ never by attributes, and an anti-drift test pins the canonical descriptions to the C++ event
19
+ structs.
20
+
21
+ ## Layout
22
+
23
+ - `readout_core/` — the installed package: `include/` (public headers), `src/`, `components/`
24
+ (McStas `.comp` files plus lib-readout.c/h), `app_config/`, `app_combine/`, `app_replay/`.
25
+ - `test/` — C++ unit tests (repository root, mcpl-style, not installed).
26
+ - `tests/` — pytest McStas-toolchain tests (mccode-antlr compile/run).
27
+ - `docs/` — Doxygen-based site: guide pages, `Doxyfile.in`, `extract_comp_docs.py` (generates
28
+ per-component markdown from the McDoc headers in the `.comp` files), `theme/`
29
+ (vendored doxygen-awesome-css). Published via `.github/workflows/docs.yml` → GitHub Pages.
30
+ - `examples/` — runnable collect → combine → replay walkthrough.
31
+
32
+ ## Building and testing
33
+
34
+ - The `build/` and `build-dev/` directories are configured with the conan **Debug** generators
35
+ and `-DREADOUT_DEVELOPMENT_MODE=ON` (see DEVELOPMENT.md). Do not reconfigure with different
36
+ flags; if needed: `cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DREADOUT_DEVELOPMENT_MODE=ON`.
37
+ - C++ tests: `cmake --build build -j8 && cd build && ctest`.
38
+ - McStas toolchain tests: `python3 -m pytest tests/` — these prefer `build-dev/` over `build/`
39
+ (tests/conftest.py), so rebuild **both** directories first or you will test stale binaries.
40
+ - After changing a `.comp` file, delete any stale `readout_core/components/*.comp.json` caches
41
+ so mccode-antlr re-parses.
42
+ - Documentation: `cmake -S . -B <scratch> -DREADOUT_DOCS_ONLY=ON && cmake --build <scratch>
43
+ --target docs` (needs doxygen; no conan, no compiled targets).
44
+
45
+ ## Remaining / external work
46
+
47
+ 1. EPICS implementation of ParameterPublisher — requirements in ParameterPublisher.md; the
48
+ transport lives in mccode-plumber, not here.
49
+ 2. Optional: fixed-count replay mode ("exactly N events") on the retained WRSWR reservoir
50
+ sampler (readout_core/src/IndexSampler.h, readout_core/src/ctream), and paced replay
51
+ (events spread over the counting time) if downstream consumers need realistic wall-clock
52
+ intervals.
@@ -0,0 +1,119 @@
1
+ cmake_minimum_required(VERSION 3.30)
2
+ cmake_policy(SET CMP0076 NEW) # Ensure target_sources converts relative paths
3
+ cmake_policy(SET CMP0017 NEW) # Prefer cmake's own files for include/find_package before CMAKE_MODULE_PATH
4
+
5
+ list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/cmake")
6
+
7
+ set(READOUT_BUILD_ON_CONDA OFF CACHE BOOL "Set to ON to build for conda")
8
+ set(READOUT_USE_CONAN ON CACHE BOOL "Use Conan to manage dependencies") # Set to OFF to use system libraries
9
+ set(READOUT_BUILD_TESTS ON CACHE BOOL "Build test binary")
10
+ set(READOUT_DOCS_ONLY OFF CACHE BOOL "Configure only the documentation target (no dependencies, no compiled targets)")
11
+
12
+ if (READOUT_DOCS_ONLY)
13
+ # Documentation needs only the version string and Doxygen: skip dependency
14
+ # resolution and every compiled target so a bare runner can configure.
15
+ set(READOUT_USE_CONAN OFF)
16
+ set(READOUT_BUILD_TESTS OFF)
17
+ endif()
18
+
19
+ if (READOUT_USE_CONAN)
20
+ set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES "${CMAKE_CURRENT_LIST_DIR}/cmake/conan_provider.cmake")
21
+ endif()
22
+
23
+ # Read the version of readout (from the VERSION file and git metadata);
24
+ # generates version.hpp in ${CMAKE_BINARY_DIR}/gen
25
+ include(check)
26
+ checkSetup(READOUT)
27
+ message(STATUS "Build Readout v${READOUT_VERSION} with type ${CMAKE_BUILD_TYPE}")
28
+ project(Readout LANGUAGES C CXX VERSION "${READOUT_VERSION}")
29
+
30
+ set(CMAKE_C_STANDARD 17)
31
+ set(CMAKE_CXX_STANDARD 23)
32
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
33
+
34
+ include(GNUInstallDirs)
35
+
36
+ # The build tree mirrors the install layout (bin/, lib/, include/, share/Readout)
37
+ # so that the self-locating readout-config resolves the same baked relative paths
38
+ # whether it runs from the build tree or an installed prefix. Multi-config
39
+ # generators (Visual Studio) would otherwise add per-config subdirectories
40
+ # (bin/Debug/...), breaking those relative paths — collapse them: one
41
+ # configuration per build tree.
42
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
43
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
44
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
45
+ foreach(READOUT_CFG IN ITEMS Debug Release RelWithDebInfo MinSizeRel)
46
+ string(TOUPPER "${READOUT_CFG}" READOUT_CFG_UP)
47
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${READOUT_CFG_UP} "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
48
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${READOUT_CFG_UP} "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
49
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${READOUT_CFG_UP} "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
50
+ endforeach()
51
+
52
+ add_definitions(-DUSE_HIGHFIVE)
53
+ if (MSVC)
54
+ # warning level 4 -- add /WX for all warnings as errors
55
+ add_compile_options(/W4)
56
+ # suppress MSVC warning C4996 about 'localtime' vs 'localtime_s'
57
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
58
+ # Allow UTF-8 identifiers https://stackoverflow.com/a/47704050
59
+ add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
60
+ add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
61
+ # Prevent Windows.h from defining its own min and max macros
62
+ add_definitions(-DNOMINMAX)
63
+ elseif(APPLE)
64
+ add_compile_options(-Wall -Wextra -pedantic)
65
+ if (READOUT_BUILD_ON_CONDA)
66
+ # Enable use of, e.g. std::filesystem::path on macOS under Conda:
67
+ # https://conda-forge.org/docs/maintainer/knowledge_base/#newer-c-features-with-old-sdk
68
+ add_definitions(-D_LIBCPP_DISABLE_AVAILABILITY)
69
+ endif()
70
+ else()
71
+ add_compile_options(-Wall -Wextra -pedantic)
72
+ endif()
73
+
74
+ if(NOT CMAKE_BUILD_TYPE)
75
+ set(CMAKE_BUILD_TYPE Debug)
76
+ endif(NOT CMAKE_BUILD_TYPE)
77
+ if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
78
+ add_definitions(-DDEBUG)
79
+ endif()
80
+
81
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
82
+ # With GCC 10+ the interprocedural optimization only adds to compilation time without improving performance
83
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
84
+
85
+ if (READOUT_BUILD_TESTS)
86
+ include(CTest)
87
+ endif()
88
+
89
+ if (NOT READOUT_DOCS_ONLY)
90
+ # The library, CLI tools, McStas components, and install rules:
91
+ add_subdirectory(readout_core)
92
+
93
+ # The test suite lives at the repository root (mcpl-style): it exercises the
94
+ # readout_core targets but is not part of any installed package.
95
+ if (READOUT_BUILD_TESTS)
96
+ add_subdirectory(test)
97
+ endif()
98
+ endif()
99
+
100
+ find_package(Doxygen QUIET)
101
+ if (DOXYGEN_FOUND)
102
+ find_package(Python3 COMPONENTS Interpreter REQUIRED)
103
+ configure_file(
104
+ "${CMAKE_CURRENT_LIST_DIR}/docs/Doxyfile.in"
105
+ "${CMAKE_BINARY_DIR}/Doxyfile"
106
+ @ONLY
107
+ )
108
+ add_custom_target(docs
109
+ COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/docs/extract_comp_docs.py"
110
+ "${CMAKE_CURRENT_LIST_DIR}/readout_core/components"
111
+ "${CMAKE_BINARY_DIR}/docs/generated"
112
+ COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile"
113
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
114
+ COMMENT "Generating static HTML documentation with Doxygen"
115
+ VERBATIM
116
+ )
117
+ else()
118
+ message(STATUS "Doxygen not found: docs target will not be available")
119
+ endif()
@@ -0,0 +1,73 @@
1
+ # Development guide
2
+
3
+ ## Layout
4
+
5
+ The repository follows the mcpl pattern (see layout_plan.md): everything that
6
+ installs lives in `readout_core/` — library sources in `src/`, public headers
7
+ in `include/`, the CLI tools in `app_config`/`app_replay`/`app_combine`, the
8
+ McStas components in `components/` — while the root CMakeLists.txt only wires
9
+ up toolchain options and the repo-level test suite in `test/` and `tests/`.
10
+
11
+ ## Building
12
+
13
+ ```bash
14
+ cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
15
+ cmake --build build -j
16
+ ```
17
+
18
+ Dependencies (HighFive, HDF5, nlohmann_json, Catch2) come through Conan by
19
+ default (`READOUT_USE_CONAN=ON`); pass `-DREADOUT_USE_CONAN=OFF` to use system
20
+ packages instead.
21
+
22
+ There are no build modes: **the build tree mirrors the install layout**
23
+ (`bin/`, `lib/`, `include/`, `share/Readout/`), and `readout-config` resolves
24
+ every resource path relative to its own binary through one set of baked
25
+ relative paths. The same binary therefore works unchanged from the build tree,
26
+ an installed prefix, or (later) a wheel — and the build tree is directly
27
+ usable by mccode-antlr:
28
+
29
+ ```bash
30
+ $ build/bin/readout-config --show compdir
31
+ /home/user/project/build/share/Readout
32
+ ```
33
+
34
+ This replaces the former `READOUT_DEVELOPMENT_MODE` option and the
35
+ `run_tests.sh` wrapper, which existed to work around PATH-inheritance problems
36
+ when McStas tools spawned `readout-config`; putting `build/bin` on PATH is all
37
+ that is needed now.
38
+
39
+ ## Testing
40
+
41
+ ```bash
42
+ cd build && ctest # C++ unit tests + CLI smoke + integration
43
+ python3 -m pytest tests/ # mccode-antlr compile/run tests
44
+ ```
45
+
46
+ ## Documentation
47
+
48
+ Install Doxygen, then generate the static HTML site locally. Use a dedicated
49
+ build directory with `READOUT_DOCS_ONLY=ON` — it skips conan and every
50
+ compiled target, so it configures anywhere without touching your development
51
+ build directories:
52
+
53
+ ```bash
54
+ cmake -S . -B build-docs -DREADOUT_DOCS_ONLY=ON
55
+ cmake --build build-docs --target docs
56
+ ```
57
+
58
+ The generated site is written to `build-docs/docs/html/`. The `docs` target
59
+ first runs `docs/extract_comp_docs.py`, which turns the McDoc headers
60
+ (`%I`/`%D`/`%P` sections) of `readout_core/components/*.comp` into markdown
61
+ pages — keep those headers up to date when changing component parameters.
62
+ The same headers make the components readable with McStas's `mcdoc`. The site
63
+ is published by `.github/workflows/docs.yml` on pushes to `main` (GitHub Pages
64
+ must be set to deploy from GitHub Actions in the repository settings).
65
+
66
+ The pytest suite discovers a build directory by looking for
67
+ `<dir>/bin/readout-config` in `build-dev`, `build`, `cmake-build-debug`,
68
+ `cmake-build-release` (in that order — rebuild every directory you keep, or
69
+ remove the stale ones, before trusting pytest results). The ctest
70
+ `integration` test skips (exit 100) when `mcstas-antlr` is not installed.
71
+
72
+ After editing a `.comp` file, delete any stale `*.comp.json` caches next to it
73
+ and the `~/.cache/mccodeantlr` directory so mccode-antlr re-parses.
@@ -0,0 +1,11 @@
1
+ Copyright 2025 Gregory Tucker, European Spallation Source ERIC
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.