ATLAS Offline Software
VBFMjjIntervalFilter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Header for this module
7 
10 #include "CLHEP/Random/RandomEngine.h"
11 #include "GaudiKernel/PhysicalConstants.h"
13 
14 // Pt High --> Low
16 public:
17  bool operator () (const xAOD::Jet *t1, const xAOD::Jet *t2) const {
18  return (t1->pt() > t2->pt());
19  }
20 };
21 
22 
23 VBFMjjIntervalFilter::VBFMjjIntervalFilter(const std::string& name, ISvcLocator* pSvcLocator)
24  : GenFilter(name, pSvcLocator),
25  m_norm(1.) //< @todo Scalefactor always set to 1.0! Remove?
26 {
27  declareProperty("RapidityAcceptance", m_yMax = 5.0);
28  declareProperty("MinSecondJetPT", m_pTavgMin = 15.0*Gaudi::Units::GeV);
29  declareProperty("MinOverlapPT", m_olapPt = 15.0*Gaudi::Units::GeV);
30  declareProperty("TruthJetContainerName", m_TruthJetContainerName = "AntiKt4TruthJets");
31  //declareProperty("DoShape", m_doShape = true);
32  declareProperty("NoJetProbability", m_prob0 = 0.0002);
33  declareProperty("OneJetProbability", m_prob1 = 0.001);
34  declareProperty("LowMjjProbability", m_prob2low = 0.005);
35  declareProperty("HighMjjProbability", m_prob2high = 1.0);
37  declareProperty("TruncateAtLowMjj", m_truncatelowmjj = false);
39  declareProperty("TruncateAtHighMjj", m_truncatehighmjj = false);
40  declareProperty("PhotonJetOverlapRemoval", m_photonjetoverlap = false);
41  declareProperty("ElectronJetOverlapRemoval", m_electronjetoverlap = true);
42  declareProperty("TauJetOverlapRemoval", m_taujetoverlap = false);
44  declareProperty("ApplyNjet",m_ApplyNjet=false);
45  declareProperty("Njets", m_NJetsMin=2);
46  declareProperty("NjetsMax",m_NJetsMax=-1);
47  declareProperty("ApplyWeighting",m_ApplyWeighting=true);
48  declareProperty("ApplyDphi",m_applyDphi=false);
49  declareProperty("dphijjMax",m_dphijj=2.5);
50 
51 }
52 
53 
55  ATH_MSG_INFO("Configured for jets in " << m_TruthJetContainerName << " inside |y|<" << m_yMax);
56 
57  CHECK(m_rndmSvc.retrieve());
58 
60  ATH_MSG_INFO("m_alpha set to" << m_alpha);
61  return StatusCode::SUCCESS;
62 }
63 
64 
66  // Get random number engine
67  const EventContext& ctx = Gaudi::Hive::currentContext();
68  CLHEP::HepRandomEngine* rndm = this->getRandomEngine(name(), ctx);
69  if (!rndm) {
70  ATH_MSG_ERROR("Failed to retrieve random number engine VBFMjjIntervalFilter");
71  setFilterPassed(false);
72  return StatusCode::SUCCESS;
73  }
74 
75  // Retrieve jet container
76  const xAOD::JetContainer* truthJetCollection = 0;
77  if ( !evtStore()->contains<xAOD::JetContainer>( m_TruthJetContainerName ) ||
78  evtStore()->retrieve( truthJetCollection, m_TruthJetContainerName).isFailure() ||
79  !truthJetCollection ) {
80  ATH_MSG_ERROR("No xAOD::JetContainer found in StoreGate with key " << m_TruthJetContainerName);
81  setFilterPassed(false);
82  return StatusCode::SUCCESS;
83  }
84 
85  // Find overlap objects
86  std::vector<HepMC::ConstGenParticlePtr> MCTruthPhotonList;
87  std::vector<HepMC::ConstGenParticlePtr> MCTruthElectronList;
88  std::vector<TLorentzVector> MCTruthTauList;
89  for (McEventCollection::const_iterator itr = events()->begin(); itr != events()->end(); ++itr) {
90  const HepMC::GenEvent* genEvt = (*itr);
91  for (const auto& pitr: *genEvt) {
92  if (m_photonjetoverlap==true) {
93  // photon - copied from VBFForwardJetsFilter.cxx
94  if ( MC::isPhoton(pitr) && MC::isStable(pitr) &&
95  pitr->momentum().perp() >= m_olapPt &&
96  std::abs(pitr->momentum().pseudoRapidity()) <= m_yMax) {
97  MCTruthPhotonList.push_back(pitr);
98  }
99  }
100  if (m_electronjetoverlap==true) {
101  // electron
102  if (MC::isElectron(pitr) && MC::isStable(pitr) &&
103  pitr->momentum().perp() >= m_olapPt &&
104  std::abs(pitr->momentum().pseudoRapidity()) <= m_yMax) {
105  MCTruthElectronList.push_back(pitr);
106  }
107  }
108  if (m_taujetoverlap==true) {
109  // tau - copied from VBFForwardJetsFilter.cxx
110  if ( MC::isTau(pitr) && MC::isPhysical(pitr) ) {
111  auto tau = pitr;
112  int leptonic = 0;
113  for (const auto& beg: *(tau->end_vertex()) ) {
114  if ( beg->production_vertex() != tau->end_vertex() ) continue;
115  if ( std::abs( beg->pdg_id() ) == 12 ) leptonic = 1;
116  if ( std::abs( beg->pdg_id() ) == 14 ) leptonic = 2;
117  if ( std::abs( beg->pdg_id() ) == 15 ) leptonic = 11;
118  }
119 
120  if (leptonic == 0) {
121  TLorentzVector nutau = sumDaughterNeutrinos( tau );
122  TLorentzVector tauvis = TLorentzVector(tau->momentum().px()-nutau.Px(),
123  tau->momentum().py()-nutau.Py(),
124  tau->momentum().pz()-nutau.Pz(),
125  tau->momentum().e()-nutau.E());
126  if (tauvis.Vect().Perp() >= m_olapPt && std::abs(tauvis.Vect().PseudoRapidity()) <= m_yMax) {
127  MCTruthTauList.push_back(tauvis);
128  }
129  }
130  }
131  }
132  }
133  }
134 
135  // Filter based on rapidity acceptance and sort
137  for (xAOD::JetContainer::const_iterator jitr = truthJetCollection->begin(); jitr != truthJetCollection->end(); ++jitr) {
138  if (std::abs( (*jitr)->rapidity() ) < m_yMax && (*jitr)->pt() >= m_olapPt) {
139  bool JetOverlapsWithPhoton = false;
140  bool JetOverlapsWithElectron = false;
141  bool JetOverlapsWithTau = false;
142 
143  if (m_photonjetoverlap==true) {
144  JetOverlapsWithPhoton = checkOverlap((*jitr)->rapidity(), (*jitr)->phi(), MCTruthPhotonList);
145  }
146  if (m_electronjetoverlap==true) {
147  JetOverlapsWithElectron = checkOverlap((*jitr)->rapidity(), (*jitr)->phi(), MCTruthElectronList);
148  }
149  if (m_taujetoverlap==true) {
150  JetOverlapsWithTau = checkOverlap((*jitr)->rapidity(), (*jitr)->phi(), MCTruthTauList);
151  }
152 
153  if (!JetOverlapsWithPhoton && !JetOverlapsWithElectron && !JetOverlapsWithTau ) {
154  filteredJets.push_back(*jitr);
155  }
156  }
157  }
158  filteredJets.sort(High2LowByJetClassPt());
159 
160  if(m_ApplyWeighting){
161 
162  double eventWeight = 1.0;
163  eventWeight = getEventWeight(filteredJets.asDataVector());
164  double rnd = rndm->flat();
165  if (1.0/eventWeight < rnd) {
166  setFilterPassed(false);
167  ATH_MSG_DEBUG("Event failed weighting. Weight is " << eventWeight);
168  return StatusCode::SUCCESS;
169  }
170 
171  // Get MC event collection for setting weight
172  const McEventCollection* mecc = 0;
173  if ( evtStore()->retrieve( mecc ).isFailure() || !mecc ){
174  setFilterPassed(false);
175  ATH_MSG_ERROR("Could not retrieve MC Event Collection - weight might not work");
176  return StatusCode::SUCCESS;
177  }
178 
179  ATH_MSG_INFO("Event passed. Will weight events " << eventWeight*m_norm);
180  McEventCollection* mec = const_cast<McEventCollection*> (&(*mecc));
181  for (unsigned int i = 0; i < mec->size(); ++i) {
182  if (!(*mec)[i]) continue;
183  double existingWeight = (*mec)[i]->weights().size()>0 ? (*mec)[i]->weights()[0] : 1.;
184  if ((*mec)[i]->weights().size()>0) {
185  (*mec)[i]->weights()[0] = existingWeight*eventWeight*m_norm;
186  } else {
187  (*mec)[i]->weights().push_back( eventWeight*m_norm*existingWeight );
188  }
189  }
190  }//Apply weighting
191  else {
192  //just compute mjj, dphi etc
193  bool pass = ApplyMassDphi(filteredJets.asDataVector());
194  if(!pass){
195  setFilterPassed(false);
196  ATH_MSG_DEBUG("Event failed filter");
197  return StatusCode::SUCCESS;
198  }
199  if(m_ApplyNjet){
200  if(filteredJets.size()<m_NJetsMin){
201  setFilterPassed(false);
202  return StatusCode::SUCCESS;
203  }
204  if(m_NJetsMax>0){
205  if(filteredJets.size()>m_NJetsMax){
206  setFilterPassed(false);
207  return StatusCode::SUCCESS;
208  }
209  }//Njets <
210  }//Apply Njets filter
211  }
212  // Made it to the end - success!
213  setFilterPassed(true);
214  return StatusCode::SUCCESS;
215 }
216 
217 
218 bool VBFMjjIntervalFilter::checkOverlap(double eta, double phi, const std::vector<HepMC::ConstGenParticlePtr> &list ) const {
219  for (size_t i = 0; i < list.size(); ++i) {
220  double pt = list.at(i)->momentum().perp();
221  if (pt > m_olapPt) {
223  double dphi = phi-list[i]->momentum().phi();
224  double deta = eta-list[i]->momentum().pseudoRapidity();
225  if (dphi > M_PI) { dphi -= 2.*M_PI; }
226  if (dphi < -M_PI) { dphi += 2.*M_PI; }
227  double dr = std::sqrt(deta*deta+dphi*dphi);
228  if (dr < 0.3) return true;
229  }
230  }
231  return false;
232 }
233 
234 
235 
236 bool VBFMjjIntervalFilter::checkOverlap(double eta, double phi, const std::vector<TLorentzVector> &list ) const{
237  for (size_t i = 0; i < list.size(); ++i) {
238  double pt = list[i].Vect().Perp();
239  if (pt > m_olapPt) {
241  double dphi = phi-list[i].Phi();
242  double deta = eta-list[i].Vect().PseudoRapidity();
243  if (dphi > M_PI) { dphi -= 2.*M_PI; }
244  if (dphi < -M_PI) { dphi += 2.*M_PI; }
245  double dr = std::sqrt(deta*deta+dphi*dphi);
246  if (dr < 0.3) return true;
247  }
248  }
249  return false;
250 }
251 
253  if(jets->size()<2) return false;
254  double mjj = (jets->at(0)->p4() + jets->at(1)->p4()).M();
255  double dphi = std::abs(jets->at(0)->p4().DeltaPhi(jets->at(1)->p4()));
256  ATH_MSG_INFO("mjj " << mjj << " dphi " << dphi);
257  bool pass = true;
258  if(mjj<m_mjjlow)pass=false;
259  if(mjj>m_mjjhigh)pass=false;
260  if(m_applyDphi && dphi > m_dphijj) pass = false;
261 
262  return pass;
263 }
264 
266  double weight = 1.0;
267  if (jets->size() == 0) {
268  weight /= m_prob0;
269  ATH_MSG_DEBUG("Event in 0-jet weighting. Weight is " << weight);
270  } else if (jets->size() == 1) {
271  weight /= m_prob1;
272  ATH_MSG_DEBUG("Event in 1-jet weighting. Weight is " << weight);
273  } else {
274  double mjj = (jets->at(0)->p4() + jets->at(1)->p4()).M();
275  if (mjj < m_mjjlow) {
276  if (m_truncatelowmjj==false) {
277  weight /= m_prob2low;
278  }
279  else {
280  weight = -1.0;
281  }
282  } else if (mjj > m_mjjhigh) {
283  if (m_truncatehighmjj==false) {
284  weight /= m_prob2high;
285  }
286  else {
287  weight = -1.0;
288  }
289  } else {
291  ATH_MSG_DEBUG("WEIGHTING:: " << mjj << "\t" << weight);
292  }
293  }
294  return weight;
295 }
296 
297 
299  TLorentzVector nu( 0, 0, 0, 0);
300 
301  if ( ( std::abs( part->pdg_id() ) == 12 ) || ( std::abs( part->pdg_id() ) == 14 ) || ( std::abs( part->pdg_id() ) == 16 ) ) {
302  nu.SetPx(part->momentum().px());
303  nu.SetPy(part->momentum().py());
304  nu.SetPz(part->momentum().pz());
305  nu.SetE(part->momentum().e());
306  return nu;
307  }
308 
309  if ( !part->end_vertex() ) return nu;
310 
311  for (const auto& beg: *(part->end_vertex()) ) nu += sumDaughterNeutrinos( beg );
312  return nu;
313 }
314 
315 
316 CLHEP::HepRandomEngine* VBFMjjIntervalFilter::getRandomEngine(const std::string& streamName,
317  const EventContext& ctx) const
318 {
319  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
320  std::string rngName = name()+streamName;
321  rngWrapper->setSeed( rngName, ctx );
322  return rngWrapper->getEngine(ctx);
323 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
VBFMjjIntervalFilter::m_applyDphi
bool m_applyDphi
Definition: VBFMjjIntervalFilter.h:61
VBFMjjIntervalFilter::m_TruthJetContainerName
std::string m_TruthJetContainerName
Definition: VBFMjjIntervalFilter.h:34
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
VBFMjjIntervalFilter::m_NJetsMax
unsigned int m_NJetsMax
Definition: VBFMjjIntervalFilter.h:59
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
VBFMjjIntervalFilter::m_ApplyWeighting
bool m_ApplyWeighting
Definition: VBFMjjIntervalFilter.h:60
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
VBFMjjIntervalFilter::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition: VBFMjjIntervalFilter.h:36
VBFMjjIntervalFilter::filterInitialize
virtual StatusCode filterInitialize()
Definition: VBFMjjIntervalFilter.cxx:54
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
ConstDataVector.h
DataVector adapter that acts like it holds const pointers.
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
VBFMjjIntervalFilter::m_prob0
double m_prob0
Definition: VBFMjjIntervalFilter.h:45
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
VBFMjjIntervalFilter::m_truncatelowmjj
bool m_truncatelowmjj
Definition: VBFMjjIntervalFilter.h:50
High2LowByJetClassPt::operator()
bool operator()(const xAOD::Jet *t1, const xAOD::Jet *t2) const
Definition: VBFForwardJetsFilter.cxx:14
VBFMjjIntervalFilter::m_prob2high
double m_prob2high
Definition: VBFMjjIntervalFilter.h:48
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
VBFMjjIntervalFilter::m_taujetoverlap
bool m_taujetoverlap
Definition: VBFMjjIntervalFilter.h:55
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
test_pyathena.pt
pt
Definition: test_pyathena.py:11
M_PI
#define M_PI
Definition: ActiveFraction.h:11
VBFMjjIntervalFilter::m_photonjetoverlap
bool m_photonjetoverlap
Definition: VBFMjjIntervalFilter.h:53
VBFMjjIntervalFilter::m_electronjetoverlap
bool m_electronjetoverlap
Definition: VBFMjjIntervalFilter.h:54
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:112
python.DataFormatRates.events
events
Definition: DataFormatRates.py:105
ConstDataVector::asDataVector
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
VBFMjjIntervalFilter::m_olapPt
double m_olapPt
Definition: VBFMjjIntervalFilter.h:31
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
VBFMjjIntervalFilter::m_norm
double m_norm
Definition: VBFMjjIntervalFilter.h:42
MC::isPhysical
bool isPhysical(const T &p)
Definition: HepMCHelpers.h:32
VBFMjjIntervalFilter::m_alpha
double m_alpha
Definition: VBFMjjIntervalFilter.h:56
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
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
VBFMjjIntervalFilter::filterEvent
virtual StatusCode filterEvent()
Definition: VBFMjjIntervalFilter.cxx:65
lumiFormat.i
int i
Definition: lumiFormat.py:92
VBFMjjIntervalFilter::m_pTavgMin
double m_pTavgMin
Definition: VBFMjjIntervalFilter.h:33
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
xAOD::EgammaHelpers::isElectron
bool isElectron(const xAOD::Egamma *eg)
is the object an electron (not Fwd)
Definition: EgammaxAODHelpers.cxx:12
VBFMjjIntervalFilter::checkOverlap
bool checkOverlap(double, double, const std::vector< HepMC::ConstGenParticlePtr > &) const
Definition: VBFMjjIntervalFilter.cxx:218
VBFMjjIntervalFilter::getRandomEngine
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, const EventContext &ctx) const
Definition: VBFMjjIntervalFilter.cxx:316
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
histSizes.list
def list(name, path='/')
Definition: histSizes.py: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
VBFMjjIntervalFilter::getEventWeight
double getEventWeight(const xAOD::JetContainer *jets) const
Definition: VBFMjjIntervalFilter.cxx:265
isTau
bool isTau(const T &p)
Definition: AtlasPID.h:148
VBFMjjIntervalFilter::m_prob2low
double m_prob2low
Definition: VBFMjjIntervalFilter.h:47
VBFMjjIntervalFilter::m_truncatehighmjj
bool m_truncatehighmjj
Definition: VBFMjjIntervalFilter.h:52
HepMC::ConstGenParticlePtr
const GenParticle * ConstGenParticlePtr
Definition: GenParticle.h:38
WriteBchToCool.beg
beg
Definition: WriteBchToCool.py:69
VBFMjjIntervalFilter::sumDaughterNeutrinos
TLorentzVector sumDaughterNeutrinos(const HepMC::ConstGenParticlePtr &) const
Definition: VBFMjjIntervalFilter.cxx:298
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
ConstDataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
VBFMjjIntervalFilter::m_ApplyNjet
bool m_ApplyNjet
Definition: VBFMjjIntervalFilter.h:57
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
VBFMjjIntervalFilter.h
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
High2LowByJetClassPt
Definition: VBFForwardJetsFilter.cxx:12
AthenaPoolExample_Copy.streamName
string streamName
Definition: AthenaPoolExample_Copy.py:39
MC::isStable
bool isStable(const T &p)
Definition: HepMCHelpers.h:30
ConstDataVector
DataVector adapter that acts like it holds const pointers.
Definition: ConstDataVector.h:76
VBFMjjIntervalFilter::ApplyMassDphi
bool ApplyMassDphi(const xAOD::JetContainer *jets) const
Definition: VBFMjjIntervalFilter.cxx:252
VBFMjjIntervalFilter::m_mjjhigh
double m_mjjhigh
Definition: VBFMjjIntervalFilter.h:51
xAOD::EgammaHelpers::isPhoton
bool isPhoton(const xAOD::Egamma *eg)
is the object a photon
Definition: EgammaxAODHelpers.cxx:21
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
VBFMjjIntervalFilter::m_mjjlow
double m_mjjlow
Definition: VBFMjjIntervalFilter.h:49
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
VBFMjjIntervalFilter::m_NJetsMin
unsigned int m_NJetsMin
Definition: VBFMjjIntervalFilter.h:58
VBFMjjIntervalFilter::VBFMjjIntervalFilter
VBFMjjIntervalFilter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: VBFMjjIntervalFilter.cxx:23
VBFMjjIntervalFilter::m_prob1
double m_prob1
Definition: VBFMjjIntervalFilter.h:46
VBFMjjIntervalFilter::m_dphijj
double m_dphijj
Definition: VBFMjjIntervalFilter.h:62
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
HepMCHelpers.h
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
VBFMjjIntervalFilter::m_yMax
double m_yMax
Definition: VBFMjjIntervalFilter.h:32