ATLAS Offline Software
JetFilter.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"
8 #include <vector>
9 #include <functional>
10 #include <algorithm>
11 
12 JetFilter::JetFilter(const std::string& name, ISvcLocator* pSvcLocator)
13  : GenFilter(name, pSvcLocator)
14 {
15  declareProperty("EtaRange", m_UserEta=2.7);
16  declareProperty("JetThreshold", m_UserThresh=17000.); // note CLHEP::MeV units
17  declareProperty("SeedThreshold", m_Stop=1000.); //note CLHEP::MeV units
18  declareProperty("ConeSize", m_Cone=0.4);
19  declareProperty("GridSizeEta", m_Gride=2);
20  declareProperty("GridSizePhi", m_Gridp=2);
21  declareProperty("JetNumber", m_UserNumber=1);
22  declareProperty("JetType", m_Type=true); // true if its a cone
23 
24  m_EtaRange = 0.;
25  m_emaxeta = 0.;
26  m_edeta = 0.;
27  m_edphi = 0.;
28  m_nphicell = 0;
29  m_netacell = 0;
30  m_nphicell2 = 0;
31  m_netacell2 = 0;
32 }
33 
34 
36  m_emaxeta = 6.0;
37  m_edphi = 2.*M_PI/m_grphi; // cell size
38  m_edeta = 2.*m_emaxeta/m_greta; // cell size
39  // How many cells in the jet cluster
40  if (!m_Type) { // it's the rectangular grid
41  m_nphicell = m_Gridp/2;
42  m_netacell = m_Gride/2;
45  } else {
46  m_nphicell = (int) (m_Cone/m_edphi); // number of cells inside cone
47  m_netacell = (int) (m_Cone/m_edeta); //number of cells inside come
48  m_nphicell2 = 2*m_nphicell+1; // guaranteed to be odd so that the highest cell is in middle
49  m_netacell2 = 2*m_netacell+1;
50  }
51  ATH_MSG_INFO("Parameters are \n ");
52  if (m_Type) {
53  ATH_MSG_INFO(" Cone algorithm: " <<
54  " Pt cut = " << m_UserThresh << ", Number= " << m_UserNumber <<
55  ", Cone size=" << m_Cone << ", Rapidity range " << m_UserEta);
56  } else {
57  ATH_MSG_INFO(" GridAlgorithm: " <<
58  " Pt cut = " << m_UserThresh << ", Number= " << m_UserNumber <<
59  ", eta size (units of 0.06) =" << m_Gride <<
60  ", phi size (units of 0.06) =" << m_Gridp << ", Rapidity range " << m_UserEta);
61  }
62  return StatusCode::SUCCESS;
63 }
64 
65 
67  // Init grid
68  double etgrid[m_grphi][m_greta]; // clean it out before we start
69  bool etgridused[m_grphi][m_greta]; //will use this to mark off cells after they are added to jets
70  for (int ie = 0; ie < m_greta; ++ie) { //initialise everything to be safe
71  for (int ip = 0; ip < m_grphi; ++ip) {
72  etgrid[ip][ie] = 0.;
73  etgridused[ip][ie] = false;
74  }
75  }
76 
77  // Loop over all particles in the event and build up the grid
78  const HepMC::GenEvent* genEvt = event();
79  for (const auto& part: *genEvt) {
81  if(MC::isGenStable(part)) { //stables only
82  if ( (!MC::isSMLepton(part)||MC::isTau(part)) &&
83  (std::abs(part->momentum().pseudoRapidity()) <= m_emaxeta) ) { // no neutrinos or muons and particles must be in active range
84  int ip, ie;
85  ip = (int) ((M_PI+ part->momentum().phi())/m_edphi); //phi is in range -CLHEP::pi to CLHEP::pi
86  ie = (int) ((part->momentum().pseudoRapidity()+m_emaxeta)/m_edeta);
87  if (ie < 0 || (ie >= m_greta)) { // its outside the ends so we should not be here
88  ATH_MSG_FATAL("Jet too close to end");
89  return StatusCode::FAILURE;
90  }
91  while (ip < 0) ip += m_grphi; //fix phi wrapping note that this is done after rr is calculated
92  while (ip > m_grphi-1) ip -= m_grphi; //fix phi wrapping note that this is done after rr is calculated
93  etgrid[ip][ie] = etgrid[ip][ie]+part->momentum().perp(); // fortran had pt here
94  }
95  }
96  }
97 
98  // Find the highest cell; we loop here until we cannot find more jets
99  double ethigh = 2.*m_Stop; // et of highest cell
100  while (ethigh > m_Stop) { // stop looping when there are no cells left above threshold;
101  ethigh = 0.;
102  int etahigh = 0;
103  int phihigh = 0;
104  for (int ie0 = m_netacell; ie0 < m_greta-m_netacell; ++ie0) { // only look away from the edges
105  for (int ip0 = 0; ip0 < m_grphi; ++ip0) {
106  if (etgrid[ip0][ie0]>ethigh && !etgridused[ip0][ie0]) {
107  ethigh = etgrid[ip0][ie0];
108  etahigh = ie0;
109  phihigh = ip0;
110  }
111  }
112  }
113 
114  if (ethigh > m_Stop) { // this passes only if there is tower above threshold
115  // new jet
116  CLHEP::HepLorentzVector FoundJet;
117  double jetpx = 0.;
118  double jetpy = 0.;
119  double jetpz = 0.;
120  double jete = 0.;
121  if (!m_Type) { //grid handle differantly if there are an even number of cells
122  if (m_netacell2 % 2 == 0 && m_nphicell2 % 2 == 1) { // eta even
123  double sum = 0.;
124  double sum1 = 0.;
125  for (int ip0 = 0; ip0 < m_nphicell2; ip0++) {
126  int ip1 = ip0-m_nphicell+phihigh;
127  sum = sum+etgrid[ip1][etahigh-1];
128  sum1 = sum1+etgrid[ip1][etahigh+1];
129  }
130  if (sum < sum1) {
131  etahigh += 1; //shift over by one
132  }
133  }
134  if (m_netacell2 % 2 == 1 && m_nphicell2 % 2 == 0) { // phi even
135  double sum = 0.;
136  double sum1 = 0.;
137  for (int ie0 = 0; ie0 < m_netacell2; ie0++) {
138  int ie1 = ie0-m_netacell+etahigh;
139  sum = sum+etgrid[(phihigh-1)%m_grphi][ie1];
140  sum1 = sum1+etgrid[(phihigh+1)%m_grphi][ie1];
141  }
142  if (sum < sum1) {
143  phihigh = (phihigh+1) % m_grphi; //shift over by one
144  }
145  }
146  if (m_netacell2 % 2 == 0 && m_nphicell2 % 2 == 0) { // both even
147  double sum = 0.;
148  double sum1 = 0.;
149  double sum2 = 0.;
150  double sum3 = 0.;
151  for (int ie0 = 0; ie0 < m_netacell2; ie0++) {
152  for (int ip0 = 0; ip0 < m_nphicell2; ip0++) {
153  int ip1 = ip0-m_nphicell+phihigh;
154  int ie1 = ie0-m_netacell+etahigh;
155  if (!etgridused[ip1][ie1]) sum=sum+etgrid[ip1][ie1];
156  if (!etgridused[ip1][ie1+1]) sum1=sum1+etgrid[ip1][ie1+1];
157  if (!etgridused[ip1+1][ie1]) sum2=sum2+etgrid[(ip1+1)%m_grphi][ie1];
158  if (!etgridused[ip1+1][ie1+1]) sum3=sum3+etgrid[(ip1+1)%m_grphi][ie1+1];
159  }
160  }
161  if (sum < sum1 && sum2 < sum1 && sum3 < sum1) etahigh=etahigh+1;
162  if (sum < sum2 && sum1 <= sum2 && sum3 < sum2) phihigh=(phihigh+1)%m_grphi;
163  if (sum < sum3 && sum2 <= sum3 && sum1 <= sum3) {
164  etahigh = etahigh+1;
165  phihigh = (phihigh+1)%m_grphi;
166  }
167  }
168  }
169  // Add up stuff around high cell
170  for (int ie0 = 0; ie0 < m_netacell2; ++ie0) {
171  int ie1 = ie0-m_netacell+etahigh;
172  if ( (ie1<0) || (ie1>= m_greta)) { // its outside the ends so we should not be here
173  ATH_MSG_FATAL(" Jet too close to end");
174  return StatusCode::FAILURE;
175  }
176  for (int ip0 = 0; ip0 < m_nphicell2; ++ip0) {
177  int ip1 = ip0-m_nphicell+phihigh;
178  // are we using a cone, if so check that its inside
179  double rr = (ie1-etahigh)*(ie1-etahigh)*m_edeta*m_edeta+(ip1-phihigh)*(ip1-phihigh)*m_edphi*m_edphi;
180  while ( ip1 < 0) ip1 += m_grphi; // fix phi wrapping note that this is done after rr is calculated
181  while (ip1 > m_grphi-1) ip1 -= m_grphi; // fix phi wrapping note that this is done after rr is calculated
182  if (rr< m_Cone*m_Cone || !m_Type) { // make sure that its inside
183  //check that the cell can be used and add energy to jet and mark the cell as used
184  if (!etgridused[ip1][ie1]) {
185  etgridused[ip1][ie1] = true;
186  jetpx = jetpx+etgrid[ip1][ie1]*cos(-M_PI+(ip1+0.5)*m_edphi);
187  jetpy = jetpy+etgrid[ip1][ie1]*sin(-M_PI+(ip1+0.5)*m_edphi);
188  jetpz = jetpz+etgrid[ip1][ie1]*sinh((ie1+0.5)*m_edeta-m_emaxeta);
189  jete = jete+etgrid[ip1][ie1]*cosh((ie1+0.5)*m_edeta-m_emaxeta);
190  }
191  }
192  }
193  }
194  FoundJet.setPx(jetpx);
195  FoundJet.setPy(jetpy);
196  FoundJet.setPz(jetpz);
197  FoundJet.setE(jete);
198  if (std::abs(FoundJet.pseudoRapidity()) < m_UserEta) {
199  m_Jets.push_back(FoundJet); //OK we found one. add it to the list if its inside the eta region
200  }
201  }
202  }
203  sort(m_Jets.begin(),m_Jets.end(),std::greater<McObj>());
204  ATH_MSG_DEBUG(" Summary. " << " Number of jets found = " << m_Jets.size() << " \n ");
205  if (m_Jets.size() > 0) {
206  ATH_MSG_DEBUG(" Highest pt (in GeV) " << (m_Jets[0].P().perp()/Gaudi::Units::GeV) << " Rapidity " <<m_Jets[0].P().pseudoRapidity()<< " Phi "<< m_Jets[0].P().phi() << "\n ");
207  ATH_MSG_DEBUG(" Second Highest pt (in GeV) " << (m_Jets[1].P().perp()/Gaudi::Units::GeV) << " Rapidity " <<m_Jets[1].P().pseudoRapidity()<< " Phi "<< m_Jets[1].P().phi() << "\n ");
208  ATH_MSG_DEBUG(" Lowest pt (in GeV) " << (m_Jets[m_Jets.size()-1].P().perp()/Gaudi::Units::GeV) << " Rapidity " <<m_Jets[m_Jets.size()-1].P().pseudoRapidity() << " Phi " << m_Jets[m_Jets.size()-1].P().phi() << "\n ");
209  }
210  // now look at the jets and check the filter
211  if (m_Jets.size() >= (unsigned) m_UserNumber) {
212  if (m_Jets[m_UserNumber-1].P().perp() > m_UserThresh) {
213  m_Jets.clear(); //clean it out
214  return StatusCode::SUCCESS;
215  }
216  }
217  setFilterPassed(false); // it failed to find any useful jets
218  m_Jets.clear(); //clean out the found jets
219  return StatusCode::SUCCESS;
220 }
221 
222 
223 
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
JetFilter::m_netacell
int m_netacell
Definition: JetFilter.h:73
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
JetFilter::m_grphi
static const int m_grphi
Definition: JetFilter.h:55
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
JetFilter::m_edphi
double m_edphi
Definition: JetFilter.h:71
JetFilter::m_EtaRange
double m_EtaRange
Definition: JetFilter.h:68
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
perp
Scalar perp() const
perp method - perpenticular length
Definition: AmgMatrixBasePlugin.h:35
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
JetFilter::m_emaxeta
double m_emaxeta
Definition: JetFilter.h:69
JetFilter::m_UserThresh
double m_UserThresh
Definition: JetFilter.h:60
M_PI
#define M_PI
Definition: ActiveFraction.h:11
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
JetFilter::m_netacell2
int m_netacell2
Definition: JetFilter.h:75
JetFilter::m_edeta
double m_edeta
Definition: JetFilter.h:70
MC::isGenStable
bool isGenStable(const T &p)
Determine if the particle is stable at the generator (not det-sim) level,.
Definition: HepMCHelpers.h:36
isSMLepton
bool isSMLepton(const T &p)
Definition: AtlasPID.h:134
PlotCalibFromCool.ie
ie
Definition: PlotCalibFromCool.py:420
JetFilter::m_Jets
std::vector< McObj > m_Jets
Definition: JetFilter.h:76
GenFilter
Base class for event generator filtering modules.
Definition: GenFilter.h:30
JetFilter::filterEvent
virtual StatusCode filterEvent()
Definition: JetFilter.cxx:66
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
JetFilter::filterInitialize
virtual StatusCode filterInitialize()
Definition: JetFilter.cxx:35
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
JetFilter::m_Gride
int m_Gride
Definition: JetFilter.h:63
JetFilter.h
JetFilter::m_Cone
double m_Cone
Definition: JetFilter.h:62
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
JetFilter::m_nphicell
int m_nphicell
Definition: JetFilter.h:72
JetFilter::m_Gridp
int m_Gridp
Definition: JetFilter.h:64
JetFilter::m_Type
bool m_Type
Definition: JetFilter.h:65
isTau
bool isTau(const T &p)
Definition: AtlasPID.h:148
JetFilter::m_Stop
double m_Stop
Definition: JetFilter.h:61
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
JetFilter::m_nphicell2
int m_nphicell2
Definition: JetFilter.h:74
JetFilter::m_UserNumber
int m_UserNumber
Definition: JetFilter.h:59
JetFilter::m_greta
static const int m_greta
Definition: JetFilter.h:56
JetFilter::JetFilter
JetFilter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: JetFilter.cxx:12
rr
const boost::regex rr(r_r)
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
JetFilter::m_UserEta
double m_UserEta
Definition: JetFilter.h:58
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
HepMCHelpers.h