ATLAS Offline Software
EgammaTrackParticleThinning.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // EgammaTrackParticleThinning.cxx, (c) ATLAS Detector software
8 // Author: James Catmore (James.Catmore@cern.ch)
9 
15 
16 namespace {
18  "originalTrackParticle");
19 }
20 
21 // Constructor
23  const std::string& t,
24  const std::string& n,
25  const IInterface* p)
26  : base_class(t, n, p)
27 {}
28 
29 // Destructor
31 = default;
32 
33 // Athena initialize and finalize
36 {
37  // Decide which collections need to be checked for ID TrackParticles
38  ATH_CHECK(m_egammaKey.initialize());
39 
40  ATH_CHECK(m_gsfSGKey.initialize(m_streamName));
41  ATH_MSG_INFO("Using " << m_gsfSGKey.key()
42  << " as the source collection for GSF track particles");
43  ATH_MSG_INFO((m_bestMatchOnly ? "Best match " : "ALL ")
44  << "GSF track particles associated with objects in "
45  << m_egammaKey.key() << '\n'
46  << " will be marked as kept true in the ThinningHandle "
47  << "otherwise as kept false");
48 
49  ATH_CHECK(m_inDetSGKey.initialize(m_streamName, !m_inDetSGKey.empty()));
50  if (!m_inDetSGKey.empty()) {
52  "Using "
53  << m_inDetSGKey.key()
54  << " as the source collection for inner detector track particles");
55 
56  ATH_MSG_INFO("Inner detector track particles refitted to produce"
57  << m_gsfSGKey.key() << '\n'
58  << " will be retained when the corresponding "
59  << m_gsfSGKey.key() << " track particle will be retained");
60  if (m_coneSize > 0) {
62  "Inner detector track particles in a cone dr "
63  << m_coneSize << " around the " << m_egammaKey.key() << '\n'
64  << " obects will be marked as kept true in the ThinningHandle "
65  << "otherwise as kept false");
66  }
67  }
68 
69  ATH_CHECK(m_gsfVtxSGKey.initialize(m_streamName, !m_gsfVtxSGKey.empty()));
70  if (!m_gsfVtxSGKey.empty()) {
71  ATH_MSG_INFO("Using " << m_gsfVtxSGKey.key()
72  << " as the source collection for GSF conversion vertices");
73  ATH_MSG_INFO((m_bestVtxMatchOnly ? "Best match " : "ALL ")
74  << " GSF conversion vertices will be kept");
75  }
76 
77  // Set up the text-parsing machinery for selectiong the objects directly
78  // according to user cuts
79  if (!m_selectionString.empty()) {
80  ATH_CHECK(initializeParser(m_selectionString));
81  }
82 
83  return StatusCode::SUCCESS;
84 }
85 
88 {
89  ATH_MSG_INFO("Selected " << m_nSelEgammas <<" out of " << m_nEgammas
90  << " objects from " << m_egammaKey.key());
91  ATH_MSG_INFO("Kept " << m_nGSFPass << " out of " << m_ntotGSF
92  << " objects from " << m_gsfSGKey.key());
93  if (!m_gsfVtxSGKey.empty()) {
94  ATH_MSG_INFO("Kept " << m_nGSFVtxPass << " out of " << m_ntotGSFVtx
95  << " vertices from " << m_gsfVtxSGKey.key());
96  }
97  if (!m_inDetSGKey.empty()) {
98  ATH_MSG_INFO("Kept " << m_npass << "out of " << m_ntot << " objects from "
99  << m_inDetSGKey.key());
100  }
101 
102  ATH_CHECK(finalizeParser());
103  return StatusCode::SUCCESS;
104 }
105 
106 // The thinning itself
109 {
110  const EventContext& ctx = Gaudi::Hive::currentContext();
111  SG::ThinningHandle<xAOD::TrackParticleContainer> importedGSFTrackParticles(
112  m_gsfSGKey, ctx);
113 
114  // Allow for not input Indet Track Particle collection
115  std::unique_ptr<SG::ThinningHandle<xAOD::TrackParticleContainer>>
116  importedTrackParticles = nullptr;
117  if (!m_inDetSGKey.empty()) {
118  importedTrackParticles =
119  std::make_unique<SG::ThinningHandle<xAOD::TrackParticleContainer>>(
120  m_inDetSGKey, ctx);
121  }
122 
123  // Check the event contains tracks
124  const xAOD::TrackParticleContainer* tps = (importedTrackParticles != nullptr)
125  ? importedTrackParticles->cptr()
126  : nullptr;
127  const xAOD::TrackParticleContainer* gsfs = importedGSFTrackParticles.cptr();
128  unsigned int nTracks = tps ? tps->size() : 0;
129  unsigned int nGSF = gsfs->size();
130 
131  ATH_MSG_DEBUG("nTracks : " << nTracks << " , nGSF : " << nGSF);
132  if (nTracks == 0 && nGSF == 0) {
133  ATH_MSG_DEBUG("Nothing to thin");
134  return StatusCode::SUCCESS;
135  }
136 
137  // Set up a mask with the same entries as the full TrackParticle collection(s)
138  std::vector<bool> mask, gsfMask;
139  mask.assign(nTracks, false); // default: don't keep any tracks
140  gsfMask.assign(nGSF, false);
141  m_ntot += nTracks;
142  m_ntotGSF += nGSF;
143 
144  // Retrieve e-gamma container
145  SG::ReadHandle<xAOD::EgammaContainer> importedEgamma(m_egammaKey, ctx);
146  if (!importedEgamma.isValid()) {
147  ATH_MSG_ERROR("No e-gamma collection with name " << m_egammaKey.key()
148  << " found in StoreGate!");
149  return StatusCode::FAILURE;
150  }
151 
152  size_t nEgammas(importedEgamma->size());
153  ATH_MSG_DEBUG("nEgammas : " << nEgammas);
154  m_nEgammas += nEgammas;
155  bool doSelect = !m_selectionString.empty();
156  if (nEgammas != 0) {
158  // Execute the text parsers if requested
159  if (doSelect) {
160  std::vector<int> entries = m_parser->evaluateAsVector();
161  unsigned int nEntries = entries.size();
162  // check the sizes are compatible
163  if (nEgammas != nEntries) {
164  ATH_MSG_ERROR("Sizes incompatible! Are you sure your selection string "
165  "used e-gamma objects??");
166  return StatusCode::FAILURE;
167  } else {
168  // identify which e-gammas to keep for the thinning check
169  for (unsigned int i = 0; i < nEgammas; ++i)
170  if (entries[i] == 1)
171  tofill.push_back(importedEgamma->at(i));
172  }
173  } // end of selection
174  const xAOD::EgammaContainer* egToCheck = doSelect
175  ? tofill.asDataVector() : importedEgamma.cptr();
176  ATH_MSG_DEBUG("Setting the masks");
177  m_nSelEgammas += egToCheck->size();
178  // Are we dealing with electrons or photons?
179  if (dynamic_cast<const xAOD::ElectronContainer*>(importedEgamma.cptr()) != nullptr)
180  setElectronMasks(mask, gsfMask, egToCheck, tps, gsfs);
181  else if (dynamic_cast<const xAOD::PhotonContainer*>(importedEgamma.cptr()) != nullptr)
182  setPhotonMasks(mask, gsfMask, egToCheck, tps, gsfs);
183  else
184  ATH_MSG_WARNING("Input container is neither for Electrons, "
185  "nor for Photons ??");
186  }//end of if nEgammas != 0
187  else if (!m_gsfVtxSGKey.empty()) {
188  clearGSFVtx(ctx);
189  }
190 
191  // Count up the mask contents
192  unsigned int n_pass = 0;
193  for (unsigned int i = 0; i < nTracks; ++i) {
194  if (mask[i]) {
195  ++n_pass;
196  }
197  }
198  m_npass += n_pass;
199  unsigned int n_gsf_pass = 0;
200  for (unsigned int i = 0; i < nGSF; ++i) {
201  if (gsfMask[i]) {
202  ++n_gsf_pass;
203  }
204  }
205  m_nGSFPass += n_gsf_pass;
206 
207  // Execute the thinning service based on the mask. Finish.
208  importedGSFTrackParticles.keep(gsfMask);
209  if (tps) {
210  importedTrackParticles->keep(mask);
211  }
212 
213  return StatusCode::SUCCESS;
214 }
215 
217  const EventContext& ctx) const
218 {
219  SG::ThinningHandle<xAOD::VertexContainer> importedGSFConversionVtx(
220  m_gsfVtxSGKey, ctx);
221  const xAOD::VertexContainer* gsfVtxs = importedGSFConversionVtx.cptr();
222  unsigned int nGSFVtx = gsfVtxs->size();
223  if (nGSFVtx == 0) {
224  ATH_MSG_DEBUG("No conversion vertex to thin");
225  return;
226  }
227  std::vector<bool> gsfVtxMask(nGSFVtx,false);
228  m_ntotGSFVtx += nGSFVtx;
229  ATH_MSG_DEBUG("nGSFVtx : " << nGSFVtx);
230  importedGSFConversionVtx.keep(gsfVtxMask);
231 }
232 
233 void
235  std::vector<bool>& mask,
236  std::vector<bool>& gsfMask,
237  const xAOD::EgammaContainer* egammas,
238  const xAOD::TrackParticleContainer* tps,
239  const xAOD::TrackParticleContainer* gsfs) const
240 {
241  if (m_gsfVtxSGKey.empty()) {
242  ATH_MSG_ERROR("Thinning track particles/vertices associated to photons"
243  "but no conversion vertex key provided");
244  return;
245  }
246 
247  SG::ThinningHandle<xAOD::VertexContainer> importedGSFConversionVtx(
248  m_gsfVtxSGKey, Gaudi::Hive::currentContext());
249  const xAOD::VertexContainer* gsfVtxs = importedGSFConversionVtx.cptr();
250  unsigned int nGSFVtx = gsfVtxs->size(), n_gsfVtx_pass = 0;
251  std::vector<bool> gsfVtxMask(nGSFVtx,false);
252  m_ntotGSFVtx += nGSFVtx;
253  ATH_MSG_DEBUG("nGSFVtx : " << nGSFVtx);
254 
256  for (const auto* egamma : *egammas) {
257  const xAOD::Photon* photon = egamma->type() == xAOD::Type::Photon
258  ? static_cast<const xAOD::Photon*>(egamma)
259  : nullptr;
260  if (!photon) {
261  ATH_MSG_ERROR("Did not get a photon object in "
262  "EgammaTrackParticleThinning::setPhotonMasks");
263  return;
264  }
265  if (tps && m_coneSize > 0.0) {
266  trIC.select(photon, m_coneSize, tps, mask);
267  } // check InDet tracks in a cone around the e-gammas
268 
269  std::vector<ElementLink<xAOD::VertexContainer>> vertexLinks =
270  photon->vertexLinks();
271  unsigned int nLinks = vertexLinks.size();
272  if (nLinks == 0) {
273  continue;
274  }
275  if (!m_bestVtxMatchOnly) {
276  for (unsigned int i = 0; i < nLinks; ++i) {
277  if (!(vertexLinks[i])) {
278  continue;
279  }
280  if (!(vertexLinks[i]).isValid()) {
281  continue;
282  }
283  gsfVtxMask[vertexLinks[i].index()] = true;
284  }
285  }
286  if (m_bestMatchOnly) {
287  nLinks = 1;
288  }
289  for (unsigned int i = 0; i < nLinks; ++i) {
290  if (!(vertexLinks[i]).isValid()) {
291  continue;
292  }
293  gsfVtxMask[vertexLinks[i].index()] = true;
294  const xAOD::Vertex* vx = *(vertexLinks[i]);
295  if (!vx) {
296  continue;
297  }
299  for (const auto& link : trackParticleLinks) {
300  if (!link.isValid()) {
301  continue;
302  }
303  gsfMask[link.index()] = true;
304  if (tps) {
305  const ElementLink<xAOD::TrackParticleContainer>& origTrackLink =
306  orig(*((*gsfs)[link.index()]));
307  if (origTrackLink.isValid()) {
308  int inDetIndex = origTrackLink.index();
309  mask[inDetIndex] = true;
310  }
311  }
312  }
313  }
314  }
315  importedGSFConversionVtx.keep(gsfVtxMask);
316  for (bool b : gsfVtxMask) {
317  if (b)
318  ++n_gsfVtx_pass;
319  }
320  m_nGSFVtxPass += n_gsfVtx_pass;
321 }
322 
323 void
325  std::vector<bool>& mask,
326  std::vector<bool>& gsfMask,
327  const xAOD::EgammaContainer* egammas,
328  const xAOD::TrackParticleContainer* tps,
329  const xAOD::TrackParticleContainer* gsfs) const
330 {
332  for (const auto *egamma : *egammas) {
333  const xAOD::Electron* electron =
334  egamma->type() == xAOD::Type::Electron
335  ? static_cast<const xAOD::Electron*>(egamma)
336  : nullptr;
337 
338  if (!electron) {
339  ATH_MSG_ERROR("Did not get an electron object in "
340  "EgammaTrackParticleThinning::setElectronMasks");
341  return;
342  }
343  if (tps && m_coneSize > 0.0)
344  trIC.select(electron,
345  m_coneSize,
346  tps,
347  mask); // check InDet tracks in a cone around the e-gammas
348 
349  unsigned int nGSFLinks = m_bestMatchOnly ? 1 : electron->nTrackParticles();
350  for (unsigned int i = 0; i < nGSFLinks; ++i) {
351  if (!(electron->trackParticleLink(i).isValid())) {
352  continue;
353  }
354  int gsfIndex = electron->trackParticleLink(i).index();
355  gsfMask[gsfIndex] = true;
356  if (tps) {
357  const ElementLink<xAOD::TrackParticleContainer>& origTrackLink =
358  orig(*((*gsfs)[gsfIndex]));
359  if (origTrackLink.isValid()) {
360  int inDetIndex = origTrackLink.index();
361  mask[inDetIndex] = true;
362  }
363  }
364  }
365  }
366 }
367 
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
ThinningHandle.h
Handle for requesting thinning for a data object.
ConstDataVector.h
DataVector adapter that acts like it holds const pointers.
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
xAOD::Vertex_v1::trackParticleLinks
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
DerivationFramework::EgammaTrackParticleThinning::finalize
virtual StatusCode finalize() override
Definition: EgammaTrackParticleThinning.cxx:87
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
isValid
bool isValid(const T &p)
Definition: AtlasPID.h:214
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
SG::ThinningHandle
Handle for requesting thinning for a data object.
Definition: ThinningHandle.h:84
ConstDataVector::asDataVector
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
egamma
Definition: egamma.h:58
DerivationFramework::EgammaTrackParticleThinning::clearGSFVtx
void clearGSFVtx(const EventContext &ctx) const
Definition: EgammaTrackParticleThinning.cxx:216
DerivationFramework::EgammaTrackParticleThinning::setPhotonMasks
void setPhotonMasks(std::vector< bool > &, std::vector< bool > &, const xAOD::EgammaContainer *, const xAOD::TrackParticleContainer *, const xAOD::TrackParticleContainer *) const
Definition: EgammaTrackParticleThinning.cxx:234
SG::ThinningHandleBase::keep
void keep(size_t ndx)
Mark that index ndx in the container should be kept (not thinned away).
Definition: ThinningHandleBase.cxx:68
EgammaTrackParticleThinning.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
DerivationFramework::EgammaTrackParticleThinning::~EgammaTrackParticleThinning
virtual ~EgammaTrackParticleThinning()
ElectronContainer.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
DerivationFramework::EgammaTrackParticleThinning::doThinning
virtual StatusCode doThinning() const override
Definition: EgammaTrackParticleThinning.cxx:108
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::TauHelpers::trackParticleLinks
std::vector< ElementLink< xAOD::TrackParticleContainer > > trackParticleLinks(const xAOD::TauJet *tau, xAOD::TauJetParameters::TauTrackFlag flag=xAOD::TauJetParameters::TauTrackFlag::classifiedCharged)
Definition: TauxAODHelpers.cxx:22
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DataVector< xAOD::TrackParticle_v1 >
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
DerivationFramework::EgammaTrackParticleThinning::initialize
virtual StatusCode initialize() override
Definition: EgammaTrackParticleThinning.cxx:35
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
ConstDataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
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
DerivationFramework::EgammaTrackParticleThinning::setElectronMasks
void setElectronMasks(std::vector< bool > &, std::vector< bool > &, const xAOD::EgammaContainer *, const xAOD::TrackParticleContainer *, const xAOD::TrackParticleContainer *) const
Definition: EgammaTrackParticleThinning.cxx:324
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
xAOD::Photon_v1
Definition: Photon_v1.h:37
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
ConstDataVector
DataVector adapter that acts like it holds const pointers.
Definition: ConstDataVector.h:76
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
entries
double entries
Definition: listroot.cxx:49
DerivationFramework::TracksInCone
Definition: TracksInCone.h:19
DerivationFramework::TracksInCone::select
void select(const xAOD::IParticle *particle, float coneSize, const xAOD::TrackParticleContainer *tracks, std::vector< bool > &mask)
Definition: TracksInCone.h:21
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
dqBeamSpot.nEntries
int nEntries
Definition: dqBeamSpot.py:73
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
PhotonContainer.h
DerivationFramework::EgammaTrackParticleThinning::EgammaTrackParticleThinning
EgammaTrackParticleThinning(const std::string &t, const std::string &n, const IInterface *p)
Definition: EgammaTrackParticleThinning.cxx:22