Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
669946c
Draft: Implement Combine backend skeleton and object-oriented fit con…
Jun 25, 2026
399160d
Feat: Port datacard writer and validation to backend
Jun 25, 2026
2b3b38d
Feat: Integrate fit subcommand and parser into FCCAnalyses wrapper
Jun 26, 2026
70ea34a
Refactor: Modularize fit command to support multiple backends via --b…
Jun 26, 2026
03e42c1
Fix systematics matrix column alignment and add multi-channel ZH phys…
Jun 26, 2026
8a1b92c
feat: add -e/--execute and -l flags for direct combine fitting
Jun 29, 2026
4f1369b
chore: remove redundant dummy_fit.py example template
Jul 2, 2026
624a38b
feat: implement double-dash argument forwarding to wrapped tools
Jul 6, 2026
04c784f
feat: strip literal double-dash from tool arguments before execution
Jul 6, 2026
6b91783
feat: implement shape systematics validation and update example template
Jul 6, 2026
4532687
fix: resolve argument conflicts when forwarding custom combine methods
Jul 6, 2026
f250900
add CLI usage examples to example script and parser help
Jul 16, 2026
050e0bf
rename configuration validation to sanitization
Jul 16, 2026
c32f37c
handle keyboard interrupt to ensure termination on Ctrl+C
Jul 16, 2026
d7a9c59
feat: organize combine output files dynamically
Jul 16, 2026
55d8c31
optimize shape sanitization via bulk pre-loading and TFile disassocia…
Jul 17, 2026
b0868c4
ensure auto-creation of missing output directories and implement CI test
Jul 17, 2026
60000a4
fix: resolve combine argument positioning and update integration test…
Jul 17, 2026
ba183c6
fix: remove redundant duplicate subprocess execution block
Jul 17, 2026
4f9c713
fix test: enforce repository root cwd
Jul 17, 2026
a9267dd
fix test: enforce sys.executable and inject local PYTHONPATH for CI r…
Jul 17, 2026
b8fdc81
fix test: skip execution test in CI environments missing combine binary
Jul 17, 2026
fee4f2e
fix test: if/elif logic to prevent fallthrough on missing combine binary
Jul 17, 2026
695c632
refactor: rename user configuration class to Fit
Jul 17, 2026
52e2da2
Potential fix for pull request finding
captainvogon Jul 21, 2026
50ab041
fix: apply copilot review suggestions for variable scoping, temp dirs…
Jul 21, 2026
fb64477
test: convert example systematic to lnN
Jul 21, 2026
f383fb1
feat: add combine_args support to Fit config, enforce --out, and hand…
Jul 21, 2026
83ef04e
update default Combine exec method from AsymptoticLimits to MultiDimFit
captainvogon Aug 7, 2026
0642801
feat: enable autodiff by default and handle --out overrides
Aug 8, 2026
27a5faa
feat: integrate python-based ROOT extraction and add extract subcommand
Aug 15, 2026
9141122
docs: add man pages and documentation for fit and extract subcommands
Aug 15, 2026
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
6 changes: 6 additions & 0 deletions bin/fccanalysis
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ from run_analysis import run
from run_final_analysis import run_final
from do_plots import do_plots
from do_combine import do_combine
from fit import run_fit
from extract import run_extract


# _____________________________________________________________________________
Expand Down Expand Up @@ -125,6 +127,10 @@ def main():
do_plots(parser)
elif args.command == 'combine':
do_combine(parser)
elif args.command == 'fit':
run_fit(parser)
elif args.command == 'extract':
run_extract(parser)
else:
run(parser)

Expand Down
104 changes: 104 additions & 0 deletions examples/fcc_ee_zh_mumu_bb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""Example configuration script for FCC-ee ZH angular/mass fitting.

Usage Examples:
1. Generate the text datacard only:
fccanalysis fit examples/fcc_ee_zh_mumu_bb.py -o outputs/datacard.txt

2. Generate datacard and run the default AsymptoticLimits engine:
fccanalysis fit examples/fcc_ee_zh_mumu_bb.py -o outputs/datacard.txt -e

3. Override the default engine with custom options (e.g. FitDiagnostics):
fccanalysis fit examples/fcc_ee_zh_mumu_bb.py -o outputs/datacard.txt -e -- -M FitDiagnostics
"""

class Fit:
def __init__(self):
Comment thread
kjvbrt marked this conversation as resolved.
# 1. Global framework configurations
self.autoMCStats = False

# 2. Path templates for the input shape histograms
self.shapes = {
"*": {
"mumu_bjets_channel": "fcc_ee_zh_shapes.root $CHANNEL/$PROCESS $CHANNEL/$PROCESS_$SYSTEMATIC",
"mumu_inter_channel": "fcc_ee_zh_shapes.root $CHANNEL/$PROCESS $CHANNEL/$PROCESS_$SYSTEMATIC"
}
}

# 3. Channel definitions based on event selection categories
# Category 1: High purity b-tagged category
# Category 2: Intermediate/loose b-tagged category (to constrain backgrounds)
self.channels = {
"mumu_bjets_channel": {
"observation": -1, # -1 instructs Combine to use asymptotic or toy datasets
"processes": {
"ZH_signal": {"type": "signal", "rate": -1},
"ZZ_bkg": {"type": "background", "rate": -1},
"Zjets_bkg": {"type": "background", "rate": -1}
}
},
"mumu_inter_channel": {
"observation": -1,
"processes": {
"ZH_signal": {"type": "signal", "rate": -1},
"ZZ_bkg": {"type": "background", "rate": -1},
"Zjets_bkg": {"type": "background", "rate": -1}
}
}
}

# 4. Systematics Matrix
# Models how uncertainties affect each process in each distinct channel
self.systematics = {
# Integrated luminosity precision at FCC-ee (highly precise, ~0.1% to 0.5%)
"lumi_FCC": {
"type": "lnN",
"apply_to": {
"ZH_signal": 1.005,
"ZZ_bkg": 1.005,
"Zjets_bkg": 1.005
}
},
# Muon tracking and Identification efficiency uncertainty
"muon_eff": {
"type": "lnN",
"apply_to": {
"ZH_signal": 1.01,
"ZZ_bkg": 1.01,
"Zjets_bkg": 1.01
}
},
# B-tagging efficiency uncertainty (highly correlated with signal)
"btag_eff": {
"type": "lnN",
"apply_to": {
"ZH_signal": {"mumu_bjets_channel": 1.03, "mumu_inter_channel": 0.98},
"ZZ_bkg": {"mumu_bjets_channel": 1.03, "mumu_inter_channel": 0.98}
}
},
# Mistag rate uncertainty for light/charm jets leaking into the b-jet channel
"mistag_light": {
"type": "lnN",
"apply_to": {
"Zjets_bkg": {"mumu_bjets_channel": 1.10, "mumu_inter_channel": 1.04}
}
},
# Theoretical cross-section uncertainty for electroweak backgrounds
"theory_ZZ_xsec": {
"type": "lnN",
"apply_to": {
"ZZ_bkg": 1.04
}
},
# Recoil mass resolution shape systematic
"recoil_res": {
"type": "lnN",
"apply_to": {
"ZH_signal": 1.05,
"ZZ_bkg": 1.05
}
}
}

# Optional: Define default command-line arguments to pass to the Combine tool
# The framework will automatically append `--out <output_dir>` to this.
self.combine_args = "-M FitDiagnostics"
33 changes: 33 additions & 0 deletions man/man1/fccanalysis-extract.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.\" Manpage for fccanalysis-extract
.\" Contact FCC-PED-SoftwareAndComputing-Analysis@cern.ch to correct errors or typos.
.TH FCCANALYSIS\-EXTRACT 1 "August 2026" "0.12.0" "fccanalysis-extract man page"

.SH NAME
\fBfccanalysis\-extract\fR \- extract parameters and uncertainties from Combine ROOT files

.SH SYNOPSIS
.B fccanalysis extract
[\fB\-h\fR | \fB\-\-help\fR]
.B input_path

.SH DESCRIPTION
.B fccanalysis\-extract
is a standalone utility that reads ROOT files generated by Higgs Combine (e.g.,
\fIhiggsCombineTest.MultiDimFit.mH120.root\fR). It performs dynamic branch detection
to locate the Parameter of Interest (POI) and applies linear interpolation to
calculate and display the 1-sigma (68% CL) crossing uncertainties.

It safely handles grid scans and gracefully falls back to displaying expected and
observed quantiles if the file was generated using the AsymptoticLimits method.

.SH OPTIONS
.TP
.B input_path
Path to a specific \fIhiggsCombine*.root\fR file, or a directory containing one.
If a directory is provided, the most recently modified Combine ROOT file will be used.
.TP
.BR \-h ", " \-\-help
Prints short help message and exits\&.

.SH SEE ALSO
fccanalysis(1), fccanalysis-fit(1)
54 changes: 54 additions & 0 deletions man/man1/fccanalysis-fit.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.\" Manpage for fccanalysis-fit
.\" Contact FCC-PED-SoftwareAndComputing-Analysis@cern.ch to correct errors or typos.
.TH FCCANALYSIS\-FIT 1 "August 2026" "0.12.0" "fccanalysis-fit man page"

.SH NAME
\fBfccanalysis\-fit\fR \- generate combine datacards and execute statistical fits

.SH SYNOPSIS
.B fccanalysis fit
[\fB\-h\fR | \fB\-\-help\fR]
[\fB\-o\fR \fIOUTPUT\fR | \fB\-\-output\fR \fIOUTPUT\fR]
[\fB\-b\fR \fIBACKEND\fR | \fB\-\-backend\fR \fIBACKEND\fR]
[\fB\-e\fR | \fB\-\-execute\fR]
.B analysis-script
\-\-
[\fICOMBINE ARGUMENTS\fR]

.SH DESCRIPTION
.B fccanalysis\-fit
parses an object-oriented Python configuration script containing a \fIFit\fR class
to dynamically generate a text-based datacard for statistical inference.

If the \fB\-\-execute\fR flag is provided, the script will automatically invoke the
underlying statistical engine (e.g., Higgs Combine) on the generated datacard.
Output ROOT files are automatically shifted to the datacard directory, and
1-sigma crossing uncertainties are automatically extracted and displayed.

.SH OPTIONS
.TP
.B analysis-script
Path to the Python analysis script containing the \fIFit\fR class.
.TP
.BR \-h ", " \-\-help
Prints short help message and exits\&.
.TP
\fB\-o\fR \fIOUTPUT\fR, \fB\-\-output\fR \fIOUTPUT\fR
Path where the generated datacard.txt will be saved\&.
.TP
\fB\-b\fR \fIBACKEND\fR, \fB\-\-backend\fR \fIBACKEND\fR
Specify the statistical backend to use\&. Currently supported: \fBcombine\fR.
.br
Default value: \fBcombine\fR.
.TP
.BR \-e ", " \-\-execute
Execute the statistical backend after generating the datacard.
.TP
.I COMBINE ARGUMENTS
Command line arguments passed after the \fB\-\-\fR separator will not be parsed
by the framework and will be forwarded directly to the backend Combine engine
(e.g., \fB\-M FitDiagnostics\fR or \fB\-\-algo grid\fR). These override any default
arguments defined in the Python class.

.SH SEE ALSO
fccanalysis(1), fccanalysis-script(7), fccanalysis-extract(1)
8 changes: 7 additions & 1 deletion man/man1/fccanalysis-run.1
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
[\fB\-\-graph\-path\fR \fIGRAPH_PATH\fR]
[\fB\-\-use-data-source\fR]
[\fB\-\-output\-dir\fR \fIOUTPUT_DIR\fR]
[\fB\-\-output\-format\fR {\fBttree\fR,\fBrntuple\fR}]
[\fB\-a\fR \fIANALYSIS_NAME\fR | \fB\-\-analysis\-name\fR \fIANALYSIS_NAME\fR]
[\fB\-\-apply\-filepath\-rewrites\fR | \fB\-\-no\-filepath\-rewrites\fR]
[\fB\-s\fR \fISAMPLE_NAME\fR | \fB\-\-sample\-name\fR \fISAMPLE_NAME\fR]
Expand Down Expand Up @@ -78,6 +79,11 @@ Load events through podio::DataSource\&.
\fB\-\-output\-dir\fR \fIOUTPUT_DIR\fR
Set global output directory for the analysis.
.TP
\fB\-\-output\-format\fR {\fBttree\fR, \fBrntuple\fR}
Specify the output ROOT file format.
.br
Default value: \fBttree\fR.
.TP
\fB\-a\fR \fIANALYSIS_NAME\fR, \fB\-\-analysis\-name\fR \fIANALYSIS_NAME\fR
Set analysis name, mostly used for the output path.
.TP
Expand Down Expand Up @@ -124,7 +130,7 @@ Controls search path for the process dictionaries. The default value is
\fI/cvmfs/fcc.cern.ch/FCCDicts/\fR\&.

.SH SEE ALSO
fccanalysis(1), fccanalysis-script(7)
fccanalysis(1), fccanalysis-script(7), fccanalysis-fit(1), fccanalysis-extract(1)

.SH BUGS
Many
Expand Down
23 changes: 22 additions & 1 deletion man/man7/fccanalysis-script.7
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ These stages do not require \fIAnalysis\fR class neither \fIbuild_graph\fR
function, they have their own set of attributes, please see the
examples in the \fIexamples\fR of FCCAnalyses repository or
fccanalysis-final-script(7) and fccanalysis-plots-script(7) manual pages.
.TP
\fBFit style analysis\fR
The analysis script needs to contain a \fIFit\fR class of the following
structure to generate Higgs Combine datacards:
.IP
class Fit():
def __init__(self, cmdline_args):
self.datacard_dir = "outputs/datacards/"
self.combine_args = "\-M MultiDimFit \-\-algo grid"
self.processes = {
"signal": 0,
"background": 1
}
self.channels = {
"channel_name": { ... }
}

.SH ATTRIBUTES
In case of running the FCCAnalysis in the staged style user can/should add the
Expand Down Expand Up @@ -149,6 +165,11 @@ the sub-folders of $FCCDICTSDIR\&.
\fBoutput_dir\fR (mandatory)
User can specify the directory for the output files\&.
.TP
\fBoutput_format\fR (optional)
Specifies the output ROOT file format. Accepted values are \fBttree\fR and \fBrntuple\fR.
.br
Default value: ttree
.TP
\fBanalysis_name\fR (optional)
Optional name for the analysis
.br
Expand Down Expand Up @@ -232,7 +253,7 @@ sample.
This section is under construction. You are invited to help :)

.SH SEE ALSO
fccanalysis(1), fccanalysis-run(1)
fccanalysis(1), fccanalysis-run(1), fccanalysis-fit(1), fccanalysis-extract(1)

.SH BUGS
Many
Expand Down
Loading
Loading