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.
- {neunorm-2.0.0 → neunorm-2.2.0}/.claude/skills/release/SKILL.md +2 -2
- neunorm-2.2.0/.claude/skills/review-pipeline/SKILL.md +155 -0
- neunorm-2.2.0/.claude/workflows/dual-family-review.js +560 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/codeql.yml +4 -1
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/dependency-scan.yml +12 -7
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/test_and_deploy.yaml +29 -18
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/workflows/update-lockfiles.yml +3 -3
- neunorm-2.2.0/.grype.yaml +30 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.pre-commit-config.yaml +1 -1
- neunorm-2.2.0/.zenodo.json +42 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/AGENTS.md +3 -2
- neunorm-2.2.0/CHANGELOG.md +176 -0
- neunorm-2.2.0/CITATION.cff +43 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/PKG-INFO +12 -9
- {neunorm-2.0.0 → neunorm-2.2.0}/README.md +11 -8
- neunorm-2.2.0/codecov.yaml +8 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/api.rst +3 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/development/DEVELOPMENT_PLAN.md +4 -4
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/index.md +1 -1
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/migration.md +11 -7
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/README.md +7 -8
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/mars_ccd_cmos.md +27 -18
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/mars_tpx3.md +26 -23
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/venus_ccd_cmos.md +32 -25
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/venus_tpx1.md +57 -62
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/workflows/venus_tpx3.md +56 -65
- {neunorm-2.0.0 → neunorm-2.2.0}/pixi.lock +16 -235
- {neunorm-2.0.0 → neunorm-2.2.0}/pyproject.toml +3 -6
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/__init__.py +1 -0
- neunorm-2.2.0/src/neunorm/_version.py +1 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/data_models/__init__.py +2 -1
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/data_models/core.py +37 -1
- neunorm-2.2.0/src/neunorm/data_models/roi.py +84 -0
- neunorm-2.2.0/src/neunorm/exporters/hdf5_writer.py +190 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/exporters/tiff_writer.py +2 -1
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/event_loader.py +10 -6
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/fits_loader.py +9 -3
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/tiff_loader.py +7 -2
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/mars_ccd.py +78 -30
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/mars_tpx3.py +20 -4
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_ccd.py +104 -37
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_tpx1.py +27 -13
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_tpx3_event.py +37 -19
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/venus_tpx3_histogram.py +27 -13
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/air_region_corrector.py +7 -5
- neunorm-2.2.0/src/neunorm/processing/normalizer.py +421 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/roi_clipper.py +8 -3
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/run_combiner.py +6 -2
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/uncertainty_calculator.py +6 -6
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/binning.py +62 -29
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/coordinate_converter.py +27 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/event_converter.py +8 -2
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/histogram_rebinner.py +7 -3
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/pulse_reconstruction.py +66 -10
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/resonance.py +1 -1
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_binning_conversions.py +132 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_event_loader.py +63 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_fits_loader.py +4 -0
- neunorm-2.2.0/tests/unit/test_hdf5_writer.py +520 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_mars_ccd.py +238 -13
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_mars_tpx3.py +28 -3
- neunorm-2.2.0/tests/unit/test_normalizer.py +586 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_pulse_reconstruction.py +24 -0
- neunorm-2.2.0/tests/unit/test_roi.py +125 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_run_combiner.py +8 -2
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_tiff_loader.py +4 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_venus_ccd.py +193 -13
- neunorm-2.0.0/CHANGELOG.md +0 -79
- neunorm-2.0.0/src/neunorm/_version.py +0 -1
- neunorm-2.0.0/src/neunorm/exporters/hdf5_writer.py +0 -123
- neunorm-2.0.0/src/neunorm/processing/normalizer.py +0 -134
- neunorm-2.0.0/tests/unit/test_hdf5_writer.py +0 -293
- neunorm-2.0.0/tests/unit/test_normalizer.py +0 -178
- {neunorm-2.0.0 → neunorm-2.2.0}/.claude/agents/bug-hunter.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.claude/skills/bughunt/SKILL.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.claude/skills/post-merge/SKILL.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.claude/workflows/bughunt-deep.js +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.gitattributes +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/CODEOWNERS +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/dependabot.yml +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.github/release.yml +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.gitignore +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/.readthedocs.yaml +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/CLAUDE.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/CONTRIBUTING.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/LICENSE +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/SECURITY.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/_utilities.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/exporter.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/loader.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/normalization.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/NeuNorm/roi.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/README.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/conda.recipe/meta.yaml +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/df/DC0000.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/df/DC0001.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/df/DC0002.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0001.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0002.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0003.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0004.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0005.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0006.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0007.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0008.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0009.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0010.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0011.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0012.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0013.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0014.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/ob/0015.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0002.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0003.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0004.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0005.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0006.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0007.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0008.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0009.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0010.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0011.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0012.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0013.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0014.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/data/sample/0015.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/Makefile +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/readthedocs-environment.yml +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/normalization_equation.png +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/normalization_principle.png +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/progress_bar_loading.png +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/_static/progress_bar_normalization.png +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/conf.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/cropping_data.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/dark_field_correction.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/export_data.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/index.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/installation.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/loading.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/normalization.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/notebook.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/retrieve_normalized_data.rst +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/tutorial_normalization_with_fewer_ob_than_sample.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/tutorial_using_array_input.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/documentation/source/tutorial_using_folder_input.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/environment.yml +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/debugging_multi_roi_bug.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/notebook_display_with_time_estimation.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/testing_new_auto_gamma_filtering.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_normalization_with_fewer_ob_than_sample.ipynb +0 -0
- {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
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_array_input.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_array_input_and_export_array.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_array_input_and_several_roi.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/notebooks/tutorial_using_folder_input.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/paper/paper.bib +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/paper/paper.md +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/scripts/clean_build_artifacts.sh +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/normalizing_test.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_cropping.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_export.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_loading.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_roi.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/NeuNorm/test_utilities.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/df001_4_by_4.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/image001_4_by_4.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/image001_with_gamma.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/not_supported_file.fake +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/different_format/ob001_4_by_4.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/df/df001.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/ob/ob001.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/ob/ob002.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/ob/ob003.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/test_roi/ob.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/fits/test_roi/sample.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/format_not_suppored.txt +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/hdf5/dump_file.hdf5 +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/ob001.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/df/df001.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/df/df002.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/df/df003.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/ob/ob001.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/ob/ob002.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/ob/ob003.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/sample_with_gamma/image001.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/special_ob/ob_0001_2rois.tiff +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/archive/neunorm-1.x/tests/data/tif/special_sample/image_0001_2rois.tiff +0 -0
- {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
- {neunorm-2.0.0 → neunorm-2.2.0}/docs/conf.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/examples/pulse_reconstruction_explained.ipynb +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/data_models/tof.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/exporters/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/filters/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/filters/gamma_filter.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/metadata_loader.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/loaders/stack_loader.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/pipelines/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/dark_corrector.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/reference_preparer.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/processing/spatial_rebinner.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/pixel_detector.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/tof/statistics_analyzer.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/utils/__init__.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/utils/_numba_compat.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/src/neunorm/utils/constants.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/fits/sample/image001.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/fits/sample/image002.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/fits/sample/image003.fits +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/tif/sample/image001.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/tif/sample/image002.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/data/tif/sample/image003.tif +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/integration/test_tof_pipeline.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/neunorm/test_version.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_air_region_corrector.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_analyze_statistics.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_binning_config.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_constants.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_dark_corrector.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_division_by_zero_guards.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_event_converter.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_eventdata_auto_validation.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_gamma_filter.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_metadata_loader.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_numba_compat.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_parallel_processing.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_pixel_detector.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_rebin_spatial.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_rebin_tof.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_reference_preparer.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_refine_boundaries_jit.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_remaining_jit.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_resonance_detection.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_roi_clipper.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_tiff_writer.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_uncertainty.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_variance_propagation_fix.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_venus_tpx1.py +0 -0
- {neunorm-2.0.0 → neunorm-2.2.0}/tests/unit/test_venus_tpx3_event.py +0 -0
- {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 `
|
|
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
|
|
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.
|