ATLAS Offline Software
Loading...
Searching...
No Matches
AsgForwardElectronIsEMSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Dear emacs, this is -*-c++-*-
6
23#include "TEnv.h"
26#include "xAODEgamma/Electron.h"
27#include "xAODEgamma/Photon.h"
28#include "xAODTracking/Vertex.h"
29#include <cstdint>
30//=============================================================================
31// Standard constructor
32//=============================================================================
33AsgForwardElectronIsEMSelector::AsgForwardElectronIsEMSelector(
34 const std::string& myname)
35 : AsgTool(myname)
36 , m_configFile{ "" }
37 , m_rootForwardTool{ nullptr }
38{
39 m_rootForwardTool = new Root::TForwardElectronIsEMSelector(myname.c_str());
40
41 declareProperty("WorkingPoint", m_WorkingPoint = "", "The Working Point");
42 declareProperty("ConfigFile",
43 m_configFile = "",
44 "The config file to use (if not setting cuts one by one)");
45 declareProperty(
46 "usePVContainer", m_usePVCont = true, "Whether to use the PV container");
47 declareProperty(
48 "nPVdefault", m_nPVdefault = 0, "The default number of PVs if not counted");
49
50 // Name of the quality to use
51 declareProperty(
52 "isEMMask",
53 m_rootForwardTool->m_isEMMask =
54 egammaPID::EgPidUndefined, // All pass by default, if not specified
55 "The mask to use");
56 // Eta binning
57 declareProperty("CutBinEta_ForwardElectron",
58 m_rootForwardTool->m_cutBinEta_ForwardElectron,
59 "Eta binning");
60 // NPV binning
61 declareProperty("CutVxp_ForwardElectron",
62 m_rootForwardTool->m_cutVxp_ForwardElectron,
63 "nvtx binning");
64 // Cut on lateral shower shape
65 declareProperty("CutLATERAL_ForwardElectron",
66 m_rootForwardTool->m_cutLATERAL_ForwardElectron,
67 "Cut on lateral shower shape in 2nd sampling");
68 // Cut on secondLambda
69 declareProperty("CutSECONDLAMBDA_ForwardElectron",
70 m_rootForwardTool->m_cutSECONDLAMBDA_ForwardElectron,
71 "Cut on secondLambda");
72 // Cut on longitudinal
73 declareProperty("CutLONGITUDINAL_ForwardElectron",
74 m_rootForwardTool->m_cutLONGITUDINAL_ForwardElectron,
75 "Cut on longitudinal");
76 // Cut on fracMax
77 declareProperty("CutCELLMAXFRAC_ForwardElectron",
78 m_rootForwardTool->m_cutCELLMAXFRAC_ForwardElectron,
79 "Cut on fracMax");
80 // Cut on centerlambda
81 declareProperty("CutCENTERLAMBDA_ForwardElectron",
82 m_rootForwardTool->m_cutCENTERLAMBDA_ForwardElectron,
83 "Cut on centerlambda");
84 // Cut on secondR
85 declareProperty("CutSECONDR_ForwardElectron",
86 m_rootForwardTool->m_cutSECONDR_ForwardElectron,
87 "Cut on secondR)");
88}
89
90//=============================================================================
91// Standard destructor
92//=============================================================================
97
98StatusCode
100{
101 // The standard status code
102 StatusCode sc = StatusCode::SUCCESS;
103
104 if (!m_WorkingPoint.empty()) {
107 }
108
109 if (!m_configFile.empty()) {
110 // find the file and read it in
111 std::string filename = PathResolverFindCalibFile(m_configFile);
112 if (filename.empty()) {
113 ATH_MSG_ERROR("Could not locate " << m_configFile);
114 sc = StatusCode::FAILURE;
115 return sc;
116 }
117 ATH_MSG_DEBUG("Configfile to use " << m_configFile);
118 TEnv env;
119 env.ReadFile(filename.c_str(), kEnvLocal);
120
122
123 // Override the mask via the config only if it is not set
124 if (m_rootForwardTool->m_isEMMask == egammaPID::EgPidUndefined) {
125 unsigned int mask(
126 env.GetValue("isEMMask", static_cast<int>(egammaPID::EgPidUndefined)));
127 m_rootForwardTool->m_isEMMask = mask;
128 }
129 //
130 ATH_MSG_DEBUG("Read in the TEnv config ");
132 m_rootForwardTool->m_cutBinEta_ForwardElectron =
133 AsgConfigHelper::HelperFloat("CutBinEta_ForwardElectron", env);
134 m_rootForwardTool->m_cutVxp_ForwardElectron =
135 AsgConfigHelper::HelperFloat("CutVxp_ForwardElectron", env);
136 m_rootForwardTool->m_cutSECONDLAMBDA_ForwardElectron =
137 AsgConfigHelper::HelperFloat("CutSECONDLAMBDA_ForwardElectron", env);
138 m_rootForwardTool->m_cutLATERAL_ForwardElectron =
139 AsgConfigHelper::HelperFloat("CutLATERAL_ForwardElectron", env);
140 m_rootForwardTool->m_cutLONGITUDINAL_ForwardElectron =
141 AsgConfigHelper::HelperFloat("CutLONGITUDINAL_ForwardElectron", env);
142 m_rootForwardTool->m_cutCELLMAXFRAC_ForwardElectron =
143 AsgConfigHelper::HelperFloat("CutCELLMAXFRAC_ForwardElectron", env);
144 m_rootForwardTool->m_cutCENTERLAMBDA_ForwardElectron =
145 AsgConfigHelper::HelperFloat("CutCENTERLAMBDA_ForwardElectron", env);
146 m_rootForwardTool->m_cutSECONDR_ForwardElectron =
147 AsgConfigHelper::HelperFloat("CutSECONDR_ForwardElectron", env);
148 } else {
149 ATH_MSG_INFO("Conf file empty. Just user Input");
150 }
151
153
154 ATH_MSG_INFO("operating point : " << this->getOperatingPointName()
155 << " with mask: "
156 << m_rootForwardTool->m_isEMMask);
157
158 // Get the message level and set the underlying ROOT tool message level
159 // accordingly
160 m_rootForwardTool->msg().setLevel(this->msg().level());
161 // We need to initialize the underlying ROOT TSelectorTool
162 if (m_rootForwardTool->initialize().isFailure()) {
163 ATH_MSG_ERROR("Could not initialize the TForwardElectronIsEMSelector!");
164 sc = StatusCode::FAILURE;
165 return sc;
166 }
167
168 return sc;
169}
170
171//=============================================================================
172// return the accept info object
173//=============================================================================
174
175const asg::AcceptInfo&
177{
178 return m_rootForwardTool->getAcceptInfo();
179}
180
181//=============================================================================
182// The main accept method: the actual cuts are applied here
183//=============================================================================
186{
187 return accept(Gaudi::Hive::currentContext(), part);
188}
189
192 const xAOD::IParticle* part) const
193{
194
195 ATH_MSG_DEBUG("Entering accept( const IParticle* part )");
196 if (part->type() == xAOD::Type::Electron ||
197 part->type() == xAOD::Type::Photon) {
198 return accept(ctx, static_cast<const xAOD::Egamma*>(part));
199 }
200
201 ATH_MSG_ERROR("AsgForwardElectronIsEMSelector::could not convert argument to "
202 "Electron/Photon");
203 return m_rootForwardTool->accept();
204}
205
208 const xAOD::Egamma* eg) const
209{
210
211 ATH_MSG_DEBUG("Entering accept( const Egamma* part )");
212 if (eg) {
213 unsigned int isEM = ~0;
214 StatusCode sc = execute(ctx, eg, isEM);
215 if (sc.isFailure()) {
216 ATH_MSG_ERROR("could not calculate isEM");
217 return m_rootForwardTool->accept();
218 }
219 return m_rootForwardTool->fillAccept(isEM);
220 }
221
223 "AsgForwardElectronIsEMSelector::accept was given a bad argument");
224 return m_rootForwardTool->accept();
225}
226
229 const xAOD::Electron* el) const
230{
232 "Entering accept( const EventContext& ctx, const Electron* part )");
233 return accept(ctx, static_cast<const xAOD::Egamma*>(el));
234}
235
238 const xAOD::Photon* ph) const
239{
241 "Entering accept( const EventContext& ctx, const Photon* part )");
242 return accept(ctx, static_cast<const xAOD::Egamma*>(ph));
243}
244
245//=============================================================================
247//=============================================================================
248std::string
250{
251
253 return "Forw Id";
254 }
255
256 ATH_MSG_INFO("Didn't recognize the given operating point with mask: "
257 << m_rootForwardTool->m_isEMMask);
258 return "";
259}
260
262StatusCode
264 const xAOD::Egamma* eg,
265 unsigned int& isEM) const
266{
267 //
268 // Particle identification for electrons based on cuts
269 //
270 ATH_MSG_DEBUG("entering execute(const Egamma* eg...)");
271 // initialisation
272 isEM = 0;
273 // protection against null pointer
274 if (eg == nullptr) {
275 // if object is bad then use the bit for "bad eta"
276 ATH_MSG_DEBUG("exiting because el is NULL");
277 isEM = (0x1 << egammaPID::BinEta_ForwardElectron);
278 return StatusCode::SUCCESS;
279 }
280
281 // retrieve associated cluster
282 const xAOD::CaloCluster* cluster = eg->caloCluster();
283 if (cluster == nullptr) {
284 // if object is bad then use the bit for "bad eta"
285 ATH_MSG_DEBUG("exiting because cluster is NULL");
286 isEM = (0x1 << egammaPID::BinEta_ForwardElectron);
287 return StatusCode::SUCCESS;
288 }
289
290 float nvtx =
291 static_cast<int>(m_usePVCont ? this->getNPrimVertices(ctx) : m_nPVdefault);
292 // This default value is only useful for candidates in EMEC inner wheel
293 // but is useless anyway
294 float eta = std::abs(cluster->etaBE(2));
295
296 // see if we have an electron, with track, for eta
297 const xAOD::Electron* el = nullptr;
298 if (eg->type() == xAOD::Type::Electron) {
299 el = static_cast<const xAOD::Electron*>(eg);
300 }
301
302 // el should always be there. So this is always OK
303 // but in Run4, this can be track eta if there is a match.
304 // So for the time being, use cluster eta since fwd isEM (very very old from 2015)
305 // is determined from cluster eta and |eta| > 2.5
306 if (el) {
307 eta = std::max(2.5,std::abs(cluster->eta()));
308 }
309 // Call the calocuts using the egamma object
310 isEM = calocuts_electrons(eg, eta, nvtx, 0);
311
312 return StatusCode::SUCCESS;
313}
314
315// ======================================================================
316//
317unsigned int
319 float eta,
320 float nvtx,
321 unsigned int iflag) const
322{
323
324 // apply cut-based selection based on calo information
325 // eg : xAOD::Electron object
326 // trigETthr : threshold in ET to apply the cuts at trigger level
327 // iflag: the starting isEM
328 //
329 const xAOD::CaloCluster* cluster2 = eg->caloCluster();
330 double secondLambda(0);
331 double lateral(0);
332 double longitudinal(0);
333 double fracMax(0);
334 double centerLambda(0);
335 double secondR(0);
336
337 bool allFound = true;
338
339 // secondLambda
340 allFound = allFound && cluster2->retrieveMoment(
342 // lateral
343 allFound =
344 allFound && cluster2->retrieveMoment(xAOD::CaloCluster::LATERAL, lateral);
345 // longitudinal
346 allFound = allFound && cluster2->retrieveMoment(
347 xAOD::CaloCluster::LONGITUDINAL, longitudinal);
348 // fracMax
349 allFound = allFound &&
351 // secondR
352 allFound =
353 allFound && cluster2->retrieveMoment(xAOD::CaloCluster::SECOND_R, secondR);
354 // centerlambda
355 allFound = allFound && cluster2->retrieveMoment(
357
358 if (!allFound) {
359 // if object is bad then use the bit for "bad eta"
360 ATH_MSG_WARNING("Have some variables missing.");
361 iflag = (0x1 << egammaPID::BinEta_ForwardElectron);
362 return iflag;
363 }
364
365 return m_rootForwardTool->calocuts_electrons(eta,
366 nvtx,
367 secondLambda,
368 lateral,
369 longitudinal,
370 fracMax,
371 centerLambda,
372 secondR,
373 iflag);
374}
375
376//=============================================================================
381unsigned int
383{
384 unsigned int nVtx(0);
386 if (!vtxCont.isValid()) {
387 return nVtx;
388 }
389 for (const auto *vtxcand : *vtxCont) {
390 if (vtxcand->nTrackParticles() >= 3)
391 nVtx++;
392 }
393 return nVtx;
394}
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
static Double_t sc
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
unsigned int calocuts_electrons(const xAOD::Egamma *eg, float eta2, float nvtx, unsigned int iflag) const
virtual asg::AcceptData accept(const xAOD::IParticle *part) const override final
Accept with generic interface.
SG::ReadHandleKey< xAOD::VertexContainer > m_primVtxContKey
read handle key to primary vertex container
bool m_usePVCont
Whether to use the PV (not available for trigger)
virtual StatusCode execute(const EventContext &ctx, const xAOD::Egamma *eg, unsigned int &isEM) const override final
==========================================================================================//
virtual StatusCode initialize() override final
Gaudi Service Interface method implementations.
Root::TForwardElectronIsEMSelector * m_rootForwardTool
Pointer to the underlying ROOT based tool.
virtual std::string getOperatingPointName() const override final
Method to get the operating point.
virtual ASG_TOOL_CLASS3(AsgForwardElectronIsEMSelector, IAsgForwardElectronIsEMSelector, IAsgEGammaIsEMSelector, IAsgSelectionTool) public ~AsgForwardElectronIsEMSelector()
Standard constructor.
unsigned int getNPrimVertices(const EventContext &ctx) const
( This is horrible!
virtual const asg::AcceptInfo & getAcceptInfo() const override final
Method to get the plain AcceptInfo.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
virtual double eta() const
The pseudorapidity ( ) of the particle.
@ SECOND_LAMBDA
Second Moment in .
@ LATERAL
Normalized lateral moment.
@ LONGITUDINAL
Normalized longitudinal moment.
@ ENG_FRAC_MAX
Energy fraction of hottest cell.
@ SECOND_R
Second Moment in .
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
Class providing the definition of the 4-vector interface.
std::string findConfigFile(const std::string &input, const std::map< std::string, std::string > &configmap)
std::vector< float > HelperFloat(const std::string &input, TEnv &env)
const std::map< std::string, std::string > ForwardElectronCutPointToConfFile
@ BinEta_ForwardElectron
cluster eta range
const unsigned int ID_ForwardElectron
cuts on all variables
const unsigned int EgPidUndefined
@ Photon
The object is a photon.
Definition ObjectType.h:47
@ Electron
The object is an electron.
Definition ObjectType.h:46
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
Photon_v1 Photon
Definition of the current "egamma version".
Electron_v1 Electron
Definition of the current "egamma version".
MsgStream & msg
Definition testRead.cxx:32