ATLAS Offline Software
TrackParticleThinning.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // TrackParticleThinning.cxx, (c) ATLAS Detector software
8 // Author: James Catmore (James.Catmore@cern.ch)
9 // Removes all ID tracks which do not pass a user-defined cut
10 
16 #include "GaudiKernel/ThreadLocalContext.h"
17 #include <vector>
18 #include <string>
21 
22 // Constructor
24  const std::string& n,
25  const IInterface* p ) :
26 base_class(t,n,p),
27 m_selectionString(""),
28 m_ntot(0),
29 m_npass(0),
30 m_ntot_pix_states(0),
31 m_npass_pix_states(0),
32 m_ntot_pix_measurements(0),
33 m_npass_pix_measurements(0),
34 m_ntot_sct_states(0),
35 m_npass_sct_states(0),
36 m_ntot_sct_measurements(0),
37 m_npass_sct_measurements(0),
38 m_ntot_trt_states(0),
39 m_npass_trt_states(0),
40 m_ntot_trt_measurements(0),
41 m_npass_trt_measurements(0),
42 m_thinHitsOnTrack(false)
43 {
44  // logic and selection settings
45  declareProperty("SelectionString", m_selectionString);
46  declareProperty("ThinHitsOnTrack", m_thinHitsOnTrack);
47 }
48 
49 // Destructor
51 
52 // Athena initialize and finalize
54 {
55  ATH_MSG_VERBOSE("initialize() ...");
56  if (m_selectionString.empty()) {
57  ATH_MSG_FATAL("No inner detector track selection string provided!");
58  return StatusCode::FAILURE;
59  } else {ATH_MSG_INFO("Track thinning selection string: " << m_selectionString);}
60 
61  // Set up the text-parsing machinery for thinning the tracks directly according to user cuts
62  if (!m_selectionString.empty()) {
63  ATH_CHECK(initializeParser(m_selectionString));
64  }
65 
66  //check xAOD::InDetTrackParticle collection
67  ATH_CHECK( m_inDetSGKey.initialize (m_streamName) );
68  ATH_MSG_INFO("Using " << m_inDetSGKey << "as the source collection for inner detector track particles");
69  //check availability of xAOD::TrackStateValidation and xAOD::TrackMeasurementValidation containers
70  if (m_thinHitsOnTrack) {
71  ATH_MSG_INFO("Pixel states collection as source for thinning: " << m_statesPixSGKey.key());
72  ATH_MSG_INFO("Pixel measurements collection as source for thinning: " << m_measurementsPixSGKey.key());
73  ATH_MSG_INFO("SCT states collection as source for thinning: " << m_statesSctSGKey.key());
74  ATH_MSG_INFO("SCT measurements collection as source for thinning: " << m_measurementsSctSGKey.key());
75  ATH_MSG_INFO("TRT states collection as source for thinning: " << m_statesTrtSGKey.key());
76  ATH_MSG_INFO("TRT measurements collection as source for thinning: " << m_measurementsTrtSGKey.key());
77  }
78  ATH_CHECK( m_statesPixSGKey.initialize (m_streamName, m_thinHitsOnTrack && !m_statesPixSGKey.empty()) );
79  ATH_CHECK( m_measurementsPixSGKey.initialize (m_streamName, m_thinHitsOnTrack && !m_measurementsPixSGKey.empty()) );
80  ATH_CHECK( m_statesSctSGKey.initialize (m_streamName, m_thinHitsOnTrack && !m_statesSctSGKey.empty()) );
81  ATH_CHECK( m_measurementsSctSGKey.initialize (m_streamName, m_thinHitsOnTrack && !m_measurementsSctSGKey.empty()) );
82  ATH_CHECK( m_statesTrtSGKey.initialize (m_streamName, m_thinHitsOnTrack && !m_statesTrtSGKey.empty()) );
83  ATH_CHECK( m_measurementsTrtSGKey.initialize (m_streamName, m_thinHitsOnTrack && !m_measurementsTrtSGKey.empty()) );
84 
85  ATH_CHECK(m_SCTDetEleCollKey.initialize( !m_SCTDetEleCollKey.key().empty() ));
86 
87  return StatusCode::SUCCESS;
88 }
89 
91 {
92  ATH_MSG_VERBOSE("finalize() ...");
93  ATH_MSG_INFO("Processed "<< m_ntot <<" tracks, "<< m_npass<< " were retained ");
94  if (m_thinHitsOnTrack) {
95  ATH_MSG_INFO("Pixel state objects thinning, Total / Passed (Efficiency): "
96  << m_ntot_pix_states << " / " << m_npass_pix_states
97  << " (" << (m_ntot_pix_states == 0 ? 0 : static_cast<float>(m_npass_pix_states) / m_ntot_pix_states) << ")");
98  ATH_MSG_INFO("Pixel measurements objects thinning, Total / Passed (Efficiency): "
99  << m_ntot_pix_measurements << " / " << m_npass_pix_measurements
100  << " (" << (m_ntot_pix_measurements == 0 ? 0 : static_cast<float>(m_npass_pix_measurements) / m_ntot_pix_measurements) << ")");
101  ATH_MSG_INFO("SCT state objects thinning, Total / Passed (Efficiency): "
102  << m_ntot_sct_states << " / " << m_npass_sct_states
103  << " (" << (m_ntot_sct_states == 0 ? 0 : static_cast<float>(m_npass_sct_states) / m_ntot_sct_states) << ")");
104  ATH_MSG_INFO("SCT measurements objects thinning, Total / Passed (Efficiency): "
105  << m_ntot_sct_measurements << " / " << m_npass_sct_measurements
106  << " (" << (m_ntot_sct_measurements == 0 ? 0 : static_cast<float>(m_npass_sct_measurements) / m_ntot_sct_measurements) << ")");
107  ATH_MSG_INFO("TRT state objects thinning, Total / Passed (Efficiency): "
108  << m_ntot_trt_states << " / " << m_npass_trt_states
109  << " (" << (m_ntot_trt_states == 0 ? 0 : static_cast<float>(m_npass_trt_states) / m_ntot_trt_states) << ")");
110  ATH_MSG_INFO("TRT measurements objects thinning, Total / Passed (Efficiency): "
111  << m_ntot_trt_measurements << " / " << m_npass_trt_measurements
112  << " (" << (m_ntot_trt_measurements == 0 ? 0 : static_cast<float>(m_npass_trt_measurements) / m_ntot_trt_measurements) << ")");
113  }
114  ATH_CHECK( finalizeParser() );
115  return StatusCode::SUCCESS;
116 }
117 
118 // The thinning itself
120 {
121  const EventContext& ctx = Gaudi::Hive::currentContext();
122 
123  // Retrieve main TrackParticle collection
125  (m_inDetSGKey, ctx);
126 
127  // Check the event contains tracks
128  unsigned int nTracks = importedTrackParticles->size();
129  if (nTracks==0) return StatusCode::SUCCESS;
130 
131  // Set up a mask with the same entries as the full TrackParticle collection
132  std::vector<bool> mask;
133  mask.assign(nTracks,false); // default: don't keep any tracks
134  m_ntot += nTracks;
135 
136  // Execute the text parser and update the mask
137  if (m_parser) {
138  std::vector<int> entries = m_parser->evaluateAsVector();
139  unsigned int nEntries = entries.size();
140  // check the sizes are compatible
141  if (nTracks != nEntries ) {
142  ATH_MSG_ERROR("Sizes incompatible! Are you sure your selection string used ID TrackParticles?");
143  return StatusCode::FAILURE;
144  } else {
145  // set mask
146  for (unsigned int i=0; i<nTracks; ++i) if (entries[i]==1) mask[i]=true;
147  }
148  }
149  // Count the mask
150  m_npass += std::count (mask.begin(), mask.end(), true);
151 
152  // Execute the thinning service based on the mask.
153  importedTrackParticles.keep (mask);
154 
155  //If thinning hits on track, look over States and Measurements collections as well
156  if (m_thinHitsOnTrack) {
157  filterTrackHits (ctx,
158  TrkState_Pixel,
159  *importedTrackParticles,
160  mask,
161  m_statesPixSGKey,
162  m_measurementsPixSGKey,
163  m_ntot_pix_states,
164  m_ntot_pix_measurements,
165  m_npass_pix_states,
166  m_npass_pix_measurements);
167  filterTrackHits (ctx,
168  TrkState_SCT,
169  *importedTrackParticles,
170  mask,
171  m_statesSctSGKey,
172  m_measurementsSctSGKey,
173  m_ntot_sct_states,
174  m_ntot_sct_measurements,
175  m_npass_sct_states,
176  m_npass_sct_measurements);
177  filterTrackHits (ctx,
178  TrkState_TRT,
179  *importedTrackParticles,
180  mask,
181  m_statesTrtSGKey,
182  m_measurementsTrtSGKey,
183  m_ntot_trt_states,
184  m_ntot_trt_measurements,
185  m_npass_trt_states,
186  m_npass_trt_measurements);
187  }
188 
189  return StatusCode::SUCCESS;
190 }
191 
192 
194  (const EventContext& ctx,
195  MeasurementType detTypeToSelect,
196  const xAOD::TrackParticleContainer& inputTrackParticles,
197  const std::vector<bool>& inputMask,
200  std::atomic<unsigned int>& ntot_states,
201  std::atomic<unsigned int>& ntot_measurements,
202  std::atomic<unsigned int>& npass_states,
203  std::atomic<unsigned int>& npass_measurements) const
204 {
205  std::vector<bool> maskStates;
206  std::vector<bool> maskMeasurements;
207 
208  selectTrackHits (inputTrackParticles, inputMask, detTypeToSelect,
209  maskStates, maskMeasurements);
210 
211  auto count = [] (const std::vector<bool>& m)
212  { return std::count (m.begin(), m.end(), true); };
213  npass_states += count (maskStates);
214  npass_measurements += count (maskMeasurements);
215 
216  if (!statesKey.empty()) {
218  (statesKey, ctx);
219  unsigned int size_states = importedStates->size();
220  if (size_states == 0) {
221  ATH_MSG_WARNING("States container is empty: " << statesKey.key());
222  }
223  else {
224  ntot_states += size_states;
225  if (maskStates.size() > size_states) {
226  ATH_MSG_ERROR("States mask size mismatch " << maskStates.size() <<
227  " > " << size_states);
228  }
229  maskStates.resize (size_states);
230  importedStates.keep (maskStates);
231  }
232  }
233 
234  if (!measurementsKey.empty()) {
236  (measurementsKey, ctx);
237  unsigned int size_measurements = importedMeasurements->size();
238  if (size_measurements == 0) {
239  ATH_MSG_WARNING("Measurements container is empty: " << measurementsKey.key());
240  }
241  else {
242  ntot_measurements += size_measurements;
243  if (maskMeasurements.size() > size_measurements) {
244  ATH_MSG_ERROR("Measurements mask size mismatch " << maskMeasurements.size() <<
245  " > " << size_measurements);
246  }
247  maskMeasurements.resize (size_measurements);
248  importedMeasurements.keep (maskMeasurements);
249  }
250  }
251 }
252 
253 
255  const std::vector<bool>& inputMask,
256  MeasurementType detTypeToSelect,
257  std::vector<bool>& outputStatesMask, std::vector<bool>& outputMeasurementsMask) const
258 {
259  // loop over track particles, consider only the ones pre-selected by the mask
260  int trkIndex=-1;
261  for (const xAOD::TrackParticle* trkIt : inputTrackParticles) {
262  trkIndex++;
263  if (not inputMask[trkIndex]) continue;
264 
265  // loop over the TrackStateValidation objects, and add them to the outputStatesMask
266  using StatesOnTrack = std::vector<ElementLink<xAOD::TrackStateValidationContainer>>;
267  static const SG::ConstAccessor< StatesOnTrack > msosLinkAcc( "msosLink" );
268  if( ! msosLinkAcc.isAvailable(*trkIt) ) {
269  ATH_MSG_DEBUG("Cannot find TrackState link from xAOD::TrackParticle. Skipping track.");
270  continue;
271  }
272  const StatesOnTrack& measurementsOnTrack = msosLinkAcc(*trkIt);
273  for( const ElementLink<xAOD::TrackStateValidationContainer>& trkState_el : measurementsOnTrack) {
274  if (not trkState_el.isValid()) {
275  ATH_MSG_DEBUG("Cannot find a valid link to TrackStateValidation object for track index: " << trkIndex);
276  continue; //not a valid link
277  }
278  if ((*trkState_el)->detType() != detTypeToSelect) {
279  ATH_MSG_VERBOSE("Discarding TrackState as not of correct type " << detTypeToSelect);
280  continue;
281  }
282  if (trkState_el.index() >= outputStatesMask.size()) {
283  outputStatesMask.resize (trkState_el.index()+1);
284  }
285  outputStatesMask[trkState_el.index()] = true;
286 
287  // get the corresponding TrackMeasurementValidation object, if any, and add it to the outputMeasurementsMask
288  const ElementLink<xAOD::TrackMeasurementValidationContainer> trkMeasurement_el = (*trkState_el)->trackMeasurementValidationLink();
289  if (not trkMeasurement_el.isValid()) {
290  ATH_MSG_VERBOSE("Cannot find a valid link to TrackMeasurementValidation object from track state for track index: " << trkIndex
291  << ", trackState index: " << trkState_el.index());
292  continue; //not a valid link
293  }
294  if (*trkMeasurement_el == nullptr) {
295  ATH_MSG_VERBOSE("Invalid pointer to TrackMeasurementValidation object from track state for track index: " << trkIndex
296  << ", trackState index: " << trkState_el.index());
297  continue; //not linking to a valid object -- is it necessary?
298  }
299  if (trkMeasurement_el.index() >= outputMeasurementsMask.size()) {
300  outputMeasurementsMask.resize (trkMeasurement_el.index()+1);
301  }
302  outputMeasurementsMask[trkMeasurement_el.index()] = true;
303  }
304  } // end loop over xAOD::TrackParticle container
305 }
TrackParticleThinning.h
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DerivationFramework::TrackParticleThinning::initialize
virtual StatusCode initialize() override
Definition: TrackParticleThinning.cxx:53
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ThinningHandleKey
HandleKey object for adding thinning to an object.
Definition: ThinningHandleKey.h:38
ThinningHandle.h
Handle for requesting thinning for a data object.
DerivationFramework::TrackParticleThinning::filterTrackHits
void filterTrackHits(const EventContext &ctx, MeasurementType detTypeToSelect, const xAOD::TrackParticleContainer &inputTrackParticles, const std::vector< bool > &inputMask, const SG::ThinningHandleKey< xAOD::TrackStateValidationContainer > &statesKey, const SG::ThinningHandleKey< xAOD::TrackMeasurementValidationContainer > &measurementsKey, std::atomic< unsigned int > &ntot_states, std::atomic< unsigned int > &ntot_measurements, std::atomic< unsigned int > &npass_states, std::atomic< unsigned int > &npass_measurements) const
Definition: TrackParticleThinning.cxx:194
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
DerivationFramework::TrackParticleThinning::finalize
virtual StatusCode finalize() override
Definition: TrackParticleThinning.cxx:90
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
DerivationFramework::TrackParticleThinning::m_thinHitsOnTrack
bool m_thinHitsOnTrack
Definition: TrackParticleThinning.h:75
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
SG::ThinningHandle
Handle for requesting thinning for a data object.
Definition: ThinningHandle.h:84
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
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
DerivationFramework::TrackParticleThinning::selectTrackHits
void selectTrackHits(const xAOD::TrackParticleContainer &inputTrackParticles, const std::vector< bool > &inputMask, MeasurementType detTypeToSelect, std::vector< bool > &outputStatesMask, std::vector< bool > &outputMeasurementsMask) const
Select TrackStateValidation and TrackMeasurementValidation objects that are used in the (thinned) tra...
Definition: TrackParticleThinning.cxx:254
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:731
DerivationFramework::TrackParticleThinning::TrackParticleThinning
TrackParticleThinning(const std::string &t, const std::string &n, const IInterface *p)
Definition: TrackParticleThinning.cxx:23
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
ExpressionParserUser.icc
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
DerivationFramework::TrackParticleThinning::m_selectionString
std::string m_selectionString
Definition: TrackParticleThinning.h:42
DerivationFramework::TrackParticleThinning::~TrackParticleThinning
virtual ~TrackParticleThinning()
TrackStateValidationContainer.h
DerivationFramework::TrackParticleThinning::MeasurementType
MeasurementType
Definition: TrackParticleThinning.h:79
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
entries
double entries
Definition: listroot.cxx:49
TrackMeasurementValidationContainer.h
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
dqBeamSpot.nEntries
int nEntries
Definition: dqBeamSpot.py:73
DerivationFramework::TrackParticleThinning::doThinning
virtual StatusCode doThinning() const override
Definition: TrackParticleThinning.cxx:119
TrackParticleContainer.h