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
21 if (name == "R10TruthLabel_R21Precision_2022v1")
23
24 if (name == "R10TruthLabel_R22v1")
26
27 if (name == "R10WZTruthLabel_R22v1")
29
30 if (name == "R4TruthLabel")
32
33 if (name == "R4TruthDressedWZLabel")
35
36 if (name == "R4InTimeTruthLabel")
38
39 if (name == "R4OutOfTimeTruthLabel")
41
43}
44
45
47
48 ATH_MSG_INFO("Initializing " << name());
49
51
54 ATH_MSG_ERROR("TruthLabelName " << m_truthLabelName << " is not supported. Exiting...");
55 return StatusCode::FAILURE;
56 }
57
59 m_useGhostJetMatch = false;
60 m_recoGhostFrac = 0.75;
61
62 switch(m_truthLabelConfig) {
66 m_truthJetCollectionKey="AntiKt10TruthJets";
68 m_dRTruthJet = 0.75;
71 m_truthGroomedJetCollectionKey="AntiKt10TruthSoftDropBeta100Zcut10Jets";
72 } else {
74 }
75 break;
78 m_truthJetCollectionKey="AntiKt10TruthDressedWZJets";
80 m_dRTruthJet = 0.75;
81 m_mLowTop = 140.0;
82 m_mLowW = 50.0;
83 m_mLowZ = 50.0;
85 m_truthGroomedJetCollectionKey="AntiKt10TruthDressedWZSoftDropBeta100Zcut10Jets";
86 break;
87
93 switch (m_truthLabelConfig) {
95 m_truthJetCollectionKey = "AntiKt4TruthJets";
96 break;
98 m_truthJetCollectionKey = "AntiKt4TruthDressedWZJets";
99 break;
101 m_truthJetCollectionKey = "InTimeAntiKt4TruthJets";
102 break;
104 m_truthJetCollectionKey = "OutOfTimeAntiKt4TruthJets";
105 break;
106 default: // Cannot hit anything else
107 break;
108 }
110 m_dRTruthJet = 0.3;
112 m_useGhostJetMatch = false;
113 m_doLargeRLabels = false;
114 break;
115 default:
116 ATH_MSG_ERROR(" Unhandled TruthLabelName " << m_truthLabelName << "! Exiting...");
117 return StatusCode::FAILURE;
118 }
119
121 m_useGhostJetMatch = false;
122 }
123
124 print();
125
128 m_split12_truthKey = m_truthJetCollectionKey.key() + ".Split12";
129 m_split23_truthKey = m_truthJetCollectionKey.key() + ".Split23";
130
131 if(!m_isTruthJetCol){
134 m_truthSplit12_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthJetSplit12";
135 m_truthSplit23_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthJetSplit23";
136
143
144 if (!m_doLargeRLabels) { //Simple naming for small R
145 m_matchedTruthJet_recoKey = m_jetContainerName + "." + "TruthMatch_Jet";
146 m_matchedTruthJetMass_recoKey = m_jetContainerName + "." + "TruthMatch_m";
147 m_matchedTruthJetPt_recoKey = m_jetContainerName + "." + "TruthMatch_pt";
148 m_matchedTruthJetRapidity_recoKey = m_jetContainerName + "." + "TruthMatch_rapidity";
149 m_matchedTruthJetPhi_recoKey = m_jetContainerName + "." + "TruthMatch_phi";
150 m_matchedTruthJetDR_recoKey = m_jetContainerName + "." + "TruthMatch_dR";
151 m_matchedPileupTag_recoKey = m_jetContainerName + "." + "TruthMatch_PileupLabel";
152 m_sumPtMatchedHSJets_recoKey = m_jetContainerName + "." + "TruthMatch_HSSumPt";
153 m_sumPtMatchedOOTJets_recoKey = m_jetContainerName + "." + "TruthMatch_OOTSumPt";
154 m_sumPtMatchedITJets_recoKey = m_jetContainerName + "." + "TruthMatch_ITSumPt";
155 }
156
157 m_matchedTruthGroomedJetMass_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthMatch_GroomedJetMass";
158 m_matchedTruthGroomedJetPt_recoKey = m_jetContainerName + "." + m_truthLabelName + "_TruthMatch_GroomedJetPt";
159 }
160
161 ATH_CHECK(m_evtInfoKey.initialize());
164
167
168 ATH_CHECK(m_label_truthKey.initialize());
169 ATH_CHECK(m_NB_truthKey.initialize());
170
173
178
185
190
193
194 return StatusCode::SUCCESS;
195}
196
198 ATH_MSG_INFO("Parameters for " << name());
199
200 ATH_MSG_INFO("xAOD information:");
201 ATH_MSG_INFO("TruthLabelName: " << m_truthLabelName);
202 ATH_MSG_INFO("TruthJetCollectionName: " << m_truthJetCollectionKey.key());
203 ATH_MSG_INFO("dRTruthJet: " << std::to_string(m_dRTruthJet));
204
206 ATH_MSG_INFO("truthGroomedJetCollectionName: " << m_truthGroomedJetCollectionKey.key());
207 }
208}
209
210
212 (const JetTruthLabelingTool& tool, const EventContext& ctx)
213{
214 auto maybeInit = [&] (auto& h,
216 {
217 if (!k.key().empty()) h.emplace (k, ctx);
218 };
219 maybeInit (labelHandle, tool.m_label_truthKey);
220 maybeInit (nbHandle, tool.m_NB_truthKey);
221 maybeInit (labelRecoHandle, tool.m_label_recoKey);
222 maybeInit (nbRecoHandle, tool.m_NB_recoKey);
223 maybeInit (split23Handle, tool.m_truthSplit23_recoKey);
224 maybeInit (split12Handle, tool.m_truthSplit12_recoKey);
225
226 maybeInit (matchedTruthJetHandle, tool.m_matchedTruthJet_recoKey);
227 maybeInit (matchedTruthJetMassHandle, tool.m_matchedTruthJetMass_recoKey);
228 maybeInit (matchedTruthJetPtHandle, tool.m_matchedTruthJetPt_recoKey);
229 maybeInit (matchedTruthJetRapidityHandle, tool.m_matchedTruthJetRapidity_recoKey);
230 maybeInit (matchedTruthJetPhiHandle, tool.m_matchedTruthJetPhi_recoKey);
231 maybeInit (matchedTruthJetDRHandle, tool.m_matchedTruthJetDR_recoKey);
232
233 maybeInit (matchedPileupTagHandle, tool.m_matchedPileupTag_recoKey);
234 maybeInit (sumPtMatchedHSJetsHandle, tool.m_sumPtMatchedHSJets_recoKey);
235 maybeInit (sumPtMatchedOOTJetsHandle, tool.m_sumPtMatchedOOTJets_recoKey);
236 maybeInit (sumPtMatchedITJetsHandle, tool.m_sumPtMatchedITJets_recoKey);
237
238 maybeInit (matchedTruthGroomedMassHandle, tool.m_matchedTruthGroomedJetMass_recoKey);
239 maybeInit (matchedTruthGroomedPtHandle, tool.m_matchedTruthGroomedJetPt_recoKey);
240}
241
243 const xAOD::Jet &jet,
244 const EventContext& ctx ) const
245{
247 bool matchW = false;
248 bool matchZ = false;
249 bool matchH = false;
250 bool matchTop = false;
251
253 int nMatchW = getNGhostParticles( jet, "GhostWBosons" );
254
255 if ( nMatchW ) {
256 matchW = true;
257 }
258
260 int nMatchZ = getNGhostParticles( jet, "GhostZBosons" );
261
262 if ( nMatchZ ) {
263 matchZ = true;
264 }
265
267 int nMatchH = getNGhostParticles( jet, "GhostHBosons" );
268
269 if ( nMatchH ) {
270 matchH = true;
271 }
272
274 int nMatchTop = getNGhostParticles( jet, "GhostTQuarksFinal" );
275
276 if ( nMatchTop ) {
277 matchTop = true;
278 }
279
280 return getLabel( dh, jet, matchH, matchW, matchZ, matchTop, ctx );
281
282}
283
285 const EventContext& ctx = Gaudi::Hive::currentContext();
286 DecorHandles dh (*this, ctx);
287
289 if(m_isTruthJetCol) {
290 return labelTruthJets(dh, jets, ctx);
291 }
292
293 else if (!m_isTruthJetCol && !m_doLargeRLabels) {
294 return labelRecoJets(dh, jets, ctx);
295 }
296
298 else {
299 ATH_CHECK( labelTruthJets(dh, ctx) );
300 return labelRecoJets(dh, jets, ctx);
301 }
302
303 return StatusCode::SUCCESS;
304}
305
307 const xAOD::JetContainer& jets,
308 const EventContext& ctx) const {
309
311
312 bool usePileupJets = true;
313
315 SG::ReadHandle<xAOD::JetContainer> outOfTimeTruthJets;
316 if (!m_doLargeRLabels) {
317 inTimeTruthJets = SG::makeHandle(m_ITJetName, ctx);
318 outOfTimeTruthJets = SG::makeHandle(m_OOTJetName, ctx);
319
320 if (!inTimeTruthJets.isValid() || !outOfTimeTruthJets.isValid()) {
321 ATH_MSG_WARNING("Pileup jet collections unavailabel for " << m_truthJetCollectionKey << ". Running without pileup tagger.");
322 usePileupJets = false;
323 }
324 }
325
326 SG::ReadHandle<xAOD::JetContainer> truthGroomedJets;
328 truthGroomedJets = SG::makeHandle(m_truthGroomedJetCollectionKey, ctx);
329 }
330
331 const SG::AuxElement::Accessor<int> nbAcc (m_truthLabelName + "_NB");
332 static const SG::ConstAccessor< ElementLink< xAOD::JetContainer > > ParentAcc ("Parent");
333
334 for(const xAOD::Jet *jet : jets) {
335
337 const xAOD::Jet* parent = nullptr;
339 ElementLink<xAOD::JetContainer> element_link = ParentAcc (*jet);
340 if ( element_link.isValid() ) {
341 parent = *element_link;
342 }
343 else {
344 ATH_MSG_ERROR("Unable to get a link to the parent jet! Returning a NULL pointer.");
345 return StatusCode::FAILURE;
346 }
347 }
349 float dRmin = 9999;
350 float oot_dRmin = 9999;
351 float it_dRmin = 9999;
352 float ghostFracNominal = 9;
353 const xAOD::Jet* matchTruthJet = nullptr;
354 const xAOD::Jet* oot_matchTruthJet = nullptr;
355 const xAOD::Jet* it_matchTruthJet = nullptr;
357 float dRminGroomed = 9999;
358 const xAOD::Jet* matchTruthGroomedJet = nullptr;
360 float sumPtMatchedHSJets = 0;
361 float sumPtMatchedOOTJets = 0;
362 float sumPtMatchedITJets = 0;
363 float bestHSpT = -9999;
364 float bestOOTpT = -9999;
365 float bestITpT = -9999;
366 float bestHSpTRatio = -9;
367 float bestOOTpTRatio = -9;
368 float bestITpTRatio = -9;
369 int nMatchedHSJets = 0;
370 int nMatchedOOTJets = 0;
371 int nMatchedITJets = 0;
373 //coverity[UNNECESSARY_STRING_COPY:FALSE]
374 static const SG::ConstAccessor<float> accGhostTruthPt("GhostTruthPt");
375
376 // Ensure that the reco jet has at least one constituent
377 // (and thus a well-defined four-vector)
378 if (jet->numConstituents() > 0) {
379 for (const xAOD::Jet* truthJet : *truthJets) { // Truth jet loop
380 // Calculate DR
381 float dR = jet->p4().DeltaR(truthJet->p4(),true);
382 // If parent jet has been retrieved, calculate dR w.r.t. it instead
383 if (parent) dR = parent->p4().DeltaR(truthJet->p4(),true);
384 // Calculate GF
385 if (m_useGhostJetMatch) { // GA matching. Upper bound applied for completeness, but realistically not needed.
386 // Access ghostTruthPt now so it is available for pileup jets
387 float ghostTruthPt = accGhostTruthPt(*jet);
388 float ghostPtFraction = (ghostTruthPt / (truthJet->pt()));
389 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
390 nMatchedHSJets += 1;
391 sumPtMatchedHSJets += truthJet->pt();
392 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
393 matchTruthJet = truthJet;
394 ghostFracNominal = ghostPtFraction;
395 }
396 }
397 }
398 else { // If m_dRTruthJet < 0, the closest truth jet is used as matched jet. Otherwise, only match if dR < m_dRTruthJet
399 if (m_dRTruthJet < 0 || dR < m_dRTruthJet) { // All matches
400 nMatchedHSJets += 1;
401 sumPtMatchedHSJets += truthJet->pt();
402 if (dR < dRmin) { // Best match
403 dRmin = dR;
404 matchTruthJet = truthJet;
405 }
406 }
407 }
408 }
409 if (!m_doLargeRLabels && usePileupJets) {
410 for (const xAOD::Jet* ootJet : *outOfTimeTruthJets) { // Out of time pileup truth jet loop
411 float dR = jet->p4().DeltaR(ootJet->p4(), true);
412 if (m_useGhostJetMatch) {
413 float ghostTruthPt = accGhostTruthPt(*jet);
414 float ghostPtFraction = (ghostTruthPt / (ootJet->pt()));
415 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
416 nMatchedOOTJets += 1;
417 sumPtMatchedOOTJets += ootJet->pt();
418 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
419 oot_matchTruthJet = ootJet;
420 }
421 }
422 }
423 else {
424 if (dR < m_dRTruthJet) { // All matches
425 nMatchedOOTJets += 1;
426 sumPtMatchedOOTJets += ootJet->pt();
427 if (dR < oot_dRmin) { // Best match
428 oot_dRmin = dR;
429 oot_matchTruthJet = ootJet;
430 }
431 }
432 }
433 }
434 for (const xAOD::Jet* itJet : *inTimeTruthJets) { // In time pileup truth jet loop
435 float dR = jet->p4().DeltaR(itJet->p4(), true);
436 if (m_useGhostJetMatch) {
437 float ghostTruthPt = accGhostTruthPt(*jet);
438 float ghostPtFraction = (ghostTruthPt / (itJet->pt()));
439 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
440 nMatchedITJets += 1;
441 sumPtMatchedITJets += itJet->pt();
442 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
443 it_matchTruthJet = itJet;
444 }
445 }
446 }
447 else {
448 if (dR < m_dRTruthJet) { // All matches
449 nMatchedITJets += 1;
450 sumPtMatchedITJets += itJet->pt();
451 if (dR < it_dRmin) { // Best match
452 it_dRmin = dR;
453 it_matchTruthJet = itJet;
454 }
455 }
456 }
457 }
458
459 //#######################################################################################
460 //# PILEUP TAGGER KEY #
461 //# 0: Hard scatter ------------- Best truth jet match has >90% of the total matched pT #
462 //# 1: Mixed hard scatter-------- Match with multiple truth jets, none >90% (no PU) #
463 //# 2: Hard scatter with pileup - Best truth jet <90%, also has pileup matches #
464 //# 3: In time pileup---------- - Best it jet match has > 90 % of the total matched pT #
465 //# 4: Mixed pileup ------------- Match with multiple pileup jets, none >90% (no HS) #
466 //# 5: Out of time pileup------ - Best oot jet match has > 90 % of the total matched pT #
467 //# 6: Other/unknown ------------ Fails all above cases #
468 //#######################################################################################
469
470 //NOTE: HS has 5 GeV pT threshold, 10 GeV and 15 GeV for IT and OOT pileup.
471
472 int nMatchedPUJets = nMatchedOOTJets + nMatchedITJets;
473
474 float totalMatchedpT = sumPtMatchedHSJets + sumPtMatchedOOTJets + sumPtMatchedITJets;
475
476 if (matchTruthJet) {
477 bestHSpT = matchTruthJet->pt();
478 bestHSpTRatio = bestHSpT / totalMatchedpT;
479 }
480 if (oot_matchTruthJet) {
481 bestOOTpT = oot_matchTruthJet->pt();
482 bestOOTpTRatio = bestOOTpT / totalMatchedpT;
483 }
484 if (it_matchTruthJet) {
485 bestITpT = it_matchTruthJet->pt();
486 bestITpTRatio = bestITpT / totalMatchedpT;
487 }
488
489 if (bestHSpTRatio >= 0.9) { //HS
490 pileupTag = SmallRJetPileupLabel::HS;
491 }
492 else if (bestITpTRatio >= 0.9) { //IT
493 pileupTag = SmallRJetPileupLabel::ITPU;
494 }
495 else if (bestOOTpTRatio >= 0.9) { //OOT
496 pileupTag = SmallRJetPileupLabel::OOTPU;
497 }
498 else if (nMatchedPUJets == 0 && nMatchedHSJets > 1) { //Mixed HS
499 pileupTag = SmallRJetPileupLabel::MixHS;
500 }
501 else if (nMatchedPUJets > 0 && nMatchedHSJets > 0) { //HS with pileup
502 pileupTag = SmallRJetPileupLabel::HSPU;
503 }
504 else if (nMatchedPUJets > 1) {//Mixed PU
505 pileupTag = SmallRJetPileupLabel::MixPU;
506 }
507 else { //No match
509 }
510
511 }
512
513 }
514
516 int truthJetNB = -1;
517 float truthJetSplit12 = -9999;
518 float truthJetSplit23 = -9999;
519
520 // Defaults to null EL
522 float truthJetMass = -9999;
523 float truthJetPt = -9999;
524 float truthJetRapidity = -9;
525 float truthJetPhi = -9999;
526 float deltaR = -2;
527
528 const xAOD::JetContainer* truthJetCont = truthJets.cptr();
529
530 //If the best match is PU, reassign the truth jet to take variables from
531 switch(pileupTag) {
533 matchTruthJet = it_matchTruthJet;
534 truthJetCont = inTimeTruthJets.cptr();
535 break;
536 }
538 matchTruthJet = oot_matchTruthJet;
539 truthJetCont = outOfTimeTruthJets.cptr();
540 break;
541 }
543 if (bestITpTRatio >= bestOOTpTRatio) {
544 matchTruthJet = it_matchTruthJet;
545 truthJetCont = inTimeTruthJets.cptr();
546 }
547 else {
548 matchTruthJet = oot_matchTruthJet;
549 truthJetCont = outOfTimeTruthJets.cptr();
550 }
551 }
552 default:
553 break;
554 }
555
556 if ( matchTruthJet ) {
557
558 // Can't use the WriteDecorHandle to read --- the decoration may have
559 // been added and locked by a previous algorithm.
560 // Not saving Truth jet decorations for small R
561 if (m_doLargeRLabels) {
562 SG::ConstAccessor<int> labelAcc(dh.labelHandle->auxid());
563 label = labelAcc(*matchTruthJet);
566 if (split23Handle.isAvailable()) truthJetSplit23 = split23Handle(*matchTruthJet);
568 if (split12Handle.isAvailable()) truthJetSplit12 = split12Handle(*matchTruthJet);
569 }
570 if (nbAcc.isAvailable(*matchTruthJet)) truthJetNB = nbAcc(*matchTruthJet);
571 }
572 ATH_MSG_VERBOSE("For reco jet " << jet->index() << ", matched truth jet index " << matchTruthJet->index());
573 truthJetEL = ElementLink<xAOD::JetContainer>(*truthJetCont, matchTruthJet->index(), ctx);
574 truthJetMass = matchTruthJet->m();
575 truthJetPt = matchTruthJet->pt();
576 truthJetRapidity = matchTruthJet->rapidity();
577 truthJetPhi = matchTruthJet->phi();
578 deltaR = dRmin;
579 }
580
581 // Save Groomed Truth Jet variables
582 float truthGroomedJetMass = -9999;
583 float truthGroomedJetPt = -9999;
585 if ( matchTruthJet ) {
586 for ( const xAOD::Jet* truthGroomedJet : *truthGroomedJets ) {
587 ElementLink<xAOD::JetContainer> element_link = ParentAcc (*truthGroomedJet);
588 if ( !element_link.isValid() ) { continue; }
589 if ( matchTruthJet == *element_link ) {
590 matchTruthGroomedJet = truthGroomedJet;
591 break;
592 }
593 }
594 }
595 // If no matched jet found or matched jet has no corresponding groomed jet, use dR matching
596 if ( !matchTruthGroomedJet && parent != nullptr) {
597 for ( const xAOD::Jet* truthGroomedJet : *truthGroomedJets ) {
598 float dR = parent->p4().DeltaR(truthGroomedJet->p4(),true);
600 if ( m_dRTruthJet < 0 || dR < m_dRTruthJet ) {
601 if ( dR < dRminGroomed ) {
602 dRminGroomed = dR;
603 matchTruthGroomedJet = truthGroomedJet;
604 }
605 }
606 }
607 }
608 if ( matchTruthGroomedJet ) {
609 truthGroomedJetMass = matchTruthGroomedJet->m();
610 truthGroomedJetPt = matchTruthGroomedJet->pt();
611 }
612 }
613
615 if (m_doLargeRLabels) {
616 (*dh.labelRecoHandle)(*jet) = label;
619 (*dh.split23Handle)(*jet) = truthJetSplit23;
620 (*dh.split12Handle)(*jet) = truthJetSplit12;
621 }
622
623 (*dh.nbRecoHandle)(*jet) = truthJetNB;
624 }
625
626 (*dh.matchedTruthJetHandle)(*jet) = truthJetEL;
627 (*dh.matchedTruthJetMassHandle)(*jet) = truthJetMass;
628 (*dh.matchedTruthJetPtHandle)(*jet) = truthJetPt;
629 (*dh.matchedTruthJetRapidityHandle)(*jet) = truthJetRapidity;
630 (*dh.matchedTruthJetPhiHandle)(*jet) = truthJetPhi;
632
633 if (!m_doLargeRLabels && usePileupJets) {
634 (*dh.matchedPileupTagHandle)(*jet) = pileupTag;
635 (*dh.sumPtMatchedHSJetsHandle)(*jet) = sumPtMatchedHSJets;
636 (*dh.sumPtMatchedOOTJetsHandle)(*jet) = sumPtMatchedOOTJets;
637 (*dh.sumPtMatchedITJetsHandle)(*jet) = sumPtMatchedITJets;
638 }
639
641 (*dh.matchedTruthGroomedMassHandle)(*jet) = truthGroomedJetMass;
642 (*dh.matchedTruthGroomedPtHandle)(*jet) = truthGroomedJetPt;
643 }
644 }
645
646 return StatusCode::SUCCESS;
647}
648
650 const EventContext& ctx) const {
651
654
656 if ( !truthJets.isValid() ) {
657 ATH_MSG_ERROR("No truth jet container retrieved. Please make sure you are using a supported TruthLabelName.");
658 return StatusCode::FAILURE;
659 }
660
661 return labelTruthJets(dh, *truthJets, ctx);
662
663}
664
666 const xAOD::JetContainer &truthJets,
667 const EventContext& ctx) const
668{
670 if ( !(truthJets.size()) ) return StatusCode::SUCCESS;
671
673 if(dh.labelHandle->isAvailable()){
674 // Beware: if we get here, the configuration is probably not MT-compatible.
675 ATH_MSG_DEBUG("labelTruthJets: Truth jet collection already labelled with " << m_truthLabelName);
676 return StatusCode::SUCCESS;
677 }
678
681 if(!eventInfo.isValid()){
682 ATH_MSG_ERROR("Failed to retrieve event information.");
683 return StatusCode::FAILURE;
684 }
685
686 if(m_doLargeRLabels) {
689 for ( const xAOD::Jet *jet : truthJets ) {
690 ATH_MSG_DEBUG("Getting truth label using ghost-association");
691 label = getTruthJetLabelGA(dh, *jet, ctx);
692 (*dh.labelHandle)(*jet) = label;
693 }
694 }
695
696 return StatusCode::SUCCESS;
697}
698
700
703
704 float split12 = -999.0;
705
707 const float c0 = 55.25;
708 const float c1 = -2.34e-3;
709
710 split12 = c0 * std::exp( c1 * pt );
711 }
712
713 return split12;
714
715}
716
718
721
722 float split23 = -999.0;
723
727
728 const float c0 = 3.3;
729 const float c1 = -6.98e-4;
730
731 split23 = std::exp( c0 + c1 * pt );
732
733 }
734
735 return split23;
736}
737
738int JetTruthLabelingTool::getNGhostParticles( const xAOD::Jet &jet, const std::string & collection ) const {
739
740 int nMatchPart = 0;
741
742 if( !jet.getAttribute<int>( collection+"Count", nMatchPart ) ){
743
744 std::vector<const xAOD::TruthParticle*> ghostParts;
745 if( !jet.getAssociatedObjects<xAOD::TruthParticle>( collection, ghostParts ) ){
746 ATH_MSG_ERROR( collection + " cannot be retrieved! Truth label definition might be wrong" );
747 }
748 nMatchPart = ghostParts.size();
749 }
750
751 return nMatchPart;
752}
753
755 const xAOD::Jet &jet,
756 bool matchH,
757 bool matchW,
758 bool matchZ,
759 bool matchTop,
760 const EventContext& ctx) const {
761
762 // store GhostBHadronsFinal count
763 int nMatchB = getNGhostParticles( jet, "GhostBHadronsFinal" );
764 (*dh.nbHandle)(jet) = nMatchB;
765
767 bool is_bb = false;
768 bool is_cc = false;
769 bool is_tautauEl = false;
770 bool is_tautauMu = false;
771 bool is_tautauHad = false;
772 bool isTop = false;
773 bool isW = false;
774 bool isZ = false;
775
776 // Use R21Precision_2022v1 definition
780 is_bb = ( nMatchB > 1 );
781 isTop = ( matchTop && matchW && nMatchB > 0 && jet.m() / 1000. > m_mLowTop && split23Handle(jet) / 1000. > getTopSplit23Cut( jet.pt() / 1000. ) );
782 isW = matchW && nMatchB == 0 && jet.m() / 1000. > m_mLowW && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
783 isZ = matchZ && jet.m() / 1000. > m_mLowZ && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
784 }
785
786 // Use R10TruthLabel_R22v1 definition
788 // get extended ghost associated truth label
789 int extended_GA_label = -1;
790 if (not jet.getAttribute("HadronGhostExtendedTruthLabelID", extended_GA_label)) {
791 ATH_MSG_ERROR( "HadronGhostExtendedTruthLabelID not available for " + m_truthJetCollectionKey.key() );
792 }
793
796 is_bb = ( extended_GA_label == 55 );
797 is_cc = ( extended_GA_label == 44 );
798 is_tautauEl = ( extended_GA_label == 151511 );
799 is_tautauMu = ( extended_GA_label == 151513 );
800 is_tautauHad = ( extended_GA_label == 1515 );
801 isTop = ( matchTop && matchW && nMatchB > 0 && jet.m() / 1000. > m_mLowTop && split23Handle(jet) / 1000. > getTopSplit23Cut( jet.pt() / 1000. ) );
802 isW = matchW && nMatchB == 0 && jet.m() / 1000. > m_mLowW && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
803 isZ = matchZ && jet.m() / 1000. > m_mLowZ && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
804 }
805
806
808
809 /* The default priority of labels is:
810 * 1) Hbb/cc/tautau
811 * 2) Contained top
812 * 3) Contained W
813 * 4) Contained Zbb/cc/qq/tautau
814 * 5) Uncontained top
815 * 6) Uncontained V
816 */
817
819 if( !(matchTop || matchW || matchZ || matchH) ) {
821 }
822
823 // Higgs
824 if ( matchH ) {
826 if ( is_bb ) return LargeRJetTruthLabel::Hbb;
828 if ( is_cc ) return LargeRJetTruthLabel::Hcc;
830 if ( is_tautauEl ) return LargeRJetTruthLabel::HtautauEl;
831 if ( is_tautauMu ) return LargeRJetTruthLabel::HtautauMu;
832 if ( is_tautauHad ) return LargeRJetTruthLabel::HtautauHad;
835 }
836
838 if ( isTop ) return LargeRJetTruthLabel::tqqb;
839
840 if ( isW ) {
842 if ( matchTop ) return LargeRJetTruthLabel::Wqq_From_t;
845 }
846
847 if ( matchZ ) {
849 if ( is_bb ) return LargeRJetTruthLabel::Zbb;
851 if ( is_cc ) return LargeRJetTruthLabel::Zcc;
853 if ( is_tautauEl ) return LargeRJetTruthLabel::ZtautauEl;
854 if ( is_tautauMu ) return LargeRJetTruthLabel::ZtautauMu;
855 if ( is_tautauHad ) return LargeRJetTruthLabel::ZtautauHad;
856 }
857 if ( isZ ) {
860 }
861
863 if ( matchTop ) return LargeRJetTruthLabel::other_From_t;
864
867
868}
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
Gaudi::Property< bool > m_forceDeltaRMatch
bool m_getTruthGroomedJetValues
Use the ungroomed reco jet parent to match to truth jet.
double m_mLowZ
Lower mass cut for W label.
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
double m_mLowTop
Ghost pT fraction to match truth jet to reco jet.
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
SG::ReadHandleKey< xAOD::JetContainer > m_truthGroomedJetCollectionKey
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.
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJetMass_recoKey
double m_recoGhostFrac
dR to match truth jet to reco jet
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthJet_recoKey
Gaudi::Property< bool > m_isTruthJetCol
TruthLabelConfiguration m_truthLabelConfig
bool m_doLargeRLabels
Lower mass cut for Z label.
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.
SG::ReadDecorHandleKey< xAOD::JetContainer > m_split23_truthKey
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
bool m_matchUngroomedParent
Is the reco jet collection small or large R, default large.
TruthLabelConfiguration parseLabel(const std::string &label)
JetTruthLabelingTool(const std::string &name="JetTruthLabelingTool")
default constructor - to be used in all derived classes
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
double m_mLowW
Lower mass cut for top label.
SG::WriteDecorHandleKey< xAOD::JetContainer > m_NB_recoKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_matchedTruthGroomedJetPt_recoKey
double m_dRTruthJet
When truth jet matching to ungroomed truth, allow saving properties of groomed truth jets.
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 constant type-safe access to aux data.
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".
Track internally if the W,Z,Top labels should be done (for large-R).
DecorHandles(const JetTruthLabelingTool &tool, const EventContext &ctx)