ATLAS Offline Software
Loading...
Searching...
No Matches
InDetTrackSystematicsToolsConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2# Configuration of InDetTrackSystematicsTools package
3from AnaAlgorithm.DualUseConfig import isAthena
4if isAthena:
5 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
6 from AthenaConfiguration.ComponentFactory import CompFactory
7from AthenaConfiguration.Enums import LHCPeriod
8from Campaigns.Utils import Campaign
9from AthenaCommon.Logging import logging
10
11def InDetTrackTruthOriginToolCfg(flags, name="InDetTrackTruthOriginTool", **kwargs):
12 acc = ComponentAccumulator()
13
14 log = logging.getLogger("InDetTrackTruthOriginTool")
15 # this might fail if we're in AthAnalysis
16 try:
17 kwargs.setdefault("isFullPileUpTruth", flags.Digitization.PileUp
18 and flags.Digitization.DigiSteeringConf in ['StandardPileUpToolsAlg',
19 'StandardInTimeOnlyTruthPileUpToolsAlg',
20 'StandardInTimeOnlyGeantinoTruthPileUpToolsAlg'])
21 except AttributeError:
22 # assume this should be false if we're unable to load flags (temporary solution)
23 kwargs.setdefault("isFullPileUpTruth", False)
24 log.warning("Unable to load digi flags, assuming isFullPileUpTruth=False. Normal if you're in AthAnalysis.")
25
26 acc.setPrivateTools(
27 CompFactory.InDet.InDetTrackTruthOriginTool(name, **kwargs))
28 return acc
29
30def InDetTrackTruthFilterToolCfg(flags, name="InDetTrackTruthFilterTool",
31 seed=1, **kwargs):
32 acc = ComponentAccumulator()
33 kwargs.setdefault("Seed", seed)
34
35 if "trackOriginTool" not in kwargs:
36 kwargs.setdefault("trackOriginTool", acc.popToolsAndMerge(
38
39 # 2022 recommendations (MC23a)
40 if flags.GeoModel.Run is LHCPeriod.Run3:
41 kwargs.setdefault("calibFileNomEff", "InDetTrackSystematicsTools/CalibData_22.0_2022-v00/TrackingRecommendations_prelim_rel22.root")
42 kwargs.setdefault("fFakeLoose", 0.40)
43 kwargs.setdefault("fFakeTight", 1.00)
44 # Run 2 recommendations (MC20)
45 elif flags.GeoModel.Run is LHCPeriod.Run2:
46 kwargs.setdefault("calibFileNomEff", "InDetTrackSystematicsTools/CalibData_22.0_2022-v00/TrackingRecommendations_prelim_rel22.root")
47 kwargs.setdefault("fFakeLoose", 0.10)
48 kwargs.setdefault("fFakeTight", 1.00)
49 else:
50 raise ValueError(f"InDetTrackTruthFilterTool: Recommendations not yet available for campaign {flags.Input.MCCampaign}! Please check the configuration and contact Tracking CP if you believe this message is in error.")
51
52 acc.setPrivateTools(
53 CompFactory.InDet.InDetTrackTruthFilterTool(name, **kwargs))
54 return acc
55
56def JetTrackFilterToolCfg(flags, name="JetTrackFilterTool", seed=2, **kwargs):
57 acc = ComponentAccumulator()
58 kwargs.setdefault("Seed", seed)
59
60 if "trackOriginTool" not in kwargs:
61 kwargs.setdefault("trackOriginTool", acc.popToolsAndMerge(
63
64 # TIDE fake rate recommendations:
65 # Run 3 (MC23): https://indico.cern.ch/event/1587937/#40-fake-tracks-in-the-jet-core
66 if flags.GeoModel.Run >= LHCPeriod.Run3:
67 kwargs.setdefault("FakeUncertainty", 0.25)
68 # Run 2 (MC20): https://cds.cern.ch/record/2859907
69 else:
70 kwargs.setdefault("FakeUncertainty", 0.35)
71
72 # TIDE FLost recommendations:
73 # Run 3 (MC23)
74 if flags.GeoModel.Run >= LHCPeriod.Run3:
75 # 2022/23 (MC23a/d): https://indico.cern.ch/event/1531052/#38-flost-update
76 if flags.Input.MCCampaign in [Campaign.MC23a, Campaign.MC23d]:
77 kwargs.setdefault("FLostUncertainty", 0.24)
78 # 2024 (MC23e): https://indico.cern.ch/event/1662051/#46-update-on-2024-flost-measur
79 elif flags.Input.MCCampaign is Campaign.MC23e:
80 kwargs.setdefault("FLostUncertainty", 0.32)
81 else:
82 raise ValueError(f"JetTrackFilterTool: Recommendations not yet available for campaign {flags.Input.MCCampaign}! Please check the configuration and contact Tracking CP if you believe this message is in error.")
83 # Run 2 (MC20)
84 else:
85 kwargs.setdefault("FLostUncertainty", 0.24)
86
87 acc.setPrivateTools(CompFactory.InDet.JetTrackFilterTool(name, **kwargs))
88 return acc
89
90def TrackFilterToolCfg(flags, name="TrackFilterTool",
91 truthSeed=1, jetSeed=2, **kwargs):
92 acc = ComponentAccumulator()
93
94 kwargs.setdefault("TruthSeed", truthSeed)
95 kwargs.setdefault("JetSeed", jetSeed)
96
97 if "trackOriginTool" not in kwargs:
98 kwargs["trackOriginTool"] = acc.popToolsAndMerge(
100 )
101
102 if flags.GeoModel.Run is LHCPeriod.Run3:
103 kwargs.setdefault("fFakeLoose", 0.40)
104 kwargs.setdefault("fFakeTight", 1.00)
105 kwargs.setdefault("fFakeUncertTIDE", 0.25)
106
107 elif flags.GeoModel.Run is LHCPeriod.Run2:
108 kwargs.setdefault("fFakeLoose", 0.10)
109 kwargs.setdefault("fFakeTight", 1.00)
110 kwargs.setdefault("fFakeUncertTIDE", 0.35)
111
112 else:
113 raise ValueError(
114 f"Unsupported campaign/run for {name}"
115 )
116
117 acc.setPrivateTools(
118 CompFactory.InDet.TrackFilterTool(name, **kwargs)
119 )
120
121 return acc
122
123def InclusiveTrackFilterToolCfg(flags, name="InclusiveTrackFilterTool",
124 seed=3, **kwargs):
125 acc = ComponentAccumulator()
126 kwargs.setdefault("Seed", seed)
127
128 # 2022 recommendations (MC23a)
129 if flags.Input.MCCampaign is Campaign.MC23a:
130 kwargs.setdefault("calibFileLRTEff", "InDetTrackSystematicsTools/CalibData_25.2_2025-v00/LargeD0TrackingRecommendations_mc23a.root")
131 elif flags.Input.MCCampaign is Campaign.MC23d:
132 kwargs.setdefault("calibFileLRTEff", "InDetTrackSystematicsTools/CalibData_25.2_2025-v00/LargeD0TrackingRecommendations_mc23d.root")
133 elif flags.Input.MCCampaign is Campaign.MC23e:
134 kwargs.setdefault("calibFileLRTEff", "InDetTrackSystematicsTools/CalibData_25.2_2025-v00/LargeD0TrackingRecommendations_mc23e.root")
135
136 # Run 2 recommendations (MC20)
137 elif flags.GeoModel.Run is LHCPeriod.Run2:
138 kwargs.setdefault("calibFileLRTEff", "InDetTrackSystematicsTools/CalibData_24.0_2023-v00/LargeD0TrackingRecommendations_20230824.root")
139 else:
140 raise ValueError(f"InclusiveTrackFilterTool: Recommendations not yet available for campaign {flags.Input.MCCampaign}! Please check the configuration and contact Tracking CP if you believe this message is in error.")
141
142 acc.setPrivateTools(
143 CompFactory.InDet.InclusiveTrackFilterTool(name, **kwargs))
144 return acc
145
146def InDetTrackSmearingToolCfg(flags, name="InDetTrackSmearingTool",
147 seed=4, **kwargs):
148 acc = ComponentAccumulator()
149 kwargs.setdefault("Seed", seed)
150
151 # 2022 recommendations (MC23a)
152 if flags.Input.MCCampaign is Campaign.MC23a:
153 kwargs.setdefault("calibFileIP_CTIDE", "InDetTrackSystematicsTools/CalibData_25.2_2025-v00/2022_d0z0_smearing_factors_v2.root")
154 # 2023 recommendations (MC23d)
155 elif flags.Input.MCCampaign is Campaign.MC23d:
156 kwargs.setdefault("calibFileIP_CTIDE", "InDetTrackSystematicsTools/CalibData_25.2_2025-v00/2023_d0z0_smearing_factors_v2.root")
157 # 2024 recommendations (MC23e)
158 elif flags.Input.MCCampaign is Campaign.MC23e:
159 kwargs.setdefault("calibFileIP_CTIDE", "InDetTrackSystematicsTools/CalibData_25.2_2025-v00/2024_d0z0_smearing_factors.root")
160 # 2025 recommendations (MC23g)
161 elif flags.Input.MCCampaign is Campaign.MC23g:
162 kwargs.setdefault("calibFileIP_CTIDE", "InDetTrackSystematicsTools/CalibData_25.2_2025-v00/2025_d0z0_smearing_factors.root")
163 # Run 2 recommendations (MC20)
164 elif flags.GeoModel.Run is LHCPeriod.Run2:
165 kwargs.setdefault("calibFileIP_CTIDE", "InDetTrackSystematicsTools/CalibData_22.0_2022-v00/d0z0_smearing_factors_Run2_v2.root")
166 elif "calibFileIP_CTIDE" not in kwargs:
167 raise ValueError(f"InDetTrackSmearingTool: Recommendations not yet available for campaign {flags.Input.MCCampaign}! Please check the configuration and contact Tracking CP if you believe this message is in error.")
168
169 acc.setPrivateTools(
170 CompFactory.InDet.InDetTrackSmearingTool(name, **kwargs))
171 return acc
172
174 """Return calibFiles/runNumberBounds kwargs for InDetTrackBiasingTool.
175
176 Selects campaign-specific calibration files and (for multi-period
177 campaigns) run-number boundaries. Raises ValueError for unknown
178 campaigns or geometries.
179 """
180 c2 = "InDetTrackSystematicsTools/CalibData_22.0_2022-v00"
181 c3 = "InDetTrackSystematicsTools/CalibData_25.2_2025-v00"
182 if flags.GeoModel.Run is LHCPeriod.Run2:
183 if flags.Input.MCCampaign is Campaign.MC20a:
184 # 2015 + 2016 recommendations (MC20a)
185 return {
186 "calibFiles": [
187 f"{c2}/REL22_REPRO_2015.root",
188 f"{c2}/REL22_REPRO_2016_1stPart.root",
189 f"{c2}/REL22_REPRO_2016_2ndPart.root",
190 ],
191 "runNumberBounds": [0, 296938, 301912, 999999],
192 }
193 elif flags.Input.MCCampaign is Campaign.MC20d:
194 # 2017 recommendations (MC20d)
195 return {
196 "calibFiles": [
197 f"{c2}/REL22_REPRO_2017_1stPart.root",
198 f"{c2}/REL22_REPRO_2017_2ndPart.root",
199 ],
200 "runNumberBounds": [0, 334842, 999999],
201 }
202 elif flags.Input.MCCampaign is Campaign.MC20e:
203 # 2018 recommendations (MC20e)
204 return {
205 "calibFiles": [
206 f"{c2}/REL22_REPRO_2018_1stPart.root",
207 f"{c2}/REL22_REPRO_2018_2ndPart.root",
208 ],
209 "runNumberBounds": [0, 353000, 999999],
210 }
211 else:
212 raise ValueError(
213 'No biasing recommendations found for campaign "'
214 + flags.Input.MCCampaign.value
215 + '" in Run 2. Please check the configuration.'
216 )
217 elif flags.GeoModel.Run is LHCPeriod.Run3:
218 if flags.Input.MCCampaign is Campaign.MC23a:
219 # 2022 recommendations (MC23a)
220 return {
221 "calibFiles": [
222 f"{c3}/2022_d0z0qoverp_biasing_factor.root",
223 ]
224 }
225 elif flags.Input.MCCampaign is Campaign.MC23d:
226 # 2023 recommendations (MC23d)
227 return {
228 "calibFiles": [
229 f"{c3}/2023_d0z0qoverp_biasing_factor.root",
230 ]
231 }
232 elif flags.Input.MCCampaign is Campaign.MC23e:
233 # 2024 recommendations (MC23e)
234 return {
235 "calibFiles": [
236 f"{c3}/2024_d0z0qoverp_biasing_factor.root",
237 ]
238 }
239 else:
240 raise ValueError(
241 'No biasing recommendations found for campaign "'
242 + flags.Input.MCCampaign.value
243 + '" in Run 3. Please check the configuration.'
244 )
245 else:
246 raise ValueError(
247 'No biasing recommendations found for geometry "'
248 + flags.GeoModel.Run.value
249 + '". Please check the configuration.'
250 )
251
252
253def InDetTrackBiasingToolCfg(flags, name="InDetTrackBiasingTool",
254 **kwargs):
255 acc = ComponentAccumulator()
256 kwargs.setdefault("isMC", flags.Input.isMC)
257 if "calibFiles" not in kwargs:
258 kwargs.update(InDetTrackBiasingCalibKwargs(flags))
259 acc.setPrivateTools(
260 CompFactory.InDet.InDetTrackBiasingTool(name, **kwargs))
261 return acc
262
263def TrackSystematicsAlgCfg(flags, name="InDetTrackSystematicsAlg", **kwargs):
264 """View container of the input tracks surviving the track filter
265 systematics (TRK_EFF_*, TRK_FAKE_RATE_*): SystematicVariationSTD for
266 standard tracks, SystematicVariationLRT for LRT tracks.
267 """
268 acc = ComponentAccumulator()
269
270 if "TrackFilterToolLRT" not in kwargs:
271 kwargs.setdefault("TrackFilterToolLRT", acc.popToolsAndMerge(
273
274 if "TrackFilterToolSTD" not in kwargs:
275 kwargs.setdefault("TrackFilterToolSTD", acc.popToolsAndMerge(
277
278 acc.addEventAlgo(CompFactory.InDet.TrackSystematicsAlg(name, **kwargs))
279 return acc
280
281
282def TrackSmearingAlgCfg(flags, syst, input_tracks, output_tracks,
283 seed=4, bias_kwargs={}, strict_mode=False):
284 """Shallow-copy input_tracks and apply smearing/biasing for one syst.
285
286 syst is a single smearing variation string (TRK_RES_*, TRK_BIAS_*), or
287 empty for a nominal (un-smeared) copy. Produces output_tracks as a
288 shallow copy with modified d0/z0/qoverp values.
289
290 Any extra keyword arguments are forwarded to InDetTrackBiasingToolCfg
291 as calibration kwargs (calibFiles, runNumberBounds, ...). If none are
292 supplied, InDetTrackBiasingCalibKwargs(flags) is called to derive them;
293 exceptions from that call propagate to the caller.
294
295 If strict_mode is True, the algorithm fails in initialize when syst
296 is not known to the smearing or biasing tool.
297 """
298 ca = ComponentAccumulator()
299
300 smearingTool = ca.popToolsAndMerge(InDetTrackSmearingToolCfg(flags, seed=seed))
301 ca.addPublicTool(smearingTool)
302
303 # Only configure the biasing tool for TRK_BIAS_* systematics.
304 # The tool reads RandomRunNumber unconditionally (needs PRW), so
305 # configuring it for nominal or RES systematics would require PRW
306 # to be scheduled even when no biasing is needed.
307 biasingTool = None
308 if 'BIAS' in syst or bias_kwargs:
309 if not bias_kwargs:
310 bias_kwargs = InDetTrackBiasingCalibKwargs(flags)
311 if bias_kwargs:
312 biasingTool = ca.popToolsAndMerge(
313 InDetTrackBiasingToolCfg(flags, **bias_kwargs))
314 ca.addPublicTool(biasingTool)
315
316 alg = CompFactory.InDet.TrackSmearingAlg(
317 f'TrackSmearingAlg_{output_tracks}',
318 SmearingTool=smearingTool,
319 InputTrackContainer=input_tracks,
320 OutputTrackContainer=output_tracks,
321 SystematicVariation=syst,
322 StrictMode=strict_mode,
323 )
324 if biasingTool is not None:
325 alg.BiasingTool = biasingTool
326
327 ca.addEventAlgo(alg)
328 return ca
329
330
332 flags, syst, jet_collection,
333 in_ghost_tracks, out_ghost_tracks,
334 seed=None):
335 """Filter ghost-track links on jets for one filter systematic.
336
337 syst is a single filter variation string (TRK_EFF_*, TRK_FAKE_RATE_*).
338 Reads in_ghost_tracks decoration from jet_collection, applies filter
339 tools per-track (dispatching LRT vs STD by patternRecoInfo bit 49),
340 and writes surviving links to out_ghost_tracks.
341
342 seed overrides the Seed property on all filter tools. If None (default),
343 each tool uses its own default seed (1 STD, 2 TIDE, 3 LRT).
344 """
345 assert syst, "JetTrackFilteringAlgCfg called with empty syst"
346
347 ca = ComponentAccumulator()
348
349 is_larged0 = 'LARGED0' in syst
350 is_tide = 'TIDE' in syst
351
352 alg = CompFactory.InDet.JetTrackFilteringAlg(
353 f'JetTrackFilteringAlg_{out_ghost_tracks}',
354 JetCollection=jet_collection,
355 InGhostTracks=in_ghost_tracks,
356 OutGhostTracks=out_ghost_tracks,
357 SystematicVariation=syst,
358 )
359 std_kwargs = {} if seed is None else {"seed": seed}
360 lrt_kwargs = {} if seed is None else {"seed": seed}
361 tide_kwargs = {} if seed is None else {"seed": seed}
362 if not is_larged0:
363 alg.STDFilterTool = ca.popToolsAndMerge(
364 InDetTrackTruthFilterToolCfg(flags, **std_kwargs)
365 )
366 ca.addPublicTool(alg.STDFilterTool)
367 if is_larged0:
368 alg.LRTFilterTool = ca.popToolsAndMerge(
369 InclusiveTrackFilterToolCfg(flags, **lrt_kwargs)
370 )
371 ca.addPublicTool(alg.LRTFilterTool)
372 if is_tide:
373 alg.JetFilterTool = ca.popToolsAndMerge(
374 JetTrackFilterToolCfg(flags, **tide_kwargs)
375 )
376 ca.addPublicTool(alg.JetFilterTool)
377
378 ca.addEventAlgo(alg)
379 return ca
380
381
382def FakeRateFilterAlgCfg(flags, name, mode, systematics, **kwargs):
383 """Configure a FakeRateFilterAlg for one systematic.
384
385 mode is one of "inclusive", "tide", or "tft" (track-filter-tool).
386 OutputTrackContainer is optional; if not provided, it defaults to
387 "InDetTrackParticles_Filtered". The output container name is modified
388 for multiple systematics to avoid collisions.
389 """
390 ca = ComponentAccumulator()
391
392 kwargs.setdefault("InputTrackContainer", "InDetTrackParticles")
393 kwargs.setdefault("JetContainer", "AntiKt4EMPFlowJets")
394 output_tracks = kwargs.pop("OutputTrackContainer", None)
395
396 if output_tracks is None:
397 output_tracks = "InDetTrackParticles_Filtered"
398
399 for syst in systematics:
400 alg_kwargs = kwargs.copy()
401 alg_kwargs["SystematicVariation"] = syst
402
403 if len(systematics) == 1:
404 alg_kwargs["OutputTrackContainer"] = output_tracks
405 else:
406 alg_kwargs["OutputTrackContainer"] = f"{output_tracks}_{syst}"
407
408 if mode == "inclusive":
409 alg_kwargs.setdefault("InclusiveFilterTool", ca.popToolsAndMerge(
411 flags,
412 name=f"InDetTrackTruthFilterTool_{syst}",
413 )
414 ))
415 elif mode == "tide":
416 alg_kwargs.setdefault("JetFilterTool", ca.popToolsAndMerge(
418 flags,
419 name=f"JetTrackFilterTool_{syst}",
420 )
421 ))
422 elif mode == "tft":
423 alg_kwargs.setdefault("TrackFilterTool", ca.popToolsAndMerge(
425 flags,
426 name=f"TrackFilterTool_{syst}",
427 )
428 ))
429 else:
430 raise ValueError(f"Unknown FakeRateFilterAlg mode: {mode}")
431
432 ca.addEventAlgo(
433 CompFactory.InDet.FakeRateFilterAlg(f"{name}_{syst}", **alg_kwargs)
434 )
435
436 return ca
JetTrackFilterToolCfg(flags, name="JetTrackFilterTool", seed=2, **kwargs)
InDetTrackTruthOriginToolCfg(flags, name="InDetTrackTruthOriginTool", **kwargs)
TrackFilterToolCfg(flags, name="TrackFilterTool", truthSeed=1, jetSeed=2, **kwargs)
JetTrackFilteringAlgCfg(flags, syst, jet_collection, in_ghost_tracks, out_ghost_tracks, seed=None)
InDetTrackSmearingToolCfg(flags, name="InDetTrackSmearingTool", seed=4, **kwargs)
TrackSmearingAlgCfg(flags, syst, input_tracks, output_tracks, seed=4, bias_kwargs={}, strict_mode=False)
FakeRateFilterAlgCfg(flags, name, mode, systematics, **kwargs)
InDetTrackTruthFilterToolCfg(flags, name="InDetTrackTruthFilterTool", seed=1, **kwargs)
InclusiveTrackFilterToolCfg(flags, name="InclusiveTrackFilterTool", seed=3, **kwargs)
InDetTrackBiasingToolCfg(flags, name="InDetTrackBiasingTool", **kwargs)
TrackSystematicsAlgCfg(flags, name="InDetTrackSystematicsAlg", **kwargs)