ATLAS Offline Software
QCDTruthJetFilter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "xAODJet/JetContainer.h"
7 #include "GaudiKernel/PhysicalConstants.h"
8 #include "TRandom3.h"
10 #include "CLHEP/Random/RandomEngine.h"
11 #include "TF1.h" // For holding the weighting function
12 
13 QCDTruthJetFilter::QCDTruthJetFilter(const std::string& name, ISvcLocator* pSvcLocator)
14  : GenFilter(name,pSvcLocator)
15  , m_total(0)
16  , m_passed(0)
17  , m_ptfailed(0)
18  , m_norm(1.)
19  , m_high(1.)
20 {
21  m_StartMinEta=-10;
23  declareProperty("MaxPt",m_MaxPt = 7000*Gaudi::Units::GeV); // LHC kinematic limit...
24  declareProperty("SymEta",m_SymEta = false);
25  declareProperty("MaxEta",m_MaxEta = 999.0);
27  declareProperty("TruthJetContainer", m_TruthJetContainerName = "AntiKt6TruthJets");
28  declareProperty("DoShape",m_doShape = false);
29  declareProperty("MinPhi",m_MinPhi = -999.0);
30  declareProperty("MaxPhi",m_MaxPhi = 999.0);
31 
32 }
33 
34 
36 
37  CHECK(m_rndmSvc.retrieve());
38 
41  if (m_MinEta == m_StartMinEta && m_MaxEta>0) m_MinEta = -1.*m_MaxEta;
42  // ATH_MSG_INFO("Configured with " << m_MinPt << "<p_T<" << m_MaxPt << " GeV and" << m_MinEta << " <|eta|<" << m_MaxEta << " for jets in " << m_TruthJetContainerName);
43  if (m_SymEta){
44  ATH_MSG_INFO("Configured with " << m_MinPt << "<p_T<" << m_MaxPt << " GeV and " << m_MinEta << "<abs(eta)<" << m_MaxEta << " for jets in " << m_TruthJetContainerName);
45  } else {
46  ATH_MSG_INFO("Configured with " << m_MinPt << "<p_T<" << m_MaxPt << " GeV and " << m_MinEta << "<eta<" << m_MaxEta << " for jets in " << m_TruthJetContainerName);
47  }
48 
49  // Special cases: min pT is above 2 TeV or max pT is below 20 GeV, use no weighting - hard-coded range of the fit in this filter
50  if (m_MinPt < 1999. && m_MaxPt > 21. && m_doShape) {
51  // Use the fit in all its glory
52  m_high = fitFn(m_MaxPt);
53  m_norm = 1./(m_high==0?1.:m_high); //(m_MaxPt-m_MinPt) / (m_norm!=0?m_norm:1.);
54  ATH_MSG_INFO("Initialized and set high to " << m_high << " and norm to " << m_norm);
55  } else if (m_doShape) {
56  ATH_MSG_INFO("Requested shaping with bounds of " << m_MinPt << " , " << m_MaxPt << " which cannot be done. Turning off shaping (sorry).");
57  m_doShape=false;
58  }
59 
60 if (m_MinPhi > -998.0 || m_MaxPhi < 998.0) {
61  ATH_MSG_INFO("Configured phi as well with min = " << m_MinPhi << " and max = " << m_MaxPhi);
62  }
63 
64 
65  return StatusCode::SUCCESS;
66 }
67 
68 
70  ATH_MSG_INFO("Total efficiency: " << 100.*double(m_passed)/double(m_total) << "% (" << 100.*double(m_ptfailed)/double(m_total) << "% failed pT cuts)");
71  return StatusCode::SUCCESS;
72 }
73 
74 
76  m_total++; // Bookkeeping
77 
78  // Grab random number engine
79  const EventContext& ctx = Gaudi::Hive::currentContext();
80  CLHEP::HepRandomEngine* rndm = this->getRandomEngine(name(), ctx);
81  if (!rndm) {
82  ATH_MSG_WARNING("Failed to retrieve random number engine QCDTruthJetFilter");
83  setFilterPassed(false);
84  return StatusCode::SUCCESS;
85  }
86 
87  // Get jet container out
88  const xAOD::JetContainer* truthjetTES = 0;
89  if (!evtStore()->contains<xAOD::JetContainer>(m_TruthJetContainerName) ||
90  evtStore()->retrieve(truthjetTES, m_TruthJetContainerName).isFailure() || !truthjetTES) {
91  ATH_MSG_ERROR("No xAOD::JetContainer found in StoreGate with key " << m_TruthJetContainerName);
92  setFilterPassed(m_MinPt < 1);
93  return StatusCode::SUCCESS;
94  }
95 
96  // Get pT of leading jet
97  double pt_lead = -1, phi_lead = 0;
98  for (xAOD::JetContainer::const_iterator it_truth = (*truthjetTES).begin(); it_truth != (*truthjetTES).end() ; ++it_truth) {
99  if (!(*it_truth)) continue;
100  if ( ( m_SymEta && !(std::abs((*it_truth)->eta())>=m_MinEta && std::abs((*it_truth)->eta())<m_MaxEta) )
101  || ( !m_SymEta && !((*it_truth)->eta()>=m_MinEta && (*it_truth)->eta()<m_MaxEta) )) continue;
102  if (pt_lead < (*it_truth)->pt()) {
103  pt_lead = (*it_truth)->pt();
104  phi_lead = (*it_truth)->phi();
105  }
106  }
107 
108  pt_lead /= Gaudi::Units::GeV; // Make sure we're in GeV
109 
110  // See if the leading jet is in the right range
111  if ((pt_lead<=m_MinPt || (pt_lead>m_MaxPt && m_MaxPt>0)) && !(pt_lead<=m_MinPt && m_MinPt<1)) {
112  m_ptfailed++;
113  setFilterPassed(false);
114  ATH_MSG_DEBUG("Failed filter on jet pT: " << pt_lead << " is not between " << m_MinPt << " and " << m_MaxPt);
115  return StatusCode::SUCCESS;
116  }
117 
118 // If appropriate, check the phi of the lead jet as well
119  if (m_MinPhi > -999.0 || m_MaxPhi < 999.0) {
120  setFilterPassed(false);
121 
122  if (phi_lead < m_MinPhi || phi_lead > m_MaxPhi) {
123  ATH_MSG_DEBUG("Failed filter on jet phi: " << phi_lead << " not between " << m_MinPhi << " and " << m_MaxPhi);
124  return StatusCode::SUCCESS;
125  }
126  else {
127  setFilterPassed(true);
128  }
129  }
130 
131 
132  // Unweight the pT spectrum
133  double w = 1.;
134  if (m_doShape) w = fitFn(pt_lead);
135  double rnd = rndm->flat();
136  if (m_high/w < rnd) {
137  setFilterPassed(false);
138  ATH_MSG_DEBUG("Event failed weighting cut. Weight is " << w << " for pt_lead of " << pt_lead << " high end is " << m_high << " rnd is " << rnd);
139  return StatusCode::SUCCESS;
140  }
141 
142  // Made it to the end - success!
143  m_passed++;
144  setFilterPassed(true);
145 
146  // Get MC event collection for setting weight
147  const McEventCollection* mecc = 0;
148  CHECK(evtStore()->retrieve(mecc, m_mcEventKey));
149  ATH_MSG_DEBUG("Event passed. Will mod event weights by " << w*m_norm << " for pt_lead of " << pt_lead << " norm " << m_norm << " w " << w << " high " << m_high << " rnd " << rnd);
150  double orig = 1.;
151  McEventCollection* mec = const_cast<McEventCollection*> (&(*mecc));
152  for (unsigned int i=0;i<mec->size();++i) {
153  if ( !(*mec)[i] ) continue;
154  orig = (*mec)[i]->weights().size()>0?(*mec)[i]->weights()[0]:1.;
155  if ((*mec)[i]->weights().size()>0) (*mec)[i]->weights()[0] = orig*w*m_norm;
156  else (*mec)[i]->weights().push_back( w*m_norm*orig );
157 
158 #ifdef HEPMC3
159  (*mec)[i]->add_attribute("filterWeight", std::make_shared<HepMC3::DoubleAttribute>(w*m_norm));
160 #endif
161 
162  }
163  return StatusCode::SUCCESS;
164 }
165 
166 
167 CLHEP::HepRandomEngine* QCDTruthJetFilter::getRandomEngine(const std::string& streamName,
168  const EventContext& ctx) const
169 {
170  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
171  std::string rngName = name()+streamName;
172  rngWrapper->setSeed( rngName, ctx );
173  return rngWrapper->getEngine(ctx);
174 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
ATHRNG::RNGWrapper::setSeed
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition: RNGWrapper.h:169
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
QCDTruthJetFilter::fitFn
static double fitFn(const double x)
Definition: QCDTruthJetFilter.h:62
QCDTruthJetFilter::filterInitialize
StatusCode filterInitialize()
Definition: QCDTruthJetFilter.cxx:35
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
QCDTruthJetFilter::m_MinPhi
double m_MinPhi
Min phi for the lead truth jet.
Definition: QCDTruthJetFilter.h:35
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
GenBase::m_mcEventKey
std::string m_mcEventKey
StoreGate key for the MC event collection (defaults to GEN_EVENT)
Definition: GenBase.h:137
QCDTruthJetFilter::m_high
double m_high
High-side function level.
Definition: QCDTruthJetFilter.h:48
QCDTruthJetFilter::QCDTruthJetFilter
QCDTruthJetFilter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: QCDTruthJetFilter.cxx:13
QCDTruthJetFilter::m_MaxPhi
double m_MaxPhi
Definition: QCDTruthJetFilter.h:36
QCDTruthJetFilter::m_MaxEta
double m_MaxEta
Max eta for the truth jets.
Definition: QCDTruthJetFilter.h:33
QCDTruthJetFilter::m_MinEta
double m_MinEta
Min eta for the truth jets.
Definition: QCDTruthJetFilter.h:32
QCDTruthJetFilter::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition: QCDTruthJetFilter.h:41
QCDTruthJetFilter::m_MaxPt
double m_MaxPt
Max pT for the truth jets.
Definition: QCDTruthJetFilter.h:31
AthCommonDataStore< AthCommonMsg< Algorithm > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
GenFilter
Base class for event generator filtering modules.
Definition: GenFilter.h:30
QCDTruthJetFilter::getRandomEngine
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, const EventContext &ctx) const
Definition: QCDTruthJetFilter.cxx:167
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
QCDTruthJetFilter::m_total
long m_total
Total number of events tested.
Definition: QCDTruthJetFilter.h:43
QCDTruthJetFilter::filterEvent
StatusCode filterEvent()
Definition: QCDTruthJetFilter.cxx:75
lumiFormat.i
int i
Definition: lumiFormat.py:92
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
QCDTruthJetFilter::m_SymEta
bool m_SymEta
Use symmetric cut for min eta? (Default false for p-Pb run filters)
Definition: QCDTruthJetFilter.h:37
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
McEventCollection
This defines the McEventCollection, which is really just an ObjectVector of McEvent objects.
Definition: McEventCollection.h:33
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
QCDTruthJetFilter::filterFinalize
StatusCode filterFinalize()
Definition: QCDTruthJetFilter.cxx:69
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
ATHRNG::RNGWrapper::getEngine
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition: RNGWrapper.h:134
RNGWrapper.h
QCDTruthJetFilter::m_ptfailed
long m_ptfailed
Number of events failing the pT cuts.
Definition: QCDTruthJetFilter.h:45
AthenaPoolExample_Copy.streamName
string streamName
Definition: AthenaPoolExample_Copy.py:39
QCDTruthJetFilter::m_passed
long m_passed
Number of events passing all cuts.
Definition: QCDTruthJetFilter.h:44
QCDTruthJetFilter::m_norm
double m_norm
Normalization for weights.
Definition: QCDTruthJetFilter.h:47
JetContainer.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
QCDTruthJetFilter::m_TruthJetContainerName
std::string m_TruthJetContainerName
Name of the truth jet container.
Definition: QCDTruthJetFilter.h:39
QCDTruthJetFilter.h
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
QCDTruthJetFilter::m_MinPt
double m_MinPt
Min pT for the truth jets.
Definition: QCDTruthJetFilter.h:30
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
QCDTruthJetFilter::m_doShape
bool m_doShape
Attempt to flatten the pT distribution.
Definition: QCDTruthJetFilter.h:50
QCDTruthJetFilter::m_StartMinEta
double m_StartMinEta
Default start value for min eta.
Definition: QCDTruthJetFilter.h:34