-
Notifications
You must be signed in to change notification settings - Fork 21
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
Updates to implentation of MiNNLO muR/muF polynomial variations (also to use them for unfolding and theory agnostic for OOA) #508
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 |
---|---|---|
|
@@ -137,6 +137,7 @@ def make_parser(parser=None): | |
parser.add_argument("--forceConstrainMass", action='store_true', help="force mass to be constrained in fit") | ||
parser.add_argument("--decorMassWidth", action='store_true', help="remove width variations from mass variations") | ||
parser.add_argument("--muRmuFPolVar", action="store_true", help="Use polynomial variations (like in theoryAgnosticPolVar) instead of binned variations for muR and muF (of course in setupCombine these are still constrained nuisances)") | ||
parser.add_argument("--muRmuFFullyCorr", action="store_true", help="Use the fully correlated muR/muF variations derived from theoryAgnosticPolVar polynomial variations instead of the binned ones (by default you take the binned fully correlated variations even if you are using the polynomial variations for muR/muF, they just take care of the \"uncorrelated\" part) (this option only works with --muRmuFPolVar, it doesn't work on its own)") | ||
parser = make_subparsers(parser) | ||
|
||
return parser | ||
|
@@ -405,6 +406,9 @@ def setup(args, inputFile, inputBaseName, inputLumiScale, fitvar, genvar=None, x | |
def assertSample(name, startsWith=["W", "Z"], excludeMatch=[]): | ||
return any(name.startswith(init) for init in startsWith) and all(excl not in name for excl in excludeMatch) | ||
|
||
def assertSampleWithOOA(name, startsWith=["W", "Z"], excludeMatch=[]): | ||
return any(name.startswith(init) for init in startsWith) and name.endswith("OOA") and all(excl not in name for excl in excludeMatch) | ||
|
||
dibosonMatch = ["WW", "WZ", "ZZ"] | ||
WMatch = ["W"] # TODO: the name of out-of-acceptance might be changed at some point, maybe to WmunuOutAcc, so W will match it as well (and can exclude it using "OutAcc" if needed) | ||
ZMatch = ["Z"] | ||
|
@@ -432,6 +436,11 @@ def assertSample(name, startsWith=["W", "Z"], excludeMatch=[]): | |
cardTool.addProcessGroup("nonsignal_samples_noOutAcc", lambda x: assertSample(x, startsWith=nonSignalMatch, excludeMatch=[*dibosonMatch, "tau", "OOA"])) | ||
cardTool.addProcessGroup("signal_samples_inctau_noOutAcc", lambda x: assertSample(x, startsWith=signalMatch, excludeMatch=[*dibosonMatch, "OOA"])) | ||
cardTool.addProcessGroup("nonsignal_samples_inctau_noOutAcc", lambda x: assertSample(x, startsWith=nonSignalMatch, excludeMatch=[*dibosonMatch, "OOA"])) | ||
# FIX for theoryAgnosticPolVar when using MiNNLO polynomial variations (we would still need these for the OOA) | ||
cardTool.addProcessGroup("signal_samples_OOA", lambda x: assertSampleWithOOA(x, startsWith=signalMatch, excludeMatch=[*dibosonMatch, "tau"])) | ||
cardTool.addProcessGroup("nonsignal_samples_OOA", lambda x: assertSampleWithOOA(x, startsWith=nonSignalMatch, excludeMatch=[*dibosonMatch, "tau"])) | ||
cardTool.addProcessGroup("signal_samples_inctau_OOA", lambda x: assertSampleWithOOA(x, startsWith=signalMatch, excludeMatch=[*dibosonMatch])) | ||
cardTool.addProcessGroup("nonsignal_samples_inctau_OOA", lambda x: assertSampleWithOOA(x, startsWith=nonSignalMatch, excludeMatch=[*dibosonMatch])) | ||
|
||
if not (isTheoryAgnostic or isUnfolding) : | ||
logger.info(f"All MC processes {cardTool.procGroups['MCnoQCD']}") | ||
|
@@ -588,7 +597,7 @@ def assertSample(name, startsWith=["W", "Z"], excludeMatch=[]): | |
for g in cardTool.procGroups["signal_samples"] for m in cardTool.datagroups.groups[g].members}, | ||
) | ||
|
||
if args.muRmuFPolVar and not isTheoryAgnosticPolVar: | ||
if args.muRmuFPolVar and not isPoiAsNoi: | ||
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. Is this change correct? Right now we are always using isPoiAsNoi = True (except maybe for one case with unfolding), so this condition would never be entered |
||
muRmuFPolVar_helper = combine_theoryAgnostic_helper.TheoryAgnosticHelper(cardTool, externalArgs=args) | ||
muRmuFPolVar_helper.configure_polVar(label, | ||
passSystToFakes, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -361,6 +361,24 @@ def hist_to_variations(hist_in, gen_axes = [], sum_axes = [], rebin_axes=[], reb | |
|
||
return variation_hist | ||
|
||
def muRmuFFullyCorrelatedVariations(hist_in): | ||
|
||
if hist_in.name is None: | ||
out_name = "hist_variations" | ||
else: | ||
out_name = hist_in.name + "_variations" | ||
|
||
variation_hist = hist.Hist(*hist_in.axes, name = out_name, storage = hist.storage.Double()) | ||
variation_hist = variation_hist[...,0:1,:] | ||
|
||
for i in range(len(hist_in.axes[len(hist_in.axes)-2])): | ||
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. Once you select the axis by ID, the number of bins for that axis can be obtained with hist.axes[id].size (or .extent if you want to include possible overflow bins when they exist, .size should always return the number of bins in acceptance regardless). In general, is it always guaranteed that the axis you want will always be the second from last, rather than the n-th from the left for example ? Perhaps, it might be safer to select the axis by name, which is more guaranteed to stay as it is (and if the name is eventually modified outside then it won't be found here and the code will just raise errors) |
||
variation_hist.values(flow=True)[...,0,0] = variation_hist.values(flow=True)[...,0,0] + hist_in.values(flow=True)[...,i,0] - (hist_in.values(flow=True)[...,0,0]+hist_in.values(flow=True)[...,0,1])/2 #this average which is subtracted is the nominal histogram (by construction, it's directly related to how the weights are defined) | ||
variation_hist.values(flow=True)[...,0,1] = variation_hist.values(flow=True)[...,0,1] + hist_in.values(flow=True)[...,i,1] - (hist_in.values(flow=True)[...,0,0]+hist_in.values(flow=True)[...,0,1])/2 | ||
variation_hist.values(flow=True)[...,0,0] = variation_hist.values(flow=True)[...,0,0] + (hist_in.values(flow=True)[...,0,0]+hist_in.values(flow=True)[...,0,1])/2 | ||
variation_hist.values(flow=True)[...,0,1] = variation_hist.values(flow=True)[...,0,1] + (hist_in.values(flow=True)[...,0,0]+hist_in.values(flow=True)[...,0,1])/2 | ||
|
||
return variation_hist | ||
|
||
|
||
def uncertainty_hist_from_envelope(h, proj_ax, entries): | ||
hdown = hh.syst_min_or_max_env_hist(h, proj_ax, "vars", entries, no_flow=["ptVgen"], do_min=True) | ||
|
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.
It might probably be possible to use the function assertSample adding more arguments to require the presence of a string or that it appears at the end (its presence is probably sufficient in this case)