NeuNorm 2.0.0__tar.gz → 2.2.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 (244) hide show
  1. {neunorm-2.0.0 → neunorm-2.2.0}/.claude/skills/release/SKILL.md +2 -2
  2. neunorm-2.2.0/.claude/skills/review-pipeline/SKILL.md +155 -0
  3. neunorm-2.2.0/.claude/workflows/dual-family-review.js +560 -0
  4. {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/codeql.yml +4 -1
  5. {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/dependency-scan.yml +12 -7
  6. {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/test_and_deploy.yaml +29 -18
  7. {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/update-lockfiles.yml +3 -3
  8. neunorm-2.2.0/.grype.yaml +30 -0
  9. {neunorm-2.0.0 → neunorm-2.2.0}/.pre-commit-config.yaml +1 -1
  10. neunorm-2.2.0/.zenodo.json +42 -0
  11. {neunorm-2.0.0 → neunorm-2.2.0}/AGENTS.md +3 -2
  12. neunorm-2.2.0/CHANGELOG.md +176 -0
  13. neunorm-2.2.0/CITATION.cff +43 -0
  14. {neunorm-2.0.0 → neunorm-2.2.0}/PKG-INFO +12 -9
  15. {neunorm-2.0.0 → neunorm-2.2.0}/README.md +11 -8
  16. neunorm-2.2.0/codecov.yaml +8 -0
  17. {neunorm-2.0.0 → neunorm-2.2.0}/docs/api.rst +3 -0
  18. {neunorm-2.0.0 → neunorm-2.2.0}/docs/development/DEVELOPMENT_PLAN.md +4 -4
  19. {neunorm-2.0.0 → neunorm-2.2.0}/docs/index.md +1 -1
  20. {neunorm-2.0.0 → neunorm-2.2.0}/docs/migration.md +11 -7
  21. {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/README.md +7 -8
  22. {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/mars_ccd_cmos.md +27 -18
  23. {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/mars_tpx3.md +26 -23
  24. {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/venus_ccd_cmos.md +32 -25
  25. {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/venus_tpx1.md +57 -62
  26. {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/venus_tpx3.md +56 -65
  27. {neunorm-2.0.0 → neunorm-2.2.0}/pixi.lock +16 -235
  28. {neunorm-2.0.0 → neunorm-2.2.0}/pyproject.toml +3 -6
  29. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/__init__.py +1 -0
  30. neunorm-2.2.0/src/neunorm/_version.py +1 -0
  31. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/data_models/__init__.py +2 -1
  32. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/data_models/core.py +37 -1
  33. neunorm-2.2.0/src/neunorm/data_models/roi.py +84 -0
  34. neunorm-2.2.0/src/neunorm/exporters/hdf5_writer.py +190 -0
  35. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/exporters/tiff_writer.py +2 -1
  36. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/event_loader.py +10 -6
  37. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/fits_loader.py +9 -3
  38. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/tiff_loader.py +7 -2
  39. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/mars_ccd.py +78 -30
  40. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/mars_tpx3.py +20 -4
  41. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_ccd.py +104 -37
  42. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_tpx1.py +27 -13
  43. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_tpx3_event.py +37 -19
  44. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_tpx3_histogram.py +27 -13
  45. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/air_region_corrector.py +7 -5
  46. neunorm-2.2.0/src/neunorm/processing/normalizer.py +421 -0
  47. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/roi_clipper.py +8 -3
  48. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/run_combiner.py +6 -2
  49. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/uncertainty_calculator.py +6 -6
  50. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/binning.py +62 -29
  51. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/coordinate_converter.py +27 -0
  52. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/event_converter.py +8 -2
  53. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/histogram_rebinner.py +7 -3
  54. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/pulse_reconstruction.py +66 -10
  55. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/resonance.py +1 -1
  56. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_binning_conversions.py +132 -0
  57. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_event_loader.py +63 -0
  58. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_fits_loader.py +4 -0
  59. neunorm-2.2.0/tests/unit/test_hdf5_writer.py +520 -0
  60. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_mars_ccd.py +238 -13
  61. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_mars_tpx3.py +28 -3
  62. neunorm-2.2.0/tests/unit/test_normalizer.py +586 -0
  63. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_pulse_reconstruction.py +24 -0
  64. neunorm-2.2.0/tests/unit/test_roi.py +125 -0
  65. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_run_combiner.py +8 -2
  66. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_tiff_loader.py +4 -0
  67. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_venus_ccd.py +193 -13
  68. neunorm-2.0.0/CHANGELOG.md +0 -79
  69. neunorm-2.0.0/src/neunorm/_version.py +0 -1
  70. neunorm-2.0.0/src/neunorm/exporters/hdf5_writer.py +0 -123
  71. neunorm-2.0.0/src/neunorm/processing/normalizer.py +0 -134
  72. neunorm-2.0.0/tests/unit/test_hdf5_writer.py +0 -293
  73. neunorm-2.0.0/tests/unit/test_normalizer.py +0 -178
  74. {neunorm-2.0.0 → neunorm-2.2.0}/.claude/agents/bug-hunter.md +0 -0
  75. {neunorm-2.0.0 → neunorm-2.2.0}/.claude/skills/bughunt/SKILL.md +0 -0
  76. {neunorm-2.0.0 → neunorm-2.2.0}/.claude/skills/post-merge/SKILL.md +0 -0
  77. {neunorm-2.0.0 → neunorm-2.2.0}/.claude/workflows/bughunt-deep.js +0 -0
  78. {neunorm-2.0.0 → neunorm-2.2.0}/.gitattributes +0 -0
  79. {neunorm-2.0.0 → neunorm-2.2.0}/.github/CODEOWNERS +0 -0
  80. {neunorm-2.0.0 → neunorm-2.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  81. {neunorm-2.0.0 → neunorm-2.2.0}/.github/dependabot.yml +0 -0
  82. {neunorm-2.0.0 → neunorm-2.2.0}/.github/release.yml +0 -0
  83. {neunorm-2.0.0 → neunorm-2.2.0}/.gitignore +0 -0
  84. {neunorm-2.0.0 → neunorm-2.2.0}/.readthedocs.yaml +0 -0
  85. {neunorm-2.0.0 → neunorm-2.2.0}/CLAUDE.md +0 -0
  86. {neunorm-2.0.0 → neunorm-2.2.0}/CONTRIBUTING.md +0 -0
  87. {neunorm-2.0.0 → neunorm-2.2.0}/LICENSE +0 -0
  88. {neunorm-2.0.0 → neunorm-2.2.0}/SECURITY.md +0 -0
  89. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/__init__.py +0 -0
  90. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/_utilities.py +0 -0
  91. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/exporter.py +0 -0
  92. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/loader.py +0 -0
  93. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/normalization.py +0 -0
  94. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/roi.py +0 -0
  95. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/README.md +0 -0
  96. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/conda.recipe/meta.yaml +0 -0
  97. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/df/DC0000.tif +0 -0
  98. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/df/DC0001.tif +0 -0
  99. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/df/DC0002.tif +0 -0
  100. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0001.tif +0 -0
  101. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0002.tif +0 -0
  102. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0003.tif +0 -0
  103. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0004.tif +0 -0
  104. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0005.tif +0 -0
  105. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0006.tif +0 -0
  106. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0007.tif +0 -0
  107. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0008.tif +0 -0
  108. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0009.tif +0 -0
  109. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0010.tif +0 -0
  110. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0011.tif +0 -0
  111. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0012.tif +0 -0
  112. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0013.tif +0 -0
  113. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0014.tif +0 -0
  114. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0015.tif +0 -0
  115. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0002.tif +0 -0
  116. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0003.tif +0 -0
  117. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0004.tif +0 -0
  118. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0005.tif +0 -0
  119. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0006.tif +0 -0
  120. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0007.tif +0 -0
  121. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0008.tif +0 -0
  122. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0009.tif +0 -0
  123. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0010.tif +0 -0
  124. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0011.tif +0 -0
  125. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0012.tif +0 -0
  126. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0013.tif +0 -0
  127. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0014.tif +0 -0
  128. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0015.tif +0 -0
  129. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/Makefile +0 -0
  130. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/readthedocs-environment.yml +0 -0
  131. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/normalization_equation.png +0 -0
  132. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/normalization_principle.png +0 -0
  133. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/progress_bar_loading.png +0 -0
  134. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/progress_bar_normalization.png +0 -0
  135. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/conf.py +0 -0
  136. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/cropping_data.rst +0 -0
  137. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/dark_field_correction.rst +0 -0
  138. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/export_data.rst +0 -0
  139. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/index.rst +0 -0
  140. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/installation.rst +0 -0
  141. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/loading.rst +0 -0
  142. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/normalization.rst +0 -0
  143. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/notebook.rst +0 -0
  144. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/retrieve_normalized_data.rst +0 -0
  145. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/tutorial_normalization_with_fewer_ob_than_sample.ipynb +0 -0
  146. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/tutorial_using_array_input.ipynb +0 -0
  147. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/tutorial_using_folder_input.ipynb +0 -0
  148. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/environment.yml +0 -0
  149. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/debugging_multi_roi_bug.ipynb +0 -0
  150. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/notebook_display_with_time_estimation.ipynb +0 -0
  151. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/testing_new_auto_gamma_filtering.ipynb +0 -0
  152. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_normalization_with_fewer_ob_than_sample.ipynb +0 -0
  153. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_normalization_with_fewer_ob_than_sample_MAYBE_BUG.ipynb +0 -0
  154. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_array_input.ipynb +0 -0
  155. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_array_input_and_export_array.ipynb +0 -0
  156. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_array_input_and_several_roi.ipynb +0 -0
  157. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_folder_input.ipynb +0 -0
  158. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/paper/paper.bib +0 -0
  159. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/paper/paper.md +0 -0
  160. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/scripts/clean_build_artifacts.sh +0 -0
  161. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/normalizing_test.py +0 -0
  162. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_cropping.py +0 -0
  163. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_export.py +0 -0
  164. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_loading.py +0 -0
  165. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_roi.py +0 -0
  166. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_utilities.py +0 -0
  167. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/df001_4_by_4.tif +0 -0
  168. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/image001_4_by_4.tif +0 -0
  169. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/image001_with_gamma.tif +0 -0
  170. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/not_supported_file.fake +0 -0
  171. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/ob001_4_by_4.tif +0 -0
  172. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/df/df001.fits +0 -0
  173. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/ob/ob001.fits +0 -0
  174. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/ob/ob002.fits +0 -0
  175. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/ob/ob003.fits +0 -0
  176. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/test_roi/ob.fits +0 -0
  177. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/test_roi/sample.fits +0 -0
  178. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/format_not_suppored.txt +0 -0
  179. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/hdf5/dump_file.hdf5 +0 -0
  180. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/ob001.fits +0 -0
  181. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/df/df001.tif +0 -0
  182. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/df/df002.tif +0 -0
  183. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/df/df003.tif +0 -0
  184. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/ob/ob001.tif +0 -0
  185. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/ob/ob002.tif +0 -0
  186. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/ob/ob003.tif +0 -0
  187. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/sample_with_gamma/image001.tif +0 -0
  188. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/special_ob/ob_0001_2rois.tiff +0 -0
  189. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/special_sample/image_0001_2rois.tiff +0 -0
  190. {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/special_sample/image_0001_roi_no_ob.tiff +0 -0
  191. {neunorm-2.0.0 → neunorm-2.2.0}/docs/conf.py +0 -0
  192. {neunorm-2.0.0 → neunorm-2.2.0}/examples/pulse_reconstruction_explained.ipynb +0 -0
  193. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/data_models/tof.py +0 -0
  194. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/exporters/__init__.py +0 -0
  195. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/filters/__init__.py +0 -0
  196. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/filters/gamma_filter.py +0 -0
  197. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/__init__.py +0 -0
  198. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/metadata_loader.py +0 -0
  199. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/stack_loader.py +0 -0
  200. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/__init__.py +0 -0
  201. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/__init__.py +0 -0
  202. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/dark_corrector.py +0 -0
  203. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/reference_preparer.py +0 -0
  204. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/spatial_rebinner.py +0 -0
  205. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/__init__.py +0 -0
  206. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/pixel_detector.py +0 -0
  207. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/statistics_analyzer.py +0 -0
  208. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/utils/__init__.py +0 -0
  209. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/utils/_numba_compat.py +0 -0
  210. {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/utils/constants.py +0 -0
  211. {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/fits/sample/image001.fits +0 -0
  212. {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/fits/sample/image002.fits +0 -0
  213. {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/fits/sample/image003.fits +0 -0
  214. {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/tif/sample/image001.tif +0 -0
  215. {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/tif/sample/image002.tif +0 -0
  216. {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/tif/sample/image003.tif +0 -0
  217. {neunorm-2.0.0 → neunorm-2.2.0}/tests/integration/test_tof_pipeline.py +0 -0
  218. {neunorm-2.0.0 → neunorm-2.2.0}/tests/neunorm/test_version.py +0 -0
  219. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_air_region_corrector.py +0 -0
  220. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_analyze_statistics.py +0 -0
  221. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_binning_config.py +0 -0
  222. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_constants.py +0 -0
  223. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_dark_corrector.py +0 -0
  224. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_division_by_zero_guards.py +0 -0
  225. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_event_converter.py +0 -0
  226. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_eventdata_auto_validation.py +0 -0
  227. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_gamma_filter.py +0 -0
  228. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_metadata_loader.py +0 -0
  229. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_numba_compat.py +0 -0
  230. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_parallel_processing.py +0 -0
  231. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_pixel_detector.py +0 -0
  232. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_rebin_spatial.py +0 -0
  233. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_rebin_tof.py +0 -0
  234. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_reference_preparer.py +0 -0
  235. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_refine_boundaries_jit.py +0 -0
  236. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_remaining_jit.py +0 -0
  237. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_resonance_detection.py +0 -0
  238. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_roi_clipper.py +0 -0
  239. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_tiff_writer.py +0 -0
  240. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_uncertainty.py +0 -0
  241. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_variance_propagation_fix.py +0 -0
  242. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_venus_tpx1.py +0 -0
  243. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_venus_tpx3_event.py +0 -0
  244. {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_venus_tpx3_histogram.py +0 -0
@@ -8,7 +8,7 @@ description: Cut a NeuNorm release — pre-flight checks, promote next->qa->main
8
8
  Drives a NeuNorm release end to end. NeuNorm uses dynamic versioning
9
9
  (**versioningit**): the **git tag** `vX.Y.Z` is the single source of the version,
10
10
  and CI (`.github/workflows/test_and_deploy.yaml`) publishes on `v*` tags to PyPI
11
- (trusted publishing) and the `neutrons` Anaconda channel. Promotion path:
11
+ (trusted publishing) and the `neutronimaging` Anaconda channel. Promotion path:
12
12
  `next -> qa -> main`.
13
13
 
14
14
  Ask the user for the target version (e.g. `2.0.0`) if not provided, then:
@@ -52,7 +52,7 @@ Ask the user for the target version (e.g. `2.0.0`) if not provided, then:
52
52
 
53
53
  ## 5. Verify artifacts
54
54
 
55
- - `pip install NeuNorm==X.Y.Z` (PyPI) and `conda install -c neutrons neunorm=X.Y.Z`.
55
+ - `pip install NeuNorm==X.Y.Z` (PyPI) and `conda install neutronimaging::neunorm=X.Y.Z`.
56
56
  - Import smoke: `python -c "import neunorm; print(neunorm.__version__)"`.
57
57
  - Create the GitHub Release (notes from `CHANGELOG.md`; `.github/release.yml`
58
58
  filters bot PRs). Confirm Read the Docs built the new version.
@@ -0,0 +1,155 @@
1
+ ---
2
+ name: review-pipeline
3
+ description: Detection-only two-LLM-family review of the current branch's diff vs next (or a named branch/scope). Runs Claude + Codex finders through the dual-family-review engine, cross-family verifies P0/P1 findings, and reports at a human gate. Use to review a PR/branch before pushing or merging. Never edits, commits, or pushes.
4
+ user-invokable: true
5
+ ---
6
+
7
+ # /review-pipeline — NeuNorm diff-scoped review
8
+
9
+ Run a **diff-scoped, two-LLM-family** review of a branch and report verified
10
+ findings at a human gate. This is **detection-only**: it finds, cross-family
11
+ verifies, and reports — it never edits files, commits, or pushes. Fixing is a
12
+ separate, explicit step you drive after the gate.
13
+
14
+ **When to use which audit skill:**
15
+
16
+ - `/review-pipeline` (this) — review the **changes** on a branch/PR (`git diff
17
+ next...HEAD`). The right tool before pushing or merging a feature branch.
18
+ - `/bughunt` / `bughunt-deep` — audit the **whole** `src/neunorm` codebase
19
+ (release gate), not a diff.
20
+
21
+ ## Architecture
22
+
23
+ The non-interactive heart — **Claude finder + Codex finder per target →
24
+ cross-LLM-family adversarial verify → structured findings** — is the
25
+ `dual-family-review` **Workflow** (`.claude/workflows/dual-family-review.js`).
26
+ This skill is the **orchestrator**: it builds the preflight + target, invokes the
27
+ engine once, and renders the result at a STOP gate. Invoking the engine here is
28
+ the sanctioned Workflow opt-in (a skill whose instructions call the Workflow tool).
29
+
30
+ Why the cross-family pass matters: a parent agent re-deriving a subagent's claim
31
+ is **not** independent confirmation (same LLM family). A finding is VERIFIED only
32
+ when a *second* family (Codex verifying Claude, or vice-versa) independently
33
+ confirms it. Codex is supplementary — if it is absent, the round is single-family
34
+ and every P0/P1 comes back NEEDS-VERIFICATION (it does not silently pass).
35
+
36
+ ## Arguments
37
+
38
+ - **No args** — review `git diff next...HEAD` (the current branch vs `next`).
39
+ - **A branch name** — review `git diff next...<branch>`.
40
+ - **`--base <ref>`** — diff against `<ref>` instead of `next`.
41
+ - **`--skip-codex`** — Claude-only (single-family; P0/P1 → NEEDS-VERIFICATION).
42
+ - **A path / glob** — scope the audit to those files instead of a diff.
43
+
44
+ ---
45
+
46
+ ## Step 1: Preflight (read-only git)
47
+
48
+ Gather, with read-only git from the repo root:
49
+
50
+ - `repoRoot` — `git rev-parse --show-toplevel`
51
+ - `headSha` — `git rev-parse --short HEAD`
52
+ - `isWorktree` — true if `git rev-parse --git-common-dir` differs from `--git-dir`
53
+ - `codexAvailable` / `codexVersion` — `command -v codex && codex --version`
54
+ (false + empty if absent; do NOT fail if missing)
55
+ - base ref — `next` unless `--base` was given
56
+ - **changed files** — `git diff --name-only <base>...HEAD` (three-dot merge-base
57
+ diff), then keep the Python files under `src/neunorm/` (and any changed
58
+ `tests/` files, which the finder may read for circular-validation checks).
59
+ - **diverged?** — `git rev-list --count <base>..HEAD`; if `0` and no explicit
60
+ path scope, report "no changes vs <base> — nothing to review" and STOP.
61
+
62
+ If a branch name was passed, use `<branch>` in place of `HEAD` above and read
63
+ changed files via `git show <branch>:<path>` (the branch may not be checked out).
64
+
65
+ ## Step 2: Build the target and invoke the engine
66
+
67
+ Build **one** target from the changed source files:
68
+
69
+ - `key`: a short slug of the branch/scope (e.g. `diff-<headSha>`).
70
+ - `name`: `"changes on <branch> vs <base>"`.
71
+ - `paths`: the deduped **package dirs** of the changed `src/neunorm/` files
72
+ (e.g. `src/neunorm/pipelines/`, `src/neunorm/processing/`). If a path scope was
73
+ given instead of a diff, use those paths.
74
+ - `blurb`: `"the diff <base>...HEAD (N files in: <packages>)"`.
75
+ - `p0`: `"A correctness regression introduced by these changes: a logic error, an
76
+ exception on valid input, a wrong normalization/TOF result, an uncertainty
77
+ (variance) error that mis-states the reported error, data corruption in HDF5/TIFF
78
+ output, or a silently-masked whole-array error."`
79
+ - `lookFor`: `[]` (the engine appends its NeuNorm CORE_CHECKLIST).
80
+ - `scopeDirective`: `"Audit ONLY the changes in 'git diff <base>...HEAD'. Run that
81
+ diff, then read each changed file IN FULL. Report findings only for code
82
+ introduced or altered by this diff, plus any pre-existing call site the diff
83
+ newly breaks."` (For a path scope, audit those files in full instead.)
84
+
85
+ Then call the **Workflow** tool:
86
+
87
+ ```
88
+ Workflow(name="dual-family-review", args={
89
+ pf: { repoRoot, codexAvailable, codexVersion, headSha, isWorktree },
90
+ targets: [ <the target above> ],
91
+ config: {
92
+ contextNote: "Per-PR review of branch <branch> vs <base>.",
93
+ roundNote: "review",
94
+ skipCodex: <true if --skip-codex>,
95
+ hardEnforce: false
96
+ }
97
+ })
98
+ ```
99
+
100
+ It runs in the background and returns:
101
+
102
+ ```
103
+ { perTarget: [{ domainKey, domainName, claudeAssessment, codexAssessment,
104
+ tierCounts:{claude,codex}, verified[], needsVerification[],
105
+ refuted[], p2s[], circular[] }],
106
+ droppedTargets, codexUsable }
107
+ ```
108
+
109
+ **Fail closed:** if `perTarget` is missing/empty for a non-empty target list, or
110
+ `droppedTargets > 0`, report that the engine under-ran — do NOT present a false
111
+ all-clear.
112
+
113
+ Each finding carries `tier` (P0/P1/P2), `file`, `line`, `claim`, `reasoning`,
114
+ `suggestedFix`, `confidence`, and a `status` (VERIFIED = a 2nd family confirmed;
115
+ NEEDS-VERIFICATION = single-family / split / codex unavailable; REFUTED =
116
+ cross-family refuted). VERIFIED findings may carry a `verifierTier` (the verifier
117
+ downgraded the original tier).
118
+
119
+ ## Step 3: Consolidation gate
120
+
121
+ Render the returned payload as a report and **STOP** for the user:
122
+
123
+ 1. **Header**: branch, base, headSha, and whether codex was usable
124
+ (`codexUsable`). If codex was disabled/absent, say so and note that P0/P1
125
+ findings are NEEDS-VERIFICATION, not cross-confirmed.
126
+ 2. **Counts**: VERIFIED P0 / VERIFIED P1 / NEEDS-VERIFICATION / REFUTED / P2,
127
+ plus Claude vs Codex `tierCounts`.
128
+ 3. **Findings detail**, grouped by confidence, each with `file:line`, claim,
129
+ reasoning, and `suggestedFix`:
130
+ - **VERIFIED** (cross-confirmed) — highest confidence; fix candidates.
131
+ - **NEEDS-VERIFICATION** (single-family) — call out explicitly that these did
132
+ NOT meet the ≥2-family bar.
133
+ - **REFUTED** — list with the refuter's reasoning so they are not re-litigated.
134
+ - **P2** — trivial; list briefly.
135
+ 4. **Circular-validation risks**: surface every non-empty `circular[]` entry
136
+ (its `note`, `file:line`, family) — a test whose oracle may mirror buggy
137
+ behaviour is a HIGH-PRIORITY signal; never drop it silently.
138
+ 5. **Suggested disposition** (you propose; the **user decides**): fix-now for
139
+ VERIFIED P0/P1, consider for NEEDS-VERIFICATION, dismiss for REFUTED.
140
+
141
+ **MANDATORY GATE — present the report and STOP. Detection-only: do NOT fix,
142
+ commit, or push.** If the user then asks for fixes, apply them as a normal,
143
+ separate editing task (run `pixi run test` and `pixi run pre-commit run
144
+ --all-files` after), and re-run `/review-pipeline` to confirm.
145
+
146
+ ## Notes
147
+
148
+ - The engine is **read-only** and enforces a DETECTION-ONLY contract on every
149
+ subagent; it writes only `/tmp` scratch files for the Codex harness.
150
+ - Codex must be able to authenticate non-interactively. If it consistently fails,
151
+ check `codex --version` / the codex login; do not work around with model
152
+ overrides — codex is supplementary, not blocking.
153
+ - Compare floating-point expectations with tolerances, never bit-exact (per
154
+ AGENTS.md): a finding that demands bit-exact equality across arches is itself
155
+ likely a false positive — weigh that at the gate.