Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 94 additions & 32 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ jobs:
python tests/make_tensor.py -o $RABBIT_OUTDIR/ --histType boost --postfix boost

- name: debug input
run: debug_inputdata.py $RABBIT_OUTDIR//test_tensor.hdf5
run: rabbit_debug_inputdata.py $RABBIT_OUTDIR//test_tensor.hdf5

- name: plot input
run: >-
Expand Down Expand Up @@ -241,11 +241,9 @@ jobs:
rabbit_fit.py $RABBIT_OUTDIR/test_tensor.hdf5 -o $RABBIT_OUTDIR/ --postfix pseudodata
-t 0 --pseudoData original --doImpacts --globalImpacts --unblind ^sig$


alternative-fits:
sparse-fits:
runs-on: [self-hosted, linux, x64]
needs: [setenv, make-tensor]

steps:
- env:
RABBIT_OUTDIR: ${{ needs.setenv.outputs.RABBIT_OUTDIR }}
Expand All @@ -265,32 +263,96 @@ jobs:
--saveHists --saveHistsPerProcess --computeHistErrors --computeHistErrorsPerProcess
-m Project ch1 a -m Project ch1 b

- name: covariance fit
run: >-
rabbit_fit.py $RABBIT_OUTDIR/test_tensor.hdf5 -o $RABBIT_OUTDIR/ --postfix covariance
-t 0 --unblind --covarianceFit --doImpacts --globalImpacts
--saveHists --saveHistsPerProcess --computeHistErrors --computeHistErrorsPerProcess
-m Project ch1 a -m Project ch1 b
alternative-fits:
runs-on: [self-hosted, linux, x64]
needs: [setenv, make-tensor]
strategy:
fail-fast: false
matrix:
include:
- name: covariance
tensor: test_tensor.hdf5
fit_args: >-
--covarianceFit
- name: linearized
tensor: test_tensor_symmetric.hdf5
fit_args: >-
--binByBinStatType normal-additive --allowNegativePOI
- name: bb_full_normal_additive
tensor: test_tensor.hdf5
fit_args: >-
--binByBinStatType normal-additive --binByBinStatMode full
- name: bb_full_normal_multiplicative
tensor: test_tensor.hdf5
fit_args: >-
--binByBinStatType normal-multiplicative --binByBinStatMode full
- name: bb_full_gamma
tensor: test_tensor.hdf5
fit_args: >-
--binByBinStatType gamma --binByBinStatMode full --globalImpactsDisableJVP

- name: linearized solution
run: >-
rabbit_fit.py $RABBIT_OUTDIR/test_tensor_symmetric.hdf5 -o $RABBIT_OUTDIR/ --postfix linearized
-t 0 --chisqFit --doImpacts --globalImpacts --binByBinStatType normal-additive --allowNegativePOI
--saveHists --saveHistsPerProcess --computeHistErrors --computeHistErrorsPerProcess
--computeHistImpacts --computeHistCov -m Project ch1 a -m Project ch1 b
steps:
- env:
RABBIT_OUTDIR: ${{ needs.setenv.outputs.RABBIT_OUTDIR }}
PYTHONPATH: ${{ needs.setenv.outputs.PYTHONPATH }}
PATH: ${{ needs.setenv.outputs.PATH }}
WEB_DIR: ${{ needs.setenv.outputs.WEB_DIR }}
PLOT_DIR: ${{ needs.setenv.outputs.PLOT_DIR }}
run: |
echo "RABBIT_OUTDIR=${RABBIT_OUTDIR}" >> $GITHUB_ENV
echo "PYTHONPATH=${PYTHONPATH}" >> $GITHUB_ENV
echo "PATH=${PATH}" >> $GITHUB_ENV
echo "WEB_DIR=${WEB_DIR}" >> $GITHUB_ENV
echo "PLOT_DIR=${PLOT_DIR}" >> $GITHUB_ENV

- name: Barlow--Beeston full (gamma)
run: >-
rabbit_fit.py $RABBIT_OUTDIR/test_tensor_symmetric.hdf5 -o $RABBIT_OUTDIR/ --postfix nonlinear
-t 0 --doImpacts --globalImpacts --globalImpactsDisableJVP --binByBinStatType gamma --binByBinStatMode full
--saveHists --saveHistsPerProcess --computeHistErrors --computeHistErrorsPerProcess
--computeHistImpacts --computeHistCov -m Project ch1 a -m Project ch1 b
- uses: actions/checkout@v5

- name: chi2 fit with Barlow--Beeston full (normal-multiplicative)
run: >-
rabbit_fit.py $RABBIT_OUTDIR/test_tensor_symmetric.hdf5 -o $RABBIT_OUTDIR/ --postfix bb_full
-t 0 --globalImpacts --binByBinStatType normal-multiplicative --binByBinStatMode full
- name: fit ${{ matrix.name }}
run: >-
rabbit_fit.py $RABBIT_OUTDIR/${{ matrix.tensor }} -o $RABBIT_OUTDIR/ --postfix ${{ matrix.name }}
-t -1 0 --doImpacts --globalImpacts --gaussianGlobalImpacts ${{ matrix.fit_args }}
-m Project ch1 a -m Project ch1 b --saveHists --saveHistsPerProcess --computeHistErrors
--computeHistErrorsPerProcess --computeHistImpacts --computeHistGaussianImpacts --computeHistCov

- name: print impacts ${{ matrix.name }}
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 -u

- name: print gaussian global impacts ${{ matrix.name }}
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 --impactType gaussian_global

- name: print global impacts ${{ matrix.name }}
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 -s --impactType global

- name: plot impacts ${{ matrix.name }}
run: >-
rabbit_plot_pulls_and_impacts.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 -o $WEB_DIR/$PLOT_DIR/${{ matrix.name }}
--otherExtensions pdf png -n 50 --config tests/style_config.py -s absimpact --subtitle "Work in progress"
--grouping max --postfix ${{ matrix.name }}

- name: plot gaussian global impacts ${{ matrix.name }}
run: >-
rabbit_plot_pulls_and_impacts.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 -o $WEB_DIR/$PLOT_DIR/${{ matrix.name }}
--otherExtensions pdf png -n 50 --config tests/style_config.py -s absimpact --subtitle Preliminary
--grouping max --postfix ${{ matrix.name }} --impactType gaussian_global
--refResult asimov --refName "asimov" --name "data"

- name: plot global impacts ${{ matrix.name }}
run: >-
rabbit_plot_pulls_and_impacts.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 -o $WEB_DIR/$PLOT_DIR/${{ matrix.name }}
--otherExtensions pdf png -n 50 --config tests/style_config.py -s absimpact
--grouping max --postfix ${{ matrix.name }} --impactType global --oneSidedImpacts

- name: plot postfit distributions ${{ matrix.name }}
run: >-
rabbit_plot_hists.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 -o $WEB_DIR/$PLOT_DIR/${{ matrix.name }}
--extraTextLoc '0.05' '0.7' --legCols 1 -m Project ch1 a -m Project ch1 b --yscale '1.2'
--subtitle "Work in progress" --config tests/style_config.py

- name: plot histogram uncertainties ${{ matrix.name }}
run: >-
rabbit_plot_hists_uncertainties.py $RABBIT_OUTDIR/fitresults_${{ matrix.name }}.hdf5 -o $WEB_DIR/$PLOT_DIR/${{ matrix.name }}
--extraTextLoc '0.05' '0.7' --legCols 1 -m Project ch1 a -m Project ch1 b --yscale '1.2'
--subtitle "Work in progress" --config tests/style_config.py

bsm:
runs-on: [self-hosted, linux, x64]
Expand Down Expand Up @@ -348,10 +410,10 @@ jobs:
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults.hdf5 -s

- name: print global impacts
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults.hdf5 -s --globalImpacts
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults.hdf5 -s --impactType global

- name: print global impacts of observable
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults.hdf5 --globalImpacts -m Project ch0_masked --ungroup --sort
run: rabbit_print_impacts.py $RABBIT_OUTDIR/fitresults.hdf5 --impactType global -m Project ch0_masked --ungroup --sort

- name: plot impacts
run: >-
Expand All @@ -362,14 +424,14 @@ jobs:
run: >-
rabbit_plot_pulls_and_impacts.py $RABBIT_OUTDIR/fitresults.hdf5 -o $WEB_DIR/$PLOT_DIR
-r $RABBIT_OUTDIR/fitresults_pseudodata.hdf5 --refResult original --refName "Pseudo data" -s absimpact
--otherExtensions pdf png -n 50 --config tests/style_config.py --oneSidedImpacts --globalImpacts --diffPullAsym --showNumbers
--otherExtensions pdf png -n 50 --config tests/style_config.py --oneSidedImpacts --impactType global --diffPullAsym --showNumbers
--grouping max --subtitle Preliminary --postfix data_vs_pseudodata

- name: plot global impacts on observable
run: >-
rabbit_plot_pulls_and_impacts.py $RABBIT_OUTDIR/fitresults.hdf5 -o $WEB_DIR/$PLOT_DIR
-s absimpact -m Project ch0_masked
--otherExtensions pdf png -n 50 --config tests/style_config.py --oneSidedImpacts --globalImpacts --showNumbers
--otherExtensions pdf png -n 50 --config tests/style_config.py --oneSidedImpacts --impactType global --showNumbers
--grouping max --subtitle Preliminary --postfix ch0_masked

- name: plot prefit distributions
Expand Down Expand Up @@ -411,7 +473,7 @@ jobs:

- name: plot histogram covariance matrices
run: >-
rabbit_plot_hists_cov.py $RABBIT_OUTDIR/fitresults.hdf5 -o $WEB_DIR/$PLOT_DIR
rabbit_plot_cov.py $RABBIT_OUTDIR/fitresults.hdf5 -o $WEB_DIR/$PLOT_DIR
--subtitle Preliminary -m Project ch1 a -m Project ch1 b --subtitle Preliminary --config tests/style_config.py


Expand Down Expand Up @@ -456,7 +518,7 @@ jobs:

copy-clean:
runs-on: [self-hosted, linux, x64]
needs: [setenv, symmerizations, alternative-fits, bsm, plotting, likelihoodscans]
needs: [setenv, symmerizations, sparse-fits, alternative-fits, bsm, plotting, likelihoodscans]
if: always()
steps:
- env:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ source env/bin/activate
pip install wums[pickling,plotting] tensorflow tensorflow-probability tf_keras numpy h5py hist scipy matplotlib mplhep seaborn pandas plotly kaleido
```
The packages `matplotlib`, `mplhep`, `seaborn`, `pandas`, `plotly`, and `kaleido` are only needed for the plotting scripts.
For the `text2hdf5.py` conversion also the `uproot` package is needed.
For the `rabbit_text2hdf5.py` conversion also the `uproot` package is needed.
In case you want to contribute to the development, please also install the linters `isort`, `flake8`, `autoflake`, `black`, and `pylint` used in the pre-commit hooks and the github CI
Deactivate the environment with `deactivate`.

Expand Down Expand Up @@ -110,15 +110,15 @@ This is done by defining `masked=True` in the `tensorwriter` `add_channel` funct
This is useful for example to compute unfolded (differential) cross sections and their uncertainties, including global impacts, taking into account all nuisance parameters that affect these channels.

### text2hdf5
The input tensor can also be generated from the input used for the [Combine tool](https://link.springer.com/article/10.1007/s41781-024-00121-4) using the `text2hdf5.py` command.
The input tensor can also be generated from the input used for the [Combine tool](https://link.springer.com/article/10.1007/s41781-024-00121-4) using the `rabbit_text2hdf5.py` command.
This script is mainly intended for users that have these inputs already and want to perform some cross checks.
Only basic functionality is supported and for complex models the conversion can take long, it is thus recommended to directly produce the input tensor using the provided interface as explained above.

### Diagnostics
Scripts for diagnosing the input tensor are available:
Running some checks for empty bins etc.
```bash
debug_inputdata.py test_tensor.hdf5
rabbit_debug_inputdata.py test_tensor.hdf5
```
Plotting the histograms that are actually used in the fit, supporting adding of systematic variations in the plot:
```bash
Expand Down
41 changes: 16 additions & 25 deletions bin/debug_inputdata.py → bin/rabbit_debug_inputdata.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
#!/usr/bin/env python
import argparse

import hist
import numpy as np
from wums import logging

from rabbit import debugdata, inputdata
from rabbit import debugdata, inputdata, parsing

logger = None


def make_parser():
parser = parsing.print_parser()
parser.description = "Debug input data for fitting"
parser.add_argument(
"--channels",
type=str,
help="Only check specified channels",
default=None,
nargs="+",
)
return parser


def debug_input_data(input_file, output_dir=None, verbose=False, channels=None):
"""
Debug input data file and report potential issues
Expand Down Expand Up @@ -254,32 +265,12 @@ def debug_input_data(input_file, output_dir=None, verbose=False, channels=None):


def main():
parser = argparse.ArgumentParser(description="Debug input data for fitting")
parser.add_argument("inputFile", help="Path to input data file")
parser.add_argument(
"-v",
"--verbose",
type=int,
default=3,
choices=[0, 1, 2, 3, 4],
help="Set verbosity level with logging, the larger the more verbose",
)
parser.add_argument(
"--noColorLogger", action="store_true", help="Do not use logging with colors"
)
parser.add_argument(
"--channels",
type=str,
help="Only check specified channels",
default=None,
nargs="+",
)
args = parser.parse_args()
args = make_parser().parse_args()

global logger
logger = logging.setup_logger(__file__, args.verbose, args.noColorLogger)

debug_input_data(args.inputFile, args.verbose, channels=args.channels)
debug_input_data(args.infile, args.verbose, channels=args.channels)


if __name__ == "__main__":
Expand Down
Loading