ATLAS Offline Software
Loading...
Searching...
No Matches
EGammaGSFCalo.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 Contact: Raphael Haberle <raphael.julien.haberle@cern.ch>
4*/
5
7
12// ========================================================================
13namespace DerivationFramework {
15 ATH_MSG_INFO("Initialize...");
16
17 ATH_CHECK(m_trkRefitTool.retrieve());
19 ATH_CHECK(m_trackSummaryTool.retrieve());
21 ATH_CHECK(m_gsfCaloTrackLinkKey.initialize());
23
24 return StatusCode::SUCCESS;
25}
26
28 ATH_MSG_INFO("Finalize...");
29
30 ATH_MSG_INFO("Electrons: " << m_allElectrons);
31 ATH_MSG_INFO("Electrons w/o xAOD::TrackParticle: " << m_noTP);
32 ATH_MSG_INFO("Electrons w/ TRT-only track: " << m_onlyTRT);
33 ATH_MSG_INFO("Electrons w/o Trk::Track: " << m_noTrk);
34 ATH_MSG_INFO("Number of failed fits: " << m_failedFits);
35 ATH_MSG_INFO("Number of successful fits: " << m_successfulFits);
36 ATH_MSG_INFO("Number of successful copyInfos(): " << m_successfulCopyInfos);
37 ATH_MSG_INFO("Number of failed createParticle(): " << m_noRefTP);
38 ATH_MSG_INFO("New container size: " << m_allNewTP);
39 ATH_MSG_INFO("TSOS: " << m_tsos);
40
41 return StatusCode::SUCCESS;
42}
43
44// ========================================================================
45
46StatusCode EGammaGSFCalo::addBranches( const EventContext& ctx ) const {
47
48 // input electron decoration handle
51 dec_gsfCaloTrackLink(m_gsfCaloTrackLinkKey, ctx);
52
53 // gsf calo electrons decorations
54 static const SG::AuxElement::Accessor<int> acc_gsfCaloStatus("gsfCaloStatus");
55 static const SG::AuxElement::Accessor<float> acc_gsfChi2oNDF(
56 "gsfChiSquareOverNDOF");
57 static const SG::AuxElement::Accessor<float> acc_gsfCaloChi2oNDF(
58 "gsfCaloChiSquareOverNDOF");
60 acc_usedElectronLink("usedElectronLink");
63 read_originalTP("originalTrackParticle");
64 static const SG::AuxElement::Accessor<
66 write_originalTP("originalTrackParticle");
67
68 // Create the final containers to be written out
71
72 ATH_CHECK(finalTrkPartContainer.record(
73 std::make_unique<xAOD::TrackParticleContainer>(),
74 std::make_unique<xAOD::TrackParticleAuxContainer>()));
75
76 xAOD::TrackParticleContainer* cPtrTrkPart = finalTrkPartContainer.ptr();
77
78 // Get the input electron container from StoreGate
80 ATH_CHECK(ehandle.isValid());
83
84 for (const auto* electron : *electronContainer) {
85 const xAOD::TrackParticle* electronTP = electron->trackParticle();
86 if (!electronTP) {
87 ATH_MSG_WARNING("Can't get electron #" << electron->index()
88 << " TrackParticle!");
89 m_noTP++;
90 continue;
91 }
92 // Electron has a xAOD::TrackParticle, proceed...
93
94 xAOD::TrackParticle* electronTPRefit = nullptr;
95 int gsfCaloStatus = -1;
96 float gsfChiSquareOverNDOF = -1;
97 float gsfCaloChiSquareOverNDOF = -1;
98
99 ATH_CHECK(electronTP->trackLink().isValid());
100 // We have a Trk::Track to re-fit...
101 uint8_t dummy(0);
102 int nSiHits = 0;
103
104 if (electronTP->summaryValue(dummy, xAOD::numberOfSCTHits))
105 nSiHits += dummy;
106 if (electronTP->summaryValue(dummy, xAOD::numberOfPixelHits))
107 nSiHits += dummy;
108 if (electronTP->summaryValue(dummy, xAOD::numberOfSCTOutliers))
109 nSiHits += dummy;
110 if (electronTP->summaryValue(dummy, xAOD::numberOfPixelOutliers))
111 nSiHits += dummy;
112
113 const Trk::Track* track = electronTP->track();
114
115 // Skip TRT-only tracks
116 if (nSiHits >= m_minNSiHits) {
117 // We want to re-fit only "silicon" Trk::Tracks
118 auto electronTrackQuality = electronTP->track()->fitQuality();
119 gsfChiSquareOverNDOF = electronTrackQuality->chiSquared() /
120 electronTrackQuality->numberDoF();
121
122 auto electronTrackRefit = std::make_unique<Trk::Track>();
124 // Add electron pointer to cache for the refitting
125 cache.electron = electron;
126 StatusCode sc = m_trkRefitTool->refitTrack(ctx, track, cache);
127
128 if (sc == StatusCode::SUCCESS) {
129 electronTrackRefit.reset(cache.refittedTrack.release());
130 // move
131 m_trackSummaryTool->updateTrack(ctx, *electronTrackRefit);
132
133 gsfCaloStatus = 1;
135
136 const xAOD::Vertex* electronTrackVertex = nullptr;
137 electronTPRefit = m_particleCreatorTool->createParticle(
138 ctx, *electronTrackRefit, cPtrTrkPart, electronTrackVertex,
140 if (electronTPRefit) {
141 copyInfo(*electronTP, *electronTPRefit, !m_isAOD);
142 auto electronTrackRefitQuality = electronTrackRefit->fitQuality();
143 gsfCaloChiSquareOverNDOF = electronTrackRefitQuality->chiSquared() /
144 electronTrackRefitQuality->numberDoF();
145 } else {
147 "Can't create a new xAOD::TrackParticle from the re-fitted "
148 "Trk::Track! Using the original xAOD::TrackParticle!");
149 gsfCaloStatus = 0;
150 m_noRefTP++;
151 }
152 } else {
154 "CALO-improved Trk::Track re-fit failed! Using the original "
155 "xAOD::TrackParticle!");
156 m_failedFits++;
157 gsfCaloStatus = 0;
158 }
159 } else {
160 ATH_MSG_DEBUG("Electron "
161 << electron->index()
162 << " has a valid track particle but is a TRT-only track");
163 gsfCaloStatus = 0;
164 m_onlyTRT++;
165 }
166
167 if (gsfCaloStatus != 1) {
168 electronTPRefit = new xAOD::TrackParticle();
169 cPtrTrkPart->push_back(electronTPRefit);
170 *electronTPRefit = *electronTP;
171 }
172 // Debug flags
173 acc_gsfCaloStatus(*electronTPRefit) = gsfCaloStatus;
174 acc_gsfChi2oNDF(*electronTPRefit) = gsfChiSquareOverNDOF;
175 acc_gsfCaloChi2oNDF(*electronTPRefit) = gsfCaloChiSquareOverNDOF;
176
177 electronTPRefit->setTrackLink(electronTP->trackLink());
178
179 // Add link to refitted TP to electron container
180 ElementLink<xAOD::TrackParticleContainer> linkToRefittedTrackParticle(
181 electronTPRefit, *cPtrTrkPart);
182 dec_gsfCaloTrackLink(*electron) = linkToRefittedTrackParticle;
183
184 // Add link to initial electron to the refitted TP container
186 linkToElectron.toIndexedElement(*electronContainer, electron->index());
187 acc_usedElectronLink(*electronTPRefit) = linkToElectron;
188
190 if (read_originalTP.isAvailable(*electronTP)) {
191 linkToOriginal = read_originalTP(*electronTP);
192 }
193 write_originalTP(*electronTPRefit) = linkToOriginal;
194 } // end of the electron container loop
195
196 m_allNewTP += cPtrTrkPart->size();
197 return StatusCode::SUCCESS;
198}
199
201 xAOD::TrackParticle& created,
202 bool isRefitted) const {
203 // Add Truth decorations. Copy from the original.
204 if (m_doTruth) {
205 static const SG::AuxElement::Accessor<
207 tPL("truthParticleLink");
208 if (tPL.isAvailable(original)) {
210 tPL(original);
211 tPL(created) = linkToTruth;
212 }
213 static const SG::AuxElement::Accessor<float> tMP("truthMatchProbability");
214 if (tMP.isAvailable(original)) {
215 float originalProbability = tMP(original);
216 tMP(created) = originalProbability;
217 }
218 static const SG::AuxElement::Accessor<int> tT("truthType");
219 if (tT.isAvailable(original)) {
220 int truthType = tT(original);
221 tT(created) = truthType;
222 }
223 static const SG::AuxElement::Accessor<int> tO("truthOrigin");
224 if (tO.isAvailable(original)) {
225 int truthOrigin = tO(original);
226 tO(created) = truthOrigin;
227 }
228 }
229
230 // It's apparently not possible to update Trk::Track when running on AOD; copy
231 // the values from the original xAOD::TrackParticle
232 if (m_isAOD) {
233 copySummaryValue(original, created, xAOD::numberOfBLayerHits);
234 copySummaryValue(original, created, xAOD::numberOfPixelHits);
236 copySummaryValue(original, created, xAOD::numberOfSCTHits);
237 copySummaryValue(original, created, xAOD::numberOfPixelHoles);
238 copySummaryValue(original, created, xAOD::numberOfSCTHoles);
241 copySummaryValue(original, created, xAOD::numberOfTRTHits);
244 }
245
246 // Copy shared hit content from the original xAOD::TrackParticle
247 // Taken from
248 // https://gitlab.cern.ch/atlas/athena/-/blob/master/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.cxx?ref_type=heads#L329
250 copySummaryValue(original, created,
252 copySummaryValue(original, created,
254 copySummaryValue(original, created,
256 copySummaryValue(original, created,
262
263 if (isRefitted) {
264 // Figure the new number of holes
265 uint8_t dummy(0);
266 if (m_doPix) {
267 int nPixHitsRefitted =
268 created.summaryValue(dummy, xAOD::numberOfPixelHits) ? dummy : -1;
269 int nPixOutliersRefitted =
270 created.summaryValue(dummy, xAOD::numberOfPixelOutliers) ? dummy : -1;
271
272 int nPixHitsOriginal =
273 original.summaryValue(dummy, xAOD::numberOfPixelHits) ? dummy : -1;
274 int nPixOutliersOriginal =
275 original.summaryValue(dummy, xAOD::numberOfPixelOutliers) ? dummy
276 : -1;
277 int nPixHolesOriginal =
278 original.summaryValue(dummy, xAOD::numberOfPixelHoles) ? dummy : -1;
279
280 uint8_t nPixHolesRefitted = nPixHitsOriginal + nPixHolesOriginal +
281 nPixOutliersOriginal - nPixOutliersRefitted -
282 nPixHitsRefitted;
283
284 created.setSummaryValue(nPixHolesRefitted, xAOD::numberOfPixelHoles);
285 }
286
287 if (m_doSCT) {
288 int nSCTHitsRefitted =
289 created.summaryValue(dummy, xAOD::numberOfSCTHits) ? dummy : -1;
290 int nSCTOutliersRefitted =
291 created.summaryValue(dummy, xAOD::numberOfSCTOutliers) ? dummy : -1;
292
293 int nSCTHitsOriginal =
294 original.summaryValue(dummy, xAOD::numberOfSCTHits) ? dummy : -1;
295 int nSCTHolesOriginal =
296 original.summaryValue(dummy, xAOD::numberOfSCTHoles) ? dummy : -1;
297 int nSCTOutliersOriginal =
298 original.summaryValue(dummy, xAOD::numberOfSCTOutliers) ? dummy : -1;
299
300 uint8_t nSCTHolesRefitted = nSCTHitsOriginal + nSCTHolesOriginal +
301 nSCTOutliersOriginal - nSCTOutliersRefitted -
302 nSCTHitsRefitted;
303
304 created.setSummaryValue(nSCTHolesRefitted, xAOD::numberOfSCTHoles);
305 }
306
307 if (m_doTRT) {
308 int nTRTHitsRefitted =
309 created.summaryValue(dummy, xAOD::numberOfTRTHits) ? dummy : -1;
310 int nTRTOutliersRefitted =
311 created.summaryValue(dummy, xAOD::numberOfTRTOutliers) ? dummy : -1;
312
313 int nTRTHitsOriginal =
314 original.summaryValue(dummy, xAOD::numberOfTRTHits) ? dummy : -1;
315 int nTRTHolesOriginal =
316 original.summaryValue(dummy, xAOD::numberOfTRTHoles) ? dummy : -1;
317 int nTRTOutliersOriginal =
318 original.summaryValue(dummy, xAOD::numberOfTRTOutliers) ? dummy : -1;
319
320 uint8_t nTRTHolesRefitted = nTRTHitsOriginal + nTRTHolesOriginal +
321 nTRTOutliersOriginal - nTRTOutliersRefitted -
322 nTRTHitsRefitted;
323
324 created.setSummaryValue(nTRTHolesRefitted, xAOD::numberOfTRTHoles);
325 }
326 }
327}
328} // namespace DerivationFramework
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sc
Handle class for adding a decoration to an object.
xAOD::ElectronContainer * electronContainer
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
ToolHandle< Trk::ITrackParticleCreatorTool > m_particleCreatorTool
Tool to create track particle.
void copySummaryValue(const xAOD::TrackParticle &src, xAOD::TrackParticle &dest, const xAOD::SummaryType &information) const
std::atomic< unsigned int > m_noTP
std::atomic< unsigned int > m_noRefTP
SG::WriteDecorHandleKey< xAOD::ElectronContainer > m_gsfCaloTrackLinkKey
std::atomic< unsigned int > m_allElectrons
Counters.
PublicToolHandle< Trk::IExtendedTrackSummaryTool > m_trackSummaryTool
Gaudi::Property< bool > m_doTRT
Gaudi::Property< bool > m_doTruth
std::atomic< unsigned int > m_successfulCopyInfos
std::atomic< unsigned int > m_successfulFits
virtual StatusCode finalize() override final
finalize method
virtual StatusCode initialize() override final
initialize method
Gaudi::Property< int > m_minNSiHits
Minimum number of silicon hits on track before it is allowed to be refitted.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_OutputTrkPartContainerKey
Gaudi::Property< bool > m_doSCT
std::atomic< unsigned int > m_allNewTP
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronCollectionKey
std::atomic< unsigned int > m_failedFits
ToolHandle< IegammaTrkRefitterTool > m_trkRefitTool
The track refitter.
Gaudi::Property< bool > m_isAOD
std::atomic< unsigned int > m_onlyTRT
std::atomic< unsigned int > m_noTrk
Gaudi::Property< bool > m_doPix
std::atomic< unsigned int > m_tsos
void copyInfo(const xAOD::TrackParticle &original, xAOD::TrackParticle &created, bool isRefitted) const
Copy TrackParticle info from the original TP.
virtual StatusCode addBranches(const EventContext &ctx) const override final
addBranches method
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
Handle class for adding a decoration to an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
void setTrackLink(const ElementLink< TrackCollection > &track)
Set the link to the original track.
const ElementLink< TrackCollection > & trackLink() const
Returns a link (which can be invalid) to the Trk::Track which was used to make this TrackParticle.
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
void setSummaryValue(uint8_t &value, const SummaryType &information)
Set method for TrackSummary values.
THE reconstruction tool.
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
@ numberOfNextToInnermostPixelLayerSharedHits
number of Pixel 1st layer barrel hits shared by several tracks.
@ numberOfNextToInnermostPixelLayerSplitHits
number of Pixel 1st layer barrel hits split by cluster splitting
@ numberOfPixelSplitHits
number of Pixel all-layer hits split by cluster splitting [unit8_t].
@ numberOfInnermostPixelLayerSharedHits
number of Pixel 0th layer barrel hits shared by several tracks.
@ numberOfPixelOutliers
these are the pixel outliers, including the b-layer [unit8_t].
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfTRTHoles
number of TRT holes [unit8_t].
@ numberOfBLayerHits
these are the hits in the first pixel layer, i.e.
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
@ numberOfBLayerSharedHits
number of Pixel b-layer hits shared by several tracks [unit8_t].
@ numberOfInnermostPixelLayerSplitHits
number of Pixel 0th layer barrel hits split by cluster splitting
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfSCTDoubleHoles
number of Holes in both sides of a SCT module [unit8_t].
@ numberOfSCTOutliers
number of SCT outliers [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
@ numberOfTRTHighThresholdHits
number of TRT hits which pass the high threshold (only xenon counted) [unit8_t].
@ numberOfTRTSharedHits
number of TRT hits used by more than one track
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
@ numberOfSCTHoles
number of SCT holes [unit8_t].
Struct Holding the result to return and intermediate objects Things are owned by the EDM or the uniqu...
std::unique_ptr< Trk::Track > refittedTrack
Pointer to the refitted track.
const xAOD::Electron * electron
pointer to the Electron input