ATLAS Offline Software
xAODJetFilter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <algorithm>
8 #include <functional>
9 #include <vector>
10 
11 #include "GaudiKernel/PhysicalConstants.h"
15 
16 xAODJetFilter::xAODJetFilter(const std::string& name, ISvcLocator* pSvcLocator)
17  : GenFilter(name, pSvcLocator) {}
18 
20  m_emaxeta = 6.0;
21  m_edphi = 2 * M_PI / m_grphi; // cell size
22  m_edeta = 2. * m_emaxeta / m_greta; // cell size
23  // How many cells in the jet cluster
24  if (!m_type) { // it's the rectangular grid
25  m_nphicell = m_gridp / 2;
26  m_netacell = m_gride / 2;
29  } else {
30  m_nphicell = static_cast<int>(m_cone / m_edphi); // number of cells inside cone
31  m_netacell = static_cast<int>(m_cone / m_edeta); // number of cells inside come
32  m_nphicell2 =
33  2 * m_nphicell +
34  1; // guaranteed to be odd so that the highest cell is in middle
35  m_netacell2 = 2 * m_netacell + 1;
36  }
37  ATH_MSG_INFO("Parameters are \n ");
38  if (m_type) {
39  ATH_MSG_INFO(" Cone algorithm: "
40  << " Pt cut = " << m_userThresh
41  << ", Number= " << m_userNumber << ", Cone size=" << m_cone
42  << ", Rapidity range " << m_userEta);
43  } else {
44  ATH_MSG_INFO(" GridAlgorithm: "
45  << " Pt cut = " << m_userThresh << ", Number= "
46  << m_userNumber << ", eta size (units of 0.06) =" << m_gride
47  << ", phi size (units of 0.06) =" << m_gridp
48  << ", Rapidity range " << m_userEta);
49  }
50 
51  return StatusCode::SUCCESS;
52 }
53 
55  // Init grid
56  double etgrid[m_grphi][m_greta]; // clean it out before we start
57  bool etgridused[m_grphi][m_greta]; // will use this to mark off cells after
58  // they are added to jets
59  for (int ie = 0; ie < m_greta; ++ie) { // initialise everything to be safe
60  for (int ip = 0; ip < m_grphi; ++ip) {
61  etgrid[ip][ie] = 0.;
62  etgridused[ip][ie] = false;
63  }
64  }
65 
66 // Retrieve TruthGen container from xAOD Gen slimmer, contains all particles witout barcode_zero and
67 // duplicated barcode ones
68  const xAOD::TruthParticleContainer* xTruthParticleContainer;
69  if (evtStore()->retrieve(xTruthParticleContainer, "TruthGen").isFailure()) {
70  ATH_MSG_ERROR("No TruthParticle collection with name " << "TruthGen" << " found in StoreGate!");
71  return StatusCode::FAILURE;
72  }
73 
74  // Loop over all particles in the event and build up the grid
75 
76  unsigned int nPart = xTruthParticleContainer->size();
77  for (unsigned int iPart = 0; iPart < nPart; ++iPart) {
78  const xAOD::TruthParticle* part = (*xTruthParticleContainer)[iPart];
79 
80  if (part->isGenStable()) { // stables only
81  if ((part->pdgId() != 13) && (part->pdgId() != -13) &&
82  (part->pdgId() != 12) && (part->pdgId() != -12) &&
83  (part->pdgId() != 14) && (part->pdgId() != -14) &&
84  (part->pdgId() != 16) && (part->pdgId() != -16) &&
85  (std::abs(part->eta()) <=
86  m_emaxeta)) { // no neutrinos or muons and particles must be in
87  // active range
88  int ip, ie;
89  ip = static_cast<int>((M_PI + part->phi()) /
90  m_edphi); // phi is in range -CLHEP::pi to CLHEP::pi
91  ie = static_cast<int>((part->eta() + m_emaxeta) / m_edeta);
92  if (ie < 0 ||
93  (ie >=
94  m_greta)) { // its outside the ends so we should not be here
95  ATH_MSG_FATAL("Jet too close to end");
96  return StatusCode::FAILURE;
97  }
98  while (ip < 0)
99  ip += m_grphi; // fix phi wrapping note that this is done after rr
100  // is calculated
101  while (ip > m_grphi - 1)
102  ip -= m_grphi; // fix phi wrapping note that this is done after rr
103  // is calculated
104  etgrid[ip][ie] = etgrid[ip][ie] + part->pt(); // fortran had pt here
105  }
106  }
107  } // end Particles loop
108 
109  // Find the highest cell; we loop here until we cannot find more jets
110  double ethigh = 2. * m_stop; // et of highest cell
111  while (
112  ethigh >
113  m_stop) { // stop looping when there are no cells left above threshold;
114  ethigh = 0.;
115  int etahigh = 0;
116  int phihigh = 0;
117  for (int ie0 = m_netacell; ie0 < m_greta - m_netacell;
118  ++ie0) { // only look away from the edges
119  for (int ip0 = 0; ip0 < m_grphi; ++ip0) {
120  if (etgrid[ip0][ie0] > ethigh && !etgridused[ip0][ie0]) {
121  ethigh = etgrid[ip0][ie0];
122  etahigh = ie0;
123  phihigh = ip0;
124  }
125  }
126  }
127 
128  if (ethigh >
129  m_stop) { // this passes only if there is tower above threshold
130  // new jet
131  CLHEP::HepLorentzVector FoundJet;
132  double jetpx = 0.;
133  double jetpy = 0.;
134  double jetpz = 0.;
135  double jete = 0.;
136  if (!m_type) { // grid handle differantly if there are an even number of
137  // cells
138  if (m_netacell2 % 2 == 0 && m_nphicell2 % 2 == 1) { // eta even
139  double sum = 0.;
140  double sum1 = 0.;
141  for (int ip0 = 0; ip0 < m_nphicell2; ip0++) {
142  int ip1 = ip0 - m_nphicell + phihigh;
143  sum = sum + etgrid[ip1][etahigh - 1];
144  sum1 = sum1 + etgrid[ip1][etahigh + 1];
145  }
146  if (sum < sum1) {
147  etahigh += 1; // shift over by one
148  }
149  }
150  if (m_netacell2 % 2 == 1 && m_nphicell2 % 2 == 0) { // phi even
151  double sum = 0.;
152  double sum1 = 0.;
153  for (int ie0 = 0; ie0 < m_netacell2; ie0++) {
154  int ie1 = ie0 - m_netacell + etahigh;
155  sum = sum + etgrid[(phihigh - 1) % m_grphi][ie1];
156  sum1 = sum1 + etgrid[(phihigh + 1) % m_grphi][ie1];
157  }
158  if (sum < sum1) {
159  phihigh = (phihigh + 1) % m_grphi; // shift over by one
160  }
161  }
162  if (m_netacell2 % 2 == 0 && m_nphicell2 % 2 == 0) { // both even
163  double sum = 0.;
164  double sum1 = 0.;
165  double sum2 = 0.;
166  double sum3 = 0.;
167  for (int ie0 = 0; ie0 < m_netacell2; ie0++) {
168  for (int ip0 = 0; ip0 < m_nphicell2; ip0++) {
169  int ip1 = ip0 - m_nphicell + phihigh;
170  int ie1 = ie0 - m_netacell + etahigh;
171  if (!etgridused[ip1][ie1])
172  sum = sum + etgrid[ip1][ie1];
173  if (!etgridused[ip1][ie1 + 1])
174  sum1 = sum1 + etgrid[ip1][ie1 + 1];
175  if (!etgridused[ip1 + 1][ie1])
176  sum2 = sum2 + etgrid[(ip1 + 1) % m_grphi][ie1];
177  if (!etgridused[ip1 + 1][ie1 + 1])
178  sum3 = sum3 + etgrid[(ip1 + 1) % m_grphi][ie1 + 1];
179  }
180  }
181  if (sum < sum1 && sum2 < sum1 && sum3 < sum1)
182  etahigh = etahigh + 1;
183  if (sum < sum2 && sum1 <= sum2 && sum3 < sum2)
184  phihigh = (phihigh + 1) % m_grphi;
185  if (sum < sum3 && sum2 <= sum3 && sum1 <= sum3) {
186  etahigh = etahigh + 1;
187  phihigh = (phihigh + 1) % m_grphi;
188  }
189  }
190  }
191  // Add up stuff around high cell
192  for (int ie0 = 0; ie0 < m_netacell2; ++ie0) {
193  int ie1 = ie0 - m_netacell + etahigh;
194  if ((ie1 < 0) ||
195  (ie1 >=
196  m_greta)) { // its outside the ends so we should not be here
197  ATH_MSG_FATAL(" Jet too close to end");
198  return StatusCode::FAILURE;
199  }
200  for (int ip0 = 0; ip0 < m_nphicell2; ++ip0) {
201  int ip1 = ip0 - m_nphicell + phihigh;
202  // are we using a cone, if so check that its inside
203  double rr = (ie1 - etahigh) * (ie1 - etahigh) * m_edeta * m_edeta +
204  (ip1 - phihigh) * (ip1 - phihigh) * m_edphi * m_edphi;
205  while (ip1 < 0)
206  ip1 += m_grphi; // fix phi wrapping note that this is done after rr
207  // is calculated
208  while (ip1 > m_grphi - 1)
209  ip1 -= m_grphi; // fix phi wrapping note that this is done after rr
210  // is calculated
211  if (rr < m_cone * m_cone || !m_type) { // make sure that its inside
212  // check that the cell can be used and add energy to jet and mark
213  // the cell as used
214  if (!etgridused[ip1][ie1]) {
215  etgridused[ip1][ie1] = true;
216  jetpx = jetpx + etgrid[ip1][ie1] *
217  std::cos(-M_PI + (ip1 + 0.5) * m_edphi);
218  jetpy = jetpy + etgrid[ip1][ie1] *
219  std::sin(-M_PI + (ip1 + 0.5) * m_edphi);
220  jetpz = jetpz + etgrid[ip1][ie1] *
221  std::sinh((ie1 + 0.5) * m_edeta - m_emaxeta);
222  jete = jete +
223  etgrid[ip1][ie1] * std::cosh((ie1 + 0.5) * m_edeta - m_emaxeta);
224  }
225  }
226  }
227  }
228  FoundJet.setPx(jetpx);
229  FoundJet.setPy(jetpy);
230  FoundJet.setPz(jetpz);
231  FoundJet.setE(jete);
232  if (std::abs(FoundJet.pseudoRapidity()) < m_userEta) {
233  m_Jets.push_back(FoundJet); // OK we found one. add it to the list if
234  // its inside the eta region
235  }
236  }
237  }
238  sort(m_Jets.begin(), m_Jets.end(), std::greater<McObj>());
239  ATH_MSG_DEBUG(" Summary. "
240  << " Number of jets found = " << m_Jets.size() << " \n ");
241  if (m_Jets.size() > 0) {
242  ATH_MSG_DEBUG(" Highest pt (in GeV) "
243  << (m_Jets[0].P().perp() / Gaudi::Units::GeV)
244  << " Rapidity " << m_Jets[0].P().pseudoRapidity()
245  << " Phi " << m_Jets[0].P().phi() << "\n ");
246  ATH_MSG_DEBUG(" Second Highest pt (in GeV) "
247  << (m_Jets[1].P().perp() / Gaudi::Units::GeV)
248  << " Rapidity " << m_Jets[1].P().pseudoRapidity()
249  << " Phi " << m_Jets[1].P().phi() << "\n ");
250  ATH_MSG_DEBUG(" Lowest pt (in GeV) "
251  << (m_Jets[m_Jets.size() - 1].P().perp() / Gaudi::Units::GeV)
252  << " Rapidity "
253  << m_Jets[m_Jets.size() - 1].P().pseudoRapidity() << " Phi "
254  << m_Jets[m_Jets.size() - 1].P().phi() << "\n ");
255  }
256  // now look at the jets and check the filter
257  if (m_Jets.size() >= (unsigned)m_userNumber) {
258  if (m_Jets[m_userNumber - 1].P().perp() > m_userThresh) {
259  m_Jets.clear(); // clean it out
260  return StatusCode::SUCCESS;
261  }
262  }
263  setFilterPassed(false); // it failed to find any useful jets
264  m_Jets.clear(); // clean out the found jets
265  return StatusCode::SUCCESS;
266 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAODJetFilter::m_userNumber
Gaudi::Property< int > m_userNumber
Definition: xAODJetFilter.h:30
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
perp
Scalar perp() const
perp method - perpenticular length
Definition: AmgMatrixBasePlugin.h:35
xAODJetFilter.h
TruthParticleContainer.h
xAODJetFilter::m_edeta
double m_edeta
Definition: xAODJetFilter.h:72
M_PI
#define M_PI
Definition: ActiveFraction.h:11
xAODJetFilter::m_userEta
Gaudi::Property< double > m_userEta
Definition: xAODJetFilter.h:24
xAODJetFilter::m_Jets
std::vector< McObj > m_Jets
Definition: xAODJetFilter.h:78
xAODJetFilter::filterEvent
virtual StatusCode filterEvent() override
Definition: xAODJetFilter.cxx:54
xAODJetFilter::m_nphicell
int m_nphicell
Definition: xAODJetFilter.h:74
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
xAODJetFilter::m_netacell
int m_netacell
Definition: xAODJetFilter.h:75
xAODJetFilter::m_netacell2
int m_netacell2
Definition: xAODJetFilter.h:77
PlotCalibFromCool.ie
ie
Definition: PlotCalibFromCool.py:420
xAODJetFilter::m_cone
Gaudi::Property< double > m_cone
Definition: xAODJetFilter.h:27
TruthParticleAuxContainer.h
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
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
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::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
xAODJetFilter::m_edphi
double m_edphi
Definition: xAODJetFilter.h:73
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
xAODJetFilter::m_grphi
static const int m_grphi
Definition: xAODJetFilter.h:66
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
xAODJetFilter::m_gride
Gaudi::Property< int > m_gride
Definition: xAODJetFilter.h:28
xAODJetFilter::filterInitialize
virtual StatusCode filterInitialize() override
Definition: xAODJetFilter.cxx:19
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
xAODJetFilter::m_nphicell2
int m_nphicell2
Definition: xAODJetFilter.h:76
xAODJetFilter::m_stop
Gaudi::Property< double > m_stop
Definition: xAODJetFilter.h:26
xAODJetFilter::m_emaxeta
double m_emaxeta
Definition: xAODJetFilter.h:71
xAODJetFilter::xAODJetFilter
xAODJetFilter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: xAODJetFilter.cxx:16
xAODJetFilter::m_userThresh
Gaudi::Property< double > m_userThresh
Definition: xAODJetFilter.h:25
xAODJetFilter::m_type
Gaudi::Property< bool > m_type
Definition: xAODJetFilter.h:31
xAODJetFilter::m_gridp
Gaudi::Property< int > m_gridp
Definition: xAODJetFilter.h:29
rr
const boost::regex rr(r_r)
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
TruthParticle.h
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAODJetFilter::m_greta
static const int m_greta
Definition: xAODJetFilter.h:67