ATLAS Offline Software
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 //=============================================================================
33 AsgForwardElectronIsEMSelector::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 //=============================================================================
94 {
95  delete m_rootForwardTool;
96 }
97 
100 {
101  // The standard status code
102  StatusCode sc = StatusCode::SUCCESS;
103 
104  if (!m_WorkingPoint.empty()) {
105  m_configFile = AsgConfigHelper::findConfigFile(
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 
152  ATH_CHECK(m_primVtxContKey.initialize(m_usePVCont));
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 
175 const 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 //=============================================================================
248 std::string
250 {
251 
252  if (m_rootForwardTool->m_isEMMask == egammaPID::ID_ForwardElectron) {
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 
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 //
317 unsigned 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(
341  xAOD::CaloCluster::SECOND_LAMBDA, secondLambda);
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(
356  xAOD::CaloCluster::CENTER_LAMBDA, centerLambda);
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 //=============================================================================
381 unsigned int
383 {
384  unsigned int nVtx(0);
385  SG::ReadHandle<xAOD::VertexContainer> vtxCont(m_primVtxContKey, ctx);
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 }
xAOD::CaloCluster_v1::SECOND_R
@ SECOND_R
Second Moment in .
Definition: CaloCluster_v1.h:123
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
AsgForwardElectronIsEMSelector::~AsgForwardElectronIsEMSelector
virtual ASG_TOOL_CLASS3(AsgForwardElectronIsEMSelector, IAsgForwardElectronIsEMSelector, IAsgEGammaIsEMSelector, IAsgSelectionTool) public ~AsgForwardElectronIsEMSelector()
Standard constructor.
Definition: AsgForwardElectronIsEMSelector.cxx:93
AsgForwardElectronIsEMSelector::execute
virtual StatusCode execute(const EventContext &ctx, const xAOD::Egamma *eg, unsigned int &isEM) const override final
==========================================================================================//
Definition: AsgForwardElectronIsEMSelector.cxx:263
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ParticleTest.eg
eg
Definition: ParticleTest.py:29
egammaPID::BinEta_ForwardElectron
@ BinEta_ForwardElectron
cluster eta range
Definition: egammaPIDdefs.h:618
CurrentContext.h
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
AsgForwardElectronIsEMSelector.h
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
xAOD::CaloCluster_v1::CENTER_LAMBDA
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
Definition: CaloCluster_v1.h:136
AsgEGammaConfigHelper.h
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
xAOD::CaloCluster_v1::ENG_FRAC_MAX
@ ENG_FRAC_MAX
Energy fraction of hottest cell.
Definition: CaloCluster_v1.h:140
AsgForwardElectronIsEMSelector::initialize
virtual StatusCode initialize() override final
Gaudi Service Interface method implementations.
Definition: AsgForwardElectronIsEMSelector.cxx:99
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
egammaPID::EgPidUndefined
const unsigned int EgPidUndefined
Definition: egammaPIDdefs.h:90
xAOD::CaloCluster_v1::SECOND_LAMBDA
@ SECOND_LAMBDA
Second Moment in .
Definition: CaloCluster_v1.h:124
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
xAOD::CaloCluster_v1::etaBE
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:644
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
asg::AcceptInfo
Definition: AcceptInfo.h:28
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
CaloCluster.h
Photon.h
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
Root::TForwardElectronIsEMSelector
Definition: TForwardElectronIsEMSelector.h:34
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::CaloCluster_v1::retrieveMoment
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
Definition: CaloCluster_v1.cxx:738
TForwardElectronIsEMSelector.h
AsgForwardElectronIsEMSelector::getNPrimVertices
unsigned int getNPrimVertices(const EventContext &ctx) const
( This is horrible! We don't want to iterate over all vertices in the event for each electron!...
Definition: AsgForwardElectronIsEMSelector.cxx:382
Vertex.h
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
PathResolver.h
AsgForwardElectronIsEMSelector::getOperatingPointName
virtual std::string getOperatingPointName() const override final
Method to get the operating point.
Definition: AsgForwardElectronIsEMSelector.cxx:249
ReadHandle.h
Handle class for reading from StoreGate.
xAOD::Electron_v1
Definition: Electron_v1.h:34
xAOD::Photon
Photon_v1 Photon
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Photon.h:17
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
AsgForwardElectronIsEMSelector::getAcceptInfo
virtual const asg::AcceptInfo & getAcceptInfo() const override final
Method to get the plain AcceptInfo.
Definition: AsgForwardElectronIsEMSelector.cxx:176
EGSelectorConfigurationMapping.h
xAOD::Photon_v1
Definition: Photon_v1.h:37
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
egammaPID::ID_ForwardElectron
const unsigned int ID_ForwardElectron
cuts on all variables
Definition: egammaPIDdefs.h:638
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
xAOD::CaloCluster_v1::LATERAL
@ LATERAL
Normalized lateral moment.
Definition: CaloCluster_v1.h:137
Electron.h
AsgConfigHelper::HelperFloat
std::vector< float > HelperFloat(const std::string &input, TEnv &env)
Definition: AsgEGammaConfigHelper.cxx:110
python.DataFormatRates.env
env
Definition: DataFormatRates.py:32
asg::AcceptData
Definition: AcceptData.h:30
xAOD::CaloCluster_v1::LONGITUDINAL
@ LONGITUDINAL
Normalized longitudinal moment.
Definition: CaloCluster_v1.h:138
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
AsgForwardElectronIsEMSelector::calocuts_electrons
unsigned int calocuts_electrons(const xAOD::Egamma *eg, float eta2, float nvtx, unsigned int iflag) const
Definition: AsgForwardElectronIsEMSelector.cxx:318
AsgForwardElectronIsEMSelector::accept
virtual asg::AcceptData accept(const xAOD::IParticle *part) const override final
Accept with generic interface.
Definition: AsgForwardElectronIsEMSelector.cxx:185
EgammaSelectors::ForwardElectronCutPointToConfFile
const std::map< std::string, std::string > ForwardElectronCutPointToConfFile
Definition: EGSelectorConfigurationMapping.h:97
AsgConfigHelper::findConfigFile
std::string findConfigFile(const std::string &input, const std::map< std::string, std::string > &configmap)
Definition: AsgEGammaConfigHelper.cxx:14