ATLAS Offline Software
QCDTruthMultiJetFilter.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 "GaudiKernel/PhysicalConstants.h"
7 #include "xAODJet/JetContainer.h"
8 #include "CLHEP/Random/RandomEngine.h"
10 #include "TF1.h" // For holding the weighting function
11 
12 QCDTruthMultiJetFilter::QCDTruthMultiJetFilter(const std::string& name, ISvcLocator* pSvcLocator)
13  : GenFilter(name,pSvcLocator)
14  , m_total(0)
15  , m_passed(0)
16  , m_ptfailed(0)
17  , m_nJetsFailed(0)
18  , m_norm(1.)
19  , m_high(1.)
20 {
21  declareProperty("Njet",m_Njet = -1.);
24  declareProperty("MaxLeadJetPt",m_MaxLeadJetPt = 7000*Gaudi::Units::GeV); // LHC kinematic limit...
25  declareProperty("MaxEta",m_MaxEta = 10.0);
26  declareProperty("TruthJetContainer", m_TruthJetContainerName = "AntiKt6TruthJets");
27  declareProperty("DoShape",m_doShape = true);
28 }
29 
30 
32 
33  CHECK(m_rndmSvc.retrieve());
34 
38 
39  ATH_MSG_INFO("Configured with " << m_Njet << " jets with p_T>" << m_NjetMinPt << " GeV, " << "|eta|<" << m_MaxEta << " and " << m_MinLeadJetPt << "<lead jet p_T<" << m_MaxLeadJetPt << " for jets in " << m_TruthJetContainerName);
40 
41  // 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
42  if (m_MinLeadJetPt < 1999. && m_MaxLeadJetPt > 21. && m_doShape) {
43  // Use the fit in all its glory
45  m_norm = 1./(m_high==0?1.:m_high); //(m_MaxLeadJetPt-m_MinLeadJetPt) / (m_norm!=0?m_norm:1.);
46  ATH_MSG_INFO("Initialized and set high to " << m_high << " and norm to " << m_norm);
47  } else if (m_doShape) {
48  ATH_MSG_INFO("Requested shaping with bounds of " << m_MinLeadJetPt << " , " << m_MaxLeadJetPt << " which cannot be done. Turning off shaping (sorry).");
49  m_doShape=false;
50  }
51  return StatusCode::SUCCESS;
52 }
53 
54 
56  ATH_MSG_INFO("Total efficiency: " << 100.*double(m_passed)/double(m_total) << "% (" << 100.*double(m_ptfailed)/double(m_total) << "% failed lead pT cut, " << 100.*double(m_nJetsFailed)/double(m_total) << "% failed nJets cut)");
57  return StatusCode::SUCCESS;
58 }
59 
60 
62  m_total++; // Bookkeeping
63 
64  // Grab random number engine - this is kept with the QCDTruthJetFilter engine
65  const EventContext& ctx = Gaudi::Hive::currentContext();
66  CLHEP::HepRandomEngine* rndm = this->getRandomEngine(name(), ctx);
67  if (!rndm) {
68  ATH_MSG_WARNING("Failed to retrieve random number engine QCDTruthJetFilter");
69  setFilterPassed(false);
70  return StatusCode::SUCCESS;
71  }
72 
73  // Get jet container out
74  const xAOD::JetContainer* truthjetTES = 0;
75  if (!evtStore()->contains<xAOD::JetContainer>(m_TruthJetContainerName) ||
76  evtStore()->retrieve(truthjetTES, m_TruthJetContainerName).isFailure() || !truthjetTES) {
77  ATH_MSG_ERROR("No xAOD::JetContainer found in StoreGate with key " << m_TruthJetContainerName);
78  setFilterPassed(m_MinLeadJetPt < 1);
79  return StatusCode::SUCCESS;
80  }
81 
82  // Count jets above m_NjetMinPt and find pT of leading jet
83  int Njet=0;
84  double pt_lead = -1;
85  for (xAOD::JetContainer::const_iterator it_truth = (*truthjetTES).begin(); it_truth != (*truthjetTES).end() ; ++it_truth) {
86  if (!(*it_truth)) continue;
87  if (std::abs( (*it_truth)->eta() ) > m_MaxEta) continue;
88  if ((*it_truth)->pt() > m_NjetMinPt*Gaudi::Units::GeV) Njet++;
89  if (pt_lead < (*it_truth)->pt()) pt_lead = (*it_truth)->pt();
90  }
91  pt_lead /= Gaudi::Units::GeV; // Make sure we're in GeV
92 
93  // See if the leading jet is in the right range
94  if (Njet < m_Njet && m_Njet > 0) {
95  m_nJetsFailed++;
96  setFilterPassed(false);
97  ATH_MSG_DEBUG("Failed filter on: " << Njet << " jets found with pT>" << m_NjetMinPt << " GeV -> less than required " << m_Njet << " jets");
98  return StatusCode::SUCCESS;
99  }
100 
101  // See if the leading jet is in the right range
102  if ((pt_lead<=m_MinLeadJetPt || (pt_lead>m_MaxLeadJetPt && m_MaxLeadJetPt>0)) && !(pt_lead<=m_MinLeadJetPt && m_MinLeadJetPt<1)) {
103  m_ptfailed++;
104  setFilterPassed(false);
105  ATH_MSG_DEBUG("Failed filter on jet pT: " << pt_lead << " is not between " << m_MinLeadJetPt << " and " << m_MaxLeadJetPt);
106  return StatusCode::SUCCESS;
107  }
108 
109  // Unweight the pT spectrum
110  double w = 1.;
111  if (m_doShape) w = fitFn(pt_lead);
112  double rnd = rndm->flat();
113  if (m_high/w < rnd) {
114  setFilterPassed(false);
115  ATH_MSG_DEBUG("Event failed weighting cut. Weight is " << w << " for pt_lead of " << pt_lead << " high end is " << m_high << " rnd is " << rnd);
116  return StatusCode::SUCCESS;
117  }
118 
119  // Made it to the end - success!
120  m_passed++;
121  setFilterPassed(true);
122 
123  // Get MC event collection for setting weight
124  const McEventCollection* mecc = 0;
125  CHECK(evtStore()->retrieve(mecc));
126  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);
127  double orig = 1.;
128  McEventCollection* mec = const_cast<McEventCollection*> (&(*mecc));
129  for (unsigned int i=0;i<mec->size();++i) {
130  if ( !(*mec)[i] ) continue;
131  orig = (*mec)[i]->weights().size()>0?(*mec)[i]->weights()[0]:1.;
132  if ((*mec)[i]->weights().size()>0) (*mec)[i]->weights()[0] = orig*w*m_norm;
133  else (*mec)[i]->weights().push_back( w*m_norm*orig );
134  }
135  return StatusCode::SUCCESS;
136 }
137 
138 
139 CLHEP::HepRandomEngine* QCDTruthMultiJetFilter::getRandomEngine(const std::string& streamName,
140  const EventContext& ctx) const
141 {
142  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
143  std::string rngName = name()+streamName;
144  rngWrapper->setSeed( rngName, ctx );
145  return rngWrapper->getEngine(ctx);
146 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
QCDTruthMultiJetFilter::m_doShape
bool m_doShape
Attempt to flatten the pT distribution.
Definition: QCDTruthMultiJetFilter.h:48
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
QCDTruthMultiJetFilter::QCDTruthMultiJetFilter
QCDTruthMultiJetFilter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: QCDTruthMultiJetFilter.cxx:12
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
QCDTruthMultiJetFilter::m_MaxLeadJetPt
double m_MaxLeadJetPt
Max pT for the leading truth jet.
Definition: QCDTruthMultiJetFilter.h:33
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
QCDTruthMultiJetFilter::m_ptfailed
long m_ptfailed
Number of events failing the pT cuts.
Definition: QCDTruthMultiJetFilter.h:42
QCDTruthMultiJetFilter.h
QCDTruthMultiJetFilter::fitFn
static double fitFn(const double x)
Definition: QCDTruthMultiJetFilter.h:60
QCDTruthMultiJetFilter::m_TruthJetContainerName
std::string m_TruthJetContainerName
Name of the truth jet container.
Definition: QCDTruthMultiJetFilter.h:36
QCDTruthMultiJetFilter::m_MaxEta
double m_MaxEta
Max eta for the truth jets.
Definition: QCDTruthMultiJetFilter.h:34
AthCommonDataStore< AthCommonMsg< Algorithm > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
QCDTruthMultiJetFilter::m_NjetMinPt
double m_NjetMinPt
Min pT for N jets truth jets required.
Definition: QCDTruthMultiJetFilter.h:31
GenFilter
Base class for event generator filtering modules.
Definition: GenFilter.h:30
QCDTruthMultiJetFilter::filterInitialize
StatusCode filterInitialize()
Definition: QCDTruthMultiJetFilter.cxx:31
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
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
QCDTruthMultiJetFilter::filterEvent
StatusCode filterEvent()
Definition: QCDTruthMultiJetFilter.cxx:61
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
QCDTruthMultiJetFilter::m_total
long m_total
Total number of events tested.
Definition: QCDTruthMultiJetFilter.h:40
QCDTruthMultiJetFilter::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number generator.
Definition: QCDTruthMultiJetFilter.h:38
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
QCDTruthMultiJetFilter::getRandomEngine
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, const EventContext &ctx) const
Definition: QCDTruthMultiJetFilter.cxx:139
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
QCDTruthMultiJetFilter::filterFinalize
StatusCode filterFinalize()
Definition: QCDTruthMultiJetFilter.cxx:55
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
QCDTruthMultiJetFilter::m_high
double m_high
High-side function level.
Definition: QCDTruthMultiJetFilter.h:46
QCDTruthMultiJetFilter::m_MinLeadJetPt
double m_MinLeadJetPt
Min pT for the leading truth jet.
Definition: QCDTruthMultiJetFilter.h:32
AthenaPoolExample_Copy.streamName
string streamName
Definition: AthenaPoolExample_Copy.py:39
JetContainer.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
QCDTruthMultiJetFilter::m_nJetsFailed
long m_nJetsFailed
Number of events failing the nJets cuts.
Definition: QCDTruthMultiJetFilter.h:43
QCDTruthMultiJetFilter::m_Njet
int m_Njet
Number of truth jets required above m_NjetMinPt.
Definition: QCDTruthMultiJetFilter.h:30
QCDTruthMultiJetFilter::m_norm
double m_norm
Normalization for weights.
Definition: QCDTruthMultiJetFilter.h:45
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
QCDTruthMultiJetFilter::m_passed
long m_passed
Number of events passing all cuts.
Definition: QCDTruthMultiJetFilter.h:41