ATLAS Offline Software
Loading...
Searching...
No Matches
KLFitterConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
4from FTagAnalysisAlgorithms.FTagHelpers import getRecommendedBTagCalib
5
6
7class KLFitterBlock(ConfigBlock):
8 """ConfigBlock for KLFitter algorithms"""
9
10 def __init__(self):
11 super(KLFitterBlock, self).__init__()
12 self.addOption ('containerName', '', type=str,
13 noneAction='error',
14 info="the name of the input container.")
15 self.addOption(
16 "electrons",
17 "",
18 type=str,
19 info="the input electron container, with a possible selection, in the format container or container.selection. The default is '' (empty string).",
20 )
21 self.addOption(
22 "muons",
23 "",
24 type=str,
25 info="the input muon container, with a possible selection, in the format container or container.selection. The default is '' (empty string).",
26 )
27 self.addOption(
28 "jets",
29 "",
30 type=str,
31 info="the input jet container, with a possible selection, in the format container or container.selection. The default is '' (empty string).",
32 )
33 self.addOption(
34 "met",
35 "",
36 type=str,
37 info="the input MET container. The default is '' (empty string).",
38 )
39 self.addOption(
40 "likelihoodType",
41 "",
42 type=str,
43 info="KLFitter likelihood, if only one is needed. See KLFitterEnums.h for possible values. The default is '' (empty string).",
44 )
45 self.addOption(
46 "leptonType",
47 "",
48 type=str,
49 info="type of lepton to use (only relevant to certain likelihood types), if only one is needed. See KLFitterEnums.h for possible values. The default is '' (empty string).",
50 )
51 self.addOption(
52 "jetSelectionMode",
53 "",
54 type=str,
55 info="jet selection mode to use, if only one is needed. See KLFitterEnums.h for possible values. The default is '' (empty string).",
56 )
57 self.addOption(
58 "btaggingMethod",
59 "kNoTag",
60 type=str,
61 info="strategy to handle b-jets, if only one is needed. See KLFitterEnums.h for possible values. The default is '' (empty string).",
62 )
63 self.addOption(
64 "bTagCDIFile",
65 None,
66 type=str,
67 info="CDI file to pass to the b-tagging efficiency tool",
68 )
69 self.addOption(
70 "btagger",
71 "GN2v01",
72 type=str,
73 info="b-tagging algorithm to use, if only one is needed. The default is 'GN2v01'.",
74 )
75 self.addOption(
76 "btagWP",
77 "",
78 type=str,
79 info="b-tagging efficiency WP to use, if only one is needed.",
80 )
81 self.addOption(
82 "btagIgnoreOutOfValidityRange",
83 False,
84 type=bool,
85 info="whether or not the b-tagger should ignore (and not fail) when a jet is outside the calibration range. The default is False.",
86 )
87 self.addOption(
88 "selectionRegionsConfig",
89 "",
90 type=str,
91 info="string of the form 'selectionName: sel1, optionA: opA, optionB: opB; selectionName: sel2, ...' where options can be likelihoodType, leptonType, jetSelectionMode, btaggingMethod, btagger or btagWP. The default is '' (empty string).",
92 )
93 self.addOption(
94 "saveAllPermutations",
95 False,
96 type=bool,
97 info="whether to save all permutations, or just the best one. The default is False (only save the best one).",
98 )
99 # list of dictionaries for the per-region config options
101
102 def instanceName (self) :
103 """Return the instance name for this block"""
104 return self.containerName
105
107 regions = self.selectionRegionsConfig.split(";")
108 if len(regions) == 0:
109 raise Exception(
110 "KLFitterConfig: Could not determine any regions in your SelectionRegionsConfig"
111 )
112 for reg in regions:
113 regstrip = reg.replace(" ", "")
114 regionopts = dict(
115 tuple(option.split(":")) for option in regstrip.split(",")
116 )
117 if "selectionName" not in regionopts:
118 raise Exception(
119 "KLFitterConfig: Could not parse SelectionRegionsConfig selectionName for region ",
120 reg,
121 )
122 if "likelihoodType" in regionopts:
123 raise Exception(
124 "KLFitterConfig: likelihoodType cannot be overriden per region. Create a separate instance of KLFitter block with different likelihoodType instead."
125 )
126
127 self.perRegionConfiguration.append(regionopts)
128
129 def makeAlgs(self, config):
131 for perRegionConfig in self.perRegionConfiguration:
132 selectionName = perRegionConfig["selectionName"]
133 alg = config.createAlgorithm(
134 "EventReco::RunKLFitterAlg",
135 f"RunKLFitterAlg_{selectionName}",
136 )
137 # input objects and their object selections
138 alg.electrons, alg.electronSelection = config.readNameAndSelection(
139 self.electrons
140 )
141 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
142 alg.jets, alg.jetSelection = config.readNameAndSelection(self.jets)
143 alg.met = config.readName(self.met)
144 alg.result = self.containerName + "_%SYS%"
145
146 # global settings, in future expect to expose more options for configuration
147 alg.SaveAllPermutations = self.saveAllPermutations
148
149 # these settings can be defined per-region, but if not, we fallback to global setting
150 alg.selectionDecorationName = selectionName + "_%SYS%,as_char"
151 alg.LHType = self.likelihoodType
152 alg.LeptonType = perRegionConfig.get("leptonType", self.leptonType)
153 alg.JetSelectionMode = perRegionConfig.get(
154 "jetSelectionMode", self.jetSelectionMode
155 )
156 btagAlgo = perRegionConfig.get("btagger", self.btagger)
157 btagWP = perRegionConfig.get("btagWP", self.btagWP)
158 alg.BTaggingDecoration = f"ftag_select_{btagAlgo}_{btagWP}"
159
160 alg.BTaggingMethod = perRegionConfig.get(
161 "btaggingMethod", self.btaggingMethod
162 )
163 if alg.BTaggingMethod == "kWorkingPoint":
164 config.addPrivateTool("btagEffTool", "BTaggingEfficiencyTool")
165 alg.btagEffTool.TaggerName = self.btagger
166 alg.btagEffTool.OperatingPoint = self.btagWP
167 jetCollection = config.originalName(self.jets.split(".")[0])
168 alg.btagEffTool.JetAuthor = jetCollection
169 alg.btagEffTool.ScaleFactorFileName = (
170 getRecommendedBTagCalib(config.geometry())
171 if self.bTagCDIFile is None
172 else self.bTagCDIFile
173 )
174 alg.btagEffTool.IgnoreOutOfValidityRange = (
175 self.btagIgnoreOutOfValidityRange
176 )
177 alg.btagEffTool.MinPt = (
178 20e3 # hardcoded to the recommendation for EMPFlow at the moment
179 )
180 # NOTE the efficiency tool is simply set to the default generator,
181 # meaning the results are not correct for alternative showering generators!!
182
183 finalizeAlg = config.createAlgorithm(
184 "EventReco::KLFitterFinalizeOutputAlg",
185 "KLFitterFinalizeOutputAlg",
186 )
187 finalizeAlg.resultContainerToCheck = self.containerName + "_%SYS%"
188 finalizeAlg.resultContainerToWrite = self.containerName + "_%SYS%"
189
190 config.setSourceName(self.containerName, self.containerName)
191 config.addOutputContainer(self.containerName, self.containerName + "_%SYS%")
192
193 config.addOutputVar(self.containerName, "eventProbability", "eventProbability")
194 config.addOutputVar(self.containerName, "logLikelihood", "logLikelihood")
196 config.addOutputVar(self.containerName, "selected", "selected")
197
198 if self.likelihoodType != "ttbar_AllHad":
199 config.addOutputVar(
200 self.containerName, "model_bhad_jetIndex", "bhad_jetIndex"
201 )
202 config.addOutputVar(
203 self.containerName, "model_blep_jetIndex", "blep_jetIndex"
204 )
205 config.addOutputVar(
206 self.containerName, "model_lq1_jetIndex", "lq1_jetIndex"
207 )
208 if self.likelihoodType != "ttbar_BoostedLJets":
209 config.addOutputVar(
210 self.containerName, "model_lq2_jetIndex", "lq2_jetIndex"
211 )
212 if self.likelihoodType == "ttH":
213 config.addOutputVar(
214 self.containerName, "model_Higgs_b1_jetIndex", "Higgs_b1_jetIndex"
215 )
216 config.addOutputVar(
217 self.containerName, "model_Higgs_b2_jetIndex", "Higgs_b2_jetIndex"
218 )
219
220 config.addOutputVar(self.containerName, "model_nu_pt", "nu_pt")
221 config.addOutputVar(self.containerName, "model_nu_eta", "nu_eta")
222 config.addOutputVar(self.containerName, "model_nu_phi", "nu_phi")
223 config.addOutputVar(self.containerName, "model_nu_E", "nu_E")
224
225 if self.likelihoodType == "ttZTrilepton":
226 config.addOutputVar(self.containerName, "model_lep_index", "lep_index")
227 config.addOutputVar(
228 self.containerName, "model_lepZ1_index", "lepZ1_index"
229 )
230 config.addOutputVar(
231 self.containerName, "model_lepZ2_index", "lepZ2_index"
232 )
233 else:
234 config.addOutputVar(
235 self.containerName, "model_b_from_top1_jetIndex", "b_from_top1_jetIndex"
236 )
237 config.addOutputVar(
238 self.containerName, "model_b_from_top2_jetIndex", "b_from_top2_jetIndex"
239 )
240 config.addOutputVar(
241 self.containerName,
242 "model_lj1_from_top1_jetIndex",
243 "lj1_from_top1_jetIndex",
244 )
245 config.addOutputVar(
246 self.containerName,
247 "model_lj2_from_top1_jetIndex",
248 "lj2_from_top1_jetIndex",
249 )
250 config.addOutputVar(
251 self.containerName,
252 "model_lj1_from_top2_jetIndex",
253 "lj1_from_top2_jetIndex",
254 )
255 config.addOutputVar(
256 self.containerName,
257 "model_lj2_from_top2_jetIndex",
258 "lj2_from_top2_jetIndex",
259 )
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177