ATLAS Offline Software
Loading...
Searching...
No Matches
JetTruthLabelingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
13
15 asg::AsgTool(name)
16{}
17
19JetTruthLabelingTool::parseLabel(const std::string& name) {
20 static const std::map<std::string, TruthLabelConfiguration> labels{
21 {"R10TruthLabel_R21Precision_2022v1", TruthLabelConfiguration::R21Precision_2022v1},
22 {"R10TruthLabel_R22v1", TruthLabelConfiguration::R10TruthLabel_R22v1},
23 {"R10WZTruthLabel_R22v1", TruthLabelConfiguration::R10WZTruthLabel_R22v1},
25 {"R4TruthDressedWZLabel", TruthLabelConfiguration::R4TruthDressedWZLabel},
26 {"R4InTimeTruthLabel", TruthLabelConfiguration::R4InTimeTruthLabel},
27 {"R4OutOfTimeTruthLabel", TruthLabelConfiguration::R4OutOfTimeTruthLabel},
28 };
29 auto it = labels.find(name);
30 return it != labels.end() ? it->second : TruthLabelConfiguration::Unknown;
31}
32
34
35 ATH_MSG_INFO("Initializing " << name());
36
38
41 ATH_MSG_ERROR("TruthLabelName " << m_truthLabelName << " is not supported. Exiting...");
42 return StatusCode::FAILURE;
43 }
44
45 print();
46
51
52 if(!m_isTruthJetCol){
55 m_truthSplit12_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthJetSplit12";
56 m_truthSplit23_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthJetSplit23";
57
64
65 if (!m_doLargeRLabels) { //Simple naming for small R
66 m_matchedTruthJet_recoKey = m_jetContainerName + "." + "TruthMatch_Jet";
68 m_matchedTruthJetPt_recoKey = m_jetContainerName + "." + "TruthMatch_pt";
69 m_matchedTruthJetRapidity_recoKey = m_jetContainerName + "." + "TruthMatch_rapidity";
70 m_matchedTruthJetPhi_recoKey = m_jetContainerName + "." + "TruthMatch_phi";
71 m_matchedTruthJetDR_recoKey = m_jetContainerName + "." + "TruthMatch_dR";
72 m_matchedPileupTag_recoKey = m_jetContainerName + "." + "TruthMatch_PileupLabel";
73 m_sumPtMatchedHSJets_recoKey = m_jetContainerName + "." + "TruthMatch_HSSumPt";
74 m_sumPtMatchedOOTJets_recoKey = m_jetContainerName + "." + "TruthMatch_OOTSumPt";
75 m_sumPtMatchedITJets_recoKey = m_jetContainerName + "." + "TruthMatch_ITSumPt";
76 }
77
78 m_matchedTruthGroomedJetMass_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthMatch_GroomedJetMass";
79 m_matchedTruthGroomedJetPt_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthMatch_GroomedJetPt";
80 }
81
82 ATH_CHECK(m_evtInfoKey.initialize());
85
88
89 ATH_CHECK(m_label_truthKey.initialize());
90 ATH_CHECK(m_NB_truthKey.initialize());
91
94
99
106
111
114
115 return StatusCode::SUCCESS;
116}
117
119 ATH_MSG_INFO("Parameters for " << name());
120
121 ATH_MSG_INFO("xAOD information:");
122 ATH_MSG_INFO("TruthLabelName: " << m_truthLabelName);
123 ATH_MSG_INFO("TruthJetCollectionName: " << m_truthJetCollectionKey.key());
124 ATH_MSG_INFO("dRTruthJet: " << std::to_string(m_dRTruthJet));
125
127 ATH_MSG_INFO("truthGroomedJetCollectionName: " << m_truthGroomedJetCollectionKey.key());
128 }
129}
130
131
133 (const JetTruthLabelingTool& tool, const EventContext& ctx)
134{
135 auto maybeInit = [&] (auto& h,
137 {
138 if (!k.key().empty()) h.emplace (k, ctx);
139 };
140 maybeInit (labelHandle, tool.m_label_truthKey);
141 maybeInit (nbHandle, tool.m_NB_truthKey);
142 maybeInit (labelRecoHandle, tool.m_label_recoKey);
143 maybeInit (nbRecoHandle, tool.m_NB_recoKey);
144 maybeInit (split23Handle, tool.m_truthSplit23_recoKey);
145 maybeInit (split12Handle, tool.m_truthSplit12_recoKey);
146
147 maybeInit (matchedTruthJetHandle, tool.m_matchedTruthJet_recoKey);
148 maybeInit (matchedTruthJetMassHandle, tool.m_matchedTruthJetMass_recoKey);
149 maybeInit (matchedTruthJetPtHandle, tool.m_matchedTruthJetPt_recoKey);
150 maybeInit (matchedTruthJetRapidityHandle, tool.m_matchedTruthJetRapidity_recoKey);
151 maybeInit (matchedTruthJetPhiHandle, tool.m_matchedTruthJetPhi_recoKey);
152 maybeInit (matchedTruthJetDRHandle, tool.m_matchedTruthJetDR_recoKey);
153
154 maybeInit (matchedPileupTagHandle, tool.m_matchedPileupTag_recoKey);
155 maybeInit (sumPtMatchedHSJetsHandle, tool.m_sumPtMatchedHSJets_recoKey);
156 maybeInit (sumPtMatchedOOTJetsHandle, tool.m_sumPtMatchedOOTJets_recoKey);
157 maybeInit (sumPtMatchedITJetsHandle, tool.m_sumPtMatchedITJets_recoKey);
158
159 maybeInit (matchedTruthGroomedMassHandle, tool.m_matchedTruthGroomedJetMass_recoKey);
160 maybeInit (matchedTruthGroomedPtHandle, tool.m_matchedTruthGroomedJetPt_recoKey);
161}
162
164 const xAOD::Jet &jet,
165 const EventContext& ctx ) const
166{
168 bool matchW = false;
169 bool matchZ = false;
170 bool matchH = false;
171 bool matchTop = false;
172
174 int nMatchW = getNGhostParticles( jet, "GhostWBosons" );
175
176 if ( nMatchW ) {
177 matchW = true;
178 }
179
181 int nMatchZ = getNGhostParticles( jet, "GhostZBosons" );
182
183 if ( nMatchZ ) {
184 matchZ = true;
185 }
186
188 int nMatchH = getNGhostParticles( jet, "GhostHBosons" );
189
190 if ( nMatchH ) {
191 matchH = true;
192 }
193
195 int nMatchTop = getNGhostParticles( jet, "GhostTQuarksFinal" );
196
197 if ( nMatchTop ) {
198 matchTop = true;
199 }
200
201 return getLabel( dh, jet, matchH, matchW, matchZ, matchTop, ctx );
202
203}
204
206 const EventContext& ctx = Gaudi::Hive::currentContext();
207 DecorHandles dh (*this, ctx);
208
210 if(m_isTruthJetCol) {
211 return labelTruthJets(dh, jets, ctx);
212 }
213
214 else if (!m_isTruthJetCol && !m_doLargeRLabels) {
215 return labelRecoJets(dh, jets, ctx);
216 }
217
219 else {
220 ATH_CHECK( labelTruthJets(dh, ctx) );
221 return labelRecoJets(dh, jets, ctx);
222 }
223
224 return StatusCode::SUCCESS;
225}
226
228 const xAOD::JetContainer& jets,
229 const EventContext& ctx) const {
230
232
233 bool usePileupJets = true;
234
236 SG::ReadHandle<xAOD::JetContainer> outOfTimeTruthJets;
237 if (!m_doLargeRLabels) {
238 inTimeTruthJets = SG::makeHandle(m_ITJetName, ctx);
239 outOfTimeTruthJets = SG::makeHandle(m_OOTJetName, ctx);
240
241 if (!inTimeTruthJets.isValid() || !outOfTimeTruthJets.isValid()) {
242 ATH_MSG_WARNING("Pileup jet collections unavailabel for " << m_truthJetCollectionKey << ". Running without pileup tagger.");
243 usePileupJets = false;
244 }
245 }
246
247 SG::ReadHandle<xAOD::JetContainer> truthGroomedJets;
249 truthGroomedJets = SG::makeHandle(m_truthGroomedJetCollectionKey, ctx);
250 }
251
252 const SG::Accessor<int> nbAcc (m_truthLabelName + "_NB");
253 static const SG::ConstAccessor< ElementLink< xAOD::JetContainer > > ParentAcc ("Parent");
254
255 for(const xAOD::Jet *jet : jets) {
256
258 const xAOD::Jet* parent = nullptr;
260 ElementLink<xAOD::JetContainer> element_link = ParentAcc (*jet);
261 if ( element_link.isValid() ) {
262 parent = *element_link;
263 }
264 else {
265 ATH_MSG_ERROR("Unable to get a link to the parent jet! Returning a NULL pointer.");
266 return StatusCode::FAILURE;
267 }
268 }
270 float dRmin = 9999;
271 float oot_dRmin = 9999;
272 float it_dRmin = 9999;
273 float ghostFracNominal = 9;
274 const xAOD::Jet* matchTruthJet = nullptr;
275 const xAOD::Jet* oot_matchTruthJet = nullptr;
276 const xAOD::Jet* it_matchTruthJet = nullptr;
278 float dRminGroomed = 9999;
279 const xAOD::Jet* matchTruthGroomedJet = nullptr;
281 float sumPtMatchedHSJets = 0;
282 float sumPtMatchedOOTJets = 0;
283 float sumPtMatchedITJets = 0;
284 float bestHSpT = -9999;
285 float bestOOTpT = -9999;
286 float bestITpT = -9999;
287 float bestHSpTRatio = -9;
288 float bestOOTpTRatio = -9;
289 float bestITpTRatio = -9;
290 int nMatchedHSJets = 0;
291 int nMatchedOOTJets = 0;
292 int nMatchedITJets = 0;
294 //coverity[UNNECESSARY_STRING_COPY:FALSE]
295 static const SG::ConstAccessor<float> accGhostTruthPt("GhostTruthPt");
296
297 // Ensure that the reco jet has at least one constituent
298 // (and thus a well-defined four-vector)
299 if (jet->numConstituents() > 0) {
300 for (const xAOD::Jet* truthJet : *truthJets) { // Truth jet loop
301 // Calculate DR
302 float dR = jet->p4().DeltaR(truthJet->p4(),true);
303 // If parent jet has been retrieved, calculate dR w.r.t. it instead
304 if (parent) dR = parent->p4().DeltaR(truthJet->p4(),true);
305 // Calculate GF
306 if (m_useGhostJetMatch) { // GA matching. Upper bound applied for completeness, but realistically not needed.
307 // Access ghostTruthPt now so it is available for pileup jets
308 float ghostTruthPt = accGhostTruthPt(*jet);
309 float ghostPtFraction = (ghostTruthPt / (truthJet->pt()));
310 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
311 nMatchedHSJets += 1;
312 sumPtMatchedHSJets += truthJet->pt();
313 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
314 matchTruthJet = truthJet;
315 ghostFracNominal = ghostPtFraction;
316 }
317 }
318 }
319 else { // If m_dRTruthJet < 0, the closest truth jet is used as matched jet. Otherwise, only match if dR < m_dRTruthJet
320 if (m_dRTruthJet < 0 || dR < m_dRTruthJet) { // All matches
321 nMatchedHSJets += 1;
322 sumPtMatchedHSJets += truthJet->pt();
323 if (dR < dRmin) { // Best match
324 dRmin = dR;
325 matchTruthJet = truthJet;
326 }
327 }
328 }
329 }
330 if (!m_doLargeRLabels && usePileupJets) {
331 for (const xAOD::Jet* ootJet : *outOfTimeTruthJets) { // Out of time pileup truth jet loop
332 float dR = jet->p4().DeltaR(ootJet->p4(), true);
333 if (m_useGhostJetMatch) {
334 float ghostTruthPt = accGhostTruthPt(*jet);
335 float ghostPtFraction = (ghostTruthPt / (ootJet->pt()));
336 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
337 nMatchedOOTJets += 1;
338 sumPtMatchedOOTJets += ootJet->pt();
339 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
340 oot_matchTruthJet = ootJet;
341 }
342 }
343 }
344 else {
345 if (dR < m_dRTruthJet) { // All matches
346 nMatchedOOTJets += 1;
347 sumPtMatchedOOTJets += ootJet->pt();
348 if (dR < oot_dRmin) { // Best match
349 oot_dRmin = dR;
350 oot_matchTruthJet = ootJet;
351 }
352 }
353 }
354 }
355 for (const xAOD::Jet* itJet : *inTimeTruthJets) { // In time pileup truth jet loop
356 float dR = jet->p4().DeltaR(itJet->p4(), true);
357 if (m_useGhostJetMatch) {
358 float ghostTruthPt = accGhostTruthPt(*jet);
359 float ghostPtFraction = (ghostTruthPt / (itJet->pt()));
360 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
361 nMatchedITJets += 1;
362 sumPtMatchedITJets += itJet->pt();
363 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
364 it_matchTruthJet = itJet;
365 }
366 }
367 }
368 else {
369 if (dR < m_dRTruthJet) { // All matches
370 nMatchedITJets += 1;
371 sumPtMatchedITJets += itJet->pt();
372 if (dR < it_dRmin) { // Best match
373 it_dRmin = dR;
374 it_matchTruthJet = itJet;
375 }
376 }
377 }
378 }
379
380 //#######################################################################################
381 //# PILEUP TAGGER KEY #
382 //# 0: Hard scatter ------------- Best truth jet match has >90% of the total matched pT #
383 //# 1: Mixed hard scatter-------- Match with multiple truth jets, none >90% (no PU) #
384 //# 2: Hard scatter with pileup - Best truth jet <90%, also has pileup matches #
385 //# 3: In time pileup---------- - Best it jet match has > 90 % of the total matched pT #
386 //# 4: Mixed pileup ------------- Match with multiple pileup jets, none >90% (no HS) #
387 //# 5: Out of time pileup------ - Best oot jet match has > 90 % of the total matched pT #
388 //# 6: Other/unknown ------------ Fails all above cases #
389 //#######################################################################################
390
391 //NOTE: HS has 5 GeV pT threshold, 10 GeV and 15 GeV for IT and OOT pileup.
392
393 int nMatchedPUJets = nMatchedOOTJets + nMatchedITJets;
394
395 float totalMatchedpT = sumPtMatchedHSJets + sumPtMatchedOOTJets + sumPtMatchedITJets;
396
397 if (matchTruthJet) {
398 bestHSpT = matchTruthJet->pt();
399 bestHSpTRatio = bestHSpT / totalMatchedpT;
400 }
401 if (oot_matchTruthJet) {
402 bestOOTpT = oot_matchTruthJet->pt();
403 bestOOTpTRatio = bestOOTpT / totalMatchedpT;
404 }
405 if (it_matchTruthJet) {
406 bestITpT = it_matchTruthJet->pt();
407 bestITpTRatio = bestITpT / totalMatchedpT;
408 }
409
410 if (bestHSpTRatio >= 0.9) { //HS
411 pileupTag = SmallRJetPileupLabel::HS;
412 }
413 else if (bestITpTRatio >= 0.9) { //IT
414 pileupTag = SmallRJetPileupLabel::ITPU;
415 }
416 else if (bestOOTpTRatio >= 0.9) { //OOT
417 pileupTag = SmallRJetPileupLabel::OOTPU;
418 }
419 else if (nMatchedPUJets == 0 && nMatchedHSJets > 1) { //Mixed HS
420 pileupTag = SmallRJetPileupLabel::MixHS;
421 }
422 else if (nMatchedPUJets > 0 && nMatchedHSJets > 0) { //HS with pileup
423 pileupTag = SmallRJetPileupLabel::HSPU;
424 }
425 else if (nMatchedPUJets > 1) {//Mixed PU
426 pileupTag = SmallRJetPileupLabel::MixPU;
427 }
428 else { //No match
430 }
431
432 }
433
434 }
435
437 int truthJetNB = -1;
438 float truthJetSplit12 = -9999;
439 float truthJetSplit23 = -9999;
440
441 // Defaults to null EL
443 float truthJetMass = -9999;
444 float truthJetPt = -9999;
445 float truthJetRapidity = -9;
446 float truthJetPhi = -9999;
447 float deltaR = -2;
448
449 const xAOD::JetContainer* truthJetCont = truthJets.cptr();
450
451 //If the best match is PU, reassign the truth jet to take variables from
452 switch(pileupTag) {
454 matchTruthJet = it_matchTruthJet;
455 truthJetCont = inTimeTruthJets.cptr();
456 break;
457 }
459 matchTruthJet = oot_matchTruthJet;
460 truthJetCont = outOfTimeTruthJets.cptr();
461 break;
462 }
464 if (bestITpTRatio >= bestOOTpTRatio) {
465 matchTruthJet = it_matchTruthJet;
466 truthJetCont = inTimeTruthJets.cptr();
467 }
468 else {
469 matchTruthJet = oot_matchTruthJet;
470 truthJetCont = outOfTimeTruthJets.cptr();
471 }
472 }
473 default:
474 break;
475 }
476
477 if ( matchTruthJet ) {
478
479 // Can't use the WriteDecorHandle to read --- the decoration may have
480 // been added and locked by a previous algorithm.
481 // Not saving Truth jet decorations for small R
482 if (m_doLargeRLabels) {
483 SG::ConstAccessor<int> labelAcc(dh.labelHandle->auxid());
484 label = labelAcc(*matchTruthJet);
487 if (split23Handle.isAvailable()) truthJetSplit23 = split23Handle(*matchTruthJet);
489 if (split12Handle.isAvailable()) truthJetSplit12 = split12Handle(*matchTruthJet);
490 }
491 if (nbAcc.isAvailable(*matchTruthJet)) truthJetNB = nbAcc(*matchTruthJet);
492 }
493 ATH_MSG_VERBOSE("For reco jet " << jet->index() << ", matched truth jet index " << matchTruthJet->index());
494 truthJetEL = ElementLink<xAOD::JetContainer>(*truthJetCont, matchTruthJet->index(), ctx);
495 truthJetMass = matchTruthJet->m();
496 truthJetPt = matchTruthJet->pt();
497 truthJetRapidity = matchTruthJet->rapidity();
498 truthJetPhi = matchTruthJet->phi();
499 deltaR = dRmin;
500 }
501
502 // Save Groomed Truth Jet variables
503 float truthGroomedJetMass = -9999;
504 float truthGroomedJetPt = -9999;
506 if ( matchTruthJet ) {
507 for ( const xAOD::Jet* truthGroomedJet : *truthGroomedJets ) {
508 ElementLink<xAOD::JetContainer> element_link = ParentAcc (*truthGroomedJet);
509 if ( !element_link.isValid() ) { continue; }
510 if ( matchTruthJet == *element_link ) {
511 matchTruthGroomedJet = truthGroomedJet;
512 break;
513 }
514 }
515 }
516 // If no matched jet found or matched jet has no corresponding groomed jet, use dR matching
517 if ( !matchTruthGroomedJet && parent != nullptr) {
518 for ( const xAOD::Jet* truthGroomedJet : *truthGroomedJets ) {
519 float dR = parent->p4().DeltaR(truthGroomedJet->p4(),true);
521 if ( m_dRTruthJet < 0 || dR < m_dRTruthJet ) {
522 if ( dR < dRminGroomed ) {
523 dRminGroomed = dR;
524 matchTruthGroomedJet = truthGroomedJet;
525 }
526 }
527 }
528 }
529 if ( matchTruthGroomedJet ) {
530 truthGroomedJetMass = matchTruthGroomedJet->m();
531 truthGroomedJetPt = matchTruthGroomedJet->pt();
532 }
533 }
534
536 if (m_doLargeRLabels) {
537 (*dh.labelRecoHandle)(*jet) = label;
540 (*dh.split23Handle)(*jet) = truthJetSplit23;
541 (*dh.split12Handle)(*jet) = truthJetSplit12;
542 }
543
544 (*dh.nbRecoHandle)(*jet) = truthJetNB;
545 }
546
547 (*dh.matchedTruthJetHandle)(*jet) = truthJetEL;
548 (*dh.matchedTruthJetMassHandle)(*jet) = truthJetMass;
549 (*dh.matchedTruthJetPtHandle)(*jet) = truthJetPt;
550 (*dh.matchedTruthJetRapidityHandle)(*jet) = truthJetRapidity;
551 (*dh.matchedTruthJetPhiHandle)(*jet) = truthJetPhi;
553
554 if (!m_doLargeRLabels && usePileupJets) {
555 (*dh.matchedPileupTagHandle)(*jet) = pileupTag;
556 (*dh.sumPtMatchedHSJetsHandle)(*jet) = sumPtMatchedHSJets;
557 (*dh.sumPtMatchedOOTJetsHandle)(*jet) = sumPtMatchedOOTJets;
558 (*dh.sumPtMatchedITJetsHandle)(*jet) = sumPtMatchedITJets;
559 }
560
562 (*dh.matchedTruthGroomedMassHandle)(*jet) = truthGroomedJetMass;
563 (*dh.matchedTruthGroomedPtHandle)(*jet) = truthGroomedJetPt;
564 }
565 }
566
567 return StatusCode::SUCCESS;
568}
569
571 const EventContext& ctx) const {
572
575
577 if ( !truthJets.isValid() ) {
578 ATH_MSG_ERROR("No truth jet container retrieved. Please make sure you are using a supported TruthLabelName.");
579 return StatusCode::FAILURE;
580 }
581
582 return labelTruthJets(dh, *truthJets, ctx);
583
584}
585
587 const xAOD::JetContainer &truthJets,
588 const EventContext& ctx) const
589{
591 if ( !(truthJets.size()) ) return StatusCode::SUCCESS;
592
594 if(dh.labelHandle->isAvailable()){
595 // Beware: if we get here, the configuration is probably not MT-compatible.
596 ATH_MSG_DEBUG("labelTruthJets: Truth jet collection already labelled with " << m_truthLabelName);
597 return StatusCode::SUCCESS;
598 }
599
602 if(!eventInfo.isValid()){
603 ATH_MSG_ERROR("Failed to retrieve event information.");
604 return StatusCode::FAILURE;
605 }
606
607 if(m_doLargeRLabels) {
610 for ( const xAOD::Jet *jet : truthJets ) {
611 ATH_MSG_DEBUG("Getting truth label using ghost-association");
612 label = getTruthJetLabelGA(dh, *jet, ctx);
613 (*dh.labelHandle)(*jet) = label;
614 }
615 }
616
617 return StatusCode::SUCCESS;
618}
619
621
624
625 float split12 = -999.0;
626
628 const float c0 = 55.25;
629 const float c1 = -2.34e-3;
630
631 split12 = c0 * std::exp( c1 * pt );
632 }
633
634 return split12;
635
636}
637
639
642
643 float split23 = -999.0;
644
648
649 const float c0 = 3.3;
650 const float c1 = -6.98e-4;
651
652 split23 = std::exp( c0 + c1 * pt );
653
654 }
655
656 return split23;
657}
658
659int JetTruthLabelingTool::getNGhostParticles( const xAOD::Jet &jet, const std::string & collection ) const {
660
661 int nMatchPart = 0;
662
663 if( !jet.getAttribute<int>( collection+"Count", nMatchPart ) ){
664
665 std::vector<const xAOD::TruthParticle*> ghostParts;
666 if( !jet.getAssociatedObjects<xAOD::TruthParticle>( collection, ghostParts ) ){
667 ATH_MSG_ERROR( collection + " cannot be retrieved! Truth label definition might be wrong" );
668 }
669 nMatchPart = ghostParts.size();
670 }
671
672 return nMatchPart;
673}
674
676 const xAOD::Jet &jet,
677 bool matchH,
678 bool matchW,
679 bool matchZ,
680 bool matchTop,
681 const EventContext& ctx) const {
682
683 // store GhostBHadronsFinal count
684 int nMatchB = getNGhostParticles( jet, "GhostBHadronsFinal" );
685 (*dh.nbHandle)(jet) = nMatchB;
686
688 bool is_bb = false;
689 bool is_cc = false;
690 bool is_tautauEl = false;
691 bool is_tautauMu = false;
692 bool is_tautauHad = false;
693 bool isTop = false;
694 bool isW = false;
695 bool isZ = false;
696
697 // Use R21Precision_2022v1 definition
701 is_bb = ( nMatchB > 1 );
702 isTop = ( matchTop && matchW && nMatchB > 0 && jet.m() / 1000. > m_mLowTop && split23Handle(jet) / 1000. > getTopSplit23Cut( jet.pt() / 1000. ) );
703 isW = matchW && nMatchB == 0 && jet.m() / 1000. > m_mLowW && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
704 isZ = matchZ && jet.m() / 1000. > m_mLowZ && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
705 }
706
707 // Use R10TruthLabel_R22v1 definition
709 // get extended ghost associated truth label
710 int extended_GA_label = -1;
711 if (not jet.getAttribute("HadronGhostExtendedTruthLabelID", extended_GA_label)) {
712 ATH_MSG_ERROR( "HadronGhostExtendedTruthLabelID not available for " + m_truthJetCollectionKey.key() );
713 }
714
717 is_bb = ( extended_GA_label == 55 );
718 is_cc = ( extended_GA_label == 44 );
719 is_tautauEl = ( extended_GA_label == 151511 );
720 is_tautauMu = ( extended_GA_label == 151513 );
721 is_tautauHad = ( extended_GA_label == 1515 );
722 isTop = ( matchTop && matchW && nMatchB > 0 && jet.m() / 1000. > m_mLowTop && split23Handle(jet) / 1000. > getTopSplit23Cut( jet.pt() / 1000. ) );
723 isW = matchW && nMatchB == 0 && jet.m() / 1000. > m_mLowW && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
724 isZ = matchZ && jet.m() / 1000. > m_mLowZ && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
725 }
726
727
729
730 /* The default priority of labels is:
731 * 1) Hbb/cc/tautau
732 * 2) Contained top
733 * 3) Contained W
734 * 4) Contained Zbb/cc/qq/tautau
735 * 5) Uncontained top
736 * 6) Uncontained V
737 */
738
740 if( !(matchTop || matchW || matchZ || matchH) ) {
742 }
743
744 // Higgs
745 if ( matchH ) {
747 if ( is_bb ) return LargeRJetTruthLabel::Hbb;
749 if ( is_cc ) return LargeRJetTruthLabel::Hcc;
751 if ( is_tautauEl ) return LargeRJetTruthLabel::HtautauEl;
752 if ( is_tautauMu ) return LargeRJetTruthLabel::HtautauMu;
753 if ( is_tautauHad ) return LargeRJetTruthLabel::HtautauHad;
756 }
757
759 if ( isTop ) return LargeRJetTruthLabel::tqqb;
760
761 if ( isW ) {
763 if ( matchTop ) return LargeRJetTruthLabel::Wqq_From_t;
766 }
767
768 if ( matchZ ) {
770 if ( is_bb ) return LargeRJetTruthLabel::Zbb;
772 if ( is_cc ) return LargeRJetTruthLabel::Zcc;
774 if ( is_tautauEl ) return LargeRJetTruthLabel::ZtautauEl;
775 if ( is_tautauMu ) return LargeRJetTruthLabel::ZtautauMu;
776 if ( is_tautauHad ) return LargeRJetTruthLabel::ZtautauHad;
777 }
778 if ( isZ ) {
781 }
782
784 if ( matchTop ) return LargeRJetTruthLabel::other_From_t;
785
788
789}
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
bool isW(const T &p)
Definition AtlasPID.h:388
bool isZ(const T &p)
Definition AtlasPID.h:385
bool isTop(const T &p)
Definition AtlasPID.h:191
Helper class to provide constant type-safe access to aux data.
ATLAS-specific HepMC functions.
Header file for AthHistogramAlgorithm.
size_type size() const noexcept
Returns the number of elements in the collection.
Gaudi::Property< std::string > m_jetContainerName
Gaudi::Property< std::string > m_truthLabelName
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJetDR_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_NB_truthKey
StatusCode labelRecoJets(DecorHandles &dh, const xAOD::JetContainer &jets, const EventContext &ctx) const
Apply labels to all jets in a container.
float getTopSplit23Cut(float pt) const
Get top label Split23 cut.
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJetPt_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_label_recoKey
StatusCode labelTruthJets(DecorHandles &dh, const EventContext &ctx) const
Label truth jet collection.
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJetPhi_recoKey
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
SG::ReadHandleKey< xAOD::JetContainer > m_truthGroomedJetCollectionKey
Gaudi::Property< bool > m_doLargeRLabels
void print() const override
Print configured parameters.
int getTruthJetLabelGA(DecorHandles &dh, const xAOD::Jet &jet, const EventContext &ctx) const
Get truth label using ghost-associated particles.
Gaudi::Property< bool > m_matchUngroomedParent
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJetMass_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJet_recoKey
Gaudi::Property< bool > m_isTruthJetCol
TruthLabelConfiguration m_truthLabelConfig
int getLabel(DecorHandles &dh, const xAOD::Jet &jet, bool matchH, bool matchW, bool matchZ, bool matchTop, const EventContext &ctx) const
Get label based on matching and containment criteria.
SG::WriteDecorHandleKey< xAOD::JetContainer > m_truthSplit23_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedPileupTag_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_sumPtMatchedOOTJets_recoKey
SG::ReadHandleKey< xAOD::JetContainer > m_ITJetName
float getWZSplit12Cut(float pt) const
Get W/Z label Split12 cut.
Gaudi::Property< double > m_mLowW
Gaudi::Property< double > m_mLowZ
Gaudi::Property< double > m_recoGhostFrac
Gaudi::Property< bool > m_getTruthGroomedJetValues
SG::ReadDecorHandleKey< xAOD::JetContainer > m_split23_truthKey
Gaudi::Property< double > m_dRTruthJet
SG::ReadDecorHandleKey< xAOD::JetContainer > m_split12_truthKey
int getNGhostParticles(const xAOD::Jet &jet, const std::string &collection) const
Get number of ghost associated particles.
SG::ReadHandleKey< xAOD::JetContainer > m_OOTJetName
parameters for truth labeling
SG::WriteDecorHandleKey< xAOD::JetContainer > m_truthSplit12_recoKey
SG::ReadHandleKey< xAOD::EventInfo > m_evtInfoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthGroomedJetMass_recoKey
TruthLabelConfiguration parseLabel(const std::string &label)
JetTruthLabelingTool(const std::string &name="JetTruthLabelingTool")
default constructor - to be used in all derived classes
Gaudi::Property< double > m_mLowTop
Large R containment cuts [GeV].
SG::WriteDecorHandleKey< xAOD::JetContainer > m_label_truthKey
StatusCode decorate(const xAOD::JetContainer &jets) const override
decorate truth label to a jet collection
SG::ReadHandleKey< xAOD::JetContainer > m_truthJetCollectionKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_NB_recoKey
Gaudi::Property< bool > m_useGhostJetMatch
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthGroomedJetPt_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJetRapidity_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_sumPtMatchedHSJets_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_sumPtMatchedITJets_recoKey
Helper class to provide type-safe access to aux data.
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Handle class for reading a decoration on an object.
bool isAvailable()
Test to see if this variable exists in the store, for the referenced object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition Jet_v1.cxx:54
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition Jet_v1.cxx:44
virtual double rapidity() const
The true rapidity (y) of the particle.
Definition Jet_v1.cxx:67
virtual double m() const
The invariant mass of the particle.
Definition Jet_v1.cxx:59
std::string label(const std::string &format, int i)
Definition label.h:19
int enumToInt(const TypeEnum type)
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
int enumToInt(const TypeEnum type)
Jet_v1 Jet
Definition of the current "jet version".
TruthParticle_v1 TruthParticle
Typedef to implementation.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
DecorHandles(const JetTruthLabelingTool &tool, const EventContext &ctx)