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
374 // Ensure that the reco jet has at least one constituent
375 // (and thus a well-defined four-vector)
376 if (jet->numConstituents() > 0) {
377 // Access ghostTruthPt now so it is available for pileup jets
378 static const SG::ConstAccessor<float> accGhostTruthPt("GhostTruthPt");
379 float ghostTruthPt = accGhostTruthPt(*jet);
380 for (const xAOD::Jet* truthJet : *truthJets) { // Truth jet loop
381 // Calculate DR
382 float dR = jet->p4().DeltaR(truthJet->p4(),true);
383 // If parent jet has been retrieved, calculate dR w.r.t. it instead
384 if (parent) dR = parent->p4().DeltaR(truthJet->p4(),true);
385 // Calculate GF
386 float ghostPtFraction = (ghostTruthPt / (truthJet->pt()));
387 if (m_useGhostJetMatch) { // GA matching. Upper bound applied for completeness, but realistically not needed.
388 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
389 nMatchedHSJets += 1;
390 sumPtMatchedHSJets += truthJet->pt();
391 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
392 matchTruthJet = truthJet;
393 ghostFracNominal = ghostPtFraction;
394 }
395 }
396 }
397 else { // If m_dRTruthJet < 0, the closest truth jet is used as matched jet. Otherwise, only match if dR < m_dRTruthJet
398 if (m_dRTruthJet < 0 || dR < m_dRTruthJet) { // All matches
399 nMatchedHSJets += 1;
400 sumPtMatchedHSJets += truthJet->pt();
401 if (dR < dRmin) { // Best match
402 dRmin = dR;
403 matchTruthJet = truthJet;
404 }
405 }
406 }
407 }
408 if (!m_doLargeRLabels && usePileupJets) {
409 for (const xAOD::Jet* ootJet : *outOfTimeTruthJets) { // Out of time pileup truth jet loop
410 float dR = jet->p4().DeltaR(ootJet->p4(), true);
411 float ghostPtFraction = (ghostTruthPt / (ootJet->pt()));
412 if (m_useGhostJetMatch) {
413 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
414 nMatchedOOTJets += 1;
415 sumPtMatchedOOTJets += ootJet->pt();
416 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
417 oot_matchTruthJet = ootJet;
418 }
419 }
420 }
421 else {
422 if (dR < m_dRTruthJet) { // All matches
423 nMatchedOOTJets += 1;
424 sumPtMatchedOOTJets += ootJet->pt();
425 if (dR < oot_dRmin) { // Best match
426 oot_dRmin = dR;
427 oot_matchTruthJet = ootJet;
428 }
429 }
430 }
431 }
432 for (const xAOD::Jet* itJet : *inTimeTruthJets) { // In time pileup truth jet loop
433 float dR = jet->p4().DeltaR(itJet->p4(), true);
434 float ghostPtFraction = (ghostTruthPt / (itJet->pt()));
435 if (m_useGhostJetMatch) {
436 if ((ghostPtFraction >= m_recoGhostFrac) && (ghostPtFraction <= (2 - m_recoGhostFrac))) { // All matches
437 nMatchedITJets += 1;
438 sumPtMatchedITJets += itJet->pt();
439 if (std::abs(1 - ghostPtFraction) < std::abs(1 - ghostFracNominal)) { // Best match
440 it_matchTruthJet = itJet;
441 }
442 }
443 }
444 else {
445 if (dR < m_dRTruthJet) { // All matches
446 nMatchedITJets += 1;
447 sumPtMatchedITJets += itJet->pt();
448 if (dR < it_dRmin) { // Best match
449 it_dRmin = dR;
450 it_matchTruthJet = itJet;
451 }
452 }
453 }
454 }
455
456 //#######################################################################################
457 //# PILEUP TAGGER KEY #
458 //# 0: Hard scatter ------------- Best truth jet match has >90% of the total matched pT #
459 //# 1: Mixed hard scatter-------- Match with multiple truth jets, none >90% (no PU) #
460 //# 2: Hard scatter with pileup - Best truth jet <90%, also has pileup matches #
461 //# 3: In time pileup---------- - Best it jet match has > 90 % of the total matched pT #
462 //# 4: Mixed pileup ------------- Match with multiple pileup jets, none >90% (no HS) #
463 //# 5: Out of time pileup------ - Best oot jet match has > 90 % of the total matched pT #
464 //# 6: Other/unknown ------------ Fails all above cases #
465 //#######################################################################################
466
467 //NOTE: HS has 5 GeV pT threshold, 10 GeV and 15 GeV for IT and OOT pileup.
468
469 int nMatchedPUJets = nMatchedOOTJets + nMatchedITJets;
470
471 float totalMatchedpT = sumPtMatchedHSJets + sumPtMatchedOOTJets + sumPtMatchedITJets;
472
473 if (matchTruthJet) {
474 bestHSpT = matchTruthJet->pt();
475 bestHSpTRatio = bestHSpT / totalMatchedpT;
476 }
477 if (oot_matchTruthJet) {
478 bestOOTpT = oot_matchTruthJet->pt();
479 bestOOTpTRatio = bestOOTpT / totalMatchedpT;
480 }
481 if (it_matchTruthJet) {
482 bestITpT = it_matchTruthJet->pt();
483 bestITpTRatio = bestITpT / totalMatchedpT;
484 }
485
486 if (bestHSpTRatio >= 0.9) { //HS
487 pileupTag = SmallRJetPileupLabel::HS;
488 }
489 else if (bestITpTRatio >= 0.9) { //IT
490 pileupTag = SmallRJetPileupLabel::ITPU;
491 }
492 else if (bestOOTpTRatio >= 0.9) { //OOT
493 pileupTag = SmallRJetPileupLabel::OOTPU;
494 }
495 else if (nMatchedPUJets == 0 && nMatchedHSJets > 1) { //Mixed HS
496 pileupTag = SmallRJetPileupLabel::MixHS;
497 }
498 else if (nMatchedPUJets > 0 && nMatchedHSJets > 0) { //HS with pileup
499 pileupTag = SmallRJetPileupLabel::HSPU;
500 }
501 else if (nMatchedPUJets > 1) {//Mixed PU
502 pileupTag = SmallRJetPileupLabel::MixPU;
503 }
504 else { //No match
506 }
507
508 }
509
510 }
511
513 int truthJetNB = -1;
514 float truthJetSplit12 = -9999;
515 float truthJetSplit23 = -9999;
516
517 // Defaults to null EL
519 float truthJetMass = -9999;
520 float truthJetPt = -9999;
521 float truthJetRapidity = -9;
522 float truthJetPhi = -9999;
523 float deltaR = -2;
524
525 //If the best match is PU, reassign the truth jet to take variables from
526 if (pileupTag == SmallRJetPileupLabel::ITPU) {
527 matchTruthJet = it_matchTruthJet;
528 }
529 else if (pileupTag == SmallRJetPileupLabel::OOTPU) {
530 matchTruthJet = oot_matchTruthJet;
531 }
532 else if (pileupTag == SmallRJetPileupLabel::MixPU) {
533 if (bestITpTRatio >= bestOOTpTRatio) {
534 matchTruthJet = it_matchTruthJet;
535 }
536 else {
537 matchTruthJet = oot_matchTruthJet;
538 }
539 }
540
541 if ( matchTruthJet ) {
542
543 // Can't use the WriteDecorHandle to read --- the decoration may have
544 // been added and locked by a previous algorithm.
545 // Not saving Truth jet decorations for small R
546 if (m_doLargeRLabels) {
547 SG::ConstAccessor<int> labelAcc(dh.labelHandle->auxid());
548 label = labelAcc(*matchTruthJet);
551 if (split23Handle.isAvailable()) truthJetSplit23 = split23Handle(*matchTruthJet);
553 if (split12Handle.isAvailable()) truthJetSplit12 = split12Handle(*matchTruthJet);
554 }
555 if (nbAcc.isAvailable(*matchTruthJet)) truthJetNB = nbAcc(*matchTruthJet);
556 }
557 truthJetEL = ElementLink<xAOD::JetContainer>(*truthJets, matchTruthJet->index(), ctx);
558 truthJetMass = matchTruthJet->m();
559 truthJetPt = matchTruthJet->pt();
560 truthJetRapidity = matchTruthJet->rapidity();
561 truthJetPhi = matchTruthJet->phi();
562 deltaR = dRmin;
563 }
564
565 // Save Groomed Truth Jet variables
566 float truthGroomedJetMass = -9999;
567 float truthGroomedJetPt = -9999;
569 if ( matchTruthJet ) {
570 for ( const xAOD::Jet* truthGroomedJet : *truthGroomedJets ) {
571 ElementLink<xAOD::JetContainer> element_link = ParentAcc (*truthGroomedJet);
572 if ( !element_link.isValid() ) { continue; }
573 if ( matchTruthJet == *element_link ) {
574 matchTruthGroomedJet = truthGroomedJet;
575 break;
576 }
577 }
578 }
579 // If no matched jet found or matched jet has no corresponding groomed jet, use dR matching
580 if ( !matchTruthGroomedJet && parent != nullptr) {
581 for ( const xAOD::Jet* truthGroomedJet : *truthGroomedJets ) {
582 float dR = parent->p4().DeltaR(truthGroomedJet->p4(),true);
584 if ( m_dRTruthJet < 0 || dR < m_dRTruthJet ) {
585 if ( dR < dRminGroomed ) {
586 dRminGroomed = dR;
587 matchTruthGroomedJet = truthGroomedJet;
588 }
589 }
590 }
591 }
592 if ( matchTruthGroomedJet ) {
593 truthGroomedJetMass = matchTruthGroomedJet->m();
594 truthGroomedJetPt = matchTruthGroomedJet->pt();
595 }
596 }
597
599 if (m_doLargeRLabels) {
600 (*dh.labelRecoHandle)(*jet) = label;
603 (*dh.split23Handle)(*jet) = truthJetSplit23;
604 (*dh.split12Handle)(*jet) = truthJetSplit12;
605 }
606
607 (*dh.nbRecoHandle)(*jet) = truthJetNB;
608 }
609
610 (*dh.matchedTruthJetHandle)(*jet) = truthJetEL;
611 (*dh.matchedTruthJetMassHandle)(*jet) = truthJetMass;
612 (*dh.matchedTruthJetPtHandle)(*jet) = truthJetPt;
613 (*dh.matchedTruthJetRapidityHandle)(*jet) = truthJetRapidity;
614 (*dh.matchedTruthJetPhiHandle)(*jet) = truthJetPhi;
616
617 if (!m_doLargeRLabels && usePileupJets) {
618 (*dh.matchedPileupTagHandle)(*jet) = pileupTag;
619 (*dh.sumPtMatchedHSJetsHandle)(*jet) = sumPtMatchedHSJets;
620 (*dh.sumPtMatchedOOTJetsHandle)(*jet) = sumPtMatchedOOTJets;
621 (*dh.sumPtMatchedITJetsHandle)(*jet) = sumPtMatchedITJets;
622 }
623
625 (*dh.matchedTruthGroomedMassHandle)(*jet) = truthGroomedJetMass;
626 (*dh.matchedTruthGroomedPtHandle)(*jet) = truthGroomedJetPt;
627 }
628 }
629
630 return StatusCode::SUCCESS;
631}
632
634 const EventContext& ctx) const {
635
638
640 if ( !truthJets.isValid() ) {
641 ATH_MSG_ERROR("No truth jet container retrieved. Please make sure you are using a supported TruthLabelName.");
642 return StatusCode::FAILURE;
643 }
644
645 return labelTruthJets(dh, *truthJets, ctx);
646
647}
648
650 const xAOD::JetContainer &truthJets,
651 const EventContext& ctx) const
652{
654 if ( !(truthJets.size()) ) return StatusCode::SUCCESS;
655
657 if(dh.labelHandle->isAvailable()){
658 // Beware: if we get here, the configuration is probably not MT-compatible.
659 ATH_MSG_DEBUG("labelTruthJets: Truth jet collection already labelled with " << m_truthLabelName);
660 return StatusCode::SUCCESS;
661 }
662
665 if(!eventInfo.isValid()){
666 ATH_MSG_ERROR("Failed to retrieve event information.");
667 return StatusCode::FAILURE;
668 }
669
670 if(m_doLargeRLabels) {
673 for ( const xAOD::Jet *jet : truthJets ) {
674 ATH_MSG_DEBUG("Getting truth label using ghost-association");
675 label = getTruthJetLabelGA(dh, *jet, ctx);
676 (*dh.labelHandle)(*jet) = label;
677 }
678 }
679
680 return StatusCode::SUCCESS;
681}
682
684
687
688 float split12 = -999.0;
689
691 const float c0 = 55.25;
692 const float c1 = -2.34e-3;
693
694 split12 = c0 * std::exp( c1 * pt );
695 }
696
697 return split12;
698
699}
700
702
705
706 float split23 = -999.0;
707
711
712 const float c0 = 3.3;
713 const float c1 = -6.98e-4;
714
715 split23 = std::exp( c0 + c1 * pt );
716
717 }
718
719 return split23;
720}
721
722int JetTruthLabelingTool::getNGhostParticles( const xAOD::Jet &jet, const std::string & collection ) const {
723
724 int nMatchPart = 0;
725
726 if( !jet.getAttribute<int>( collection+"Count", nMatchPart ) ){
727
728 std::vector<const xAOD::TruthParticle*> ghostParts;
729 if( !jet.getAssociatedObjects<xAOD::TruthParticle>( collection, ghostParts ) ){
730 ATH_MSG_ERROR( collection + " cannot be retrieved! Truth label definition might be wrong" );
731 }
732 nMatchPart = ghostParts.size();
733 }
734
735 return nMatchPart;
736}
737
739 const xAOD::Jet &jet,
740 bool matchH,
741 bool matchW,
742 bool matchZ,
743 bool matchTop,
744 const EventContext& ctx) const {
745
746 // store GhostBHadronsFinal count
747 int nMatchB = getNGhostParticles( jet, "GhostBHadronsFinal" );
748 (*dh.nbHandle)(jet) = nMatchB;
749
751 bool is_bb = false;
752 bool is_cc = false;
753 bool is_tautauEl = false;
754 bool is_tautauMu = false;
755 bool is_tautauHad = false;
756 bool isTop = false;
757 bool isW = false;
758 bool isZ = false;
759
760 // Use R21Precision_2022v1 definition
764 is_bb = ( nMatchB > 1 );
765 isTop = ( matchTop && matchW && nMatchB > 0 && jet.m() / 1000. > m_mLowTop && split23Handle(jet) / 1000. > getTopSplit23Cut( jet.pt() / 1000. ) );
766 isW = matchW && nMatchB == 0 && jet.m() / 1000. > m_mLowW && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
767 isZ = matchZ && jet.m() / 1000. > m_mLowZ && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
768 }
769
770 // Use R10TruthLabel_R22v1 definition
772 // get extended ghost associated truth label
773 int extended_GA_label = -1;
774 if (not jet.getAttribute("HadronGhostExtendedTruthLabelID", extended_GA_label)) {
775 ATH_MSG_ERROR( "HadronGhostExtendedTruthLabelID not available for " + m_truthJetCollectionKey.key() );
776 }
777
780 is_bb = ( extended_GA_label == 55 );
781 is_cc = ( extended_GA_label == 44 );
782 is_tautauEl = ( extended_GA_label == 151511 );
783 is_tautauMu = ( extended_GA_label == 151513 );
784 is_tautauHad = ( extended_GA_label == 1515 );
785 isTop = ( matchTop && matchW && nMatchB > 0 && jet.m() / 1000. > m_mLowTop && split23Handle(jet) / 1000. > getTopSplit23Cut( jet.pt() / 1000. ) );
786 isW = matchW && nMatchB == 0 && jet.m() / 1000. > m_mLowW && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
787 isZ = matchZ && jet.m() / 1000. > m_mLowZ && split12Handle(jet) / 1000. > getWZSplit12Cut( jet.pt() / 1000. );
788 }
789
790
792
793 /* The default priority of labels is:
794 * 1) Hbb/cc/tautau
795 * 2) Contained top
796 * 3) Contained W
797 * 4) Contained Zbb/cc/qq/tautau
798 * 5) Uncontained top
799 * 6) Uncontained V
800 */
801
803 if( !(matchTop || matchW || matchZ || matchH) ) {
805 }
806
807 // Higgs
808 if ( matchH ) {
810 if ( is_bb ) return LargeRJetTruthLabel::Hbb;
812 if ( is_cc ) return LargeRJetTruthLabel::Hcc;
814 if ( is_tautauEl ) return LargeRJetTruthLabel::HtautauEl;
815 if ( is_tautauMu ) return LargeRJetTruthLabel::HtautauMu;
816 if ( is_tautauHad ) return LargeRJetTruthLabel::HtautauHad;
819 }
820
822 if ( isTop ) return LargeRJetTruthLabel::tqqb;
823
824 if ( isW ) {
826 if ( matchTop ) return LargeRJetTruthLabel::Wqq_From_t;
829 }
830
831 if ( matchZ ) {
833 if ( is_bb ) return LargeRJetTruthLabel::Zbb;
835 if ( is_cc ) return LargeRJetTruthLabel::Zcc;
837 if ( is_tautauEl ) return LargeRJetTruthLabel::ZtautauEl;
838 if ( is_tautauMu ) return LargeRJetTruthLabel::ZtautauMu;
839 if ( is_tautauHad ) return LargeRJetTruthLabel::ZtautauHad;
840 }
841 if ( isZ ) {
844 }
845
847 if ( matchTop ) return LargeRJetTruthLabel::other_From_t;
848
851
852}
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(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:382
bool isZ(const T &p)
Definition AtlasPID.h:379
bool isTop(const T &p)
Definition AtlasPID.h:185
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?
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)