simind-python-connector 1.1.1__tar.gz → 1.1.2__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 (165) hide show
  1. simind_python_connector-1.1.2/.dockerignore +17 -0
  2. simind_python_connector-1.1.2/MANIFEST.in +24 -0
  3. {simind_python_connector-1.1.1/simind_python_connector.egg-info → simind_python_connector-1.1.2}/PKG-INFO +27 -12
  4. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/README.md +24 -8
  5. simind_python_connector-1.1.2/docker/README.md +92 -0
  6. simind_python_connector-1.1.2/docker/compose.yaml +72 -0
  7. simind_python_connector-1.1.2/docker/constraints.txt +6 -0
  8. simind_python_connector-1.1.2/docker/import_guard/sitecustomize.py +52 -0
  9. simind_python_connector-1.1.2/docker/python/Dockerfile +39 -0
  10. simind_python_connector-1.1.2/docker/python/install_mpich_compat.sh +22 -0
  11. simind_python_connector-1.1.2/docker/pytomography/Dockerfile +34 -0
  12. simind_python_connector-1.1.2/docker/sirf/Dockerfile +31 -0
  13. simind_python_connector-1.1.2/docker/stir/Dockerfile +33 -0
  14. simind_python_connector-1.1.2/docs/_static/.gitkeep +0 -0
  15. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/backends.rst +2 -1
  16. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/changelog.rst +158 -0
  17. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/conf.py +1 -1
  18. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2/docs}/examples/01_basic_simulation.py +2 -1
  19. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2/docs}/examples/02_runtime_switch_comparison.py +4 -3
  20. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2/docs}/examples/03_multi_window.py +2 -1
  21. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2/docs}/examples/05_scattwin_vs_penetrate_comparison.py +2 -1
  22. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2/docs}/examples/07A_stir_adaptor_osem.py +9 -17
  23. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2/docs}/examples/07B_sirf_adaptor_osem.py +5 -13
  24. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples/07C_pytomography_adaptor_osem.py +9 -15
  25. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/geometry.rst +42 -6
  26. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/installation.rst +8 -1
  27. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/testing.rst +24 -22
  28. simind_python_connector-1.1.2/docs/usage.rst +243 -0
  29. {simind_python_connector-1.1.1/docs → simind_python_connector-1.1.2}/examples/01_basic_simulation.py +2 -1
  30. {simind_python_connector-1.1.1/docs → simind_python_connector-1.1.2}/examples/02_runtime_switch_comparison.py +4 -3
  31. {simind_python_connector-1.1.1/docs → simind_python_connector-1.1.2}/examples/03_multi_window.py +2 -1
  32. {simind_python_connector-1.1.1/docs → simind_python_connector-1.1.2}/examples/05_scattwin_vs_penetrate_comparison.py +2 -1
  33. {simind_python_connector-1.1.1/docs → simind_python_connector-1.1.2}/examples/07A_stir_adaptor_osem.py +9 -17
  34. {simind_python_connector-1.1.1/docs → simind_python_connector-1.1.2}/examples/07B_sirf_adaptor_osem.py +5 -13
  35. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/examples/07C_pytomography_adaptor_osem.py +9 -15
  36. simind_python_connector-1.1.2/examples/run_all_examples.sh +246 -0
  37. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/pyproject.toml +24 -4
  38. simind_python_connector-1.1.2/scripts/fix.sh +14 -0
  39. simind_python_connector-1.1.2/scripts/release.sh +119 -0
  40. simind_python_connector-1.1.2/scripts/run_all_examples.py +270 -0
  41. simind_python_connector-1.1.2/scripts/run_container_examples.sh +287 -0
  42. simind_python_connector-1.1.2/scripts/run_container_validation.sh +319 -0
  43. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/__init__.py +1 -1
  44. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/backends/__init__.py +4 -3
  45. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/backends/stir_backend.py +36 -17
  46. simind_python_connector-1.1.2/simind_python_connector/connectors/_spacing.py +199 -0
  47. simind_python_connector-1.1.2/simind_python_connector/connectors/python_connector.py +810 -0
  48. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/connectors/pytomography_adaptor.py +49 -7
  49. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/connectors/sirf_adaptor.py +54 -9
  50. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/connectors/stir_adaptor.py +54 -9
  51. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/converters/simind_to_stir.py +63 -31
  52. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/core/config.py +419 -108
  53. simind_python_connector-1.1.2/simind_python_connector/core/executor.py +374 -0
  54. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/core/types.py +21 -8
  55. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/data/__init__.py +5 -3
  56. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/__init__.py +3 -3
  57. simind_python_connector-1.1.2/simind_python_connector/utils/geometry_phantom.py +42 -0
  58. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/import_helpers.py +33 -5
  59. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/interfile_numpy.py +15 -1
  60. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/simind_utils.py +31 -1
  61. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2/simind_python_connector.egg-info}/PKG-INFO +27 -12
  62. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector.egg-info/SOURCES.txt +27 -11
  63. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector.egg-info/requires.txt +1 -1
  64. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/conftest.py +6 -34
  65. simind_python_connector-1.1.2/tests/fixtures/minimal_variable_sections.smc +36 -0
  66. simind_python_connector-1.1.2/tests/test_adaptor_release_simind.py +150 -0
  67. simind_python_connector-1.1.2/tests/test_anisotropic_voxels_simind.py +54 -0
  68. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_backends.py +60 -14
  69. simind_python_connector-1.1.2/tests/test_connector_backend_separation.py +201 -0
  70. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_container_library_isolation.py +8 -1
  71. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_container_scripts.py +0 -86
  72. simind_python_connector-1.1.2/tests/test_energy_window_filename_simind.py +34 -0
  73. simind_python_connector-1.1.2/tests/test_executor.py +570 -0
  74. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_interfile_numpy.py +32 -0
  75. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_native_adaptors.py +402 -74
  76. simind_python_connector-1.1.2/tests/test_native_geometry_real.py +54 -0
  77. simind_python_connector-1.1.2/tests/test_packaging_resources.py +109 -0
  78. simind_python_connector-1.1.2/tests/test_patch_release_simind.py +535 -0
  79. simind_python_connector-1.1.2/tests/test_python_connector.py +1449 -0
  80. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_pytomography_adaptor.py +96 -11
  81. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_simind_to_stir_converter.py +265 -9
  82. simind_python_connector-1.1.2/tests/test_simulation_config.py +562 -0
  83. simind_python_connector-1.1.2/tests/test_single_window_simind.py +84 -0
  84. simind_python_connector-1.1.2/tests/test_stir_backend_arithmetic.py +163 -0
  85. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_utils_small.py +37 -3
  86. simind_python_connector-1.1.1/MANIFEST.in +0 -13
  87. simind_python_connector-1.1.1/docs/usage.rst +0 -152
  88. simind_python_connector-1.1.1/requirements-dev.txt +0 -23
  89. simind_python_connector-1.1.1/requirements.txt +0 -10
  90. simind_python_connector-1.1.1/simind_python_connector/connectors/_spacing.py +0 -83
  91. simind_python_connector-1.1.1/simind_python_connector/connectors/python_connector.py +0 -480
  92. simind_python_connector-1.1.1/simind_python_connector/core/executor.py +0 -136
  93. simind_python_connector-1.1.1/tests/test_connector_backend_separation.py +0 -118
  94. simind_python_connector-1.1.1/tests/test_connectors_base.py +0 -27
  95. simind_python_connector-1.1.1/tests/test_example_config_profile.py +0 -66
  96. simind_python_connector-1.1.1/tests/test_examples_backend_separation.py +0 -74
  97. simind_python_connector-1.1.1/tests/test_executor.py +0 -246
  98. simind_python_connector-1.1.1/tests/test_geometry_isolation_forward_projection.py +0 -352
  99. simind_python_connector-1.1.1/tests/test_legacy_surface_policy.py +0 -20
  100. simind_python_connector-1.1.1/tests/test_marker_policy.py +0 -117
  101. simind_python_connector-1.1.1/tests/test_osem_geometry_diagnostics.py +0 -363
  102. simind_python_connector-1.1.1/tests/test_package_identity.py +0 -18
  103. simind_python_connector-1.1.1/tests/test_packaging_resources.py +0 -113
  104. simind_python_connector-1.1.1/tests/test_python_connector.py +0 -748
  105. simind_python_connector-1.1.1/tests/test_simulation_config.py +0 -221
  106. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/LICENSE +0 -0
  107. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/api.rst +0 -0
  108. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/connector_modernization_plan.rst +0 -0
  109. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/contributing.rst +0 -0
  110. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples/04_custom_config.py +0 -0
  111. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples/06_schneider_density_conversion.py +0 -0
  112. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples/08A_stir_adaptor_from_dicom.py +0 -0
  113. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples/08B_sirf_adaptor_from_dicom.py +0 -0
  114. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples/08C_pytomography_adaptor_from_dicom.py +0 -0
  115. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples/_python_connector_helpers.py +0 -0
  116. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/examples.rst +0 -0
  117. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/index.rst +0 -0
  118. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/docs/intro.rst +0 -0
  119. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/examples/04_custom_config.py +0 -0
  120. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/examples/06_schneider_density_conversion.py +0 -0
  121. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/examples/08A_stir_adaptor_from_dicom.py +0 -0
  122. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/examples/08B_sirf_adaptor_from_dicom.py +0 -0
  123. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/examples/08C_pytomography_adaptor_from_dicom.py +0 -0
  124. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/examples/_python_connector_helpers.py +0 -0
  125. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/setup.cfg +0 -0
  126. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/backends/base.py +0 -0
  127. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/backends/sirf_backend.py +0 -0
  128. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/builders/__init__.py +0 -0
  129. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/builders/acquisition_builder.py +0 -0
  130. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/builders/image_builder.py +0 -0
  131. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/configs/AnyScan.yaml +0 -0
  132. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/configs/Discovery670.yaml +0 -0
  133. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/configs/Example.yaml +0 -0
  134. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/configs/MLD001_SCAN0.yaml +0 -0
  135. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/configs/__init__.py +0 -0
  136. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/configs/input.smc +0 -0
  137. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/connectors/__init__.py +0 -0
  138. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/connectors/base.py +0 -0
  139. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/converters/__init__.py +0 -0
  140. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/converters/attenuation.py +0 -0
  141. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/converters/dicom_to_stir.py +0 -0
  142. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/core/__init__.py +0 -0
  143. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/data/Schneider2000.json +0 -0
  144. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/data/bone.atn +0 -0
  145. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/data/h2o.atn +0 -0
  146. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/backend_access.py +0 -0
  147. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/interfile_parser.py +0 -0
  148. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/io_utils.py +0 -0
  149. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/sirf_stir_utils.py +0 -0
  150. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector/utils/stir_utils.py +0 -0
  151. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector.egg-info/dependency_links.txt +0 -0
  152. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/simind_python_connector.egg-info/top_level.txt +0 -0
  153. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/__init__.py +0 -0
  154. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_acquisition_builder_unit.py +0 -0
  155. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_arithmetic_operations.py +0 -0
  156. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_attenuation_utils.py +0 -0
  157. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_dicom_builder.py +0 -0
  158. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_image_builder_unit.py +0 -0
  159. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_integration.py +0 -0
  160. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_interfile_parser.py +0 -0
  161. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_non_square_slices_simind.py +0 -0
  162. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_schneider_density.py +0 -0
  163. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_sirf_stir_utils.py +0 -0
  164. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_stir_utils_backend_choice_unit.py +0 -0
  165. {simind_python_connector-1.1.1 → simind_python_connector-1.1.2}/tests/test_utils.py +0 -0
@@ -0,0 +1,17 @@
1
+ .git
2
+ .venv
3
+ simind
4
+ dist
5
+ build
6
+ *.egg-info
7
+ *.tar.gz
8
+ .pytest_cache
9
+ .ruff_cache
10
+ .uv-cache
11
+ .uv-tools
12
+ .coverage
13
+ .coverage.*
14
+ coverage.xml
15
+ docs/_build
16
+ output
17
+ results
@@ -0,0 +1,24 @@
1
+ include README.md
2
+ include LICENSE
3
+ include .dockerignore
4
+ recursive-include simind_python_connector/data *.atn
5
+ recursive-include simind_python_connector/data *.json
6
+ recursive-include simind_python_connector/configs *.smc *.yaml
7
+ recursive-include docs *.rst *.py
8
+ include docs/_static/.gitkeep
9
+ recursive-include tests *.py
10
+ recursive-include tests/fixtures *.smc
11
+ recursive-include examples *.py *.sh
12
+ recursive-include scripts *.py *.sh
13
+ recursive-include docker Dockerfile *.md *.txt *.yaml *.yml *.py *.sh
14
+ exclude AGENTS.md
15
+ exclude opencode.jsonc
16
+ exclude CLAUDE.md
17
+ exclude simind_manual.pdf
18
+ prune simind
19
+ prune docs/superpowers
20
+ prune docs/_build
21
+ prune docs/_generated
22
+ global-exclude __pycache__
23
+ global-exclude *.py[co]
24
+ global-exclude .DS_Store
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simind-python-connector
3
- Version: 1.1.1
3
+ Version: 1.1.2
4
4
  Summary: Python SIMIND Monte Carlo connector with STIR/SIRF/PyTomography adaptors
5
5
  Author-email: Sam Porter <sam.porter.18@ucl.ac.uk>, Rebecca Gillen <rebecca.gillen.18@ucl.ac.uk>, "Efstathios (Stahis) Varzakis" <efstathios.varzakis.22@ucl.ac.uk>
6
6
  Maintainer-email: Sam Porter <sam.porter.18@ucl.ac.uk>
@@ -15,14 +15,13 @@ Classifier: Development Status :: 4 - Beta
15
15
  Classifier: Intended Audience :: Science/Research
16
16
  Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
17
17
  Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.9
19
18
  Classifier: Programming Language :: Python :: 3.10
20
19
  Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
22
- Requires-Python: >=3.9
21
+ Requires-Python: >=3.10
23
22
  Description-Content-Type: text/markdown
24
23
  License-File: LICENSE
25
- Requires-Dist: numpy>=1.20.0
24
+ Requires-Dist: numpy<2.0,>=1.20.0
26
25
  Requires-Dist: pydicom>=2.0.0
27
26
  Requires-Dist: pyyaml>=5.4.0
28
27
  Provides-Extra: dev
@@ -48,7 +47,7 @@ Python SIMIND Monte Carlo Connector.
48
47
  [![Tests](https://github.com/samdporter/simind-python-connector/workflows/Tests/badge.svg)](https://github.com/samdporter/simind-python-connector/actions)
49
48
  [![Documentation Status](https://readthedocs.org/projects/simind-python-connector/badge/?version=latest)](https://simind-python-connector.readthedocs.io/en/latest/?badge=latest)
50
49
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
51
- [![Python Version](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
50
+ [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
52
51
 
53
52
  A Python toolkit that lets you run SIMIND from Python and use the outputs in
54
53
  common reconstruction ecosystems (STIR, SIRF, PyTomography).
@@ -99,6 +98,12 @@ For example plotting dependencies:
99
98
  pip install "simind-python-connector[examples]"
100
99
  ```
101
100
 
101
+ **NumPy**: the package requires `numpy>=1.20.0,<2.0`. The `<2.0` cap is a
102
+ binary-ABI / backend-compatibility guard for the legacy 1.1.x line: the STIR
103
+ and SIRF bindings are compiled against NumPy 1.x and crash with NumPy 2, so the
104
+ cap applies package-wide. It is not a Python-version constraint; interpreter
105
+ support is stated separately as Python 3.10+.
106
+
102
107
  ### Adaptor Dependencies
103
108
 
104
109
  `SimindPythonConnector` works without SIRF/STIR/PyTomography.
@@ -116,7 +121,7 @@ Install from conda:
116
121
  conda install -c conda-forge stir "numpy<2.0"
117
122
  ```
118
123
 
119
- **Important**: As of November 2025, the STIR conda package (v6.3.0) requires NumPy < 2.0 due to binary compatibility issues with NumPy 2.x. The package was compiled against NumPy 1.x and will crash with memory errors if NumPy 2.x is installed. This should be resolved in future STIR releases.
124
+ **Important**: As of November 2025, the STIR conda package (v6.3.0) requires NumPy < 2.0 due to binary compatibility issues with NumPy 2.x. The package was compiled against NumPy 1.x and will crash with memory errors if NumPy 2.x is installed. This should be resolved in future STIR releases. Like the package-wide pin, this is a backend binary-ABI compatibility guard, not a Python-version constraint.
120
125
 
121
126
  Or build from source:
122
127
  ```bash
@@ -182,6 +187,7 @@ executable is available as `simind` on `PATH`.
182
187
  import numpy as np
183
188
  from simind_python_connector import SimindPythonConnector
184
189
  from simind_python_connector.configs import get
190
+ from simind_python_connector.core.types import DEFAULT_QUANTIZATION_SCALE
185
191
 
186
192
  source = np.zeros((32, 32, 32), dtype=np.float32) # z, y, x
187
193
  source[12:20, 12:20, 12:20] = 1.0
@@ -192,7 +198,7 @@ connector = SimindPythonConnector(
192
198
  config_source=get("Example.yaml"),
193
199
  output_dir="output/basic",
194
200
  output_prefix="case01",
195
- quantization_scale=0.05,
201
+ quantization_scale=0.05 * DEFAULT_QUANTIZATION_SCALE,
196
202
  )
197
203
 
198
204
  connector.configure_voxel_phantom(
@@ -247,11 +253,20 @@ For minimal toy runs with smaller projection/image settings, use
247
253
  `quantization_scale` controls source integer quantization before writing SIMIND
248
254
  `.smi` files:
249
255
 
250
- - `1.0`: uses full internal source integer range (best numeric precision)
251
- - `< 1.0`: reduces integer scale for faster toy runs but increases rounding error
252
-
253
- SIMIND treats source maps as integer weights; absolute activity/time scaling is
254
- controlled separately by simulation settings.
256
+ - the default (`500 / 32767`) preserves the legacy 500-weight source budget;
257
+ - `1.0` uses the full signed 16-bit source range (`32767`), the best numeric
258
+ precision;
259
+ - `< 1.0` reduces the integer scale for faster toy runs but increases rounding
260
+ error.
261
+
262
+ SIMIND reads the source and density maps as signed 16-bit integers, so values
263
+ of `32768` and above wrap negative and silently corrupt the map; the connector
264
+ caps both maps at `32767`. Explicit `quantization_scale` values are used as
265
+ given, with no automatic migration of scales calibrated for the former
266
+ 500-weight maximum: rescale an old scale with
267
+ `old_scale * DEFAULT_QUANTIZATION_SCALE`. SIMIND treats source maps as integer
268
+ weights; absolute activity/time scaling is controlled separately by simulation
269
+ settings.
255
270
 
256
271
  ## Docker Environments
257
272
 
@@ -5,7 +5,7 @@ Python SIMIND Monte Carlo Connector.
5
5
  [![Tests](https://github.com/samdporter/simind-python-connector/workflows/Tests/badge.svg)](https://github.com/samdporter/simind-python-connector/actions)
6
6
  [![Documentation Status](https://readthedocs.org/projects/simind-python-connector/badge/?version=latest)](https://simind-python-connector.readthedocs.io/en/latest/?badge=latest)
7
7
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
8
- [![Python Version](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
8
+ [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
9
9
 
10
10
  A Python toolkit that lets you run SIMIND from Python and use the outputs in
11
11
  common reconstruction ecosystems (STIR, SIRF, PyTomography).
@@ -56,6 +56,12 @@ For example plotting dependencies:
56
56
  pip install "simind-python-connector[examples]"
57
57
  ```
58
58
 
59
+ **NumPy**: the package requires `numpy>=1.20.0,<2.0`. The `<2.0` cap is a
60
+ binary-ABI / backend-compatibility guard for the legacy 1.1.x line: the STIR
61
+ and SIRF bindings are compiled against NumPy 1.x and crash with NumPy 2, so the
62
+ cap applies package-wide. It is not a Python-version constraint; interpreter
63
+ support is stated separately as Python 3.10+.
64
+
59
65
  ### Adaptor Dependencies
60
66
 
61
67
  `SimindPythonConnector` works without SIRF/STIR/PyTomography.
@@ -73,7 +79,7 @@ Install from conda:
73
79
  conda install -c conda-forge stir "numpy<2.0"
74
80
  ```
75
81
 
76
- **Important**: As of November 2025, the STIR conda package (v6.3.0) requires NumPy < 2.0 due to binary compatibility issues with NumPy 2.x. The package was compiled against NumPy 1.x and will crash with memory errors if NumPy 2.x is installed. This should be resolved in future STIR releases.
82
+ **Important**: As of November 2025, the STIR conda package (v6.3.0) requires NumPy < 2.0 due to binary compatibility issues with NumPy 2.x. The package was compiled against NumPy 1.x and will crash with memory errors if NumPy 2.x is installed. This should be resolved in future STIR releases. Like the package-wide pin, this is a backend binary-ABI compatibility guard, not a Python-version constraint.
77
83
 
78
84
  Or build from source:
79
85
  ```bash
@@ -139,6 +145,7 @@ executable is available as `simind` on `PATH`.
139
145
  import numpy as np
140
146
  from simind_python_connector import SimindPythonConnector
141
147
  from simind_python_connector.configs import get
148
+ from simind_python_connector.core.types import DEFAULT_QUANTIZATION_SCALE
142
149
 
143
150
  source = np.zeros((32, 32, 32), dtype=np.float32) # z, y, x
144
151
  source[12:20, 12:20, 12:20] = 1.0
@@ -149,7 +156,7 @@ connector = SimindPythonConnector(
149
156
  config_source=get("Example.yaml"),
150
157
  output_dir="output/basic",
151
158
  output_prefix="case01",
152
- quantization_scale=0.05,
159
+ quantization_scale=0.05 * DEFAULT_QUANTIZATION_SCALE,
153
160
  )
154
161
 
155
162
  connector.configure_voxel_phantom(
@@ -204,11 +211,20 @@ For minimal toy runs with smaller projection/image settings, use
204
211
  `quantization_scale` controls source integer quantization before writing SIMIND
205
212
  `.smi` files:
206
213
 
207
- - `1.0`: uses full internal source integer range (best numeric precision)
208
- - `< 1.0`: reduces integer scale for faster toy runs but increases rounding error
209
-
210
- SIMIND treats source maps as integer weights; absolute activity/time scaling is
211
- controlled separately by simulation settings.
214
+ - the default (`500 / 32767`) preserves the legacy 500-weight source budget;
215
+ - `1.0` uses the full signed 16-bit source range (`32767`), the best numeric
216
+ precision;
217
+ - `< 1.0` reduces the integer scale for faster toy runs but increases rounding
218
+ error.
219
+
220
+ SIMIND reads the source and density maps as signed 16-bit integers, so values
221
+ of `32768` and above wrap negative and silently corrupt the map; the connector
222
+ caps both maps at `32767`. Explicit `quantization_scale` values are used as
223
+ given, with no automatic migration of scales calibrated for the former
224
+ 500-weight maximum: rescale an old scale with
225
+ `old_scale * DEFAULT_QUANTIZATION_SCALE`. SIMIND treats source maps as integer
226
+ weights; absolute activity/time scaling is controlled separately by simulation
227
+ settings.
212
228
 
213
229
  ## Docker Environments
214
230
 
@@ -0,0 +1,92 @@
1
+ Docker Environments
2
+ ===================
3
+
4
+ This directory provides dedicated container setups for:
5
+
6
+ - Core Python workflows (no SIRF/STIR/PyTomography)
7
+ - STIR workflows
8
+ - SIRF workflows
9
+ - PyTomography workflows
10
+
11
+ Quick start
12
+ -----------
13
+
14
+ Build and run a specific environment:
15
+
16
+ ```bash
17
+ docker compose -f docker/compose.yaml build stir
18
+ docker compose -f docker/compose.yaml run --rm stir
19
+ ```
20
+
21
+ Run the dedicated connector + OSEM examples directly:
22
+
23
+ ```bash
24
+ docker compose -f docker/compose.yaml run --rm stir python examples/07A_stir_adaptor_osem.py
25
+ docker compose -f docker/compose.yaml run --rm sirf python examples/07B_sirf_adaptor_osem.py
26
+ docker compose -f docker/compose.yaml run --rm pytomography python examples/07C_pytomography_adaptor_osem.py
27
+ ```
28
+
29
+ Run the containerized test matrix:
30
+
31
+ ```bash
32
+ bash scripts/run_container_validation.sh
33
+ ```
34
+
35
+ Include SIMIND-dependent examples/integration tests:
36
+
37
+ ```bash
38
+ bash scripts/run_container_validation.sh --with-simind
39
+ ```
40
+
41
+ Run selected example groups:
42
+
43
+ ```bash
44
+ bash scripts/run_container_examples.sh --only-core
45
+ bash scripts/run_container_examples.sh --only-pytomography
46
+ bash scripts/run_container_examples.sh --only-osem
47
+ ```
48
+
49
+ Set a specific Docker platform when needed:
50
+
51
+ ```bash
52
+ bash scripts/run_container_examples.sh --only-core --docker-platform linux/amd64
53
+ bash scripts/run_container_validation.sh --with-simind --docker-platform linux/amd64
54
+ ```
55
+
56
+ Require SIMIND explicitly (fail fast if missing):
57
+
58
+ ```bash
59
+ bash scripts/run_container_examples.sh --only-osem --require-simind
60
+ bash scripts/run_container_validation.sh --with-simind --require-simind
61
+ ```
62
+
63
+ Services
64
+ --------
65
+
66
+ - `python`: Core Python image for non-backend examples/tests.
67
+ - `stir`: STIR-focused image (based on `synerbi/sirf`) with this repository installed.
68
+ - `sirf`: SIRF-focused image (based on `synerbi/sirf`) with this repository installed.
69
+ - `pytomography`: Python image with PyTomography + this repository installed.
70
+ - Each service enables an import guard so only its target library is importable
71
+ during tests/examples (`stir`, `sirf.STIR`, or `pytomography` respectively;
72
+ `python` blocks all three backend libraries).
73
+
74
+ Notes
75
+ -----
76
+
77
+ - The SIRF container build arg is `SIRF_BASE_IMAGE`.
78
+ - The STIR container build arg is `STIR_BASE_IMAGE`.
79
+ - Install SIMIND by following the official installation instructions on the SIMIND website.
80
+ - For quick local use with these containers, put SIMIND at `./simind` in this repo
81
+ so the executable is available as `./simind/simind`.
82
+ - SIMIND-dependent examples require the `simind` executable inside the container.
83
+ Runner scripts now auto-check `./simind/simind` and skip SIMIND-dependent checks
84
+ when missing (or fail fast if `--require-simind` is used).
85
+ - For mixed host/runtime architectures, the runner scripts auto-detect SIMIND
86
+ binary architecture (`x86_64`/`aarch64`) and set Docker platform automatically;
87
+ use `--docker-platform` to override.
88
+ - `input.smc` is bundled in `simind_python_connector/configs`; SIMIND runtime checks
89
+ only gate external executable availability.
90
+ - The toy adaptor examples use `simind_python_connector/configs/Example.yaml`,
91
+ a reduced projection-space profile derived from `AnyScan.yaml`.
92
+ - These images are intended to run examples and interactive exploration.
@@ -0,0 +1,72 @@
1
+ services:
2
+ python:
3
+ build:
4
+ context: ..
5
+ dockerfile: docker/python/Dockerfile
6
+ image: simind-python-connector/python:dev
7
+ working_dir: /workspace
8
+ environment:
9
+ SIMIND_CONNECTOR_BACKEND: python
10
+ SIMIND_ROOT: /workspace/simind
11
+ SIMIND_BIN: ${SIMIND_BIN:-/workspace/simind/simind}
12
+ SIMIND_MPI_BIN: ${SIMIND_MPI_BIN:-/workspace/simind/simind_mpi}
13
+ SIMIND_SMC_DIR: ${SIMIND_SMC_DIR:-/workspace/simind/smc_dir/}
14
+ SIMIND_DATA_DIR: /workspace/simind/smc_dir/
15
+ SMC_DIR: /workspace/simind/smc_dir/
16
+ volumes:
17
+ - ..:/workspace
18
+ command: python examples/06_schneider_density_conversion.py
19
+
20
+ stir:
21
+ build:
22
+ context: ..
23
+ dockerfile: docker/stir/Dockerfile
24
+ image: simind-python-connector/stir:dev
25
+ working_dir: /workspace
26
+ environment:
27
+ SIMIND_CONNECTOR_BACKEND: stir
28
+ SIMIND_ROOT: /workspace/simind
29
+ SIMIND_BIN: ${SIMIND_BIN:-/workspace/simind/simind}
30
+ SIMIND_MPI_BIN: ${SIMIND_MPI_BIN:-/workspace/simind/simind_mpi}
31
+ SIMIND_SMC_DIR: ${SIMIND_SMC_DIR:-/workspace/simind/smc_dir/}
32
+ SIMIND_DATA_DIR: /workspace/simind/smc_dir/
33
+ SMC_DIR: /workspace/simind/smc_dir/
34
+ volumes:
35
+ - ..:/workspace
36
+ command: python examples/07A_stir_adaptor_osem.py
37
+
38
+ sirf:
39
+ build:
40
+ context: ..
41
+ dockerfile: docker/sirf/Dockerfile
42
+ image: simind-python-connector/sirf:dev
43
+ working_dir: /workspace
44
+ environment:
45
+ SIMIND_CONNECTOR_BACKEND: sirf
46
+ SIMIND_ROOT: /workspace/simind
47
+ SIMIND_BIN: ${SIMIND_BIN:-/workspace/simind/simind}
48
+ SIMIND_MPI_BIN: ${SIMIND_MPI_BIN:-/workspace/simind/simind_mpi}
49
+ SIMIND_SMC_DIR: ${SIMIND_SMC_DIR:-/workspace/simind/smc_dir/}
50
+ SIMIND_DATA_DIR: /workspace/simind/smc_dir/
51
+ SMC_DIR: /workspace/simind/smc_dir/
52
+ volumes:
53
+ - ..:/workspace
54
+ command: python examples/07B_sirf_adaptor_osem.py
55
+
56
+ pytomography:
57
+ build:
58
+ context: ..
59
+ dockerfile: docker/pytomography/Dockerfile
60
+ image: simind-python-connector/pytomography:dev
61
+ working_dir: /workspace
62
+ environment:
63
+ SIMIND_CONNECTOR_BACKEND: pytomography
64
+ SIMIND_ROOT: /workspace/simind
65
+ SIMIND_BIN: ${SIMIND_BIN:-/workspace/simind/simind}
66
+ SIMIND_MPI_BIN: ${SIMIND_MPI_BIN:-/workspace/simind/simind_mpi}
67
+ SIMIND_SMC_DIR: ${SIMIND_SMC_DIR:-/workspace/simind/smc_dir/}
68
+ SIMIND_DATA_DIR: /workspace/simind/smc_dir/
69
+ SMC_DIR: /workspace/simind/smc_dir/
70
+ volumes:
71
+ - ..:/workspace
72
+ command: python examples/07C_pytomography_adaptor_osem.py
@@ -0,0 +1,6 @@
1
+ # Version constraints shared by backend Dockerfiles.
2
+ # NumPy is capped below 2.x: the STIR/SIRF binaries in the synerbi/sirf base
3
+ # images are compiled against NumPy 1.x and crash with NumPy 2 (see README
4
+ # "NumPy ABI" notes).
5
+ numpy<2.0
6
+ pytest==8.4.2
@@ -0,0 +1,52 @@
1
+ """
2
+ Import guard used by backend-isolated Docker environments.
3
+
4
+ Set SIMIND_PYTHON_CONNECTOR_BLOCK_IMPORTS to a comma-separated list of top-level module
5
+ names. Any import matching one of those module roots will raise ImportError.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import builtins
11
+ import importlib.abc
12
+ import os
13
+ import sys
14
+
15
+
16
+ BLOCKED_IMPORTS = {
17
+ entry.strip()
18
+ for entry in os.environ.get("SIMIND_PYTHON_CONNECTOR_BLOCK_IMPORTS", "").split(",")
19
+ if entry.strip()
20
+ }
21
+
22
+ if BLOCKED_IMPORTS:
23
+ _ORIGINAL_IMPORT = builtins.__import__
24
+
25
+ class _BlockedModuleFinder(importlib.abc.MetaPathFinder):
26
+ """Prevent loading blocked module roots through all import paths."""
27
+
28
+ def find_spec(self, fullname, path=None, target=None):
29
+ root = fullname.split(".", 1)[0]
30
+ if root in BLOCKED_IMPORTS:
31
+ raise ModuleNotFoundError(
32
+ f"Module '{root}' is blocked in this backend-isolated container.",
33
+ name=root,
34
+ )
35
+ return None
36
+
37
+ for module_name in list(sys.modules):
38
+ if module_name.split(".", 1)[0] in BLOCKED_IMPORTS:
39
+ del sys.modules[module_name]
40
+
41
+ sys.meta_path.insert(0, _BlockedModuleFinder())
42
+
43
+ def _guarded_import(name, globals=None, locals=None, fromlist=(), level=0):
44
+ root = name.split(".", 1)[0]
45
+ if root in BLOCKED_IMPORTS:
46
+ raise ModuleNotFoundError(
47
+ f"Module '{root}' is blocked in this backend-isolated container.",
48
+ name=root,
49
+ )
50
+ return _ORIGINAL_IMPORT(name, globals, locals, fromlist, level)
51
+
52
+ builtins.__import__ = _guarded_import
@@ -0,0 +1,39 @@
1
+ ARG PYTHON_BASE_IMAGE=python:3.12-slim
2
+ FROM ${PYTHON_BASE_IMAGE}
3
+
4
+ ENV PYTHONDONTWRITEBYTECODE=1
5
+ ENV PYTHONUNBUFFERED=1
6
+ ENV SIMIND_ROOT=/workspace/simind
7
+ ENV SIMIND_BIN=${SIMIND_ROOT}/simind
8
+ ENV SIMIND_MPI_BIN=${SIMIND_ROOT}/simind_mpi
9
+ ENV SIMIND_SMC_DIR=${SIMIND_ROOT}/smc_dir/
10
+ ENV SIMIND_DATA_DIR=${SIMIND_ROOT}/smc_dir/
11
+ ENV SMC_DIR=${SIMIND_ROOT}/smc_dir/
12
+ ENV SIMIND_PYTHON_CONNECTOR_BLOCK_IMPORTS=sirf,stir,stirextra,pytomography
13
+ ENV PYTHONPATH=/workspace/docker/import_guard:${PYTHONPATH}
14
+ ENV PATH=${SIMIND_ROOT}/bin:${SIMIND_ROOT}:${PATH}
15
+
16
+ # MPICH runtime for SIMIND's MPI binary; the compat script exposes the library
17
+ # names that binary was built against. See docker/python/install_mpich_compat.sh.
18
+ RUN apt-get update \
19
+ && apt-get install -y --no-install-recommends mpich \
20
+ && rm -rf /var/lib/apt/lists/*
21
+
22
+ COPY docker/python/install_mpich_compat.sh /usr/local/bin/install_mpich_compat.sh
23
+ RUN chmod +x /usr/local/bin/install_mpich_compat.sh \
24
+ && install_mpich_compat.sh
25
+
26
+ WORKDIR /workspace
27
+
28
+ COPY . /workspace
29
+
30
+ RUN python -m pip install --upgrade pip \
31
+ && pip install --constraint /workspace/docker/constraints.txt -e ".[dev,examples]" \
32
+ && python - <<'PY'
33
+ import importlib
34
+ for module in ("numpy", "matplotlib", "pytest"):
35
+ importlib.import_module(module)
36
+ print("Core Python modules available")
37
+ PY
38
+
39
+ CMD ["python", "examples/06_schneider_density_conversion.py"]
@@ -0,0 +1,22 @@
1
+ #!/bin/sh
2
+ # SIMIND's Linux binary links against the historical MPICH names
3
+ # libmpi.so.12 / libmpifort.so.12. Debian's mpich package ships
4
+ # libmpich.so.12 / libmpichfort.so.12; expose the expected names when the
5
+ # loader cannot find them.
6
+ set -eu
7
+
8
+ multiarch="$(python3 -c 'import sysconfig; print(sysconfig.get_config_var("MULTIARCH"))')"
9
+ libdir="/usr/lib/${multiarch}"
10
+
11
+ link_if_missing() {
12
+ target="$1"
13
+ link_name="$2"
14
+ if [ ! -e "${libdir}/${link_name}" ] && [ -e "${libdir}/${target}" ]; then
15
+ ln -s "${target}" "${libdir}/${link_name}"
16
+ fi
17
+ }
18
+
19
+ link_if_missing libmpich.so.12 libmpi.so.12
20
+ link_if_missing libmpichfort.so.12 libmpifort.so.12
21
+
22
+ ldconfig
@@ -0,0 +1,34 @@
1
+ ARG PYTOMO_BASE_IMAGE=synerbi/sirf:latest
2
+ FROM ${PYTOMO_BASE_IMAGE}
3
+
4
+ ENV PYTHONDONTWRITEBYTECODE=1
5
+ ENV PYTHONUNBUFFERED=1
6
+ ENV SIRF_INSTALL_PATH=/opt/SIRF-SuperBuild/INSTALL
7
+ ENV SIMIND_ROOT=/workspace/simind
8
+ ENV SIMIND_BIN=${SIMIND_ROOT}/simind
9
+ ENV SIMIND_MPI_BIN=${SIMIND_ROOT}/simind_mpi
10
+ ENV SIMIND_SMC_DIR=${SIMIND_ROOT}/smc_dir/
11
+ ENV SIMIND_DATA_DIR=${SIMIND_ROOT}/smc_dir/
12
+ ENV SMC_DIR=${SIMIND_ROOT}/smc_dir/
13
+ ENV SIMIND_PYTHON_CONNECTOR_BLOCK_IMPORTS=sirf,stir,stirextra
14
+ ENV PYTHONPATH=/workspace/docker/import_guard:${SIRF_INSTALL_PATH}/python
15
+ ENV LD_LIBRARY_PATH=/opt/conda/lib:${SIRF_INSTALL_PATH}/lib:${SIRF_INSTALL_PATH}/lib64:${LD_LIBRARY_PATH}
16
+ ENV PATH=${SIMIND_ROOT}/bin:${SIMIND_ROOT}:${SIRF_INSTALL_PATH}/bin:${PATH}
17
+
18
+ WORKDIR /workspace
19
+
20
+ COPY --chown=1000:100 . /workspace
21
+
22
+ RUN python -m pip install --upgrade pip \
23
+ && pip install --index-url https://download.pytorch.org/whl/cpu torch \
24
+ && pip install pytomography --no-deps \
25
+ && pip install fft-conv-pytorch kornia pydicom rt-utils torchrbf uproot \
26
+ && pip install --constraint /workspace/docker/constraints.txt -e ".[dev,examples]" \
27
+ && python - <<'PY'
28
+ import importlib
29
+ for module in ("torch", "pytomography", "pytest"):
30
+ importlib.import_module(module)
31
+ print("PyTomography modules available")
32
+ PY
33
+
34
+ CMD ["python", "examples/07C_pytomography_adaptor_osem.py"]
@@ -0,0 +1,31 @@
1
+ ARG SIRF_BASE_IMAGE=synerbi/sirf:latest
2
+ FROM ${SIRF_BASE_IMAGE}
3
+
4
+ ENV PYTHONDONTWRITEBYTECODE=1
5
+ ENV PYTHONUNBUFFERED=1
6
+ ENV SIRF_INSTALL_PATH=/opt/SIRF-SuperBuild/INSTALL
7
+ ENV SIMIND_ROOT=/workspace/simind
8
+ ENV SIMIND_BIN=${SIMIND_ROOT}/simind
9
+ ENV SIMIND_MPI_BIN=${SIMIND_ROOT}/simind_mpi
10
+ ENV SIMIND_SMC_DIR=${SIMIND_ROOT}/smc_dir/
11
+ ENV SIMIND_DATA_DIR=${SIMIND_ROOT}/smc_dir/
12
+ ENV SMC_DIR=${SIMIND_ROOT}/smc_dir/
13
+ ENV SIMIND_PYTHON_CONNECTOR_BLOCK_IMPORTS=stir,stirextra,pytomography
14
+ ENV PYTHONPATH=/workspace/docker/import_guard:${SIRF_INSTALL_PATH}/python:${PYTHONPATH}
15
+ ENV LD_LIBRARY_PATH=/opt/conda/lib:${SIRF_INSTALL_PATH}/lib:${SIRF_INSTALL_PATH}/lib64:${LD_LIBRARY_PATH}
16
+ ENV PATH=${SIMIND_ROOT}/bin:${SIMIND_ROOT}:${SIRF_INSTALL_PATH}/bin:${PATH}
17
+
18
+ WORKDIR /workspace
19
+
20
+ COPY --chown=1000:100 . /workspace
21
+
22
+ RUN python -m pip install --upgrade pip \
23
+ && pip install --constraint /workspace/docker/constraints.txt -e ".[dev,examples]" \
24
+ && python - <<'PY'
25
+ import importlib
26
+ for module in ("sirf.STIR", "pytest"):
27
+ importlib.import_module(module)
28
+ print("SIRF Python modules available")
29
+ PY
30
+
31
+ CMD ["python", "examples/07B_sirf_adaptor_osem.py"]
@@ -0,0 +1,33 @@
1
+ ARG STIR_BASE_IMAGE=synerbi/sirf:latest
2
+ FROM ${STIR_BASE_IMAGE}
3
+
4
+ ENV PYTHONDONTWRITEBYTECODE=1
5
+ ENV PYTHONUNBUFFERED=1
6
+ ENV SIRF_INSTALL_PATH=/opt/SIRF-SuperBuild/INSTALL
7
+ ENV SIMIND_ROOT=/workspace/simind
8
+ ENV SIMIND_BIN=${SIMIND_ROOT}/simind
9
+ ENV SIMIND_MPI_BIN=${SIMIND_ROOT}/simind_mpi
10
+ ENV SIMIND_SMC_DIR=${SIMIND_ROOT}/smc_dir/
11
+ ENV SIMIND_DATA_DIR=${SIMIND_ROOT}/smc_dir/
12
+ ENV SMC_DIR=${SIMIND_ROOT}/smc_dir/
13
+ ENV SIMIND_PYTHON_CONNECTOR_BLOCK_IMPORTS=sirf,pytomography
14
+ ENV PYTHONPATH=/workspace/docker/import_guard:${SIRF_INSTALL_PATH}/python:${PYTHONPATH}
15
+ ENV LD_LIBRARY_PATH=/opt/conda/lib:${SIRF_INSTALL_PATH}/lib:${SIRF_INSTALL_PATH}/lib64:${LD_LIBRARY_PATH}
16
+ ENV PATH=${SIMIND_ROOT}/bin:${SIMIND_ROOT}:${SIRF_INSTALL_PATH}/bin:${PATH}
17
+
18
+ WORKDIR /workspace
19
+
20
+ COPY --chown=1000:100 . /workspace
21
+
22
+ RUN python -m pip install --upgrade pip \
23
+ && pip install --constraint /workspace/docker/constraints.txt -e ".[dev,examples]" \
24
+ && python - <<'PY'
25
+ import stir # noqa: F401
26
+ import pytest # noqa: F401
27
+ from simind_python_connector.utils.import_helpers import _import_stir_extra
28
+
29
+ _import_stir_extra()
30
+ print("STIR Python modules available")
31
+ PY
32
+
33
+ CMD ["python", "examples/07A_stir_adaptor_osem.py"]
File without changes
@@ -16,7 +16,8 @@ Dependency Matrix
16
16
  * - ``SimindPythonConnector``
17
17
  - SIMIND executable on ``PATH`` (no SIRF/STIR/PyTomography requirement)
18
18
  * - ``StirSimindAdaptor``
19
- - STIR Python (``stir`` and ``stirextra``)
19
+ - STIR Python (``stir`` plus ``stir.extra``, with the legacy ``stirextra``
20
+ module as a fallback)
20
21
  * - ``SirfSimindAdaptor``
21
22
  - SIRF (``sirf.STIR``)
22
23
  * - ``PyTomographySimindAdaptor``