ATLAS Offline Software
Loading...
Searching...
No Matches
MergeTruthJetsTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
9#include "GaudiKernel/SystemOfUnits.h"
10
12 const std::string& name,
13 const IInterface* parent)
14 : PileUpToolBase(type, name, parent)
15{
16}
17
19{
20 ATH_MSG_DEBUG ( "Initializing " << name());
21 ATH_CHECK(m_pMergeSvc.retrieve());
22 return StatusCode::SUCCESS;
23}
24
25StatusCode MergeTruthJetsTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents)
26{
27 ATH_MSG_VERBOSE ( "prepareEvent()" );
28 ATH_MSG_DEBUG ( "prepareEvent: there are " << nInputEvents << " subevents in this event." );
29 m_first_event = true;
30
31 m_inTimeOutputJetContainer = std::make_unique< xAOD::JetContainer >();
32 m_inTimeOutputJetAuxContainer = std::make_unique< xAOD::JetAuxContainer >();
34
35 m_outOfTimeOutputJetContainer = std::make_unique< xAOD::JetContainer >();
36 m_outOfTimeOutputJetAuxContainer = std::make_unique< xAOD::JetAuxContainer >();
38
39 return StatusCode::SUCCESS;
40}
41
42StatusCode MergeTruthJetsTool::processBunchXing(int bunchXing,
43 SubEventIterator bSubEvents,
44 SubEventIterator eSubEvents)
45{
46 ATH_MSG_VERBOSE ( "processBunchXing()" );
47 SubEventIterator iEvt(bSubEvents);
48 while (iEvt != eSubEvents) {
49 const xAOD::JetContainer* inputJetContainer(nullptr);
50 if (m_pMergeSvc->retrieveSingleSubEvtData(m_inputJetCollKey.value(), inputJetContainer,
51 bunchXing, iEvt).isSuccess()) {
52 ATH_MSG_VERBOSE("Found an xAOD::JetContainer in storeGate.");
53 if ( !inputJetContainer ) {
54 ATH_MSG_ERROR("Unable to retrieve input jet container: " << m_inputJetCollKey);
55 return StatusCode::FAILURE;
56 }
57 ATH_MSG_DEBUG ( "processBunchXing: bunch Crossing = " << bunchXing << " JetContainer size = " << inputJetContainer->size());
58 const int eventNumber{iEvt->index()};
59 if (bunchXing==0) {
60 if (m_first_event) {//FIXME this may not be robust in the case that there is no TruthJet container from the signal event.
61 m_signal_max_pT = this->processJetContainer(&(*inputJetContainer), nullptr, 0.0, 0.0, eventNumber);
62 ATH_MSG_DEBUG ( "Setting m_signal_max_pT = " << m_signal_max_pT);
64 (void)this->processJetContainer(&(*inputJetContainer), m_inTimeOutputJetContainer.get(), m_inTimePtCut, 0.0, eventNumber);
65 }
66 else {
67 ATH_MSG_VERBOSE ( "Don't include signal events in output Truth Jet Containers.");
68 }
69 m_first_event=false;
70 ++iEvt;
71 continue;
72 }
73 const double pileup_this_pT=this->processJetContainer(&(*inputJetContainer), m_inTimeOutputJetContainer.get(), m_inTimePtCut, 0.0, eventNumber);
74 ATH_MSG_VERBOSE ( "highest jet pT in the current background event = " << pileup_this_pT);
75 if (pileup_this_pT>m_pileup_max_pT) m_pileup_max_pT=pileup_this_pT;
76 ATH_MSG_DEBUG ( "highest in-time background jet pT so far = " << m_pileup_max_pT);
77 }
78 else {
79 const float timeOfBCID(static_cast<float>(iEvt->time()));
80 (void)this->processJetContainer(&(*inputJetContainer), m_outOfTimeOutputJetContainer.get(), m_outOfTimePtCut, timeOfBCID, eventNumber);
81 }
82 }
83 else {
84 ATH_MSG_DEBUG ( "processBunchXing: No JetContainers found." );
85 }
86 ++iEvt;
87 }
88 //signal is always the first event, so even if we didn't see
89 //anything should set this to false here.
90 if(m_first_event) {m_first_event=false;}
91 return StatusCode::SUCCESS;
92}
93
94StatusCode MergeTruthJetsTool::mergeEvent(const EventContext& /*ctx*/)
95{
96 ATH_MSG_VERBOSE ( "mergeEvent" );
97
98 // Veto event when m_pileup_max_pT>m_signal_max_pT
100 ATH_MSG_INFO ( "Highest pT Jet in Hard-scatter event = " << m_signal_max_pT
101 << ", highest pT jet in a background event = " << m_pileup_max_pT
102 << ". Therefore filtering this hard-scatter event." );
103 m_filterPassed = false;
104 }
105
106 ATH_CHECK( evtStore()->record( std::move( m_inTimeOutputJetContainer ),
108 ATH_CHECK( evtStore()->record( std::move( m_inTimeOutputJetAuxContainer
109 ), m_inTimeOutputJetCollKey + "Aux." ) );
110
111 ATH_CHECK( evtStore()->record( std::move( m_outOfTimeOutputJetContainer
113 ATH_CHECK( evtStore()->record( std::move(
115 ) );
116
117 return StatusCode::SUCCESS;
118}
119
120StatusCode MergeTruthJetsTool::processAllSubEvents(const EventContext& /*ctx*/)
121{
122 ATH_MSG_VERBOSE ( "processAllSubEvents()" );
123
124 m_first_event = true;
125
126 m_inTimeOutputJetContainer = std::make_unique< xAOD::JetContainer >();
127 m_inTimeOutputJetAuxContainer = std::make_unique< xAOD::JetAuxContainer >();
129
130 m_outOfTimeOutputJetContainer = std::make_unique< xAOD::JetContainer >();
131 m_outOfTimeOutputJetAuxContainer = std::make_unique< xAOD::JetAuxContainer >();
133
135 TruthJetList truthList;
136 if ( (m_pMergeSvc->retrieveSubEvtsData(m_inputJetCollKey.value(), truthList)).isSuccess() ) {
137 if (!truthList.empty()) {
138 //now merge all collections into one
139 TruthJetList::const_iterator jetColl_iter(truthList.begin());
140 const TruthJetList::const_iterator endOfJetColls(truthList.end());
141 while (jetColl_iter!=endOfJetColls) {
142 const int eventNumber = (jetColl_iter)->first.index();
143 //FIXME we are forced to do a deep copy
144 if (static_cast<int>((jetColl_iter)->first.time())==0) {
145 if (m_first_event) {
146 //FIXME this may not be robust in the case that there is no TruthJet container from the signal event.
147 m_signal_max_pT = this->processJetContainer(&(*((jetColl_iter)->second)), nullptr, 0.0, 0.0, eventNumber);
149 (void)this->processJetContainer(&(*((jetColl_iter)->second)), m_inTimeOutputJetContainer.get(), m_inTimePtCut, 0.0, eventNumber);
150 }
151 else {
152 ATH_MSG_VERBOSE ( "Don't include signal events in output Truth Jet Containers.");
153 }
154 m_first_event=false;
155 ++jetColl_iter;
156 continue;
157 }
158 const double pileup_this_pT=this->processJetContainer(&(*((jetColl_iter)->second)), m_inTimeOutputJetContainer.get(), m_inTimePtCut, 0.0, eventNumber);
159 ATH_MSG_VERBOSE ( "highest jet pT in the current background event = " << pileup_this_pT);
160 if (pileup_this_pT>m_pileup_max_pT) m_pileup_max_pT=pileup_this_pT;
161 ATH_MSG_DEBUG ( "highest in-time background jet pT so far = " << m_pileup_max_pT);
162 }
163 else {
164 const float timeOfBCID(static_cast<float>((jetColl_iter)->first.time()));
165 (void)this->processJetContainer(&(*((jetColl_iter)->second)), m_outOfTimeOutputJetContainer.get(), m_outOfTimePtCut, timeOfBCID, eventNumber);
166 }
167 //signal is always the first event, so if the first event
168 //wasn't in-time, then the signal collection was missing and
169 //we should skip further checks.
170 if(m_first_event) {m_first_event=false;}
171 ++jetColl_iter;
172 }
173 }
174 else {
175 ATH_MSG_DEBUG ( "processAllSubEvents: TruthJetList is empty" );
176 }
177 }
178 else {
179 ATH_MSG_ERROR ( "processAllSubEvents: Can not find TruthJetList" );
180 }
181 // Veto event when m_pileup_max_pT>m_signal_max_pT
183 ATH_MSG_INFO ( "Highest pT Jet in Hard-scatter event = " << m_signal_max_pT
184 << ", highest pT jet in a background event = " << m_pileup_max_pT
185 << ". Therefore filtering this hard-scatter event." );
186 m_filterPassed = false;
187 }
188 ATH_CHECK( evtStore()->record( std::move( m_inTimeOutputJetContainer ),
190 ATH_CHECK( evtStore()->record( std::move( m_inTimeOutputJetAuxContainer
191 ), m_inTimeOutputJetCollKey + "Aux." ) );
192
193 ATH_CHECK( evtStore()->record( std::move( m_outOfTimeOutputJetContainer
195 ATH_CHECK( evtStore()->record( std::move(
197 ) );
198
199 return StatusCode::SUCCESS;
200}
201
202//use a float for timeOfBCID as Jet moments are stored as floats.
203double MergeTruthJetsTool::processJetContainer(const xAOD::JetContainer* inputJetContainer, xAOD::JetContainer *outputJetContainer, const double& ptCut, const float& timeOfBCID, int eventNumber)
204{
205 const static SG::AuxElement::Accessor< float > timingAccessor("Timing");
206 const static SG::AuxElement::Accessor< int > eventNumberAccessor("pileupEventNumber");
207 double max_pT=-1.;
208 for (const xAOD::Jet *origTruthJet : *inputJetContainer) {
209 if (not origTruthJet) continue;
210 try {
211 if (origTruthJet->pt()<ptCut) {
212 ATH_MSG_VERBOSE( "processJetContainer: Jet with pT = " << origTruthJet->pt() << " GeV failed ptCut of " << ptCut << "GeV." );
213 continue;
214 }
215 if (max_pT<origTruthJet->pt()) max_pT=origTruthJet->pt();
216 ATH_MSG_VERBOSE( "processJetContainer: Jet with pT = " << origTruthJet->pt() << " GeV passed ptCut of " << ptCut << "GeV." );
217 }
218 catch (...) {
219 ATH_MSG_ERROR ( "Failed to find Truth jet pT for Jet in a BCID at time = " << timeOfBCID );
220 }
221 if (!outputJetContainer) continue;
222 xAOD::Jet* outputTruthJet = new xAOD::Jet();
223 outputJetContainer->push_back(outputTruthJet);
224 *outputTruthJet = *origTruthJet; // deep-copy
225 if (timingAccessor.isAvailable(*origTruthJet)) {
226 timingAccessor(*outputTruthJet) = timeOfBCID + timingAccessor(*origTruthJet);
227 } else {
228 timingAccessor(*outputTruthJet) = timeOfBCID;
229 }
230 // add the pile-up event number
231 eventNumberAccessor(*outputTruthJet) = eventNumber;
232 }
233 return max_pT;
234}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition IPileUpTool.h:22
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.
Gaudi::Property< std::string > m_inputJetCollKey
std::unique_ptr< xAOD::JetContainer > m_outOfTimeOutputJetContainer
ServiceHandle< PileUpMergeSvc > m_pMergeSvc
virtual StatusCode mergeEvent(const EventContext &ctx) override final
called at the end of the subevts loop.
virtual StatusCode prepareEvent(const EventContext &ctx, unsigned int nInputEvents) override final
called before the subevts loop.
virtual StatusCode processAllSubEvents(const EventContext &ctx) override final
Merge the Truth JetContainers using the PileUpMergeSvc.
std::unique_ptr< xAOD::JetAuxContainer > m_outOfTimeOutputJetAuxContainer
Gaudi::Property< bool > m_activateFilter
virtual double processJetContainer(const xAOD::JetContainer *inputJetContainer, xAOD::JetContainer *outputJetContainer, const double &ptCut, const float &timeOfBCID, int eventNumber)
JetContainer Loop.
MergeTruthJetsTool(const std::string &type, const std::string &name, const IInterface *parent)
std::unique_ptr< xAOD::JetAuxContainer > m_inTimeOutputJetAuxContainer
StatusCode initialize() override final
Initialize.
std::unique_ptr< xAOD::JetContainer > m_inTimeOutputJetContainer
Gaudi::Property< double > m_inTimePtCut
virtual StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final
called for each active bunch-crossing to process current SubEvents bunchXing is in ns
Gaudi::Property< std::string > m_inTimeOutputJetCollKey
Gaudi::Property< bool > m_includeSignalJets
Gaudi::Property< std::string > m_outOfTimeOutputJetCollKey
Gaudi::Property< double > m_outOfTimePtCut
PileUpToolBase(const std::string &type, const std::string &name, const IInterface *parent)
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.
Jet_v1 Jet
Definition of the current "jet version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".
std::list< value_t > type
type of the collection of timed data object