rootfig 0.3.0__tar.gz → 0.5.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.
- {rootfig-0.3.0 → rootfig-0.5.0}/CONTRIBUTING.md +29 -18
- {rootfig-0.3.0 → rootfig-0.5.0}/PKG-INFO +26 -6
- {rootfig-0.3.0 → rootfig-0.5.0}/README.md +25 -5
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/api.md +3 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/composable.md +17 -5
- rootfig-0.5.0/docs/gallery/index.md +67 -0
- rootfig-0.5.0/docs/hooks/gallery.py +251 -0
- rootfig-0.5.0/docs/images/gallery/arrays-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/arrays-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/correlation.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/density_flow.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/efficiency-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/expressions-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/fill_stats-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/hist2d-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/log_axes-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/luminosity-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/many_plots-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/many_plots.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/object_vs_event-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/overlay_ratio-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/profile-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/quick-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/ratio_reference-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/robust_range-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/stack_data.png +0 -0
- rootfig-0.5.0/docs/images/gallery/style_colors-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/systematics.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/variable_bins-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-alice-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-alice.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-atlas-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-atlas.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-cms-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-cms.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-dune-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-dune.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-lhcb-dark.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio-lhcb.png +0 -0
- rootfig-0.5.0/docs/images/gallery/xbreak_ratio.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/index.md +4 -2
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/plotting.md +140 -7
- rootfig-0.5.0/docs/stylesheets/gallery.css +58 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/examples/gallery/__init__.py +298 -186
- {rootfig-0.3.0 → rootfig-0.5.0}/examples/gallery/__main__.py +8 -4
- {rootfig-0.3.0 → rootfig-0.5.0}/examples/gallery/data.py +12 -2
- {rootfig-0.3.0 → rootfig-0.5.0}/examples/gallery/registry.py +56 -11
- {rootfig-0.3.0 → rootfig-0.5.0}/mkdocs.yml +17 -1
- {rootfig-0.3.0 → rootfig-0.5.0}/pyproject.toml +2 -1
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/__init__.py +9 -3
- rootfig-0.5.0/src/rootfig/_mapping.py +43 -0
- rootfig-0.5.0/src/rootfig/api/__init__.py +28 -0
- rootfig-0.5.0/src/rootfig/api/_common.py +59 -0
- rootfig-0.5.0/src/rootfig/api/data.py +186 -0
- rootfig-0.5.0/src/rootfig/api/measures.py +302 -0
- rootfig-0.5.0/src/rootfig/api/plots1d.py +610 -0
- rootfig-0.5.0/src/rootfig/api/plots2d.py +208 -0
- rootfig-0.5.0/src/rootfig/api/tables.py +135 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/errors.py +4 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/histograms/__init__.py +4 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/histograms/build.py +127 -10
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/histograms/normalize.py +27 -3
- rootfig-0.5.0/src/rootfig/histograms/pipeline.py +476 -0
- rootfig-0.5.0/src/rootfig/histograms/ratio.py +241 -0
- rootfig-0.5.0/src/rootfig/histograms/systematics.py +175 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/io/sources.py +4 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/model/__init__.py +10 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/model/samples.py +48 -9
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/model/style.py +2 -2
- rootfig-0.5.0/src/rootfig/model/systematics.py +254 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/model/variables.py +2 -2
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/__init__.py +8 -1
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/annotations.py +2 -2
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/correlation.py +14 -1
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/figure.py +1 -1
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/hist1d.py +118 -70
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/ratio.py +73 -30
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/result.py +52 -2
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/style.py +289 -58
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_api.py +455 -1
- rootfig-0.5.0/tests/test_gallery.py +266 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_histograms.py +537 -3
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_model.py +182 -15
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_plotting.py +111 -0
- rootfig-0.5.0/tests/type_checks/systematics.py +20 -0
- rootfig-0.3.0/docs/gallery.md +0 -74
- rootfig-0.3.0/docs/hooks/gallery.py +0 -99
- rootfig-0.3.0/docs/images/gallery/cms_density.png +0 -0
- rootfig-0.3.0/docs/images/gallery/correlation.png +0 -0
- rootfig-0.3.0/docs/images/gallery/many_plots.png +0 -0
- rootfig-0.3.0/docs/images/gallery/xbreak_ratio.png +0 -0
- rootfig-0.3.0/src/rootfig/api.py +0 -1363
- rootfig-0.3.0/src/rootfig/histograms/pipeline.py +0 -236
- rootfig-0.3.0/src/rootfig/histograms/ratio.py +0 -161
- rootfig-0.3.0/tests/test_gallery.py +0 -173
- {rootfig-0.3.0 → rootfig-0.5.0}/.gitignore +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/LICENSE +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/ecosystem.md +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/expressions.md +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/arrays.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/efficiency.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/expressions.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/hist2d.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/log_axes.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/luminosity.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/profile.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/quick.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/robust_range.png +0 -0
- /rootfig-0.3.0/docs/images/gallery/stack_data.png → /rootfig-0.5.0/docs/images/gallery/stack_data-atlas.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/style_colors.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins.png +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/docs/quickstart.md +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/_typing.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/expressions/__init__.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/expressions/functions.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/expressions/parser.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/histograms/cutflow.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/histograms/efficiency.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/histograms/stats.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/io/__init__.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/model/binning.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/model/cuts.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/model/units.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/hist2d.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/plotting/points.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/py.typed +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/selection/__init__.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/src/rootfig/selection/columns.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/conftest.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/data/split_collection.root +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_expressions.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_io.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_selection.py +0 -0
- {rootfig-0.3.0 → rootfig-0.5.0}/tests/test_tutorials.py +0 -0
|
@@ -36,7 +36,7 @@ tests that require ROOT or network access.
|
|
|
36
36
|
|
|
37
37
|
```
|
|
38
38
|
src/rootfig/
|
|
39
|
-
api
|
|
39
|
+
api/ plot(), histogram(), load(), ... (orchestration only)
|
|
40
40
|
errors.py exception hierarchy
|
|
41
41
|
expressions/ parse, validate and evaluate expression strings
|
|
42
42
|
io/ file and in-memory data sources
|
|
@@ -90,32 +90,43 @@ f.Close()
|
|
|
90
90
|
## Figures and the gallery
|
|
91
91
|
|
|
92
92
|
The `examples/gallery` package is both the showcase and the image-regression
|
|
93
|
-
suite: `__init__.py` holds the shared `define()` block
|
|
94
|
-
writes the toy files and `registry.py` extracts the source
|
|
95
|
-
example is a small function returning a `Plot
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
suite: `__init__.py` holds the shared `define()` block, the `STYLES` and the
|
|
94
|
+
examples, `data.py` writes the toy files and `registry.py` extracts the source
|
|
95
|
+
shown in the docs. Each example is a small function returning a `Plot`. The
|
|
96
|
+
MkDocs hook `docs/hooks/gallery.py` turns them into the gallery: an overview
|
|
97
|
+
(`docs/gallery/index.md`, a card per example, section by section) and a
|
|
98
|
+
generated page per example with its figure and complete code, one tab per
|
|
99
|
+
style. `tests/test_gallery.py` renders all of them and, with `--mpl`, compares
|
|
98
100
|
them pixel-wise (pytest-mpl, RMS tolerance 2) against `docs/images/gallery/`.
|
|
99
|
-
|
|
101
|
+
An example whose function takes a `style` is rendered in every entry of
|
|
102
|
+
`STYLES` (the neutral default, ATLAS, CMS, LHCb, ALICE, DUNE) as
|
|
103
|
+
`<name>-<style>.png`, `<name>.png` for the default; every rendering is made
|
|
104
|
+
twice, as shown and inside `rf.dark_theme()` (`-dark`), and the docs pick one
|
|
105
|
+
per palette. Those PNGs are therefore the documentation images *and* the
|
|
106
|
+
baselines. The experiment styles are drawn only when images are compared or
|
|
107
|
+
generated, and `-n auto` runs that on every core.
|
|
100
108
|
|
|
101
109
|
```bash
|
|
102
|
-
MPLBACKEND=Agg uv run python examples/gallery
|
|
103
|
-
uv run
|
|
104
|
-
uv run pytest tests/test_gallery.py --mpl-
|
|
110
|
+
MPLBACKEND=Agg uv run python examples/gallery # look at examples/out/*.png
|
|
111
|
+
MPLBACKEND=Agg uv run python examples/gallery --style CMS # ... in another style
|
|
112
|
+
uv run pytest tests/test_gallery.py --mpl -n auto # compare against the baselines
|
|
113
|
+
uv run pytest tests/test_gallery.py -n auto --mpl-generate-path=docs/images/gallery # accept changes
|
|
105
114
|
```
|
|
106
115
|
|
|
107
116
|
After any visual change: regenerate the baselines, open the PNGs and check
|
|
108
117
|
them by eye, and commit them with the code. CI compares on Linux only (fonts
|
|
109
118
|
differ elsewhere) and, when a comparison fails, uploads an HTML report with
|
|
110
119
|
baseline, result and difference images as the `mpl-results-*` artifact. To add
|
|
111
|
-
an example, register a function with `@example(name, title)` and
|
|
112
|
-
docstring; the test suite fails until its baseline
|
|
113
|
-
are attribute names of `Dataset`,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
an example, register a function with `@example(name, title, section=...)` and
|
|
121
|
+
give it a docstring; the test suite fails until its baseline images exist. Its
|
|
122
|
+
parameters are attribute names of `Dataset`, plus `style` when the figure should
|
|
123
|
+
be shown in every style (pass it on as `style=style`; leave it out when a style
|
|
124
|
+
is the point of the example or the figure goes into axes of your own). It runs
|
|
125
|
+
inside the directory holding the toy files (so name them `"signal.root"`, never
|
|
126
|
+
through a variable), and the hook prints only the body (blank lines and
|
|
127
|
+
comments included) — write it as a user would. Put an object into `define()` —
|
|
128
|
+
the *Setup* block of the example pages — only when several examples use it;
|
|
129
|
+
anything a single example needs belongs in that example.
|
|
119
130
|
|
|
120
131
|
## Pull requests
|
|
121
132
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: rootfig
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Publication-quality figures straight from ROOT trees, without ROOT: uproot + Awkward + hist + mplhep with a TTree::Draw-like API.
|
|
5
5
|
Project-URL: Homepage, https://github.com/jbeirer/rootfig
|
|
6
6
|
Project-URL: Documentation, https://jbeirer.github.io/rootfig/
|
|
@@ -73,19 +73,20 @@ panels as your analysis grows. Every plot gives you a matplotlib figure to
|
|
|
73
73
|
customise and save.
|
|
74
74
|
|
|
75
75
|
<p align="center">
|
|
76
|
-
<a href="https://jbeirer.github.io/rootfig/gallery
|
|
76
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/log_axes/"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/log_axes-dark.png"><img src="docs/images/gallery/log_axes.png" alt="Logarithmic axes with log-spaced bins" width="46%"></picture></a>
|
|
77
77
|
|
|
78
|
-
<a href="https://jbeirer.github.io/rootfig/gallery
|
|
78
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/hist2d/"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/hist2d-dark.png"><img src="docs/images/gallery/hist2d.png" alt="Two-dimensional histogram" width="46%"></picture></a>
|
|
79
79
|
</p>
|
|
80
80
|
<p align="center">
|
|
81
|
-
<a href="https://jbeirer.github.io/rootfig/gallery/#
|
|
81
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/xbreak_ratio/#atlas"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/xbreak_ratio-atlas-dark.png"><img src="docs/images/gallery/xbreak_ratio-atlas.png" alt="Broken x axis with a ratio panel" width="46%"></picture></a>
|
|
82
82
|
|
|
83
|
-
<a href="https://jbeirer.github.io/rootfig/gallery
|
|
83
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/luminosity/"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/luminosity-dark.png"><img src="docs/images/gallery/luminosity.png" alt="FCC-ee stack scaled to luminosity with a significance panel" width="43%"></picture></a>
|
|
84
84
|
</p>
|
|
85
85
|
|
|
86
86
|
**[Explore the gallery →](https://jbeirer.github.io/rootfig/gallery/)**
|
|
87
87
|
See each figure alongside the code that makes it, from simple overlays to
|
|
88
|
-
stacked data/MC comparisons, broken axes and 2D histograms
|
|
88
|
+
stacked data/MC comparisons, broken axes and 2D histograms, in the neutral
|
|
89
|
+
style or in that of ATLAS, CMS, LHCb, ALICE or DUNE.
|
|
89
90
|
|
|
90
91
|
## Installation
|
|
91
92
|
|
|
@@ -159,6 +160,10 @@ matplotlib `Figure`/`Axes`, `p.hists` are `hist.Hist` objects, and
|
|
|
159
160
|
and `(n, low, high)` are used as given, while a range inferred from the data
|
|
160
161
|
ignores far outliers, so `-999` sentinels do not set the axis. Normalise to
|
|
161
162
|
unity, density, bin width or luminosity.
|
|
163
|
+
- **Show systematic uncertainties.** Attach weight, branch, file or
|
|
164
|
+
normalisation variations to a sample; stacks and ratio panels draw the
|
|
165
|
+
combined statistical and systematic band, and every component stays
|
|
166
|
+
accessible.
|
|
162
167
|
- **Style figures for your analysis.** Add experiment labels, units, log axes
|
|
163
168
|
and broken axes, then refine the result with matplotlib.
|
|
164
169
|
- **Go beyond 1D plots.** Draw 2D histograms, correlations, efficiencies,
|
|
@@ -209,6 +214,21 @@ uv run mypy
|
|
|
209
214
|
|
|
210
215
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
|
211
216
|
|
|
217
|
+
## Citation
|
|
218
|
+
|
|
219
|
+
If `rootfig` is useful in your research, please cite it:
|
|
220
|
+
|
|
221
|
+
```bibtex
|
|
222
|
+
@software{rootfig,
|
|
223
|
+
author = {Beirer, Joshua Falco},
|
|
224
|
+
doi = {10.5281/zenodo.22726311},
|
|
225
|
+
license = {MIT},
|
|
226
|
+
title = {{rootfig}},
|
|
227
|
+
url = {https://github.com/jbeirer/rootfig},
|
|
228
|
+
year = {2026}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
212
232
|
## License
|
|
213
233
|
|
|
214
234
|
MIT. See [LICENSE](LICENSE).
|
|
@@ -40,19 +40,20 @@ panels as your analysis grows. Every plot gives you a matplotlib figure to
|
|
|
40
40
|
customise and save.
|
|
41
41
|
|
|
42
42
|
<p align="center">
|
|
43
|
-
<a href="https://jbeirer.github.io/rootfig/gallery
|
|
43
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/log_axes/"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/log_axes-dark.png"><img src="docs/images/gallery/log_axes.png" alt="Logarithmic axes with log-spaced bins" width="46%"></picture></a>
|
|
44
44
|
|
|
45
|
-
<a href="https://jbeirer.github.io/rootfig/gallery
|
|
45
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/hist2d/"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/hist2d-dark.png"><img src="docs/images/gallery/hist2d.png" alt="Two-dimensional histogram" width="46%"></picture></a>
|
|
46
46
|
</p>
|
|
47
47
|
<p align="center">
|
|
48
|
-
<a href="https://jbeirer.github.io/rootfig/gallery/#
|
|
48
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/xbreak_ratio/#atlas"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/xbreak_ratio-atlas-dark.png"><img src="docs/images/gallery/xbreak_ratio-atlas.png" alt="Broken x axis with a ratio panel" width="46%"></picture></a>
|
|
49
49
|
|
|
50
|
-
<a href="https://jbeirer.github.io/rootfig/gallery
|
|
50
|
+
<a href="https://jbeirer.github.io/rootfig/gallery/luminosity/"><picture><source media="(prefers-color-scheme: dark)" srcset="docs/images/gallery/luminosity-dark.png"><img src="docs/images/gallery/luminosity.png" alt="FCC-ee stack scaled to luminosity with a significance panel" width="43%"></picture></a>
|
|
51
51
|
</p>
|
|
52
52
|
|
|
53
53
|
**[Explore the gallery →](https://jbeirer.github.io/rootfig/gallery/)**
|
|
54
54
|
See each figure alongside the code that makes it, from simple overlays to
|
|
55
|
-
stacked data/MC comparisons, broken axes and 2D histograms
|
|
55
|
+
stacked data/MC comparisons, broken axes and 2D histograms, in the neutral
|
|
56
|
+
style or in that of ATLAS, CMS, LHCb, ALICE or DUNE.
|
|
56
57
|
|
|
57
58
|
## Installation
|
|
58
59
|
|
|
@@ -126,6 +127,10 @@ matplotlib `Figure`/`Axes`, `p.hists` are `hist.Hist` objects, and
|
|
|
126
127
|
and `(n, low, high)` are used as given, while a range inferred from the data
|
|
127
128
|
ignores far outliers, so `-999` sentinels do not set the axis. Normalise to
|
|
128
129
|
unity, density, bin width or luminosity.
|
|
130
|
+
- **Show systematic uncertainties.** Attach weight, branch, file or
|
|
131
|
+
normalisation variations to a sample; stacks and ratio panels draw the
|
|
132
|
+
combined statistical and systematic band, and every component stays
|
|
133
|
+
accessible.
|
|
129
134
|
- **Style figures for your analysis.** Add experiment labels, units, log axes
|
|
130
135
|
and broken axes, then refine the result with matplotlib.
|
|
131
136
|
- **Go beyond 1D plots.** Draw 2D histograms, correlations, efficiencies,
|
|
@@ -176,6 +181,21 @@ uv run mypy
|
|
|
176
181
|
|
|
177
182
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
|
178
183
|
|
|
184
|
+
## Citation
|
|
185
|
+
|
|
186
|
+
If `rootfig` is useful in your research, please cite it:
|
|
187
|
+
|
|
188
|
+
```bibtex
|
|
189
|
+
@software{rootfig,
|
|
190
|
+
author = {Beirer, Joshua Falco},
|
|
191
|
+
doi = {10.5281/zenodo.22726311},
|
|
192
|
+
license = {MIT},
|
|
193
|
+
title = {{rootfig}},
|
|
194
|
+
url = {https://github.com/jbeirer/rootfig},
|
|
195
|
+
year = {2026}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
179
199
|
## License
|
|
180
200
|
|
|
181
201
|
MIT. See [LICENSE](LICENSE).
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
::: rootfig.ratio
|
|
19
19
|
::: rootfig.log_bins
|
|
20
20
|
::: rootfig.use_style
|
|
21
|
+
::: rootfig.dark_theme
|
|
21
22
|
|
|
22
23
|
## Descriptions
|
|
23
24
|
|
|
@@ -25,12 +26,14 @@
|
|
|
25
26
|
::: rootfig.Variable
|
|
26
27
|
::: rootfig.Cut
|
|
27
28
|
::: rootfig.Style
|
|
29
|
+
::: rootfig.Systematic
|
|
28
30
|
|
|
29
31
|
## Results
|
|
30
32
|
|
|
31
33
|
::: rootfig.Plot
|
|
32
34
|
::: rootfig.Histogram
|
|
33
35
|
::: rootfig.Ratio
|
|
36
|
+
::: rootfig.Uncertainty
|
|
34
37
|
::: rootfig.Summary
|
|
35
38
|
::: rootfig.SummaryTable
|
|
36
39
|
::: rootfig.Cutflow
|
|
@@ -28,8 +28,9 @@ mem = rf.Sample({"x": awkward_array, "w": weights}, label="in memory")
|
|
|
28
28
|
implementing the [`Source`][rootfig.io.Source] protocol.
|
|
29
29
|
- `selection` and `weight` belong to the sample and combine with the ones
|
|
30
30
|
given to `plot()` (`&` and `*` respectively).
|
|
31
|
-
- `is_data=True` draws
|
|
32
|
-
stacks and makes it the
|
|
31
|
+
- `is_data=True` draws points with error bars (in the style's text colour
|
|
32
|
+
unless `color` is set), keeps the sample out of stacks and makes it the
|
|
33
|
+
numerator of ratios.
|
|
33
34
|
- `xsec` and `ngen` describe simulated processes: the cross section (pb, or a
|
|
34
35
|
string with a unit such as `"1.2 fb"`) and the number of generated events (a
|
|
35
36
|
number, the name of an object in the file holding it, e.g. FCCAnalyses'
|
|
@@ -48,7 +49,14 @@ mem = rf.Sample({"x": awkward_array, "w": weights}, label="in memory")
|
|
|
48
49
|
(a plot reads every needed branch of every file into memory at once). For a
|
|
49
50
|
ready-made `FileSource`, give the range to the source itself; passing it to
|
|
50
51
|
`Sample` afterwards raises a [`SourceError`][rootfig.SourceError].
|
|
51
|
-
- `
|
|
52
|
+
- `systematics={name: variation}` lists the sample's sources of systematic
|
|
53
|
+
uncertainty: weight expressions (`("w_up", "w_down")`), normalisation
|
|
54
|
+
uncertainties (`0.05`, `(1.1, 0.95)`), varied branches
|
|
55
|
+
(`{"Jet_pt": ("Jet_pt_up", "Jet_pt_down")}`) and varied files
|
|
56
|
+
([`Systematic.samples`][rootfig.Systematic]). Sources with
|
|
57
|
+
the same name are correlated across samples; see
|
|
58
|
+
[Systematic uncertainties](plotting.md#systematic-uncertainties).
|
|
59
|
+
- `sample.replace(label="...")` returns a copy with the given fields changed; new values are
|
|
52
60
|
validated like constructor arguments.
|
|
53
61
|
|
|
54
62
|
Passing a list of files to `plot()` creates one sample per file. To merge
|
|
@@ -113,8 +121,12 @@ neutral = rf.Style(
|
|
|
113
121
|
given.
|
|
114
122
|
- `base` can be any mplhep or matplotlib style name (`"ATLAS"`, `"ggplot"`,
|
|
115
123
|
...) or a mapping of rcParams; `rc` adds overrides on top; `colors` replaces
|
|
116
|
-
the colour cycle. `label_loc`
|
|
117
|
-
|
|
124
|
+
the colour cycle. `label_loc` overrides the experiment's convention: 0 puts
|
|
125
|
+
the experiment and secondary text above the frame; 3 puts the experiment
|
|
126
|
+
above and secondary text inside; 1, 2, and 4 put both inside. Luminosity stays
|
|
127
|
+
above for locations 0–3 and inside for 4. 2D histograms and correlation
|
|
128
|
+
matrices default to location 0; only `label_loc=1`, `2`, or `4` moves the
|
|
129
|
+
experiment inside the frame.
|
|
118
130
|
- The centre-of-mass energy and luminosity appear only when `com`/`lumi` are
|
|
119
131
|
given; nothing is invented for you.
|
|
120
132
|
- `legend` is `True`, `False` or a location string; `legend_kwargs` are
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
hide:
|
|
3
|
+
- toc
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Gallery
|
|
7
|
+
|
|
8
|
+
Every figure below is drawn by the code on its page. Most examples use a toy
|
|
9
|
+
ROOT dataset: three simulated processes and one "observed" sample with muons,
|
|
10
|
+
jets and event-level quantities. The in-memory arrays example generates its
|
|
11
|
+
own NumPy data.
|
|
12
|
+
|
|
13
|
+
Choose a style: examples with style tabs follow your choice here and on their
|
|
14
|
+
individual pages. The other examples keep their own styles.
|
|
15
|
+
|
|
16
|
+
<!-- gallery-overview -->
|
|
17
|
+
|
|
18
|
+
## Run the examples
|
|
19
|
+
|
|
20
|
+
The examples live in
|
|
21
|
+
[`examples/gallery`](https://github.com/jbeirer/rootfig/blob/main/examples/gallery/__init__.py),
|
|
22
|
+
and one command writes the toy files and every figure in a few seconds:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
python examples/gallery # everything ends up in examples/out/
|
|
26
|
+
python examples/gallery --style CMS # CMS for examples with style tabs
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Each picture is also the reference image the test suite compares against, so
|
|
30
|
+
what you see is what the current release draws.
|
|
31
|
+
|
|
32
|
+
## Beyond figures
|
|
33
|
+
|
|
34
|
+
The same inputs feed tables and arrays (`mc` and `signal` are the samples from
|
|
35
|
+
the setup block of the example pages):
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
# entries, mean, std, sem, skewness, min, max per sample and variable
|
|
39
|
+
print(rf.summarize(mc, ["MET", "Muon_pt"], selection="nMuon > 0"))
|
|
40
|
+
|
|
41
|
+
# a cut flow: yields, raw counts and step efficiencies per sample
|
|
42
|
+
print(
|
|
43
|
+
rf.cutflow(
|
|
44
|
+
mc,
|
|
45
|
+
["nMuon >= 2", rf.Cut("MET > 50", label="MET > 50 GeV"), "any(Jet_btag > 0.8)"],
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# evaluated expressions as an Awkward record array
|
|
50
|
+
events = rf.load(signal, ["MET", "count(Muon_pt)", "first(Muon_pt)"], selection="nJet >= 2")
|
|
51
|
+
events["MET"]
|
|
52
|
+
|
|
53
|
+
# a plain hist.Hist to feed into your own code
|
|
54
|
+
h = rf.histogram(signal, "MET", bins=(40, 0, 400), selection="nJet >= 2")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Cuts compose with `&`, `|` and `~`, carry optional labels, and combine with
|
|
58
|
+
selections given to `plot()`:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
base = rf.Cut("nMuon >= 2", label="2 muons")
|
|
62
|
+
signal_region = base & "abs(Muon_eta) < 2.4" & ~rf.Cut("any(Jet_btag > 0.8)")
|
|
63
|
+
control_region = base & rf.Cut("any(Jet_btag > 0.8)") | "MET > 200"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
See [Plotting options](../plotting.md) for every keyword and
|
|
67
|
+
[Expressions and selections](../expressions.md) for the per-event/per-object rules.
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"""MkDocs hook that builds the gallery pages from the ``examples/gallery`` package.
|
|
2
|
+
|
|
3
|
+
The gallery is an overview page and one page per example, all made from the
|
|
4
|
+
registry:
|
|
5
|
+
|
|
6
|
+
``gallery/index.md``
|
|
7
|
+
carries the ``<!-- gallery-overview -->`` marker, replaced by one tab per
|
|
8
|
+
gallery style, each holding the examples section by section as a grid of
|
|
9
|
+
cards (thumbnail and title, linking to the example's page);
|
|
10
|
+
``gallery/<name>.md``
|
|
11
|
+
generated for every example (``on_files``), with no file in ``docs/``: the
|
|
12
|
+
title, the description, one tab per style the example is drawn in with its
|
|
13
|
+
image (``docs/images/gallery/<name>[-<style>].png``, and ``-dark`` for the
|
|
14
|
+
dark palette, switched by Material's ``#only-light``/``#only-dark``) and the
|
|
15
|
+
complete code, and the setup block the code relies on.
|
|
16
|
+
|
|
17
|
+
The Gallery entry of the navigation, ``gallery/index.md``, becomes a section with
|
|
18
|
+
the overview and the example pages, grouped like the overview (``on_config``).
|
|
19
|
+
Every tab set uses the same labels, so Material's ``content.tabs.link`` switches
|
|
20
|
+
all figures on all pages together. Tabs, cards and the setup block are
|
|
21
|
+
pymdownx blocks, which nest without indentation.
|
|
22
|
+
|
|
23
|
+
The gallery module is imported, never executed, so building the docs needs no
|
|
24
|
+
data and draws nothing. Because the images are also the baselines of
|
|
25
|
+
``tests/test_gallery.py``, picture and code cannot drift apart.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import importlib.util
|
|
31
|
+
import re
|
|
32
|
+
import sys
|
|
33
|
+
import textwrap
|
|
34
|
+
from collections.abc import Iterable, Sequence
|
|
35
|
+
from pathlib import Path
|
|
36
|
+
from types import ModuleType
|
|
37
|
+
from typing import TYPE_CHECKING, Any
|
|
38
|
+
|
|
39
|
+
if TYPE_CHECKING: # MkDocs runs the hook; the tests import it without MkDocs installed
|
|
40
|
+
from mkdocs.config.defaults import MkDocsConfig
|
|
41
|
+
from mkdocs.structure.files import Files
|
|
42
|
+
|
|
43
|
+
ROOT = Path(__file__).resolve().parents[2]
|
|
44
|
+
GALLERY_DIR = ROOT / "examples" / "gallery"
|
|
45
|
+
OVERVIEW = "gallery/index.md"
|
|
46
|
+
OVERVIEW_MARKER = "<!-- gallery-overview -->"
|
|
47
|
+
IMAGES = "../images/gallery" # relative to the gallery pages
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _load_gallery(name: str = "rootfig_gallery_docs") -> ModuleType:
|
|
51
|
+
"""Import ``examples/gallery`` as a fresh package, without ``examples/`` on ``sys.path``.
|
|
52
|
+
|
|
53
|
+
Every call re-executes the package (``mkdocs serve`` rebuilds on each change),
|
|
54
|
+
so its submodules are evicted from ``sys.modules`` first: a cached
|
|
55
|
+
``registry`` would keep its ``EXAMPLES`` list and the re-run decorators would
|
|
56
|
+
register every example a second time.
|
|
57
|
+
"""
|
|
58
|
+
for cached in [m for m in sys.modules if m == name or m.startswith(f"{name}.")]:
|
|
59
|
+
del sys.modules[cached]
|
|
60
|
+
spec = importlib.util.spec_from_file_location(
|
|
61
|
+
name, GALLERY_DIR / "__init__.py", submodule_search_locations=[str(GALLERY_DIR)]
|
|
62
|
+
)
|
|
63
|
+
if spec is None or spec.loader is None:
|
|
64
|
+
msg = f"cannot load {GALLERY_DIR}"
|
|
65
|
+
raise RuntimeError(msg)
|
|
66
|
+
module = importlib.util.module_from_spec(spec)
|
|
67
|
+
sys.modules[name] = module
|
|
68
|
+
spec.loader.exec_module(module)
|
|
69
|
+
return module
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# --------------------------------------------------------------------------------------
|
|
73
|
+
# MkDocs events
|
|
74
|
+
# --------------------------------------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def on_config(config: MkDocsConfig) -> MkDocsConfig:
|
|
78
|
+
"""Turn the navigation's gallery entry into the gallery section."""
|
|
79
|
+
if config.nav is not None:
|
|
80
|
+
config.nav = gallery_nav(config.nav, _load_gallery())
|
|
81
|
+
return config
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def on_files(files: Files, config: MkDocsConfig) -> Files:
|
|
85
|
+
"""Add a generated page for every example."""
|
|
86
|
+
from mkdocs.structure.files import File # noqa: PLC0415 - only MkDocs calls this
|
|
87
|
+
|
|
88
|
+
gallery = _load_gallery()
|
|
89
|
+
for example in gallery.EXAMPLES:
|
|
90
|
+
content = render_page(gallery, example)
|
|
91
|
+
files.append(File.generated(config, page_path(example), content=content))
|
|
92
|
+
return files
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def on_page_markdown(markdown: str, **_: Any) -> str:
|
|
96
|
+
"""Expand the overview marker (MkDocs ``on_page_markdown`` event)."""
|
|
97
|
+
if OVERVIEW_MARKER not in markdown:
|
|
98
|
+
return markdown
|
|
99
|
+
return markdown.replace(OVERVIEW_MARKER, render_overview(_load_gallery()))
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# --------------------------------------------------------------------------------------
|
|
103
|
+
# Navigation
|
|
104
|
+
# --------------------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def page_path(example: Any) -> str:
|
|
108
|
+
"""Path of an example's page, relative to ``docs/``."""
|
|
109
|
+
return f"gallery/{example.name}.md"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def sections(examples: Iterable[Any]) -> dict[str, list[Any]]:
|
|
113
|
+
"""Group ``examples`` by section, sections in order of their first example."""
|
|
114
|
+
grouped: dict[str, list[Any]] = {}
|
|
115
|
+
for example in examples:
|
|
116
|
+
grouped.setdefault(example.section, []).append(example)
|
|
117
|
+
return grouped
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def gallery_nav(nav: Sequence[Any], gallery: ModuleType) -> list[Any]:
|
|
121
|
+
"""Return ``nav`` with its ``gallery/index.md`` entry expanded into the gallery section."""
|
|
122
|
+
pages = [
|
|
123
|
+
{title: [page_path(example) for example in examples]}
|
|
124
|
+
for title, examples in sections(gallery.EXAMPLES).items()
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
def expand(item: Any) -> Any:
|
|
128
|
+
if isinstance(item, dict) and list(item.values()) == [OVERVIEW]:
|
|
129
|
+
return {title: [OVERVIEW, *pages] for title in item}
|
|
130
|
+
return item
|
|
131
|
+
|
|
132
|
+
return [expand(item) for item in nav]
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# --------------------------------------------------------------------------------------
|
|
136
|
+
# Markdown
|
|
137
|
+
# --------------------------------------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def render_overview(gallery: ModuleType) -> str:
|
|
141
|
+
"""One tab per gallery style; each holds every section's cards in that style."""
|
|
142
|
+
grouped = sections(gallery.EXAMPLES)
|
|
143
|
+
tabs = []
|
|
144
|
+
for style in gallery.STYLES:
|
|
145
|
+
content = "\n\n".join(
|
|
146
|
+
_block("html", 'p.gallery-section[role="heading" aria-level="2"]', title, level=5)
|
|
147
|
+
+ "\n\n"
|
|
148
|
+
+ _block(
|
|
149
|
+
"html", "div.grid.cards.gallery-cards", _cards(gallery, examples, style), level=5
|
|
150
|
+
)
|
|
151
|
+
for title, examples in grouped.items()
|
|
152
|
+
)
|
|
153
|
+
tabs.append((style, content))
|
|
154
|
+
return _block("html", "div.gallery-overview", _tabs(tabs, level=4), level=3)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _cards(gallery: ModuleType, examples: Iterable[Any], style: str) -> str:
|
|
158
|
+
cards = []
|
|
159
|
+
for example in examples:
|
|
160
|
+
shown = style if style in gallery.styles_of(example) else gallery.DEFAULT_STYLE
|
|
161
|
+
images = _images(example, shown, alt="", width=None)
|
|
162
|
+
link = f"[{example.title}]({page_path(example).removeprefix('gallery/')})"
|
|
163
|
+
card = textwrap.indent(f"{images}\n\n{link}", " ")
|
|
164
|
+
cards.append(f"-{card[1:]}") # the list marker takes the first indent's place
|
|
165
|
+
return "\n\n".join(cards)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def render_page(gallery: ModuleType, example: Any) -> str:
|
|
169
|
+
"""The page of one example: title, description, figure and code per style, setup."""
|
|
170
|
+
figures = [
|
|
171
|
+
(style, _figure(gallery, example, style if example.styled else None))
|
|
172
|
+
for style in gallery.styles_of(example)
|
|
173
|
+
]
|
|
174
|
+
shown = _tabs(figures, level=3) if example.styled else figures[0][1]
|
|
175
|
+
# no table of contents (a page has one heading), so figure and code get its width
|
|
176
|
+
parts = ["---\nhide:\n - toc\n---", f"# {example.title}", example.description, shown]
|
|
177
|
+
setup = _setup(gallery, example)
|
|
178
|
+
return "\n\n".join([*parts, *([setup] if setup else [])]) + "\n"
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _figure(gallery: ModuleType, example: Any, style: str | None) -> str:
|
|
182
|
+
"""The image pair and the complete code of ``example`` in ``style`` (``None``: unstyled)."""
|
|
183
|
+
alt = example.title if style is None else f"{example.title}, {style} style"
|
|
184
|
+
images = _images(example, style or gallery.DEFAULT_STYLE, alt=alt, width=example.image_width)
|
|
185
|
+
code, highlighted = example_code(gallery, example, style)
|
|
186
|
+
options = f' hl_lines="{" ".join(map(str, highlighted))}"' if highlighted else ""
|
|
187
|
+
figure = _block("html", "figure.gallery-figure", images, level=4)
|
|
188
|
+
return f"{figure}\n\n```python{options}\n{code}```"
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _images(example: Any, style: str, *, alt: str, width: str | None) -> str:
|
|
192
|
+
"""Markdown for the light and the dark image of ``example`` in ``style``, lazily loaded."""
|
|
193
|
+
attributes = f'width="{width}" loading=lazy' if width else "loading=lazy"
|
|
194
|
+
return "\n".join(
|
|
195
|
+
f"}#only-{theme}){{ {attributes} }}"
|
|
196
|
+
for dark, theme in ((False, "light"), (True, "dark"))
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def example_code(gallery: ModuleType, example: Any, style: str | None) -> tuple[str, list[int]]:
|
|
201
|
+
"""The code shown for ``example``, and the numbers of the lines to highlight.
|
|
202
|
+
|
|
203
|
+
It starts with the imports the body uses and, for a style, the line that makes
|
|
204
|
+
that style; the highlighted lines are that line and those passing it on, so
|
|
205
|
+
switching tabs shows exactly what changes.
|
|
206
|
+
"""
|
|
207
|
+
body = gallery.body_source(example.func).splitlines()
|
|
208
|
+
imports = [
|
|
209
|
+
f"import {module} as {alias}"
|
|
210
|
+
for module, alias in (("matplotlib.pyplot", "plt"), ("numpy", "np"))
|
|
211
|
+
if any(re.search(rf"\b{alias}\.", text) for text in body)
|
|
212
|
+
]
|
|
213
|
+
lines = [*imports, "import rootfig as rf", ""]
|
|
214
|
+
highlighted = []
|
|
215
|
+
if style is not None:
|
|
216
|
+
lines += [f"style = {gallery.style_source(gallery.STYLES[style])}", ""]
|
|
217
|
+
highlighted.append(len(lines) - 1)
|
|
218
|
+
highlighted += [len(lines) + n for n, text in enumerate(body, 1) if "style=style" in text]
|
|
219
|
+
return "\n".join([*lines, *body]) + "\n", highlighted
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _setup(gallery: ModuleType, example: Any) -> str | None:
|
|
223
|
+
"""How to run ``example``: where the toy files come from, and the definitions it uses."""
|
|
224
|
+
shared = any(name != "style" for name in example.parameters)
|
|
225
|
+
parts = []
|
|
226
|
+
if example.toy_data:
|
|
227
|
+
parts.append(
|
|
228
|
+
"The code reads the toy dataset. In a checkout of "
|
|
229
|
+
"[rootfig](https://github.com/jbeirer/rootfig), `python examples/gallery` writes "
|
|
230
|
+
"it to `examples/out/` in a few seconds; run the code inside that directory."
|
|
231
|
+
)
|
|
232
|
+
if shared:
|
|
233
|
+
code = gallery.body_source(gallery.define, returns="omit")
|
|
234
|
+
parts.append(
|
|
235
|
+
"It uses these samples and variables, shared by the gallery examples (see "
|
|
236
|
+
f"[Samples, variables, cuts and styles](../composable.md)):\n\n```python\n{code}```"
|
|
237
|
+
)
|
|
238
|
+
if not parts:
|
|
239
|
+
return None
|
|
240
|
+
return _block("details", "Setup", "\n\n".join(parts), level=3, options="type: abstract")
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def _tabs(tabs: Iterable[tuple[str, str]], *, level: int) -> str:
|
|
244
|
+
return "\n\n".join(_block("tab", label, content, level=level) for label, content in tabs)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _block(kind: str, argument: str, content: str, *, level: int, options: str = "") -> str:
|
|
248
|
+
"""A pymdownx block; nested blocks need more slashes than the block around them."""
|
|
249
|
+
fence = "/" * level
|
|
250
|
+
header = f"{fence} {kind} | {argument}" + (f"\n {options}" if options else "")
|
|
251
|
+
return f"{header}\n\n{content}\n\n{fence}"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|