-
Notifications
You must be signed in to change notification settings - Fork 429
WIP: First implementation of ATLAS-style global impacts #1197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -38,25 +38,33 @@ def list_from_workspace(file, workspace, set): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return res | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def prefit_from_workspace(file, workspace, params, setPars=None): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def prefit_from_workspace(file, workspace, params, setPars=None, constPars=None): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Given a list of params, return a dictionary of [-1sig, nominal, +1sig]""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| wsFile = ROOT.TFile(file) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ws = wsFile.Get(workspace) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ROOT.RooMsgService.instance().setGlobalKillBelow(ROOT.RooFit.WARNING) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updatePars = dict() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if setPars is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parsToSet = [tuple(x.split("=")) for x in setPars.split(",")] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allParams = ws.allVars() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allParams.add(ws.allCats()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for par, val in parsToSet: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmp = allParams.find(par) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isrvar = tmp.IsA().InheritsFrom(ROOT.RooRealVar.Class()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if isrvar: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updatePars[par] = (float(val), True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if constPars is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for par, val in constPars.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updatePars[par] = (float(val), False) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allParams = ws.allVars() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allParams.add(ws.allCats()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for par, (val, verbose) in updatePars.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmp = allParams.find(par) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isrvar = tmp.IsA().InheritsFrom(ROOT.RooRealVar.Class()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if isrvar: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if verbose: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Setting parameter {par} to {float(val):g}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmp.setVal(float(val)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmp.setVal(float(val)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if verbose: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Setting index {par} to {float(val):g}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmp.setIndex(int(val)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmp.setIndex(int(val)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for p in params: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res[p] = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -87,6 +95,29 @@ def prefit_from_workspace(file, workspace, params, setPars=None): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errlo = -1 * var.getErrorLo() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errhi = +1 * var.getErrorHi() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res[p]["prefit"] = [val - errlo, val, val + errhi] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # For non-Gaussian, the best fit and uncertainties of the gobs (given x), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # may not be the same as the best fit and uncertainties on x. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Let's calculate these here in case we want them later | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var.setConstant(True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gobs.setConstant(False) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nll2 = ROOT.RooConstraintSum("NLL", "", ROOT.RooArgSet(pdf), ROOT.RooArgSet(gobs)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minim = ROOT.RooMinimizer(nll2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minim.setEps(0.001) # Might as well get some better precision... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minim.setErrorLevel(0.5) # Unlike for a RooNLLVar we must set this explicitly | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minim.setPrintLevel(-1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minim.setVerbose(False) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Run the fit then run minos for the error | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minim.minimize("Minuit2", "migrad") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minim.minos(ROOT.RooArgSet(gobs)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Should really have checked that these converged ok... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # var.Print() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # pdf.Print() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val = gobs.getVal() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errlo = -1 * gobs.getErrorLo() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errhi = +1 * gobs.getErrorHi() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res[p]["globalobs"] = [val - errlo, val, val + errhi] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+102
to
+119
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Restore constant flags after the globalobs fit.
🔧 Proposed fix- var.setConstant(True)
- gobs.setConstant(False)
- nll2 = ROOT.RooConstraintSum("NLL", "", ROOT.RooArgSet(pdf), ROOT.RooArgSet(gobs))
- minim = ROOT.RooMinimizer(nll2)
- minim.setEps(0.001) # Might as well get some better precision...
- minim.setErrorLevel(0.5) # Unlike for a RooNLLVar we must set this explicitly
- minim.setPrintLevel(-1)
- minim.setVerbose(False)
- # Run the fit then run minos for the error
- minim.minimize("Minuit2", "migrad")
- minim.minos(ROOT.RooArgSet(gobs))
- # Should really have checked that these converged ok...
- # var.Print()
- # pdf.Print()
- val = gobs.getVal()
- errlo = -1 * gobs.getErrorLo()
- errhi = +1 * gobs.getErrorHi()
- res[p]["globalobs"] = [val - errlo, val, val + errhi]
+ var_was_const = var.isConstant()
+ gobs_was_const = gobs.isConstant()
+ try:
+ var.setConstant(True)
+ gobs.setConstant(False)
+ nll2 = ROOT.RooConstraintSum("NLL", "", ROOT.RooArgSet(pdf), ROOT.RooArgSet(gobs))
+ minim = ROOT.RooMinimizer(nll2)
+ minim.setEps(0.001) # Might as well get some better precision...
+ minim.setErrorLevel(0.5) # Unlike for a RooNLLVar we must set this explicitly
+ minim.setPrintLevel(-1)
+ minim.setVerbose(False)
+ # Run the fit then run minos for the error
+ minim.minimize("Minuit2", "migrad")
+ minim.minos(ROOT.RooArgSet(gobs))
+ # Should really have checked that these converged ok...
+ # var.Print()
+ # pdf.Print()
+ val = gobs.getVal()
+ errlo = -1 * gobs.getErrorLo()
+ errhi = +1 * gobs.getErrorHi()
+ res[p]["globalobs"] = [val - errlo, val, val + errhi]
+ finally:
+ var.setConstant(var_was_const)
+ gobs.setConstant(gobs_was_const)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if pdf.IsA().InheritsFrom(ROOT.RooGaussian.Class()): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res[p]["type"] = "Gaussian" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif pdf.IsA().InheritsFrom(ROOT.RooPoisson.Class()): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -183,3 +214,13 @@ def get_fixed_results(file, params): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res["deltaNLL"] = getattr(t, "deltaNLL") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res["pvalue"] = getattr(t, "quantileExpected") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return res | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def get_rfr_constvars(filename, rfr_name): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f = ROOT.TFile(filename) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rfr = f.Get(rfr_name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res = dict() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| constpars = rfr.constPars() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for v in constpars: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res[v.GetName()] = v.getVal() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f.Close() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return res | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,92 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env python3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import math | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import argparse | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def IsConstrained(param_info): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return param_info["type"] != "Unconstrained" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser = argparse.ArgumentParser() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser.add_argument("--input", "-i", help="input json file") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args = parser.parse_args() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Load the json output of combineTool.py -M Impacts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with open(args.input) as jsonfile: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data = json.load(jsonfile) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+9
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Require --input to avoid cryptic failures. Without ✅ Proposed fix-parser.add_argument("--input", "-i", help="input json file")
+parser.add_argument("--input", "-i", required=True, help="input json file")📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # # Set the global plotting style | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # plot.ModTDRStyle(l=args.left_margin, b=0.10, width=(900 if args.checkboxes else 700), height=args.height) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # # We will assume the first POI is the one to plot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| POIs = [ele["name"] for ele in data["POIs"]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| POIdata = {ele["name"]: ele for ele in data["POIs"]} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| proto = {POI: 0. for POI in POIs} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fit_val = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_tot_hi = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_tot_lo = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get the list of groups | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| groups = set(["TOTAL"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ele in data["params"]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| groups.update(ele["groups"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_hi = {grp : dict(proto) for grp in groups} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_lo = {grp : dict(proto) for grp in groups} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for POI in POIs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fit_val[POI] = POIdata[POI]["fit"][1] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_tot_hi[POI] = POIdata[POI]["fit"][2] - POIdata[POI]["fit"][1] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_tot_lo[POI] = POIdata[POI]["fit"][1] - POIdata[POI]["fit"][0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for ele in data["params"]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if IsConstrained(ele): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name = ele["name"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # We expect to find "global_[POI]" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for POI in POIs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| impact = ele[f"global_{POI}"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| impact_hi = impact[2] - impact[1] # impact from shifting global obs up | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| impact_lo = impact[0] - impact[1] # impact from shifting global obs down | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check different situations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_hi = 0. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_lo = 0. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if impact_hi >= 0. and impact_lo <= 0.: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_hi = impact_hi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_lo = impact_lo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif impact_hi <=0. and impact_lo >= 0.: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_lo = impact_hi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_hi = impact_lo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif impact_hi >= 0. and impact_lo >= 0.: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Warning, parameter {name} has global impact on {POI} that are both positive: ({impact_hi},{impact_lo}), we will take the max of the two") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_hi = max(impact_hi, impact_lo) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif impact_lo <= 0. and impact_lo <= 0.: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Warning, parameter {name} has global impact on {POI} that are both negative: ({impact_hi},{impact_lo}), we will take the min of the two") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contrib_lo = min(impact_hi, impact_lo) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+55
to
+67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the sign-logic condition typo. The “both negative” branch repeats 🧩 Proposed fix- elif impact_lo <= 0. and impact_lo <= 0.:
+ elif impact_hi <= 0. and impact_lo <= 0.:📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for grp in ["TOTAL"] + ele["groups"]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_hi[grp][POI] += pow(contrib_hi, 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_lo[grp][POI] += pow(contrib_lo, 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # print(ele["name"], POI, impact_hi, impact_lo, contrib_hi, contrib_lo) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_hi["STAT"] = dict(proto) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_lo["STAT"] = dict(proto) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for POI in POIs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_hi["STAT"][POI] = math.sqrt(pow(err_tot_hi[POI], 2) - err_hi["TOTAL"][POI]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_lo["STAT"][POI] = math.sqrt(pow(err_tot_lo[POI], 2) - err_lo["TOTAL"][POI]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+73
to
+77
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard against negative under the square root for STAT. Rounding or over-aggregation can make the term slightly negative, which will crash with a math domain error. Clamp at zero and optionally warn. 🧪 Proposed fix for POI in POIs:
- err_hi["STAT"][POI] = math.sqrt(pow(err_tot_hi[POI], 2) - err_hi["TOTAL"][POI])
- err_lo["STAT"][POI] = math.sqrt(pow(err_tot_lo[POI], 2) - err_lo["TOTAL"][POI])
+ stat_hi_sq = pow(err_tot_hi[POI], 2) - err_hi["TOTAL"][POI]
+ stat_lo_sq = pow(err_tot_lo[POI], 2) - err_lo["TOTAL"][POI]
+ err_hi["STAT"][POI] = math.sqrt(max(0.0, stat_hi_sq))
+ err_lo["STAT"][POI] = math.sqrt(max(0.0, stat_lo_sq))🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for grp in groups: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for POI in POIs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_hi[grp][POI] = math.sqrt(err_hi[grp][POI]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err_lo[grp][POI] = math.sqrt(err_lo[grp][POI]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for POI in POIs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f'POI: {POI:<20} {"Best-fit":>20} : {fit_val[POI]:<10.3f}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f'POI: {POI:<20} {"Total uncertainty":>20} : +{err_tot_hi[POI]:<10.3f} -{err_tot_lo[POI]:<10.3f}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f'POI: {POI:<20} {"Stat":>20} : +{err_hi["STAT"][POI]:<10.3f} -{err_lo["STAT"][POI]:<10.3f}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f'POI: {POI:<20} {"Syst":>20} : +{err_hi["TOTAL"][POI]:<10.3f} -{err_lo["TOTAL"][POI]:<10.3f}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for grp in groups: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if grp in ["TOTAL", "STAT"]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f'POI: {POI:<20} {grp:>20} : +{err_hi[grp][POI]:<10.3f} -{err_lo[grp][POI]:<10.3f}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard against unknown parameters in updatePars.
allParams.find(par)can returnNone, leading to an AttributeError. Add a clear error instead.🧯 Proposed fix
🤖 Prompt for AI Agents