ATLAS Offline Software
Loading...
Searching...
No Matches
PseudoTrackSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// PseudoTrackSelector
7// Author: Sebastien Rettie, sebastien.rettie@cern.ch
8// This is a modified version of exisitng TrackParticleMerger
10
12// Pseudotrack selector to be used mainly for creating new track
13// collections with a subset of input pseudotracks
15
17#include "GaudiKernel/MsgStream.h"
22// Constructor
24
25namespace DerivationFramework {
26
27 // The default goal of this selector is to create a track collection from a subset of pseudo tracks
28
30 // Initialisation
32
34 {
35 ATH_MSG_DEBUG("Initializing PseudoTrackSelector");
41 ATH_CHECK( m_out_recoPlusPseudo.initialize() );
44 ATH_CHECK( m_out_recoNoFakes.initialize() );
45 ATH_CHECK( m_out_recoNoFakesFromB.initialize() );
47 ATH_CHECK( m_trackOriginTool.retrieve() );
48 return StatusCode::SUCCESS;
49 }
50
51 StatusCode PseudoTrackSelector::addBranches(const EventContext& ctx) const
52 {
53 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoReplacedWithPseudo = std::make_unique<xAOD::TrackParticleContainer>();
54 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoReplacedWithPseudoAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
55 outputRecoReplacedWithPseudo->setStore(outputRecoReplacedWithPseudoAux.get());
56 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoReplacedWithPseudoFromB = std::make_unique<xAOD::TrackParticleContainer>();
57 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoReplacedWithPseudoFromBAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
58 outputRecoReplacedWithPseudoFromB->setStore(outputRecoReplacedWithPseudoFromBAux.get());
59 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoReplacedWithPseudoNotFromB = std::make_unique<xAOD::TrackParticleContainer>();
60 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoReplacedWithPseudoNotFromBAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
61 outputRecoReplacedWithPseudoNotFromB->setStore(outputRecoReplacedWithPseudoNotFromBAux.get());
62 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoPlusPseudo = std::make_unique<xAOD::TrackParticleContainer>();
63 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoPlusPseudoAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
64 outputRecoPlusPseudo->setStore(outputRecoPlusPseudoAux.get());
65 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoPlusPseudoFromB = std::make_unique<xAOD::TrackParticleContainer>();
66 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoPlusPseudoFromBAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
67 outputRecoPlusPseudoFromB->setStore(outputRecoPlusPseudoFromBAux.get());
68 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoPlusPseudoNotFromB = std::make_unique<xAOD::TrackParticleContainer>();
69 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoPlusPseudoNotFromBAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
70 outputRecoPlusPseudoNotFromB->setStore(outputRecoPlusPseudoNotFromBAux.get());
71 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoNoFakes = std::make_unique<xAOD::TrackParticleContainer>();
72 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoNoFakesAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
73 outputRecoNoFakes->setStore(outputRecoNoFakesAux.get());
74 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoNoFakesFromB = std::make_unique<xAOD::TrackParticleContainer>();
75 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoNoFakesFromBAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
76 outputRecoNoFakesFromB->setStore(outputRecoNoFakesFromBAux.get());
77 std::unique_ptr<xAOD::TrackParticleContainer> outputRecoNoFakesNotFromB = std::make_unique<xAOD::TrackParticleContainer>();
78 std::unique_ptr<xAOD::TrackParticleAuxContainer> outputRecoNoFakesNotFromBAux = std::make_unique<xAOD::TrackParticleAuxContainer>();
79 outputRecoNoFakesNotFromB->setStore(outputRecoNoFakesNotFromBAux.get());
80
81 // retrieve reco and pseudo tracks
84
85 // fail if containers not available
86 if (!recoTrackParticleCol.isValid()){
87 ATH_MSG_ERROR( m_in_recoTrackParticleLocation.key() << " not valid!" );
88 return StatusCode::FAILURE;
89 }
90 if (!pseudoTrackParticleCol.isValid()){
91 ATH_MSG_ERROR( m_in_pseudoTrackParticleLocation.key() << " not valid!" );
92 return StatusCode::FAILURE;
93 }
94
95 // select subset of tracks
96 fillRecoReplacedWithPseudo(recoTrackParticleCol.cptr(), pseudoTrackParticleCol.cptr(), outputRecoReplacedWithPseudo.get());
97 fillRecoReplacedWithPseudo(recoTrackParticleCol.cptr(), pseudoTrackParticleCol.cptr(), outputRecoReplacedWithPseudoFromB.get(), true, false);
98 fillRecoReplacedWithPseudo(recoTrackParticleCol.cptr(), pseudoTrackParticleCol.cptr(), outputRecoReplacedWithPseudoNotFromB.get(), false, true);
99 fillRecoPlusPseudo(recoTrackParticleCol.cptr(), pseudoTrackParticleCol.cptr(), outputRecoPlusPseudo.get());
100 fillRecoPlusPseudo(recoTrackParticleCol.cptr(), pseudoTrackParticleCol.cptr(), outputRecoPlusPseudoFromB.get(), true, false);
101 fillRecoPlusPseudo(recoTrackParticleCol.cptr(), pseudoTrackParticleCol.cptr(), outputRecoPlusPseudoNotFromB.get(), false, true);
102 fillRecoNoFakes(recoTrackParticleCol.cptr(), outputRecoNoFakes.get());
103 fillRecoNoFakes(recoTrackParticleCol.cptr(), outputRecoNoFakesFromB.get(), true, false);
104 fillRecoNoFakes(recoTrackParticleCol.cptr(), outputRecoNoFakesNotFromB.get(), false, true);
105
106 // Write tracks to store
107 ATH_MSG_DEBUG("outputRecoReplacedWithPseudo has "<<outputRecoReplacedWithPseudo.get()->size()<<" tracks");
109 ATH_CHECK(h_write_recoReplacedWithPseudo.record(std::move(outputRecoReplacedWithPseudo), std::move(outputRecoReplacedWithPseudoAux)));
110 ATH_MSG_DEBUG("wrote "<<m_out_recoReplacedWithPseudo<<" to store");
111
112 ATH_MSG_DEBUG("outputRecoReplacedWithPseudoFromB has "<<outputRecoReplacedWithPseudoFromB.get()->size()<<" tracks");
114 ATH_CHECK(h_write_recoReplacedWithPseudoFromB.record(std::move(outputRecoReplacedWithPseudoFromB), std::move(outputRecoReplacedWithPseudoFromBAux)));
115 ATH_MSG_DEBUG("wrote "<<m_out_recoReplacedWithPseudoFromB<<" to store");
116
117 ATH_MSG_DEBUG("outputRecoReplacedWithPseudoNotFromB has "<<outputRecoReplacedWithPseudoNotFromB.get()->size()<<" tracks");
119 ATH_CHECK(h_write_recoReplacedWithPseudoNotFromB.record(std::move(outputRecoReplacedWithPseudoNotFromB), std::move(outputRecoReplacedWithPseudoNotFromBAux)));
121
122 ATH_MSG_DEBUG("outputRecoPlusPseudo has "<<outputRecoPlusPseudo.get()->size()<<" tracks");
124 ATH_CHECK(h_write_recoPlusPseudo.record(std::move(outputRecoPlusPseudo), std::move(outputRecoPlusPseudoAux)));
125 ATH_MSG_DEBUG("wrote "<<m_out_recoPlusPseudo<<" to store");
126
127 ATH_MSG_DEBUG("outputRecoPlusPseudoFromB has "<<outputRecoPlusPseudoFromB.get()->size()<<" tracks");
129 ATH_CHECK(h_write_recoPlusPseudoFromB.record(std::move(outputRecoPlusPseudoFromB), std::move(outputRecoPlusPseudoFromBAux)));
130 ATH_MSG_DEBUG("wrote "<<m_out_recoPlusPseudoFromB<<" to store");
131
132 ATH_MSG_DEBUG("outputRecoPlusPseudoNotFromB has "<<outputRecoPlusPseudoNotFromB.get()->size()<<" tracks");
134 ATH_CHECK(h_write_recoPlusPseudoNotFromB.record(std::move(outputRecoPlusPseudoNotFromB), std::move(outputRecoPlusPseudoNotFromBAux)));
135 ATH_MSG_DEBUG("wrote "<<m_out_recoPlusPseudoNotFromB<<" to store");
136
137 ATH_MSG_DEBUG("outputRecoNoFakes has "<<outputRecoNoFakes.get()->size()<<" tracks");
139 ATH_CHECK(h_write_recoNoFakes.record(std::move(outputRecoNoFakes), std::move(outputRecoNoFakesAux)));
140 ATH_MSG_DEBUG("wrote "<<m_out_recoNoFakes<<" to store");
141
142 ATH_MSG_DEBUG("outputRecoNoFakesFromB has "<<outputRecoNoFakesFromB.get()->size()<<" tracks");
144 ATH_CHECK(h_write_recoNoFakesFromB.record(std::move(outputRecoNoFakesFromB), std::move(outputRecoNoFakesFromBAux)));
145 ATH_MSG_DEBUG("wrote "<<m_out_recoNoFakesFromB<<" to store");
146
147 ATH_MSG_DEBUG("outputRecoNoFakesNotFromB has "<<outputRecoNoFakesNotFromB.get()->size()<<" tracks");
149 ATH_CHECK(h_write_recoNoFakesNotFromB.record(std::move(outputRecoNoFakesNotFromB), std::move(outputRecoNoFakesNotFromBAux)));
150 ATH_MSG_DEBUG("wrote "<<m_out_recoNoFakesNotFromB<<" to store");
151
152 return StatusCode::SUCCESS;
153 }
154
156 // Select relevant pseudo tracks
158
160 const xAOD::TrackParticleContainer* pseudoTrackParticleCol,
162 bool onlyFromB /*= false*/,
163 bool onlyNotFromB /*= false*/) const
164 {
165 ATH_MSG_DEBUG("Start fillRecoReplacedWithPseudo with onlyFromB = "<<onlyFromB<<" and onlyNotFromB = "<<onlyNotFromB);
166 // loop over tracks, accept them and add them into output collection
167 if((recoTrackParticleCol && !recoTrackParticleCol->empty()) &&
168 (pseudoTrackParticleCol && !pseudoTrackParticleCol->empty())) {
169 ATH_MSG_DEBUG("Size of reco track particle collection " << recoTrackParticleCol->size());
170 ATH_MSG_DEBUG("Size of pseudo track particle collection " << pseudoTrackParticleCol->size());
171 int n_saved = 0;
172 // loop over reco tracks
173 for(const auto *const tp_reco: *recoTrackParticleCol){
174 // Get truth particle
175 const xAOD::TruthParticle* truth_reco = getTruth(tp_reco);
176 if (truth_reco){
177 bool match_found = false;
178 // loop over pseudo tracks to look for a match
179 for(const auto *const tp_pseudo: *pseudoTrackParticleCol){
180 const xAOD::TruthParticle* truth_pseudo = getTruth(tp_pseudo);
181 if (truth_reco == truth_pseudo){
182 ATH_MSG_DEBUG("reco track has truth-matched pseudo track!");
183 match_found = true;
184 // add pseudo track into output
185 if (!onlyFromB && !onlyNotFromB){
186 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_pseudo);
187 outputCol->push_back(newTrackParticle);
188 n_saved++;
189 ATH_MSG_DEBUG("saving pseudo track");
190 }
191 // Check origin of track
192 int origin = m_trackOriginTool->getTrackOrigin(tp_pseudo);
193 ATH_MSG_DEBUG("fromB: "<<InDet::TrkOrigin::isFromB(origin));
194 if (onlyFromB){
195 if (InDet::TrkOrigin::isFromB(origin)){
196 // Track is from B hadron, replace with pseudo track
197 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_pseudo);
198 outputCol->push_back(newTrackParticle);
199 n_saved++;
200 ATH_MSG_DEBUG("saving fromB pseudo track");
201 }
202 else{
203 // Track is not from B hadron, keep reco track
204 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_reco);
205 outputCol->push_back(newTrackParticle);
206 n_saved++;
207 ATH_MSG_DEBUG("keeping notFromB reco track");
208 }
209 }
210 if (onlyNotFromB){
211 if (!InDet::TrkOrigin::isFromB(origin)){
212 // Track is not from B hadron, replace with pseudo track
213 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_pseudo);
214 outputCol->push_back(newTrackParticle);
215 n_saved++;
216 ATH_MSG_DEBUG("saving notFromB pseudo track");
217 }
218 else{
219 // Track is from B hadron, keep reco track
220 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_reco);
221 outputCol->push_back(newTrackParticle);
222 n_saved++;
223 ATH_MSG_DEBUG("keeping FromB reco track");
224 }
225 }
226 // Found match and replaced relevant track
227 break;
228 }
229 else{
230 ATH_MSG_VERBOSE("truth-matched pseudo track not found yet...");
231 }
232 }
233 if(!match_found){
234 ATH_MSG_DEBUG("reco track that has truth link DOES NOT have truth-matched pseudo track! :(");
235 }
236 }
237 else{
238 ATH_MSG_DEBUG("no truth particle for reco track!");
239 }
240 }
241 ATH_MSG_DEBUG("Size of output track particle collection " << outputCol->size() <<" (sanity: "<<n_saved<<")");
242 }
243 }
244
246 const xAOD::TrackParticleContainer* pseudoTrackParticleCol,
248 bool onlyFromB /*= false*/,
249 bool onlyNotFromB /*= false*/) const
250 {
251 ATH_MSG_DEBUG("Start fillRecoPlusPseudo with onlyFromB = "<<onlyFromB<<" and onlyNotFromB = "<<onlyNotFromB);
252 // loop over tracks, accept them and add them into output collection
253 if((recoTrackParticleCol && !recoTrackParticleCol->empty()) &&
254 (pseudoTrackParticleCol && !pseudoTrackParticleCol->empty())) {
255 ATH_MSG_DEBUG("Size of reco track particle collection " << recoTrackParticleCol->size());
256 ATH_MSG_DEBUG("Size of pseudo track particle collection " << pseudoTrackParticleCol->size());
257 int n_saved = 0;
258 // Start by keeping reco tracks
259 for(const auto *const tp_reco: *recoTrackParticleCol){
260 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_reco);
261 outputCol->push_back(newTrackParticle);
262 n_saved++;
263 }
264 // Now add pseudo tracks that are not matched to reco tracks
265 for(const auto *const tp_pseudo: *pseudoTrackParticleCol){
266 bool match_found = false;
267 const xAOD::TruthParticle* truth_pseudo = getTruth(tp_pseudo);
268 for(const auto *const tp_reco: *recoTrackParticleCol){
269 // Get truth particle
270 const xAOD::TruthParticle* truth_reco = getTruth(tp_reco);
271 if (truth_reco){
272 if (truth_reco == truth_pseudo){
273 ATH_MSG_DEBUG("reco track has truth-matched pseudo track!");
274 match_found = true;
275 break;
276 }
277 }
278 else{
279 ATH_MSG_DEBUG("no truth particle for reco track!");
280 }
281 }
282 if(!match_found){
283 ATH_MSG_DEBUG("no match found, so adding pseudo track to output");
284 if(!onlyFromB && !onlyNotFromB){
285 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_pseudo);
286 outputCol->push_back(newTrackParticle);
287 n_saved++;
288 ATH_MSG_DEBUG("saving pseudo track");
289 }
290 int origin = m_trackOriginTool->getTrackOrigin(tp_pseudo);
291 ATH_MSG_DEBUG("fromB: "<<InDet::TrkOrigin::isFromB(origin));
292 if(onlyFromB && InDet::TrkOrigin::isFromB(origin)){
293 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_pseudo);
294 outputCol->push_back(newTrackParticle);
295 n_saved++;
296 ATH_MSG_DEBUG("saving fromB pseudo track");
297 }
298 if(onlyNotFromB && !InDet::TrkOrigin::isFromB(origin)){
299 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_pseudo);
300 outputCol->push_back(newTrackParticle);
301 n_saved++;
302 ATH_MSG_DEBUG("saving notFromB pseudo track");
303 }
304 }
305 else{
306 ATH_MSG_DEBUG("match found so not adding pseudo track to output");
307 }
308 }
309 ATH_MSG_DEBUG("Size of output track particle collection " << outputCol->size() <<" (sanity: "<<n_saved<<")");
310 }
311 }
312
315 bool onlyFromB /*= false*/,
316 bool onlyNotFromB /*= false*/) const
317 {
318 ATH_MSG_DEBUG("Start fillRecoNoFakes with onlyFromB = "<<onlyFromB<<" and onlyNotFromB = "<<onlyNotFromB);
319 // loop over tracks, accept them and add them into output collection
320 if((recoTrackParticleCol && !recoTrackParticleCol->empty())){
321 ATH_MSG_DEBUG("Size of reco track particle collection " << recoTrackParticleCol->size());
322 int n_saved = 0;
323 static const SG::ConstAccessor< float > acc_truthProb("truthMatchProbability");
324
325 // loop over tracks
326 for(const auto *const tp_reco: *recoTrackParticleCol){
327 // place cut on truth match probability
328 if (!onlyFromB && !onlyNotFromB){
329 if( acc_truthProb( *tp_reco ) < 0.5) {
330 ATH_MSG_DEBUG("Fake track!");
331 continue;
332 }
333 }
334 int origin = m_trackOriginTool->getTrackOrigin(tp_reco);
335 ATH_MSG_DEBUG("fromB: "<<InDet::TrkOrigin::isFromB(origin));
336 if (onlyFromB && InDet::TrkOrigin::isFromB(origin)){
337 if( acc_truthProb( *tp_reco ) < 0.5) {
338 ATH_MSG_DEBUG("Fake track fromB!");
339 continue;
340 }
341 }
342 if (onlyNotFromB && !InDet::TrkOrigin::isFromB(origin)){
343 if( acc_truthProb( *tp_reco ) < 0.5) {
344 ATH_MSG_DEBUG("Fake track notFromB!");
345 continue;
346 }
347 }
348 // add track into output
349 xAOD::TrackParticle* newTrackParticle = new xAOD::TrackParticle(*tp_reco);
350 outputCol->push_back(newTrackParticle);
351 n_saved++;
352 }
353 ATH_MSG_DEBUG("Size of output track particle collection " << outputCol->size() <<" (sanity: "<<n_saved<<")");
354 }
355 }
356
358 // create a pointer to a truth particle which will correspond to this track
359 const xAOD::TruthParticle* linkedTruthParticle = nullptr;
360
361 // if the track doesnt't have a valid truth link, skip to the next track
362 // in practice, all tracks seem to have a truth link, but we need to also
363 // check whether it's valid
364 static const SG::ConstAccessor<TruthLink> truthParticleLinkAcc("truthParticleLink");
365 if ( !truthParticleLinkAcc.isAvailable(*track) ) {
366 return nullptr;
367 }
368
369 // retrieve the link and check its validity
370 const TruthLink &link = truthParticleLinkAcc(*track);
371
372 // a missing or invalid link implies truth particle has been dropped from
373 // the truth record at some stage - probably it was a pileup or low pT GEANT
374 // particle.
375 if(!link or !link.isValid()) {
376 return nullptr;
377 }
378
379 // seems safe to access and return the linked truth particle
380 linkedTruthParticle = (*link);
381 return linkedTruthParticle;
382 }
383}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Helper class to provide constant type-safe access to aux data.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
void fillRecoReplacedWithPseudo(const xAOD::TrackParticleContainer *recoTrackParticleCol, const xAOD::TrackParticleContainer *pseudoTrackParticleCol, xAOD::TrackParticleContainer *outputCol, bool onlyFromB=false, bool onlyNotFromB=false) const
Output track collection.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoReplacedWithPseudoFromB
Output track collection.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoPlusPseudo
Output track collection.
virtual StatusCode addBranches(const EventContext &ctx) const override final
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoReplacedWithPseudoNotFromB
Output track collection.
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_in_pseudoTrackParticleLocation
Reco track collection.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoPlusPseudoNotFromB
Output track collection.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoPlusPseudoFromB
Output track collection.
ElementLink< xAOD::TruthParticleContainer > TruthLink
ToolHandle< InDet::IInDetTrackTruthOriginTool > m_trackOriginTool
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoNoFakesNotFromB
Output track collection.
virtual StatusCode initialize() override final
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_in_recoTrackParticleLocation
Protected data:
static const xAOD::TruthParticle * getTruth(const xAOD::TrackParticle *track)
void fillRecoNoFakes(const xAOD::TrackParticleContainer *recoTrackParticleCol, xAOD::TrackParticleContainer *outputCol, bool onlyFromB=false, bool onlyNotFromB=false) const
void fillRecoPlusPseudo(const xAOD::TrackParticleContainer *recoTrackParticleCol, const xAOD::TrackParticleContainer *pseudoTrackParticleCol, xAOD::TrackParticleContainer *outputCol, bool onlyFromB=false, bool onlyNotFromB=false) const
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoNoFakes
Output track collection.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoNoFakesFromB
Output track collection.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_out_recoReplacedWithPseudo
Pseudo track collection.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
THE reconstruction tool.
bool isFromB(int origin)
from B decay chain including B-->D
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TruthParticle_v1 TruthParticle
Typedef to implementation.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".