ATLAS Offline Software
Loading...
Searching...
No Matches
egammaAODFixesConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
4from AthenaConfiguration.ComponentFactory import CompFactory
5from AthenaConfiguration.AccumulatorCache import AccumulatorCache
6from AthenaConfiguration.Enums import LHCPeriod
7from RecJobTransforms.AODFixHelper import releaseInRange
8from AthenaCommon.Logging import logging
9from PathResolver import PathResolver
10import pickle
11
12def getfunc():
13 from inspect import currentframe, getframeinfo
14 caller = currentframe().f_back
15 func_name = getframeinfo(caller)[2]
16 caller = caller.f_back
17 func = caller.f_locals.get(
18 func_name, caller.f_globals.get(
19 func_name))
20
21 return func
22
23@AccumulatorCache
24def FixFromAMITag(flags):
25 doFixFromAMITags = []
26
27
28 msg=logging.getLogger("listOfRecoReleases")
29 from PyUtils.AMITagHelperConfig import inputAMITags
30 listOfTags = inputAMITags(flags)
31 listOfRecoTags = []
32 nr = 0
33 nf = 0
34 for ie,e in enumerate(listOfTags):
35 # no idea why it can return an empty string...
36 msg.debug('tag %s at position %i',e,ie)
37 if not len(e):
38 continue
39 if e[0] == 'r':
40 nr += 1
41 listOfRecoTags.append(e)
42 if e[0] == 'f':
43 nf += 1
44 listOfRecoTags.append(e)
45
46 msg.info('List of tags %s %s %s',' '.join(listOfTags),', of reco tags ',' '.join(listOfRecoTags))
47 # use case : a DRAW file was produced at T0 (f-tag), and recoed in reprocessing (r-tag)
48 if nf >= 1 and nr >= 1:
49 msg.info('Both r- and f-tags are present, will remove the f ones')
50 listOfRecoTags = [ e for e in listOfRecoTags if e[0] == 'r' ]
51 listOfRecoTags_noMerge = [ ]
52 has_been_merged = False
53
54
55 if not listOfRecoTags:
56 msg.info("no reco tags")
57 doFixFromAMITags.append((True,True))
58 return doFixFromAMITags, listOfRecoTags
59
60
61 filename_merging = PathResolver.FindCalibFile("egammaAlgs/Merging_reco_tag.pkl")
62 for e in listOfRecoTags:
63 msg.info('Testing %s',e)
64 with open(filename_merging, "rb") as f:
65 releases = pickle.load(f)
66 if e in releases:
67 msg.info('it is a merging tag; skip')
68 has_been_merged = True
69 continue
70 if not has_been_merged:
71 listOfRecoTags_noMerge.append(e)
72
73
74 if not listOfRecoTags_noMerge:
75 msg.info("no reco tags after merge removal")
76 doFixFromAMITags.append((True,True))
77 return doFixFromAMITags, listOfRecoTags_noMerge
78
79 listOfRecoTags_noMerge_set= set(listOfRecoTags_noMerge)
80 msg.info('remaining tag after removing merge tag %s',listOfRecoTags_noMerge)
81
82 filename_timingTag = PathResolver.FindCalibFile("egammaAlgs/Timing_fix_reco_tag.pkl")
83 filename_AmbiguityTag = PathResolver.FindCalibFile("egammaAlgs/Ambiguity_fix_reco_tag.pkl")
84
85 doFix_timing = False
86 doFix_amb = False
87 with open(filename_timingTag, "rb") as f:
88 TimingTag = pickle.load(f)
89 if(not listOfRecoTags_noMerge_set.intersection(TimingTag)):
90 doFix_timing = True
91 with open(filename_AmbiguityTag, "rb") as f:
92 AmbiguityTag = pickle.load(f)
93 if(listOfRecoTags_noMerge_set.intersection(AmbiguityTag)):
94 doFix_amb = True
95
96
97 doFixFromAMITags.append((doFix_timing,doFix_amb))
98
99 return doFixFromAMITags,listOfRecoTags_noMerge
100
101
102def doFixTime(flags,relNum = None):
103 return releaseInRange(flags,"Athena-23.0.12","Athena-23.0.200",relNum) or \
104 releaseInRange(flags,"Athena-24.0.0","Athena-24.0.200",relNum) or \
105 releaseInRange(flags,"Athena-25.0.0","Athena-25.0.200",relNum)
106
107def runAODFix(flags, correctCluster = True, checkRelMerge = True):
108
109 msg=logging.getLogger("GetDecisionToRunAODFix")
110
111 ALToFix = "egammaAmbiguityLinksFix" not in flags.Input.AODFixesDone
112 TimeToFix = "egammatopoIsoFix" not in flags.Input.AODFixesDone
113
114 if flags.GeoModel.Run >= LHCPeriod.Run3:
115 doFix_meta = doFixTime(flags) and TimeToFix
116 else:
117 doFix_meta=False
118 checkRelMerge=False #no need to cross-check when a run 2 or run 1 are used
119 doAmbiguityFix_meta = releaseInRange(flags,"Athena-24.0.0","Athena-24.0.83") and ALToFix
120
121 doFix = doFix_meta or doAmbiguityFix_meta
122 doFix_time = doFix_meta
123 doAmbiguityFix = doAmbiguityFix_meta
124
125
126 if checkRelMerge:
127 doFixFromAMITags = []
128 doFixFromAMITags, inputReleaseFromAMITags = FixFromAMITag(flags)
129 if inputReleaseFromAMITags:
130 msg.info('doFix from AMI tags = %s',doFixFromAMITags)
131 for ie, e in enumerate(doFixFromAMITags):
132 if e[0] != doFix_time or e[1] != doAmbiguityFix:
133 msg.warning('Inconsistent information from AMI reco tag release %s and input release %s', \
134 inputReleaseFromAMITags[ie],flags.Input.Release)
135 if ie ==0:
136 msg.warning('if no flag , will use the info collected from AMI')
137 doFix_time = e[0] and TimeToFix
138 doAmbiguityFix = e[1] and ALToFix
139 doFix = doFix_time or doAmbiguityFix
140
141 fixes = set()
142 if doFix:
143 if doAmbiguityFix:
144 fixes.add('egammaAmbiguityLinksFix')
145 # no timing cut in HI reco, so not these fixes
146 if doFix_time and not flags.Reco.EnableHI:
147 fixes.add('egammatopoIsoFix')
148 if correctCluster:
149 fixes.add('egClusterL2_3Fix')
150 else:
151 doFix = doAmbiguityFix
152
153 return doFix, fixes
154
155def egammaAODFixesCfg(flags, correctCluster = True):
156
157 msg=logging.getLogger("egammaAODFixes")
158 #first check if we need to apply this AODFix
159 doFix, fixes = runAODFix(flags, correctCluster)
160 msg.info('Decision for egamma AOD fix = %s',doFix)
161 if not doFix:
162 return None
163 else:
164 if fixes:
165 msg.info('Will apply fixes = %s', ', '.join(fixes))
166 else:
167 msg.info('Range is ok but there are no fix to apply')
168 return None
169
170 # I do this because there are in fact two AOD fixes here:
171 # one for ambiguity links, one for timing issue (topoetcone + cluster fixes)
172 # sometimes, the ambiguity link fix is not needed, need to now this
173 getfunc().__name__ = " ".join(fixes)
174
175 result=ComponentAccumulator()
176
177 # No fix if nothing relevant in input
178 hasElectrons = "Electrons" in flags.Input.Collections
179 hasPhotons = "Photons" in flags.Input.Collections
180 if not hasElectrons and not hasPhotons:
181 return None
182
183 # TO BE FIXED
184 # if only one collection is present, this will crash
185
186 #Use the AddressRemappingSvc to rename the input object
187 from SGComps.AddressRemappingConfig import InputRenameCfg
188 if hasElectrons:
189 result.merge(InputRenameCfg("xAOD::ElectronContainer", "Electrons", "old_Electrons"))
190 result.merge(InputRenameCfg("xAOD::ElectronAuxContainer", "ElectronsAux.", "old_ElectronsAux."))
191 if hasPhotons:
192 result.merge(InputRenameCfg("xAOD::PhotonContainer", "Photons", "old_Photons"))
193 result.merge(InputRenameCfg("xAOD::PhotonAuxContainer", "PhotonsAux.", "old_PhotonsAux."))
194
195 kwargs = dict()
196 kwargs['CorrectCluster'] = 'egClusterL2_3Fix' in fixes
197 kwargs['FixAmbiguityLinks'] = 'egammaAmbiguityLinksFix' in fixes
198 kwargs['FixEGTopoetcone']= 'egammatopoIsoFix' in fixes
199 if 'egClusterL2_3Fix' in fixes:
200 # First some detector config
201 # TO BE UNDERSTOOD : why is this explicitely needed here (without it : ERROR SG::ExcNoCondCont: Can't retrieve CondCont from ReadCondHandle for key ConditionStore+LArBadChannel. Can't retrieve.)
202 from LArBadChannelTool.LArBadChannelConfig import LArBadChannelCfg
203 result.merge(LArBadChannelCfg(flags))
204 #from TileConditions.TileBadChannelsConfig import TileBadChannelsCondAlgCfg
205 #result.merge( TileBadChannelsCondAlgCfg(flags, **kwargs) )
206 from CaloBadChannelTool.CaloBadChanToolConfig import CaloBadChanToolCfg
207 result.popToolsAndMerge( CaloBadChanToolCfg(flags) )
208 from LArGeoAlgsNV.LArGMConfig import LArGMCfg
209 result.merge(LArGMCfg(flags))
210 # then the AODFix itself
211 result.merge(InputRenameCfg("xAOD::CaloClusterContainer", "egammaClusters", "old_egammaClusters"))
212 result.merge(InputRenameCfg("xAOD::CaloClusterAuxContainer", "egammaClustersAux.", "old_egammaClustersAux."))
213 result.merge(InputRenameCfg("CaloClusterCellLinkContainer", "egammaClusters_links", "old_egammaClusters_links"))
214 kwargs['CaloDetDescrManager'] = 'CaloDetDescrManager'
215 from egammaTools.egammaSwToolConfig import egammaSwToolCfg
216 kwargs['ClusterCorrectionTool'] = result.popToolsAndMerge(egammaSwToolCfg(flags))
217 from egammaMVACalib.egammaMVACalibConfig import egammaMVASvcCfg
218 kwargs['MVACalibSvc'] = result.getPrimaryAndMerge(egammaMVASvcCfg(flags))
219 kwargs['EGammaClustersOutputName'] = flags.Egamma.Keys.Output.CaloClusters
220 kwargs['EGammaClustersInputName'] = f'old_{flags.Egamma.Keys.Output.CaloClusters}'
221
222 kwargs['IsoLeakCorrectionTool'] = CompFactory.CP.IsolationCorrectionTool(
223 LogLogFitForLeakage = True)
224
225 #Re-run the required algorithms
226 result.addEventAlgo(CompFactory.egammaAODFixes(**kwargs))
227
228 return result
229
230
231
if(pathvar)
static std::string FindCalibFile(const std::string &logical_file_name)
STL class.
egammaAODFixesCfg(flags, correctCluster=True)
runAODFix(flags, correctCluster=True, checkRelMerge=True)
doFixTime(flags, relNum=None)