ATLAS Offline Software
DirectPhotonFilter.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 <limits>
7 #include <algorithm>
9 
10 DirectPhotonFilter::DirectPhotonFilter(const std::string& name, ISvcLocator* pSvcLocator)
11  : GenFilter(name, pSvcLocator)
12 {
13  declareProperty("NPhotons", m_NPhotons = 1);
14  declareProperty("OrderPhotons",m_OrderPhotons = true);
15  declareProperty("Ptmin",m_Ptmin = std::vector<double>(m_NPhotons, 10000.));
16  declareProperty("Ptmax",m_Ptmax = std::vector<double>(m_NPhotons, std::numeric_limits<double>::max()));
17  declareProperty("Etacut", m_EtaRange = 2.50);
18  declareProperty("AllowSUSYDecay",m_AllowSUSYDecay = false);
19 
20 }
21 
23 
24  ATH_MSG_INFO("Initialising DirectPhoton filter with OrderPhotons="<<m_OrderPhotons);
25 
26  if (m_Ptmin.size()>m_NPhotons || m_Ptmax.size()>m_NPhotons) {
27  ATH_MSG_ERROR("Too many Ptmin/max for given NPhotons");
28  return StatusCode::FAILURE;
29  }
30 
31  if (!m_OrderPhotons && (m_Ptmin.size()>1 || m_Ptmax.size()>1)) {
32  ATH_MSG_ERROR("Too many Ptmin/max requirements for OrderPhotons=false case.");
33  return StatusCode::FAILURE;
34  }
35 
36  // allow specifying only one pTmin/max to be applied to all (further) photons
37  // for backward compatibility
38  if (m_Ptmin.size()<m_NPhotons) {
39  size_t origsize = m_Ptmin.size();
40  double lastPt = m_Ptmin.back();
41  m_Ptmin.resize(m_NPhotons);
42  for (size_t i=origsize; i<m_NPhotons; ++i) m_Ptmin[i]=lastPt;
43  }
44  if (m_Ptmax.size()<m_NPhotons) {
45  size_t origsize = m_Ptmax.size();
46  double lastPt = m_Ptmax.back();
47  m_Ptmax.resize(m_NPhotons);
48  for (size_t i=origsize; i<m_NPhotons; ++i) m_Ptmax[i]=lastPt;
49  }
50  return StatusCode::SUCCESS;
51 }
52 
54  return (p1->momentum().perp()>p2->momentum().perp());
55 }
56 
58  std::vector<HepMC::ConstGenParticlePtr> promptPhotonsInEta;
59 
60  int phot = 0;
61  for(const HepMC::GenEvent* genEvt : *events_const()) {
62  // Find all prompt photons with within given eta range
63  for (const auto& pitr: *genEvt) {
64  if (MC::isPhoton(pitr) &&
65  MC::isStable(pitr) &&
66  std::abs(pitr->momentum().pseudoRapidity()) <= m_EtaRange) {
67 
68  // iterate over parent particles to exclude photons from hadron decays
69  auto prodVtx = pitr->production_vertex();
70  bool fromHadron(false);
71 #ifdef HEPMC3
72  for (const auto& parent: prodVtx->particles_in()) {
73 #else
74  for (auto parent_it = prodVtx->particles_begin(HepMC::parents); parent_it != prodVtx->particles_end(HepMC::parents); ++parent_it) {
75  auto parent=*parent_it;
76 #endif
77  int pdgindex = std::abs(parent->pdg_id());
78  ATH_MSG_DEBUG("Looping on Production (parents) vertex : " << parent->pdg_id() << parent);
79  if (pdgindex > 100) {
80  fromHadron = true;
81  if (m_AllowSUSYDecay && ( (pdgindex > 1000000 && pdgindex < 1000040) || (pdgindex > 2000000 && pdgindex < 2000016) ) ) fromHadron = false;
82  }
83  }
84  phot++;
85  if (!fromHadron) promptPhotonsInEta.push_back(pitr);
86  else ATH_MSG_DEBUG("non-prompt photon ignored");
87  }
88  }
89  }
90 
91  ATH_MSG_DEBUG("number of photons" << phot);
92 
93  if (promptPhotonsInEta.size()<m_NPhotons) {
94  setFilterPassed(false);
95  }
96  else {
97  for (const auto& photon: promptPhotonsInEta) {
98 
99  ATH_MSG_DEBUG("Found prompt photon with pt="<<photon->momentum().perp());
100  }
101  if (m_OrderPhotons) { // apply cuts to leading/subleading/... photon as specified
102  std::sort(promptPhotonsInEta.begin(), promptPhotonsInEta.end(), DirectPhotonFilterCmpByPt);
103 
104  bool pass = true;
105  for (size_t i = 0; i < m_NPhotons; ++i) {
106  double pt = promptPhotonsInEta[i]->momentum().perp();
107  if (pt < m_Ptmin[i] || pt > m_Ptmax[i]) {
108 
109  ATH_MSG_DEBUG(" rejected pt="<<pt);
110  pass = false;
111  }
112  }
113 
114  if (pass) {
115  ATH_MSG_DEBUG("Passed!");
116  }
117  setFilterPassed(pass);
118  }
119  else { // just require NPhotons to pass m_Ptmin/max[0]
120  size_t NPhotons=0;
121  for (size_t i = 0; i < promptPhotonsInEta.size(); ++i) {
122  double pt = promptPhotonsInEta[i]->momentum().perp();
123  if (pt > m_Ptmin[0] && pt < m_Ptmax[0]) ++NPhotons;
124  }
125 
126  if (NPhotons>=m_NPhotons) ATH_MSG_DEBUG("Passed!");
127  setFilterPassed(NPhotons>=m_NPhotons);
128  }
129  }
130  return StatusCode::SUCCESS;
131 }
max
#define max(a, b)
Definition: cfImp.cxx:41
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
DirectPhotonFilter::DirectPhotonFilter
DirectPhotonFilter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: DirectPhotonFilter.cxx:10
MC::fromHadron
bool fromHadron(T p, T hadptr, bool &fromTau, bool &fromBSM)
Function to classify the particle.
Definition: HepMCHelpers.h:184
GenBase::events_const
const McEventCollection * events_const() const
Access the current event's McEventCollection (const)
Definition: GenBase.h:96
DirectPhotonFilter::m_Ptmax
std::vector< double > m_Ptmax
Definition: DirectPhotonFilter.h:21
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
python.DecayParser.parents
parents
print ("==> buf:",buf)
Definition: DecayParser.py:31
DirectPhotonFilter::m_AllowSUSYDecay
bool m_AllowSUSYDecay
Definition: DirectPhotonFilter.h:24
test_pyathena.pt
pt
Definition: test_pyathena.py:11
DirectPhotonFilter::m_OrderPhotons
bool m_OrderPhotons
Definition: DirectPhotonFilter.h:25
GenFilter
Base class for event generator filtering modules.
Definition: GenFilter.h:30
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
DirectPhotonFilter::filterEvent
virtual StatusCode filterEvent()
Definition: DirectPhotonFilter.cxx:57
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
test_pyathena.parent
parent
Definition: test_pyathena.py:15
HepMC::ConstGenParticlePtr
const GenParticle * ConstGenParticlePtr
Definition: GenParticle.h:38
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
DirectPhotonFilter::m_NPhotons
size_t m_NPhotons
Definition: DirectPhotonFilter.h:23
MC::isStable
bool isStable(const T &p)
Definition: HepMCHelpers.h:30
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
xAOD::EgammaHelpers::isPhoton
bool isPhoton(const xAOD::Egamma *eg)
is the object a photon
Definition: EgammaxAODHelpers.cxx:21
DirectPhotonFilter::m_EtaRange
double m_EtaRange
Definition: DirectPhotonFilter.h:22
DirectPhotonFilterCmpByPt
bool DirectPhotonFilterCmpByPt(const HepMC::ConstGenParticlePtr &p1, const HepMC::ConstGenParticlePtr &p2)
Definition: DirectPhotonFilter.cxx:53
DirectPhotonFilter.h
DirectPhotonFilter::filterInitialize
virtual StatusCode filterInitialize()
Definition: DirectPhotonFilter.cxx:22
DirectPhotonFilter::m_Ptmin
std::vector< double > m_Ptmin
Definition: DirectPhotonFilter.h:20
HepMCHelpers.h