ATLAS Offline Software
Loading...
Searching...
No Matches
PFOMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8#include "xAODPFlow/PFO.h"
10#include "AthenaKernel/Units.h"
11using Athena::Units::GeV;
12
13PFOMonitorAlgorithm::PFOMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
14:AthMonitorAlgorithm(name,pSvcLocator)
15{}
16
17
18PFOMonitorAlgorithm::~PFOMonitorAlgorithm() = default;
19
20
22 // initialize superclass
24
25 ATH_CHECK( m_ChargedPFOContainerKey.initialize() );
26 ATH_CHECK( m_NeutralPFOContainerKey.initialize() );
27
28 return StatusCode::SUCCESS;
29}
30
31
32StatusCode PFOMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
33 using namespace Monitored;
34 const std::string allPFOs{"PFOMonitorAllPFOs"};
35 const std::string chargedPFOs{"PFOMonitorChargedPFOs"};
36 const std::string neutralPFOs{"PFOMonitorNeutralPFOs"};
37
38 // Declare the quantities which should be monitored
39 auto nPFOs = Monitored::Scalar<int>("nPFOs",0.0);
40 auto pT = Monitored::Scalar<float>("pfopT",0.0);
41 auto eta = Monitored::Scalar<float>("pfoEta",0.0);
42 auto phi = Monitored::Scalar<float>("pfoPhi",0.0);
43 auto mass = Monitored::Scalar<float>("pfoMass",0.0);
44 auto E = Monitored::Scalar<float>("pfoE",0.0);
45 auto y = Monitored::Scalar<float>("pfoRapidity",0.0);
46
47 auto nChPFOs = Monitored::Scalar<int>("nChPFOs",0.0);
48 auto ChpT = Monitored::Scalar<float>("ChpfopT",0.0);
49 auto Cheta = Monitored::Scalar<float>("ChpfoEta",0.0);
50 auto Chphi = Monitored::Scalar<float>("ChpfoPhi",0.0);
51 auto Chmass = Monitored::Scalar<float>("ChpfoMass",0.0);
52 auto ChE = Monitored::Scalar<float>("ChpfoE",0.0);
53 auto Chy = Monitored::Scalar<float>("ChpfoRapidity",0.0);
54 auto ChExpE = Monitored::Scalar<float>("ChpfoExpE",0.0);
55 auto ChDenseEnv = Monitored::Scalar<int>("ChpfoDenseEnv",0.0);
56
57// Declare cutmasks for dense environment
58 auto DenseEnvFlag = Monitored::Scalar<bool>("DenseEnvFlag",false);
59
60 auto nNuPFOs = Monitored::Scalar<int>("nNuPFOs",0.0);
61 auto NupT = Monitored::Scalar<float>("NupfopT",0.0);
62 auto Nueta = Monitored::Scalar<float>("NupfoEta",0.0);
63 auto Nuphi = Monitored::Scalar<float>("NupfoPhi",0.0);
64 auto Numass = Monitored::Scalar<float>("NupfoMass",0.0);
65 auto NuE = Monitored::Scalar<float>("NupfoE",0.0);
66 auto Nuy = Monitored::Scalar<float>("NupfoRapidity",0.0);
67 auto NuSecondR = Monitored::Scalar<float>("NupfoSecondR",0.0);
68 auto NuSecondLambda = Monitored::Scalar<float>("NupfoSecondLambda",0.0);
69 auto NuCenterLambda = Monitored::Scalar<float>("NupfoCenterLambda",0.0);
70 auto NuNBadCells = Monitored::Scalar<float>("NupfoNBadCells",0.0);
71 auto NuEBadCells = Monitored::Scalar<float>("NupfoEBadCells",0.0);
72 auto NuBadLarQFrac= Monitored::Scalar<float>("NupfoBadLarQFrac",0.0);
73 auto NuIso = Monitored::Scalar<float>("NupfoIsolation",0.0);
74 auto NuEPos = Monitored::Scalar<float>("NupfoEPos",0.0);
75 auto NuNBadC = Monitored::Scalar<int>("NupfoNBadCells",0);
76 auto NuAvgLarQ= Monitored::Scalar<float>("NupfoAvgLarQ",0.0);
77 auto NuAvgTileQ= Monitored::Scalar<float>("NupfoAvgTileQ",0.0);
78 auto NuEMProb= Monitored::Scalar<float>("NupfoEMProb",0.0);
79 // Not currently filled in the xAOD
80 //auto NuSignif = Monitored::Scalar<float>("NupfoSignificance",0.0);
81 //auto NuEFracMX= Monitored::Scalar<float>("NupfoEFracMax",0.0);
82
83 // Access the Particle Flow Objects via StoreGate
85 if (! chpfos.isValid() ) {
86 ATH_MSG_WARNING("evtStore() does not contain PFO Collection with name "<< m_ChargedPFOContainerKey);
87 return StatusCode::SUCCESS; //Return SUCCESS so processing proceeds
88 }
89
91 if (! nupfos.isValid() ) {
92 ATH_MSG_WARNING("evtStore() does not contain PFO Collection with name "<< m_NeutralPFOContainerKey);
93 return StatusCode::SUCCESS; //Return SUCCESS so processing proceeds
94 }
95
96 // Set monitored variables for this event
97 nPFOs = chpfos->size() + nupfos->size();
98 nChPFOs = chpfos->size();
99 nNuPFOs = nupfos->size();
100
101 fill(allPFOs,nPFOs);
102 fill(chargedPFOs,nChPFOs);
103 fill(neutralPFOs,nNuPFOs);
104
105 // Accessors for neutral PFO moments
106 const static SG::AuxElement::ConstAccessor<float> acc_SECOND_R("SECOND_R");
107 const static SG::AuxElement::ConstAccessor<float> acc_CENTER_LAMBDA("CENTER_LAMBDA");
108 const static SG::AuxElement::ConstAccessor<float> acc_ISOLATION("ISOLATION");
109 const static SG::AuxElement::ConstAccessor<float> acc_N_BAD_CELLS("N_BAD_CELLS");
110 const static SG::AuxElement::ConstAccessor<float> acc_ENG_BAD_CELLS("ENG_BAD_CELLS");
111 const static SG::AuxElement::ConstAccessor<float> acc_BADLARQ_FRAC("BADLARQ_FRAC");
112 const static SG::AuxElement::ConstAccessor<float> acc_ENG_POS("ENG_POS");
113 const static SG::AuxElement::ConstAccessor<float> acc_AVG_LAR_Q("AVG_LAR_Q");
114 const static SG::AuxElement::ConstAccessor<float> acc_AVG_TILE_Q("AVG_TILE_Q");
115 const static SG::AuxElement::ConstAccessor<float> acc_EM_PROBABILITY("EM_PROBABILITY");
116 const static SG::AuxElement::ConstAccessor<float> acc_SECOND_LAMBDA("SECOND_LAMBDA");
117 // Not currently filled in the xAOD
118 //const static SG::AuxElement::ConstAccessor<float> acc_SIGNIFICANCE("SIGNIFICANCE");
119 //const static SG::AuxElement::ConstAccessor<float> acc_ENG_FRAC_MAX("ENG_FRAC_MAX");
120
121 // Accessors for charged PFO moments
122 const static SG::AuxElement::ConstAccessor<int> acc_IsInDenseEnvironment("IsInDenseEnvironment");
123 const static SG::AuxElement::ConstAccessor<float> acc_tracksExpectedEnergyDeposit("TracksExpectedEnergyDeposit");
124
125 for (const auto pfo : *chpfos) {
126 pT = pfo->pt()/GeV;
127 eta = pfo->eta();
128 phi = pfo->phi();
129 mass= pfo->m()/GeV;
130 E = pfo->e()/GeV;
131 y = pfo->rapidity();
132 //float score = bdtPi0Score();
133
134 int denseEnv = 0;
135 float expectedEnergy = -1.0;
136
137 // Fill moments associated with tracks and track association
138 if(acc_IsInDenseEnvironment.isAvailable(*pfo)) {denseEnv = acc_IsInDenseEnvironment(*pfo);}
139 else {ATH_MSG_DEBUG("This charged PFO did not have IsInDenseEnvironment set");}
140
141 if(acc_tracksExpectedEnergyDeposit.isAvailable(*pfo)) {expectedEnergy = acc_tracksExpectedEnergyDeposit(*pfo);}
142 else {ATH_MSG_DEBUG("This charged PFO did not have TracksExpectedEnergyDeposit set");}
143
144 ChpT = pfo->pt()/GeV;
145 Cheta = pfo->eta();
146 Chphi = pfo->phi();
147 Chmass= pfo->m()/GeV;
148 ChE = pfo->e()/GeV;
149 Chy = pfo->rapidity();
150 ChDenseEnv = denseEnv;
151 ChExpE= expectedEnergy;
152
153 // Fill. First argument is the tool name, all others are the variables to be saved.
154 fill(allPFOs,pT,eta,phi,mass,E,y);
155 DenseEnvFlag = denseEnv;
156 fill(chargedPFOs,ChpT,Cheta,Chphi,Chmass,ChE,Chy,ChDenseEnv,ChExpE,DenseEnvFlag);
157
158 }
159
160 for (const auto pfo : *nupfos) {
161 E = pfo->e()/GeV;
162 //some neutral particle flow FlowELement can have their energy set to exactly zero. Will get FPE if
163 //try to calculate rapidity, so skip these.
164 if (0 == E) continue;
165 pT = pfo->pt()/GeV;
166 eta = pfo->eta();
167 phi = pfo->phi();
168 mass= pfo->m()/GeV;
169 y = pfo->rapidity();
170
171 NupT = pfo->pt()/GeV;
172 Nueta = pfo->eta();
173 Nuphi = pfo->phi();
174 Numass= pfo->m()/GeV;
175 NuE = pfo->e()/GeV;
176 Nuy = pfo->rapidity();
177
178 if (acc_ISOLATION.isAvailable(*pfo)) {NuIso = acc_ISOLATION(*pfo);}
179 else {ATH_MSG_DEBUG("This neutral PFO did not have ISOLATION set");}
180
181 if (acc_ENG_POS.isAvailable(*pfo)) {NuEPos= acc_ENG_POS(*pfo);}
182 else {ATH_MSG_DEBUG("This neutral PFO did not have ENG_POS set");}
183
184 if (acc_N_BAD_CELLS.isAvailable(*pfo)) {NuNBadCells = acc_N_BAD_CELLS(*pfo);}
185 else {ATH_MSG_DEBUG("This neutral PFO did not have N_BAD_CELLS set");}
186
187 if (acc_ENG_BAD_CELLS.isAvailable(*pfo)) {NuEBadCells = acc_ENG_BAD_CELLS(*pfo);}
188 else {ATH_MSG_DEBUG("This neutral PFO did not have ENG_BAD_CELLS set");}
189
190 if (acc_AVG_LAR_Q.isAvailable(*pfo)) {NuAvgLarQ = acc_AVG_LAR_Q(*pfo);}
191 else {ATH_MSG_DEBUG("This neutral PFO did not have AVG_LAR_Q set");}
192
193 if (acc_AVG_TILE_Q.isAvailable(*pfo)) {NuAvgTileQ = acc_AVG_TILE_Q(*pfo);}
194 else {ATH_MSG_DEBUG("This neutral PFO did not have AVG_TILE_Q set");}
195
196 if (acc_SECOND_R.isAvailable(*pfo)) {NuSecondR = acc_SECOND_R(*pfo);}
197 else {ATH_MSG_DEBUG("This neutral PFO did not have SECOND_R set");}
198
199 if (acc_SECOND_LAMBDA.isAvailable(*pfo)) {NuSecondLambda = acc_SECOND_LAMBDA(*pfo);}
200 else {ATH_MSG_DEBUG("This neutral PFO did not have SECOND_LAMBDA set");}
201
202 if (acc_CENTER_LAMBDA.isAvailable(*pfo)) {NuCenterLambda = acc_CENTER_LAMBDA(*pfo);}
203 else {ATH_MSG_DEBUG("This neutral PFO did not have CENTER_LAMBDA set");}
204
205 if (acc_BADLARQ_FRAC.isAvailable(*pfo)) {NuBadLarQFrac = acc_BADLARQ_FRAC(*pfo);}
206 else {ATH_MSG_DEBUG("This neutral PFO did not have BAD_LARQ_FRAC set");}
207
208 if (acc_EM_PROBABILITY.isAvailable(*pfo)) {NuEMProb = acc_EM_PROBABILITY(*pfo);}
209 else {ATH_MSG_DEBUG("This neutral PFO did not have BAD_LARQ_FRAC set");}
210
211 // These moments do not appear to be filled currently in the xAOD, but leave commented out
212 // in case they are turned on later.
213 //if (acc_SIGNIFICANCE.isAvailable(*pfo)) {NuSignif = acc_SIGNIFICANCE(*pfo);}
214 //else {ATH_MSG_DEBUG("This charged PFO did not have SIGNIFICANCE set");}
215 //if (acc_ENG_FRAC_MAX.isAvailable(*pfo)) {NuEFracMAX = acc_ENG_FRAC_MAX(*pfo);}
216 //else {ATH_MSG_DEBUG("This neutral PFO did not have ENG_FRAC_MAX set");}
217
218 // Fill. First argument is the tool name, all others are the variables to be saved.
219 fill(allPFOs,pT,eta,phi,mass,E,y);
220 fill(neutralPFOs,NupT,Nueta,Nuphi,Numass,NuE,Nuy,NuIso,NuEPos,NuNBadC,NuEBadCells,NuAvgLarQ,NuSecondR,NuCenterLambda,NuSecondLambda,NuBadLarQFrac,NuEMProb);
221 }
222
223 return StatusCode::SUCCESS;
224}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Header file to be included by clients of the Monitored infrastructure.
Wrapper to avoid constant divisions when using units.
#define y
virtual StatusCode initialize() override
initialize
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Declare a monitored scalar variable.
SG::ReadHandleKey< xAOD::FlowElementContainer > m_ChargedPFOContainerKey
PFOMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode initialize() override
initialize
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
SG::ReadHandleKey< xAOD::FlowElementContainer > m_NeutralPFOContainerKey
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Generic monitoring tool for athena components.
void fill(H5::Group &out_file, size_t iterations)