48 const EventContext& ctx = info ? info->eventContext : Gaudi::Hive::currentContext();
52 if (!truthParticleContainerReadHandle.
isValid()) {
53 ATH_MSG_WARNING(
" Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.
key());
68 double LeadingPhtPT(0);
69 double LeadingPartPT(0);
70 double LeadingPhtdR(999.);
71 double LeadingPartdR(999.);
72 double BestPartdR(999.);
73 double etaClus = clus->
etaBE(2);
74 double phiClus = clus->
phiBE(2);
76 etaClus = clus->
eta();
79 phiClus = clus->
phi();
81 std::vector<const xAOD::TruthParticle*> tps;
87 for (
const auto*
const thePart : tps) {
93 long iParticlePDG = thePart->pdgId();
95 if (std::abs(iParticlePDG) == 12 || std::abs(iParticlePDG) == 14 || std::abs(iParticlePDG) == 16)
continue;
96 double pt = thePart->pt() / Athena::Units::GeV;
97 double q = thePart->charge();
101 float deltaPhi = std::abs(std::remainder(phiClus - thePart->phi(), 2*std::numbers::pi));
102 float deteta = std::abs(etaClus - thePart->eta());
109 (((etaClus < 0) - (thePart->eta() < 0) != 0)
118 bool isNCone =
false;
119 bool isExt =
genPartToCalo(ctx, clus, thePart, isFwrdEle, dR, isNCone, *caloDDMgr);
120 if (!isExt)
continue;
123 info->egPartPtr.push_back(thePart);
124 info->egPartdR.push_back(dR);
131 if ((iParticlePDG == 22 || std::abs(iParticlePDG) == 11) && isNCone && pt > LeadingPhtPT) {
138 if ((iParticlePDG != 22 && std::abs(iParticlePDG) != 11) && isNCone && pt > LeadingPartPT) {
139 theLeadingPartInCone = thePart;
145 if (!isNCone && dR < BestPartdR) {
146 theBestPartOutCone = thePart;
150 if (dR < BestPartdR) {
151 theBestPartdR = thePart;
157 if (theEgamma !=
nullptr) {
159 if (info) info->deltaRMatch = LeadingPhtdR;
160 }
else if (theLeadingPartInCone !=
nullptr) {
161 theMatchPart =
MC::findMatching(truthParticleContainerReadHandle.
ptr(),theLeadingPartInCone);
162 if (info) info->deltaRMatch = LeadingPartdR;
163 }
else if (theBestPartOutCone !=
nullptr) {
164 theMatchPart =
MC::findMatching(truthParticleContainerReadHandle.
ptr(),theBestPartOutCone);
165 if (info) info->deltaRMatch = BestPartdR;
166 }
else if (isFwrdEle && theBestPartdR !=
nullptr) {
168 if (info) info->deltaRMatch = BestPartdR;
170 theMatchPart =
nullptr;
172 if (isFwrdEle || theMatchPart !=
nullptr || !
m_inclG4part)
return theMatchPart;
175 for (
const auto*
const thePart : tps) {
178 long iParticlePDG = thePart->pdgId();
180 if (std::abs(iParticlePDG) == 12 || std::abs(iParticlePDG) == 14 || std::abs(iParticlePDG) == 16)
continue;
181 if (thePart->decayVtx() !=
nullptr)
continue;
182 const double dPhi = std::abs(std::remainder(phiClus - thePart->phi(), 2*std::numbers::pi));
183 const double dEta = std::abs(etaClus - thePart->eta());
186 double pt = thePart->pt() / Athena::Units::GeV;
187 double q = thePart->charge();
193 bool isNCone =
false;
194 bool isExt =
genPartToCalo(ctx, clus, thePart, isFwrdEle, dR, isNCone, *caloDDMgr);
195 if (!isExt)
continue;
199 info->egPartPtr.push_back(thePart);
200 info->egPartdR.push_back(dR);
205 if ((iParticlePDG == 22 || std::abs(iParticlePDG) == 11) && isNCone && pt > LeadingPhtPT) {
212 if ((iParticlePDG != 22 && std::abs(iParticlePDG) != 11) && isNCone && pt > LeadingPartPT) {
213 theLeadingPartInCone = thePart;
219 if (!isNCone && dR < BestPartdR) {
220 theBestPartOutCone = thePart;
225 if (theEgamma !=
nullptr) {
227 if (info) info->deltaRMatch = LeadingPhtdR;
228 }
else if (theLeadingPartInCone !=
nullptr) {
229 theMatchPart =
MC::findMatching(truthParticleContainerReadHandle.
ptr(),theLeadingPartInCone);
230 if (info) info->deltaRMatch = LeadingPartdR;
231 }
else if (theBestPartOutCone !=
nullptr) {
232 theMatchPart =
MC::findMatching(truthParticleContainerReadHandle.
ptr(),theBestPartOutCone);
233 if (info) info->deltaRMatch = BestPartdR;
235 theMatchPart =
nullptr;
250 isNarrowCone =
false;
251 if (thePart ==
nullptr)
return false;
252 double phiClus = clus->
phiBE(2);
253 double etaClus = clus->
etaBE(2);
254 if (etaClus < -900) {
255 etaClus = clus->
eta();
257 if (phiClus < -900) {
258 phiClus = clus->
phi();
261 if (isFwrdEle || (etaClus == 0. && phiClus == 0.)) {
262 phiClus = clus->
phi();
263 etaClus = clus->
eta();
270 sample = CaloSampling::EMB2;
274 sample = CaloSampling::EME2;
275 }
else if (isFwrdEle && clus->
inEndcap()) {
277 sample = CaloSampling::FCAL2;
281 std::unique_ptr<Trk::CurvilinearParameters> params = extractParamFromTruth(*thePart);
282 if (!params)
return false;
284 std::vector<CaloSampling::CaloSample> samples = { sample };
285 auto extension =
m_caloExtensionTool->layersCaloExtension(ctx, *params, samples, etaClus, caloDDMgr);
286 bool extensionOK = (!extension.empty());
288 ATH_MSG_WARNING(
"extrapolation of Truth Particle with eta " << thePart->
eta() <<
" , charge " << thePart->
charge() <<
" , Pt " << thePart->
pt() <<
" to calo failed");
291 double etaCalo = extension[0].second->position().eta();
292 double phiCalo = extension[0].second->position().phi();
294 const double dPhi = std::abs(std::remainder(phiCalo - phiClus, 2*std::numbers::pi));
295 const double dEta = std::abs(etaCalo - etaClus);
296 dRmatch = std::hypot(dPhi, dEta);
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses