CMS 3D CMS Logo

TrackingTruthAccumulator.cc
Go to the documentation of this file.
1 
34 
35 #include <memory>
36 
49 
57 
58 // Turn on integrity checking
59 //#define DO_DEBUG_TESTING
60 
61 //---------------------------------------------------------------------------------
62 //---------------------------------------------------------------------------------
63 //---------------------------------------------------------------------------------
64 //------ ------
65 //------ Declarations for utility classes and functions in the unnamed ------
66 //------ namespace. The definitions are right at the bottom of the file. ------
67 //------ ------
68 //---------------------------------------------------------------------------------
69 //---------------------------------------------------------------------------------
70 //---------------------------------------------------------------------------------
71 
72 namespace {
77  struct DecayChainTrack {
78  int simTrackIndex;
79  struct DecayChainVertex *pParentVertex;
80  // Some things have multiple decay vertices. Not sure how that works but it
81  // seems to be mostly electrons and some photons.
82  std::vector<struct DecayChainVertex *> daughterVertices;
83  DecayChainTrack *pMergedBremSource;
84  DecayChainTrack() : simTrackIndex(-1), pParentVertex(nullptr), pMergedBremSource(nullptr) {}
85  DecayChainTrack(int newSimTrackIndex)
86  : simTrackIndex(newSimTrackIndex), pParentVertex(nullptr), pMergedBremSource() {}
87  };
88 
94  struct DecayChainVertex {
95  int simVertexIndex;
96  DecayChainTrack *pParentTrack;
97  std::vector<DecayChainTrack *> daughterTracks;
98  DecayChainVertex *pMergedBremSource;
99  DecayChainVertex() : simVertexIndex(-1), pParentTrack(nullptr), pMergedBremSource(nullptr) {}
100  DecayChainVertex(int newIndex) : simVertexIndex(newIndex), pParentTrack(nullptr), pMergedBremSource(nullptr) {}
101  };
102 
115  struct DecayChain {
116  public:
117  DecayChain(const std::vector<SimTrack> &trackCollection, const std::vector<SimVertex> &vertexCollection);
118  const size_t decayTracksSize;
119  const size_t decayVerticesSize;
120 
121 #if defined(DO_DEBUG_TESTING)
122 
128  void integrityCheck();
129 #endif
130  const SimTrack &getSimTrack(const ::DecayChainTrack *pDecayTrack) const {
131  return simTrackCollection_.at(pDecayTrack->simTrackIndex);
132  }
133  const SimVertex &getSimVertex(const ::DecayChainVertex *pDecayVertex) const {
134  return simVertexCollection_.at(pDecayVertex->simVertexIndex);
135  }
136 
137  private:
138  void findBrem(const std::vector<SimTrack> &trackCollection, const std::vector<SimVertex> &vertexCollection);
139  std::unique_ptr<::DecayChainTrack[]> decayTracks_;
140  std::unique_ptr<::DecayChainVertex[]> decayVertices_;
141 
144  std::vector<::DecayChainVertex *> rootVertices_;
145 
146  // Keep a record of the constructor parameters
147  const std::vector<SimTrack> &simTrackCollection_;
148  const std::vector<SimVertex> &simVertexCollection_;
149 
150  public:
151  const std::unique_ptr<::DecayChainTrack[]> &decayTracks;
152  const std::unique_ptr<::DecayChainVertex[]> &decayVertices;
154  const std::vector<::DecayChainVertex *> &rootVertices;
156  };
158 
163  class TrackingParticleFactory {
164  public:
165  TrackingParticleFactory(const ::DecayChain &decayChain,
166  const edm::Handle<std::vector<reco::GenParticle>> &hGenParticles,
167  const edm::Handle<edm::HepMCProduct> &hepMCproduct,
168  const edm::Handle<std::vector<int>> &hHepMCGenParticleIndices,
169  const std::vector<const PSimHit *> &simHits,
170  double volumeRadius,
171  double volumeZ,
172  double vertexDistanceCut,
173  bool allowDifferentProcessTypes);
174  TrackingParticle createTrackingParticle(const DecayChainTrack *pTrack, const TrackerTopology *tTopo) const;
175  TrackingVertex createTrackingVertex(const DecayChainVertex *pVertex) const;
176  bool vectorIsInsideVolume(const math::XYZTLorentzVectorD &vector) const;
177 
178  private:
179  const ::DecayChain &decayChain_;
180  const edm::Handle<std::vector<reco::GenParticle>> &hGenParticles_;
181  const edm::Handle<edm::HepMCProduct> &hepMCproduct_;
182  std::vector<int> genParticleIndices_;
183  const std::vector<const PSimHit *> &simHits_;
184  const double volumeRadius_;
185  const double volumeZ_;
186  const double vertexDistanceCut2_; // distance based on which HepMC::GenVertexs
187  // are added to SimVertexs
188  std::multimap<unsigned int, size_t> trackIdToHitIndex_;
189  bool allowDifferentProcessTypeForDifferentDetectors_;
191  };
194 
200  class OutputCollectionWrapper {
201  public:
202  OutputCollectionWrapper(const DecayChain &decayChain,
204  TrackingParticle *addTrackingParticle(const ::DecayChainTrack *pDecayTrack,
205  const TrackingParticle &trackingParticle);
206  TrackingVertex *addTrackingVertex(const ::DecayChainVertex *pDecayVertex, const TrackingVertex &trackingVertex);
207  TrackingParticle *getTrackingParticle(const ::DecayChainTrack *pDecayTrack);
210  void setProxy(const ::DecayChainTrack *pOriginalTrack, const ::DecayChainTrack *pProxyTrack);
211  void setProxy(const ::DecayChainVertex *pOriginalVertex, const ::DecayChainVertex *pProxyVertex);
212  TrackingVertex *getTrackingVertex(const ::DecayChainVertex *pDecayVertex);
213  TrackingParticleRef getRef(const ::DecayChainTrack *pDecayTrack);
214  TrackingVertexRef getRef(const ::DecayChainVertex *pDecayVertex);
215 
216  private:
217  void associateToExistingObjects(const ::DecayChainVertex *pChainVertex);
218  void associateToExistingObjects(const ::DecayChainTrack *pChainTrack);
220  std::vector<int> trackingParticleIndices_;
221  std::vector<int> trackingVertexIndices_;
222  };
223 
229  TrackingParticle *addTrackAndParentVertex(::DecayChainTrack *pDecayTrack,
230  const TrackingParticle &trackingParticle,
231  ::OutputCollectionWrapper *pOutput);
232 
239  void addTrack(::DecayChainTrack *pDecayChainTrack,
240  const TrackingParticleSelector *pSelector,
241  ::OutputCollectionWrapper *pUnmergedOutput,
242  ::OutputCollectionWrapper *pMergedOutput,
243  const ::TrackingParticleFactory &objectFactory,
244  bool addAncestors,
245  const TrackerTopology *tTopo);
246 
247 } // namespace
248 
249 //---------------------------------------------------------------------------------
250 //---------------------------------------------------------------------------------
251 //---------------------------------------------------------------------------------
252 //------ ------
253 //------ Definitions for the TrackingTruthAccumulator methods ------
254 //------ are below. ------
255 //------ ------
256 //---------------------------------------------------------------------------------
257 //---------------------------------------------------------------------------------
258 //---------------------------------------------------------------------------------
259 
261  edm::ProducesCollector producesCollector,
263  : messageCategory_("TrackingTruthAccumulator"),
264  volumeRadius_(config.getParameter<double>("volumeRadius")),
265  volumeZ_(config.getParameter<double>("volumeZ")),
266  vertexDistanceCut_(config.getParameter<double>("vertexDistanceCut")),
267  ignoreTracksOutsideVolume_(config.getParameter<bool>("ignoreTracksOutsideVolume")),
268  maximumPreviousBunchCrossing_(config.getParameter<unsigned int>("maximumPreviousBunchCrossing")),
269  maximumSubsequentBunchCrossing_(config.getParameter<unsigned int>("maximumSubsequentBunchCrossing")),
270  createUnmergedCollection_(config.getParameter<bool>("createUnmergedCollection")),
271  createMergedCollection_(config.getParameter<bool>("createMergedBremsstrahlung")),
272  createInitialVertexCollection_(config.getParameter<bool>("createInitialVertexCollection")),
273  addAncestors_(config.getParameter<bool>("alwaysAddAncestors")),
274  removeDeadModules_(config.getParameter<bool>("removeDeadModules")),
275  simTrackLabel_(config.getParameter<edm::InputTag>("simTrackCollection")),
276  simVertexLabel_(config.getParameter<edm::InputTag>("simVertexCollection")),
277  collectionTags_(),
278  genParticleLabel_(config.getParameter<edm::InputTag>("genParticleCollection")),
279  hepMCproductLabel_(config.getParameter<edm::InputTag>("HepMCProductLabel")),
280  allowDifferentProcessTypeForDifferentDetectors_(config.getParameter<bool>("allowDifferentSimHitProcesses")) {
281  //
282  // Make sure at least one of the merged and unmerged collections have been set
283  // to be created.
284  //
286  edm::LogError(messageCategory_) << "Both \"createUnmergedCollection\" and "
287  "\"createMergedBremsstrahlung\" have been"
288  << "set to false, which means no collections will be created";
289 
290  // Initialize selection for building TrackingParticles
291  //
292  if (config.exists("select")) {
293  edm::ParameterSet param = config.getParameter<edm::ParameterSet>("select");
294  selector_ = TrackingParticleSelector(param.getParameter<double>("ptMinTP"),
295  param.getParameter<double>("ptMaxTP"),
296  param.getParameter<double>("minRapidityTP"),
297  param.getParameter<double>("maxRapidityTP"),
298  param.getParameter<double>("tipTP"),
299  param.getParameter<double>("lipTP"),
300  param.getParameter<int>("minHitTP"),
301  param.getParameter<bool>("signalOnlyTP"),
302  param.getParameter<bool>("intimeOnlyTP"),
303  param.getParameter<bool>("chargedOnlyTP"),
304  param.getParameter<bool>("stableOnlyTP"),
305  param.getParameter<std::vector<int>>("pdgIdTP"));
306  selectorFlag_ = true;
307 
308  // Also set these two variables, which are used to drop out early if the
309  // SimTrack doesn't conform. The selector_ requires a full TrackingParticle
310  // object, but these two variables can veto things early.
311  chargedOnly_ = param.getParameter<bool>("chargedOnlyTP");
312  signalOnly_ = param.getParameter<bool>("signalOnlyTP");
313  } else {
314  selectorFlag_ = false;
315  chargedOnly_ = false;
316  signalOnly_ = false;
317  }
318 
319  //
320  // Need to state what collections are going to be added to the event. This
321  // depends on which of the merged and unmerged collections have been
322  // configured to be created.
323  //
325  producesCollector.produces<TrackingVertexCollection>();
326  producesCollector.produces<TrackingParticleCollection>();
327  }
328 
330  producesCollector.produces<TrackingParticleCollection>("MergedTrackTruth");
331  producesCollector.produces<TrackingVertexCollection>("MergedTrackTruth");
332  }
333 
335  producesCollector.produces<TrackingVertexCollection>("InitialVertices");
336  }
337 
338  iC.consumes<std::vector<SimTrack>>(simTrackLabel_);
339  iC.consumes<std::vector<SimVertex>>(simVertexLabel_);
340  iC.consumes<std::vector<reco::GenParticle>>(genParticleLabel_);
341  iC.consumes<std::vector<int>>(genParticleLabel_);
342  iC.consumes<std::vector<int>>(hepMCproductLabel_);
343 
344  // Fill the collection tags
345  const edm::ParameterSet &simHitCollectionConfig = config.getParameterSet("simHitCollections");
346  std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
347 
348  for (const auto &parameterName : parameterNames) {
349  std::vector<edm::InputTag> tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
350  collectionTags_.insert(collectionTags_.end(), tags.begin(), tags.end());
351  }
352 
353  for (const auto &collectionTag : collectionTags_) {
354  iC.consumes<std::vector<PSimHit>>(collectionTag);
355  }
356 }
357 
360  unmergedOutput_.pTrackingParticles = std::make_unique<TrackingParticleCollection>();
361  unmergedOutput_.pTrackingVertices = std::make_unique<TrackingVertexCollection>();
363  const_cast<edm::Event &>(event).getRefBeforePut<TrackingParticleCollection>();
364  unmergedOutput_.refTrackingVertexes = const_cast<edm::Event &>(event).getRefBeforePut<TrackingVertexCollection>();
365  }
366 
368  mergedOutput_.pTrackingParticles = std::make_unique<TrackingParticleCollection>();
369  mergedOutput_.pTrackingVertices = std::make_unique<TrackingVertexCollection>();
371  const_cast<edm::Event &>(event).getRefBeforePut<TrackingParticleCollection>("MergedTrackTruth");
373  const_cast<edm::Event &>(event).getRefBeforePut<TrackingVertexCollection>("MergedTrackTruth");
374  }
375 
377  pInitialVertices_ = std::make_unique<TrackingVertexCollection>();
378  }
379 }
380 
387 
389  // Call the templated version that does the same for both signal and pileup
390  // events
391 
393  event.getByLabel(hepMCproductLabel_, hepmc);
394 
395  accumulateEvent(event, setup, hepmc);
396 }
397 
399  edm::EventSetup const &setup,
400  edm::StreamID const &) {
401  // If this bunch crossing is outside the user configured limit, don't do
402  // anything.
403  if (event.bunchCrossing() >= -static_cast<int>(maximumPreviousBunchCrossing_) &&
404  event.bunchCrossing() <= static_cast<int>(maximumSubsequentBunchCrossing_)) {
405  // edm::LogInfo(messageCategory_) << "Analysing pileup event for bunch
406  // crossing " << event.bunchCrossing();
407 
408  // simply create empty handle as we do not have a HepMCProduct in PU anyway
410  accumulateEvent(event, setup, hepmc);
411  } else
412  edm::LogInfo(messageCategory_) << "Skipping pileup event for bunch crossing " << event.bunchCrossing();
413 }
414 
417  edm::LogInfo("TrackingTruthAccumulator")
418  << "Adding " << unmergedOutput_.pTrackingParticles->size() << " TrackingParticles and "
419  << unmergedOutput_.pTrackingVertices->size() << " TrackingVertexs to the event.";
420 
423  }
424 
426  edm::LogInfo("TrackingTruthAccumulator")
427  << "Adding " << mergedOutput_.pTrackingParticles->size() << " merged TrackingParticles and "
428  << mergedOutput_.pTrackingVertices->size() << " merged TrackingVertexs to the event.";
429 
430  event.put(std::move(mergedOutput_.pTrackingParticles), "MergedTrackTruth");
431  event.put(std::move(mergedOutput_.pTrackingVertices), "MergedTrackTruth");
432  }
433 
435  edm::LogInfo("TrackingTruthAccumulator")
436  << "Adding " << pInitialVertices_->size() << " initial TrackingVertexs to the event.";
437 
438  event.put(std::move(pInitialVertices_), "InitialVertices");
439  }
440 }
441 
442 template <class T>
444  const edm::EventSetup &setup,
445  const edm::Handle<edm::HepMCProduct> &hepMCproduct) {
446  //
447  // Get the collections
448  //
452  edm::Handle<std::vector<int>> hGenParticleIndices;
453 
454  event.getByLabel(simTrackLabel_, hSimTracks);
455  event.getByLabel(simVertexLabel_, hSimVertices);
456 
457  try {
458  event.getByLabel(genParticleLabel_, hGenParticles);
459  event.getByLabel(genParticleLabel_, hGenParticleIndices);
460  } catch (cms::Exception &exception) {
461  //
462  // The Monte Carlo is not always available, e.g. for pileup events. The
463  // information is only used if it's available, but for some reason the
464  // PileUpEventPrincipal wrapper throws an exception here rather than waiting
465  // to see if the handle is used (as is the case for edm::Event). So I just
466  // want to catch this exception and use the normal handle checking later on.
467  //
468  }
469 
470  // Retrieve tracker topology from geometry
471  edm::ESHandle<TrackerTopology> tTopoHandle;
472  setup.get<TrackerTopologyRcd>().get(tTopoHandle);
473  const TrackerTopology *const tTopo = tTopoHandle.product();
474 
475  // Run through the collections and work out the decay chain of each
476  // track/vertex. The information in SimTrack and SimVertex only allows
477  // traversing upwards, but this will allow traversal in both directions. This
478  // is required for things like grouping electrons that bremsstrahlung as one
479  // TrackingParticle if "mergedBremsstrahlung" is set in the config file.
480  DecayChain decayChain(*hSimTracks, *hSimVertices);
481 
482  // I only want to create these collections if they're actually required
483  std::unique_ptr<::OutputCollectionWrapper> pUnmergedCollectionWrapper;
484  std::unique_ptr<::OutputCollectionWrapper> pMergedCollectionWrapper;
486  pUnmergedCollectionWrapper = std::make_unique<::OutputCollectionWrapper>(decayChain, unmergedOutput_);
488  pMergedCollectionWrapper = std::make_unique<::OutputCollectionWrapper>(decayChain, mergedOutput_);
489 
490  std::vector<const PSimHit *> simHitPointers;
491  fillSimHits(simHitPointers, event, setup);
492  TrackingParticleFactory objectFactory(decayChain,
493  hGenParticles,
494  hepMCproduct,
495  hGenParticleIndices,
496  simHitPointers,
498  volumeZ_,
501 
502 #if defined(DO_DEBUG_TESTING)
503  // While I'm testing, perform some checks.
504  // TODO - drop this call once I'm happy it works in all situations.
505  decayChain.integrityCheck();
506 #endif
507 
508  TrackingParticleSelector *pSelector = nullptr;
509  if (selectorFlag_)
510  pSelector = &selector_;
511 
512  // Run over all of the SimTracks, but because I'm interested in the decay
513  // hierarchy do it through the DecayChainTrack objects. These are looped over
514  // in sequence here but they have the hierarchy information for the functions
515  // called to traverse the decay chain.
516 
517  for (size_t index = 0; index < decayChain.decayTracksSize; ++index) {
518  ::DecayChainTrack *pDecayTrack = &decayChain.decayTracks[index];
519  const SimTrack &simTrack = hSimTracks->at(pDecayTrack->simTrackIndex);
520 
521  // Perform some quick checks to see if we can drop out early. Note that
522  // these are a subset of the cuts in the selector_ so the created
523  // TrackingParticle could still fail. The selector_ requires the full
524  // TrackingParticle to be made however, which can be computationally
525  // expensive.
526  if (chargedOnly_ && simTrack.charge() == 0)
527  continue;
528  if (signalOnly_ && (simTrack.eventId().bunchCrossing() != 0 || simTrack.eventId().event() != 0))
529  continue;
530 
531  // Also perform a check to see if the production vertex is inside the
532  // tracker volume (if required).
534  const SimVertex &simVertex = hSimVertices->at(pDecayTrack->pParentVertex->simVertexIndex);
535  if (!objectFactory.vectorIsInsideVolume(simVertex.position()))
536  continue;
537  }
538 
539  // This function creates the TrackinParticle and adds it to the collection
540  // if it passes the selection criteria specified in the configuration. If
541  // the config specifies adding ancestors, the function is called recursively
542  // to do that.
543  ::addTrack(pDecayTrack,
544  pSelector,
545  pUnmergedCollectionWrapper.get(),
546  pMergedCollectionWrapper.get(),
547  objectFactory,
549  tTopo);
550  }
551 
552  // If configured to create a collection of initial vertices, add them from
553  // this bunch crossing. No selection is applied on this collection, but it
554  // also has no links to the TrackingParticle decay products. There are a lot
555  // of "initial vertices", I'm not entirely sure what they all are (nuclear
556  // interactions in the detector maybe?), but the one for the main event is the
557  // one with vertexId==0.
559  // Pretty sure the one with vertexId==0 is always the first one, but doesn't
560  // hurt to check
561  for (const auto &pRootVertex : decayChain.rootVertices) {
562  const SimVertex &vertex = hSimVertices->at(decayChain.rootVertices[0]->simVertexIndex);
563  if (vertex.vertexId() != 0)
564  continue;
565 
566  pInitialVertices_->push_back(objectFactory.createTrackingVertex(pRootVertex));
567  break;
568  }
569  }
570 }
571 
572 template <class T>
573 void TrackingTruthAccumulator::fillSimHits(std::vector<const PSimHit *> &returnValue,
574  const T &event,
575  const edm::EventSetup &setup) {
576  // loop over the collections
577  for (const auto &collectionTag : collectionTags_) {
579  event.getByLabel(collectionTag, hSimHits);
580 
581  // TODO - implement removing the dead modules
582  for (const auto &simHit : *hSimHits) {
583  returnValue.push_back(&simHit);
584  }
585 
586  } // end of loop over InputTags
587 
588  // sort the SimHits according to their time of flight,
589  // necessary for looping over them "in order" in
590  // TrackingParticleFactory::createTrackingParticle()
591  std::sort(returnValue.begin(), returnValue.end(), [](const PSimHit *a, const PSimHit *b) {
592  const auto atof =
593  edm::isFinite(a->timeOfFlight()) ? a->timeOfFlight() : std::numeric_limits<decltype(a->timeOfFlight())>::max();
594  const auto btof =
595  edm::isFinite(b->timeOfFlight()) ? b->timeOfFlight() : std::numeric_limits<decltype(b->timeOfFlight())>::max();
596  return atof < btof;
597  });
598 }
599 
600 //---------------------------------------------------------------------------------
601 //---------------------------------------------------------------------------------
602 //---------------------------------------------------------------------------------
603 //------ ------
604 //------ End of the definitions for the TrackingTruthAccumulator methods.
605 //------
606 //------ Definitions for the functions and classes declared in the unnamed
607 //------
608 //------ namespace are below. Documentation for those is above, where ------
609 //------ they're declared. ------
610 //------ ------
611 //---------------------------------------------------------------------------------
612 //---------------------------------------------------------------------------------
613 //---------------------------------------------------------------------------------
614 
615 namespace // Unnamed namespace for things only used in this file
616 {
617  //---------------------------------------------------------------------------------
618  //---------------------------------------------------------------------------------
619  //---- TrackingParticleFactory methods
620  //----------------------------------------
621  //---------------------------------------------------------------------------------
622  //---------------------------------------------------------------------------------
623 
624  ::TrackingParticleFactory::TrackingParticleFactory(const ::DecayChain &decayChain,
625  const edm::Handle<std::vector<reco::GenParticle>> &hGenParticles,
626  const edm::Handle<edm::HepMCProduct> &hepMCproduct,
627  const edm::Handle<std::vector<int>> &hHepMCGenParticleIndices,
628  const std::vector<const PSimHit *> &simHits,
629  double volumeRadius,
630  double volumeZ,
631  double vertexDistanceCut,
632  bool allowDifferentProcessTypes)
633  : decayChain_(decayChain),
634  hGenParticles_(hGenParticles),
635  hepMCproduct_(hepMCproduct),
636  simHits_(simHits),
637  volumeRadius_(volumeRadius),
638  volumeZ_(volumeZ),
639  vertexDistanceCut2_(vertexDistanceCut * vertexDistanceCut),
640  allowDifferentProcessTypeForDifferentDetectors_(allowDifferentProcessTypes) {
641  // Need to create a multimap to get from a SimTrackId to all of the hits in
642  // it. The SimTrackId is an unsigned int.
643  for (size_t index = 0; index < simHits_.size(); ++index) {
644  trackIdToHitIndex_.insert(std::make_pair(simHits_[index]->trackId(), index));
645  }
646 
647  if (hHepMCGenParticleIndices.isValid()) // Monte Carlo might not be available
648  // for the pileup events
649  {
650  genParticleIndices_.resize(hHepMCGenParticleIndices->size() + 1);
651 
652  // What I need is the reverse mapping of this vector. The sizes are already
653  // equivalent because I set the size in the initialiser list.
654  for (size_t recoGenParticleIndex = 0; recoGenParticleIndex < hHepMCGenParticleIndices->size();
655  ++recoGenParticleIndex) {
656  size_t hepMCGenParticleIndex = (*hHepMCGenParticleIndices)[recoGenParticleIndex];
657 
658  // They should be the same size, give or take a fencepost error, so this
659  // should never happen - but just in case
660  if (genParticleIndices_.size() <= hepMCGenParticleIndex)
661  genParticleIndices_.resize(hepMCGenParticleIndex + 1);
662 
663  genParticleIndices_[hepMCGenParticleIndex] = recoGenParticleIndex;
664  }
665  }
666  }
667 
668  TrackingParticle TrackingParticleFactory::createTrackingParticle(const ::DecayChainTrack *pChainTrack,
669  const TrackerTopology *tTopo) const {
671  typedef math::XYZPoint Vector;
672 
673  const SimTrack &simTrack = decayChain_.getSimTrack(pChainTrack);
674  const SimVertex &parentSimVertex = decayChain_.getSimVertex(pChainTrack->pParentVertex);
675 
676  LorentzVector position(0, 0, 0, 0);
677  if (!simTrack.noVertex())
678  position = parentSimVertex.position();
679 
680  int pdgId = simTrack.type();
681 
682  TrackingParticle returnValue;
683  // N.B. The sim track is added a few lines below, the parent and decay
684  // vertices are added in another function later on.
685 
686  //
687  // If there is some valid Monte Carlo for this track, take some information
688  // from that. Only do so if it is from the signal event however. Not sure why
689  // but that's what the old code did.
690  //
691  if (simTrack.eventId().event() == 0 &&
692  simTrack.eventId().bunchCrossing() == 0) // if this is a track in the signal event
693  {
694  int hepMCGenParticleIndex = simTrack.genpartIndex();
695  if (hepMCGenParticleIndex >= 0 && hepMCGenParticleIndex < static_cast<int>(genParticleIndices_.size()) &&
696  hGenParticles_.isValid()) {
697  int recoGenParticleIndex = genParticleIndices_[hepMCGenParticleIndex];
698  reco::GenParticleRef generatorParticleRef(hGenParticles_, recoGenParticleIndex);
699  pdgId = generatorParticleRef->pdgId();
700  returnValue.addGenParticle(generatorParticleRef);
701  }
702  }
703 
704  returnValue.addG4Track(simTrack);
705 
706  // I need to run over the sim hits and count up the different types of hits.
707  // To be honest I don't fully understand this next section of code, I copied
708  // it from the old TrackingTruthProducer to provide the same results. The
709  // different types of hits that I need to count are:
710  size_t matchedHits = 0; // As far as I can tell, this is the number of tracker layers with hits
711  // on them, i.e. taking account of overlaps.
712  size_t numberOfHits = 0; // The total number of hits not taking account of overlaps.
713  size_t numberOfTrackerHits = 0; // The number of tracker hits not taking account of overlaps.
714 
715  bool init = true;
716  int processType = 0;
717  int particleType = 0;
718  int oldLayer = 0;
719  int newLayer = 0;
720  DetId oldDetector;
721  DetId newDetector;
722 
723  // Loop over the SimHits associated to this SimTrack
724  // in the order defined by time of flight, which is
725  // probably the best quantity available for going
726  // through the hits "in order" (ok, most important is
727  // to get the first hit right because processType and
728  // particleType are taken from it)
729  for (auto iHitIndex = trackIdToHitIndex_.lower_bound(simTrack.trackId()),
730  end = trackIdToHitIndex_.upper_bound(simTrack.trackId());
731  iHitIndex != end;
732  ++iHitIndex) {
733  const auto &pSimHit = simHits_[iHitIndex->second];
734 
735  // Skip hits with particle type different from SimTrack pdgId
736  if (pSimHit->particleType() != pdgId)
737  continue;
738 
739  // Initial condition for consistent simhit selection
740  if (init) {
741  processType = pSimHit->processType();
742  particleType = pSimHit->particleType();
743  newDetector = DetId(pSimHit->detUnitId());
744  init = false;
745  }
746 
747  oldDetector = newDetector;
748  newDetector = DetId(pSimHit->detUnitId());
749 
750  // Fast sim seems to have different processType between tracker and muons,
751  // so if this flag has been set allow the processType to change if the
752  // detector changes.
753  if (allowDifferentProcessTypeForDifferentDetectors_ && newDetector.det() != oldDetector.det())
754  processType = pSimHit->processType();
755 
756  // Check for delta and interaction products discards
757  if (processType == pSimHit->processType() && particleType == pSimHit->particleType()) {
758  ++numberOfHits;
759  oldLayer = newLayer;
760  newLayer = 0;
761  if (newDetector.det() == DetId::Tracker) {
762  ++numberOfTrackerHits;
763 
764  newLayer = tTopo->layer(newDetector);
765 
766  // Count hits using layers for glued detectors
767  if ((oldLayer != newLayer || (oldLayer == newLayer && oldDetector.subdetId() != newDetector.subdetId())))
768  ++matchedHits;
769  }
770  }
771  } // end of loop over the sim hits for this sim track
772 
773  returnValue.setNumberOfTrackerLayers(matchedHits);
774  returnValue.setNumberOfHits(numberOfHits);
775  returnValue.setNumberOfTrackerHits(numberOfTrackerHits);
776 
777  return returnValue;
778  }
779 
780  TrackingVertex TrackingParticleFactory::createTrackingVertex(const ::DecayChainVertex *pChainVertex) const {
782  typedef math::XYZPoint Vector;
784 
785  const SimVertex &simVertex = decayChain_.getSimVertex(pChainVertex);
786 
787  bool isInVolume = this->vectorIsInsideVolume(simVertex.position());
788 
789  TrackingVertex returnValue(simVertex.position(), isInVolume, simVertex.eventId());
790 
791  // add the SimVertex to the TrackingVertex
792  returnValue.addG4Vertex(simVertex);
793 
794  // also add refs to nearby HepMC::GenVertexs; the way this is done (i.e. based
795  // on the position) is transcribed over from the old TrackingTruthProducer
796  if (simVertex.eventId().event() == 0 && simVertex.eventId().bunchCrossing() == 0 &&
797  hepMCproduct_.isValid()) // if this is a track in the signal event
798  {
799  const HepMC::GenEvent *genEvent = hepMCproduct_->GetEvent();
800 
801  if (genEvent != nullptr) {
802  Vector tvPosition(returnValue.position().x(), returnValue.position().y(), returnValue.position().z());
803 
804  for (HepMC::GenEvent::vertex_const_iterator iGenVertex = genEvent->vertices_begin();
805  iGenVertex != genEvent->vertices_end();
806  ++iGenVertex) {
807  HepMC::ThreeVector rawPosition = (*iGenVertex)->position();
808 
809  Vector genPosition(rawPosition.x() * 0.1, rawPosition.y() * 0.1, rawPosition.z() * 0.1);
810 
811  auto distance2 = (tvPosition - genPosition).mag2();
812 
813  if (distance2 < vertexDistanceCut2_)
814  returnValue.addGenVertex(GenVertexRef(hepMCproduct_, (*iGenVertex)->barcode()));
815  }
816  }
817  }
818 
819  return returnValue;
820  }
821 
822  bool ::TrackingParticleFactory::vectorIsInsideVolume(const math::XYZTLorentzVectorD &vector) const {
823  return (vector.Pt() < volumeRadius_ && std::abs(vector.z()) < volumeZ_);
824  }
825 
826  //---------------------------------------------------------------------------------
827  //---------------------------------------------------------------------------------
828  //---- DecayChain methods
829  //-----------------------------------------------------
830  //---------------------------------------------------------------------------------
831  //---------------------------------------------------------------------------------
832 
833  ::DecayChain::DecayChain(const std::vector<SimTrack> &trackCollection, const std::vector<SimVertex> &vertexCollection)
834  : decayTracksSize(trackCollection.size()),
835  decayVerticesSize(vertexCollection.size()),
836  decayTracks_(new DecayChainTrack[decayTracksSize]),
837  decayVertices_(new DecayChainVertex[decayVerticesSize]),
838  simTrackCollection_(trackCollection),
839  simVertexCollection_(vertexCollection),
840  decayTracks(decayTracks_), // These const references map onto the actual
841  // members for public const access
842  decayVertices(decayVertices_),
843  rootVertices(rootVertices_) {
844  // I need some maps to be able to get object pointers from the track/vertex ID
845  std::map<int, ::DecayChainTrack *> trackIdToDecayTrack;
846  std::map<int, ::DecayChainVertex *> vertexIdToDecayVertex;
847 
848  // First create a DecayChainTrack for every SimTrack and make a note of the
849  // trackIds in the map. Also add a pointer to the daughter list of the parent
850  // DecayChainVertex, which might include creating the vertex object if it
851  // doesn't already exist.
852  size_t decayVertexIndex = 0; // The index of the next free slot in the DecayChainVertex array.
853  for (size_t index = 0; index < trackCollection.size(); ++index) {
854  ::DecayChainTrack *pDecayTrack = &decayTracks_[index]; // Get a pointer for ease of use
855 
856  // This is the array index of the SimTrack that this DecayChainTrack
857  // corresponds to. At the moment this is a 1 to 1 relationship with the
858  // DecayChainTrack index, but they won't necessarily be accessed through the
859  // array later so it's still required to store it.
860  pDecayTrack->simTrackIndex = index;
861 
862  trackIdToDecayTrack[trackCollection[index].trackId()] = pDecayTrack;
863 
864  int parentVertexIndex = trackCollection[index].vertIndex();
865  if (parentVertexIndex >= 0) {
866  // Get the DecayChainVertex corresponding to this SimVertex, or initialise
867  // it if it hasn't been done already.
868  ::DecayChainVertex *&pParentVertex = vertexIdToDecayVertex[parentVertexIndex];
869  if (pParentVertex == nullptr) {
870  // Note that I'm using a reference, so changing pParentVertex will
871  // change the entry in the map too.
872  pParentVertex = &decayVertices_[decayVertexIndex];
873  ++decayVertexIndex;
874  pParentVertex->simVertexIndex = parentVertexIndex;
875  }
876  pParentVertex->daughterTracks.push_back(pDecayTrack);
877  pDecayTrack->pParentVertex = pParentVertex;
878  } else
879  throw std::runtime_error(
880  "TrackingTruthAccumulator: Found a track with "
881  "an invalid parent vertex index.");
882  }
883 
884  // This assert was originally in to check the internal consistency of the
885  // decay chain. Fast sim pileup seems to have a load of vertices with no
886  // tracks pointing to them though, so fast sim fails this assert if pileup is
887  // added. I don't think the problem is vital however, so if the assert is
888  // taken out these extra vertices are ignored.
889  // assert( vertexIdToDecayVertex.size()==vertexCollection.size() &&
890  // vertexCollection.size()==decayVertexIndex );
891 
892  // I still need to set DecayChainTrack::daughterVertices and
893  // DecayChainVertex::pParentTrack. The information to do this comes from
894  // SimVertex::parentIndex. I couldn't do this before because I need all of the
895  // DecayChainTracks initialised.
896  for (auto &decayVertexMapPair : vertexIdToDecayVertex) {
897  ::DecayChainVertex *pDecayVertex = decayVertexMapPair.second;
898  int parentTrackIndex = vertexCollection[pDecayVertex->simVertexIndex].parentIndex();
899  if (parentTrackIndex != -1) {
900  std::map<int, ::DecayChainTrack *>::iterator iParentTrackMapPair = trackIdToDecayTrack.find(parentTrackIndex);
901  if (iParentTrackMapPair == trackIdToDecayTrack.end()) {
902  std::stringstream errorStream;
903  errorStream << "TrackingTruthAccumulator: Something has gone wrong "
904  "with the indexing. Parent track index is "
905  << parentTrackIndex << ".";
906  throw std::runtime_error(errorStream.str());
907  }
908 
909  ::DecayChainTrack *pParentTrackHierarchy = iParentTrackMapPair->second;
910 
911  pParentTrackHierarchy->daughterVertices.push_back(pDecayVertex);
912  pDecayVertex->pParentTrack = pParentTrackHierarchy;
913  } else
914  rootVertices_.push_back(pDecayVertex); // Has no parent so is at the top of the decay chain.
915  } // end of loop over the vertexIdToDecayVertex map
916 
918 
919  } // end of ::DecayChain constructor
920 
921 #if defined(DO_DEBUG_TESTING)
922  // Function documentation is with the declaration above. This function is only
923  // used for testing.
924  void ::DecayChain::integrityCheck() {
925  //
926  // Start off checking the tracks
927  //
928  for (size_t index = 0; index < decayTracksSize; ++index) {
929  const auto &decayTrack = decayTracks[index];
930  //
931  // Tracks should always have a production vertex
932  //
933  if (decayTrack.pParentVertex == NULL)
934  throw std::runtime_error(
935  "TrackingTruthAccumulator.cc integrityCheck(): "
936  "Found DecayChainTrack with no parent vertex.");
937 
938  //
939  // Make sure the parent has this as a child. Also make sure it's only listed
940  // once.
941  //
942  size_t numberOfTimesListed = 0;
943  for (const auto pSiblingTrack : decayTrack.pParentVertex->daughterTracks) {
944  if (pSiblingTrack == &decayTrack)
945  ++numberOfTimesListed;
946  }
947  if (numberOfTimesListed != 1)
948  throw std::runtime_error(
949  "TrackingTruthAccumulator.cc integrityCheck(): "
950  "Found DecayChainTrack whose parent does not "
951  "have it listed once and only once as a child.");
952 
953  //
954  // Make sure all of the children have this listed as a parent.
955  //
956  for (const auto pDaughterVertex : decayTrack.daughterVertices) {
957  if (pDaughterVertex->pParentTrack != &decayTrack)
958  throw std::runtime_error(
959  "TrackingTruthAccumulator.cc integrityCheck(): Found "
960  "DecayChainTrack whose child does not have it listed as the "
961  "parent.");
962  }
963 
964  //
965  // Follow the chain up to the root vertex, and make sure that is listed in
966  // rootVertices
967  //
968  const DecayChainVertex *pAncestorVertex = decayTrack.pParentVertex;
969  while (pAncestorVertex->pParentTrack != NULL) {
970  if (pAncestorVertex->pParentTrack->pParentVertex == NULL)
971  throw std::runtime_error(
972  "TrackingTruthAccumulator.cc integrityCheck(): Found "
973  "DecayChainTrack with no parent vertex higher in the decay chain.");
974  pAncestorVertex = pAncestorVertex->pParentTrack->pParentVertex;
975  }
976  if (std::find(rootVertices.begin(), rootVertices.end(), pAncestorVertex) == rootVertices.end()) {
977  throw std::runtime_error(
978  "TrackingTruthAccumulator.cc integrityCheck(): Found DecayChainTrack "
979  "whose root vertex is not recorded anywhere.");
980  }
981  } // end of loop over decayTracks
982 
983  //
984  // Now check the vertices
985  //
986  for (size_t index = 0; index < decayVerticesSize; ++index) {
987  const auto &decayVertex = decayVertices[index];
988 
989  //
990  // Make sure this, or a vertex higher in the chain, is in the list of root
991  // vertices.
992  //
993  const DecayChainVertex *pAncestorVertex = &decayVertex;
994  while (pAncestorVertex->pParentTrack != NULL) {
995  if (pAncestorVertex->pParentTrack->pParentVertex == NULL)
996  throw std::runtime_error(
997  "TrackingTruthAccumulator.cc integrityCheck(): Found "
998  "DecayChainTrack with no parent vertex higher in the vertex decay "
999  "chain.");
1000  pAncestorVertex = pAncestorVertex->pParentTrack->pParentVertex;
1001  }
1002  if (std::find(rootVertices.begin(), rootVertices.end(), pAncestorVertex) == rootVertices.end()) {
1003  throw std::runtime_error(
1004  "TrackingTruthAccumulator.cc integrityCheck(): Found DecayChainTrack "
1005  "whose root vertex is not recorded anywhere.");
1006  }
1007 
1008  //
1009  // Make sure the parent has this listed in its daughters once and only once.
1010  //
1011  if (decayVertex.pParentTrack != NULL) {
1012  size_t numberOfTimesListed = 0;
1013  for (const auto pSibling : decayVertex.pParentTrack->daughterVertices) {
1014  if (pSibling == &decayVertex)
1015  ++numberOfTimesListed;
1016  }
1017  if (numberOfTimesListed != 1)
1018  throw std::runtime_error(
1019  "TrackingTruthAccumulator.cc integrityCheck(): Found "
1020  "DecayChainVertex whose parent does not have it listed once and "
1021  "only once as a child.");
1022  }
1023 
1024  //
1025  // Make sure all of the children have this listed as the parent
1026  //
1027  for (const auto pDaughter : decayVertex.daughterTracks) {
1028  if (pDaughter->pParentVertex != &decayVertex)
1029  throw std::runtime_error(
1030  "TrackingTruthAccumulator.cc integrityCheck(): Found "
1031  "DecayChainVertex whose child does not have it listed as the "
1032  "parent.");
1033  }
1034  } // end of loop over decay vertices
1035 
1036  std::cout << "TrackingTruthAccumulator.cc integrityCheck() completed successfully" << std::endl;
1037  } // end of ::DecayChain::integrityCheck()
1038 #endif
1039 
1040  void ::DecayChain::findBrem(const std::vector<SimTrack> &trackCollection,
1041  const std::vector<SimVertex> &vertexCollection) {
1042  for (size_t index = 0; index < decayVerticesSize; ++index) {
1043  auto &vertex = decayVertices_[index];
1044 
1045  // Make sure parent is an electron
1046  if (vertex.pParentTrack == nullptr)
1047  continue;
1048  int parentTrackPDG = trackCollection[vertex.pParentTrack->simTrackIndex].type();
1049  if (std::abs(parentTrackPDG) != 11)
1050  continue;
1051 
1052  size_t numberOfElectrons = 0;
1053  size_t numberOfNonElectronsOrPhotons = 0;
1054  for (auto &pDaughterTrack : vertex.daughterTracks) {
1055  const auto &simTrack = trackCollection[pDaughterTrack->simTrackIndex];
1056  if (simTrack.type() == 11 || simTrack.type() == -11)
1057  ++numberOfElectrons;
1058  else if (simTrack.type() != 22)
1059  ++numberOfNonElectronsOrPhotons;
1060  }
1061  if (numberOfElectrons == 1 && numberOfNonElectronsOrPhotons == 0) {
1062  // This is a valid brem, run through and tell all daughters to use the
1063  // parent as the brem
1064  for (auto &pDaughterTrack : vertex.daughterTracks)
1065  pDaughterTrack->pMergedBremSource = vertex.pParentTrack;
1066  vertex.pMergedBremSource = vertex.pParentTrack->pParentVertex;
1067  }
1068  }
1069  } // end of ::DecayChain::findBrem()
1070 
1071  //---------------------------------------------------------------------------------
1072  //---------------------------------------------------------------------------------
1073  //---- OutputCollectionWrapper methods
1074  //----------------------------------------
1075  //---------------------------------------------------------------------------------
1076  //---------------------------------------------------------------------------------
1077 
1078  ::OutputCollectionWrapper::OutputCollectionWrapper(const ::DecayChain &decayChain,
1080  : output_(outputCollections),
1081  trackingParticleIndices_(decayChain.decayTracksSize, -1),
1082  trackingVertexIndices_(decayChain.decayVerticesSize, -1) {
1083  // No operation besides the initialiser list
1084  }
1085 
1086  TrackingParticle * ::OutputCollectionWrapper::addTrackingParticle(const ::DecayChainTrack *pDecayTrack,
1087  const TrackingParticle &trackingParticle) {
1088  if (trackingParticleIndices_[pDecayTrack->simTrackIndex] != -1)
1089  throw std::runtime_error(
1090  "OutputCollectionWrapper::addTrackingParticle - "
1091  "trying to add a particle twice");
1092 
1093  trackingParticleIndices_[pDecayTrack->simTrackIndex] = output_.pTrackingParticles->size();
1094  output_.pTrackingParticles->push_back(trackingParticle);
1095 
1096  // Clear any associations in case there were any beforehand
1097  output_.pTrackingParticles->back().clearDecayVertices();
1098  output_.pTrackingParticles->back().clearParentVertex();
1099 
1100  // Associate to the objects that are already in the output collections
1101  associateToExistingObjects(pDecayTrack);
1102 
1103  return &output_.pTrackingParticles->back();
1104  }
1105 
1106  TrackingVertex * ::OutputCollectionWrapper::addTrackingVertex(const ::DecayChainVertex *pDecayVertex,
1107  const TrackingVertex &trackingVertex) {
1108  if (trackingVertexIndices_[pDecayVertex->simVertexIndex] != -1)
1109  throw std::runtime_error(
1110  "OutputCollectionWrapper::addTrackingVertex - "
1111  "trying to add a vertex twice");
1112 
1113  trackingVertexIndices_[pDecayVertex->simVertexIndex] = output_.pTrackingVertices->size();
1114  output_.pTrackingVertices->push_back(trackingVertex);
1115 
1116  // Associate the new vertex to any parents or children that are already in the
1117  // output collections
1118  associateToExistingObjects(pDecayVertex);
1119 
1120  return &output_.pTrackingVertices->back();
1121  }
1122 
1123  TrackingParticle * ::OutputCollectionWrapper::getTrackingParticle(const ::DecayChainTrack *pDecayTrack) {
1124  const int index = trackingParticleIndices_[pDecayTrack->simTrackIndex];
1125  if (index == -1)
1126  return nullptr;
1127  else
1128  return &(*output_.pTrackingParticles)[index];
1129  }
1130 
1131  TrackingVertex * ::OutputCollectionWrapper::getTrackingVertex(const ::DecayChainVertex *pDecayVertex) {
1132  const int index = trackingVertexIndices_[pDecayVertex->simVertexIndex];
1133  if (index == -1)
1134  return nullptr;
1135  else
1136  return &(*output_.pTrackingVertices)[index];
1137  }
1138 
1139  TrackingParticleRef OutputCollectionWrapper::getRef(const ::DecayChainTrack *pDecayTrack) {
1140  const int index = trackingParticleIndices_[pDecayTrack->simTrackIndex];
1141  if (index == -1)
1142  throw std::runtime_error(
1143  "OutputCollectionWrapper::getRefTrackingParticle - ref requested for a "
1144  "non existent TrackingParticle");
1145  else
1146  return TrackingParticleRef(output_.refTrackingParticles, index);
1147  }
1148 
1149  TrackingVertexRef OutputCollectionWrapper::getRef(const ::DecayChainVertex *pDecayVertex) {
1150  const int index = trackingVertexIndices_[pDecayVertex->simVertexIndex];
1151  if (index == -1)
1152  throw std::runtime_error(
1153  "OutputCollectionWrapper::getRefTrackingParticle - ref requested for a "
1154  "non existent TrackingVertex");
1155  else
1156  return TrackingVertexRef(output_.refTrackingVertexes, index);
1157  }
1158 
1159  void ::OutputCollectionWrapper::setProxy(const ::DecayChainTrack *pOriginalTrack,
1160  const ::DecayChainTrack *pProxyTrack) {
1161  int &index = trackingParticleIndices_[pOriginalTrack->simTrackIndex];
1162  if (index != -1)
1163  throw std::runtime_error(
1164  "OutputCollectionWrapper::setProxy() was called for a TrackingParticle "
1165  "that has already been created");
1166  // Note that index is a reference so this call changes the value in the vector
1167  // too
1168  index = trackingParticleIndices_[pProxyTrack->simTrackIndex];
1169  }
1170 
1171  void ::OutputCollectionWrapper::setProxy(const ::DecayChainVertex *pOriginalVertex,
1172  const ::DecayChainVertex *pProxyVertex) {
1173  int &index = trackingVertexIndices_[pOriginalVertex->simVertexIndex];
1174  const int newIndex = trackingVertexIndices_[pProxyVertex->simVertexIndex];
1175 
1176  if (index != -1 && index != newIndex)
1177  throw std::runtime_error(
1178  "OutputCollectionWrapper::setProxy() was called for a TrackingVertex "
1179  "that has already been created");
1180 
1181  // Note that index is a reference so this call changes the value in the vector
1182  // too
1183  index = newIndex;
1184  }
1185 
1186  void ::OutputCollectionWrapper::associateToExistingObjects(const ::DecayChainVertex *pChainVertex) {
1187  // First make sure the DecayChainVertex supplied has been turned into a
1188  // TrackingVertex
1189  TrackingVertex *pTrackingVertex = getTrackingVertex(pChainVertex);
1190  if (pTrackingVertex == nullptr)
1191  throw std::runtime_error("associateToExistingObjects was passed a non existent TrackingVertex");
1192 
1193  //
1194  // Associate to the parent track (if there is one)
1195  //
1196  ::DecayChainTrack *pParentChainTrack = pChainVertex->pParentTrack;
1197  if (pParentChainTrack != nullptr) // Make sure there is a parent track first
1198  {
1199  // There is a parent track, but it might not have been turned into a
1200  // TrackingParticle yet
1201  TrackingParticle *pParentTrackingParticle = getTrackingParticle(pParentChainTrack);
1202  if (pParentTrackingParticle != nullptr) {
1203  pParentTrackingParticle->addDecayVertex(getRef(pChainVertex));
1204  pTrackingVertex->addParentTrack(getRef(pParentChainTrack));
1205  }
1206  // Don't worry about the "else" case - the parent track might not
1207  // necessarily get added to the output collection at all. A check is done on
1208  // daughter vertices when tracks are added, so the association will be
1209  // picked up then.
1210  }
1211 
1212  //
1213  // A parent TrackingVertex is always associated to a daughter TrackingParticle
1214  // when the TrackingParticle is created. Hence there is no need to check the
1215  // list of daughter tracks.
1216  //
1217  }
1218 
1219  void ::OutputCollectionWrapper::associateToExistingObjects(const ::DecayChainTrack *pChainTrack) {
1220  //
1221  // First make sure this DecayChainTrack has been turned into a
1222  // TrackingParticle
1223  //
1224  TrackingParticle *pTrackingParticle = getTrackingParticle(pChainTrack);
1225  if (pTrackingParticle == nullptr)
1226  throw std::runtime_error(
1227  "associateToExistingObjects was passed a non "
1228  "existent TrackingParticle");
1229 
1230  // Get the parent vertex. This should always already have been turned into a
1231  // TrackingVertex, and there should always be a parent DecayChainVertex.
1232  ::DecayChainVertex *pParentChainVertex = pChainTrack->pParentVertex;
1233  TrackingVertex *pParentTrackingVertex = getTrackingVertex(pParentChainVertex);
1234 
1235  //
1236  // First associate to the parent vertex.
1237  //
1238  pTrackingParticle->setParentVertex(getRef(pParentChainVertex));
1239  pParentTrackingVertex->addDaughterTrack(getRef(pChainTrack));
1240 
1241  // If there are any daughter vertices that have already been made into a
1242  // TrackingVertex make sure they know about each other. If the daughter
1243  // vertices haven't been made into TrackingVertexs yet, I won't do anything
1244  // and create the association when the vertex is made.
1245  for (auto pDaughterChainVertex : pChainTrack->daughterVertices) {
1246  TrackingVertex *pDaughterTrackingVertex = getTrackingVertex(pDaughterChainVertex);
1247  if (pDaughterTrackingVertex != nullptr) {
1248  pTrackingParticle->addDecayVertex(getRef(pDaughterChainVertex));
1249  pDaughterTrackingVertex->addParentTrack(getRef(pChainTrack));
1250  }
1251  }
1252  }
1253 
1254  TrackingParticle *addTrackAndParentVertex(::DecayChainTrack *pDecayTrack,
1255  const TrackingParticle &trackingParticle,
1256  ::OutputCollectionWrapper *pOutput) {
1257  // See if this TrackingParticle has already been created (could be if the
1258  // DecayChainTracks are looped over in a funny order). If it has then there's
1259  // no need to do anything.
1260  TrackingParticle *pTrackingParticle = pOutput->getTrackingParticle(pDecayTrack);
1261  if (pTrackingParticle == nullptr) {
1262  // Need to make sure the production vertex has been created first
1263  if (pOutput->getTrackingVertex(pDecayTrack->pParentVertex) == nullptr) {
1264  // TrackingVertex doesn't exist in the output collection yet. However,
1265  // it's already been created in the addTrack() function and a temporary
1266  // reference to it set in the TrackingParticle. I'll use that reference to
1267  // create a copy in the output collection. When the TrackingParticle is
1268  // added to the output collection a few lines below the temporary
1269  // reference to the parent vertex will be cleared, and the correct one
1270  // referring to the output collection will be set.
1271  pOutput->addTrackingVertex(pDecayTrack->pParentVertex, *trackingParticle.parentVertex());
1272  }
1273 
1274  pTrackingParticle = pOutput->addTrackingParticle(pDecayTrack, trackingParticle);
1275  }
1276 
1277  return pTrackingParticle;
1278  }
1279 
1280  void addTrack(::DecayChainTrack *pDecayChainTrack,
1281  const TrackingParticleSelector *pSelector,
1282  ::OutputCollectionWrapper *pUnmergedOutput,
1283  ::OutputCollectionWrapper *pMergedOutput,
1284  const ::TrackingParticleFactory &objectFactory,
1285  bool addAncestors,
1286  const TrackerTopology *tTopo) {
1287  if (pDecayChainTrack == nullptr)
1288  return; // This is required for when the addAncestors_ recursive call
1289  // reaches the top of the chain
1290 
1291  // Check to see if this particle has already been processed while traversing
1292  // up the parents of another split in the decay chain. The check in the line
1293  // above only stops when the top of the chain is reached, whereas this will
1294  // stop when a previously traversed split is reached.
1295  { // block to limit the scope of temporary variables
1296  bool alreadyProcessed = true;
1297  if (pUnmergedOutput != nullptr) {
1298  if (pUnmergedOutput->getTrackingParticle(pDecayChainTrack) == nullptr)
1299  alreadyProcessed = false;
1300  }
1301  if (pMergedOutput != nullptr) {
1302  if (pMergedOutput->getTrackingParticle(pDecayChainTrack) == nullptr)
1303  alreadyProcessed = false;
1304  }
1305  if (alreadyProcessed)
1306  return;
1307  }
1308 
1309  // Create a TrackingParticle.
1310  TrackingParticle newTrackingParticle = objectFactory.createTrackingParticle(pDecayChainTrack, tTopo);
1311 
1312  // The selector checks the impact parameters from the vertex, so I need to
1313  // have a valid reference to the parent vertex in the TrackingParticle before
1314  // that can be called. TrackingParticle needs an edm::Ref for the parent
1315  // TrackingVertex though. I still don't know if this is going to be added to
1316  // the collection so I can't take it from there, so I need to create a
1317  // temporary one. When the addTrackAndParentVertex() is called (assuming it
1318  // passes selection) it will use the temporary reference to create a copy of
1319  // the parent vertex, put that in the output collection, and then set the
1320  // reference in the TrackingParticle properly.
1321  TrackingVertexCollection dummyCollection; // Only needed to create an edm::Ref
1322  dummyCollection.push_back(objectFactory.createTrackingVertex(pDecayChainTrack->pParentVertex));
1323  TrackingVertexRef temporaryRef(&dummyCollection, 0);
1324  newTrackingParticle.setParentVertex(temporaryRef);
1325 
1326  // If a selector has been supplied apply it on the new TrackingParticle and
1327  // return if it fails.
1328  if (pSelector) {
1329  if (!(*pSelector)(newTrackingParticle))
1330  return; // Return if the TrackingParticle fails selection
1331  }
1332 
1333  // Add the ancestors first (if required) so that the collection has some kind
1334  // of chronological order. I don't know how important that is but other code
1335  // might assume chronological order. If adding ancestors, no selection is
1336  // applied. Note that I've already checked that all DecayChainTracks have a
1337  // pParentVertex.
1338  if (addAncestors)
1339  addTrack(pDecayChainTrack->pParentVertex->pParentTrack,
1340  nullptr,
1341  pUnmergedOutput,
1342  pMergedOutput,
1343  objectFactory,
1344  addAncestors,
1345  tTopo);
1346 
1347  // If creation of the unmerged collection has been turned off in the config
1348  // this pointer will be null.
1349  if (pUnmergedOutput != nullptr)
1350  addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pUnmergedOutput);
1351 
1352  // If creation of the merged collection has been turned off in the config this
1353  // pointer will be null.
1354  if (pMergedOutput != nullptr) {
1355  ::DecayChainTrack *pBremParentChainTrack = pDecayChainTrack;
1356  while (pBremParentChainTrack->pMergedBremSource != nullptr)
1357  pBremParentChainTrack = pBremParentChainTrack->pMergedBremSource;
1358 
1359  if (pBremParentChainTrack != pDecayChainTrack) {
1360  TrackingParticle *pBremParentTrackingParticle =
1361  addTrackAndParentVertex(pBremParentChainTrack, newTrackingParticle, pMergedOutput);
1362  // The original particle in the bremsstrahlung decay chain has been
1363  // created (or retrieved if it already existed), now copy in the
1364  // extra information.
1365  // TODO - copy extra information.
1366 
1367  if (std::abs(newTrackingParticle.pdgId()) == 22) {
1368  // Photons are added as separate TrackingParticles, but with the
1369  // production vertex changed to be the production vertex of the original
1370  // electron.
1371 
1372  // Set up a proxy, so that all requests for the parent TrackingVertex
1373  // get redirected to the brem parent's TrackingVertex.
1374  pMergedOutput->setProxy(pDecayChainTrack->pParentVertex, pBremParentChainTrack->pParentVertex);
1375 
1376  // Now that pMergedOutput thinks the parent vertex is the brem parent's
1377  // vertex I can call this and it will set the TrackingParticle parent
1378  // vertex correctly to the brem parent vertex.
1379  addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pMergedOutput);
1380  } else if (std::abs(newTrackingParticle.pdgId()) == 11) {
1381  // Electrons have their G4 tracks and SimHits copied to the parent
1382  // TrackingParticle.
1383  for (const auto &trackSegment : newTrackingParticle.g4Tracks()) {
1384  pBremParentTrackingParticle->addG4Track(trackSegment);
1385  }
1386 
1387  // Also copy the generator particle references
1388  for (const auto &genParticleRef : newTrackingParticle.genParticles()) {
1389  pBremParentTrackingParticle->addGenParticle(genParticleRef);
1390  }
1391 
1392  pBremParentTrackingParticle->setNumberOfHits(pBremParentTrackingParticle->numberOfHits() +
1393  newTrackingParticle.numberOfHits());
1394  pBremParentTrackingParticle->setNumberOfTrackerHits(pBremParentTrackingParticle->numberOfTrackerHits() +
1395  newTrackingParticle.numberOfTrackerHits());
1396  pBremParentTrackingParticle->setNumberOfTrackerLayers(pBremParentTrackingParticle->numberOfTrackerLayers() +
1397  newTrackingParticle.numberOfTrackerLayers());
1398 
1399  // Set a proxy in the output collection wrapper so that any attempt to
1400  // get objects for this DecayChainTrack again get redirected to the brem
1401  // parent.
1402  pMergedOutput->setProxy(pDecayChainTrack, pBremParentChainTrack);
1403  }
1404  } else {
1405  // This is not the result of bremsstrahlung so add to the collection as
1406  // normal.
1407  addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pMergedOutput);
1408  }
1409  } // end of "if( pMergedOutput!=NULL )", i.e. end of "if bremsstrahlung
1410  // merging is turned on"
1411 
1412  } // end of addTrack function
1413 
1414 } // namespace
1415 
1416 // Register with the framework
TrackingParticle::numberOfTrackerHits
int numberOfTrackerHits() const
The number of hits in the tracker. Hits on overlaps in the same layer count separately.
Definition: TrackingParticle.h:200
edm::ESHandle::product
T const * product() const
Definition: ESHandle.h:86
TrackingParticle::numberOfTrackerLayers
int numberOfTrackerLayers() const
The number of tracker layers with a hit.
Definition: TrackingParticle.h:209
edm::StreamID
Definition: StreamID.h:30
TrackingParticle::addGenParticle
void addGenParticle(const reco::GenParticleRef &ref)
Definition: TrackingParticle.cc:21
electrons_cff.bool
bool
Definition: electrons_cff.py:393
PixelSubdetector.h
SimVertex
Definition: SimVertex.h:5
MessageLogger.h
ESHandle.h
edm
HLT enums.
Definition: AlignableModifier.h:19
TrackerTopology
Definition: TrackerTopology.h:16
TrackingTruthAccumulator::OutputCollections
Definition: TrackingTruthAccumulator.h:175
DetId::det
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
math::XYZTLorentzVectorD
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
gather_cfg.cout
cout
Definition: gather_cfg.py:144
TrackingParticle::addDecayVertex
void addDecayVertex(const TrackingVertexRef &ref)
Definition: TrackingParticle.cc:35
HLT_FULL_cff.InputTag
InputTag
Definition: HLT_FULL_cff.py:89287
TrackingVertexCollection
std::vector< TrackingVertex > TrackingVertexCollection
Definition: TrackingVertexContainer.h:8
FastTrackerRecHitCombiner_cfi.simHits
simHits
Definition: FastTrackerRecHitCombiner_cfi.py:5
TrackingParticle::parentVertex
const TrackingVertexRef & parentVertex() const
Definition: TrackingParticle.h:90
TrackerTopology::layer
unsigned int layer(const DetId &id) const
Definition: TrackerTopology.cc:47
TrackingTruthAccumulator
Replacement for TrackingTruthProducer in the new pileup mixing setup.
Definition: TrackingTruthAccumulator.h:89
TrackingVertex.h
PileUpEventPrincipal
Definition: PileUpEventPrincipal.h:19
TrackingTruthAccumulator.h
TrackingTruthAccumulator::accumulate
void accumulate(const edm::Event &event, const edm::EventSetup &setup) override
Definition: TrackingTruthAccumulator.cc:388
TrackingParticleSelector
Definition: TrackingParticleSelector.h:16
edm::LogInfo
Log< level::Info, false > LogInfo
Definition: MessageLogger.h:125
spr::find
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
TrackingParticle::setNumberOfTrackerLayers
void setNumberOfTrackerLayers(const int numberOfTrackerLayers)
Definition: TrackingParticle.cc:51
edm::Handle
Definition: AssociativeIterator.h:50
TrackingTruthAccumulator::vertexDistanceCut_
const double vertexDistanceCut_
maximum distance for HepMC::GenVertex to be added to SimVertex
Definition: TrackingTruthAccumulator.h:118
singleTopDQM_cfi.setup
setup
Definition: singleTopDQM_cfi.py:37
TrackingTruthAccumulator::chargedOnly_
bool chargedOnly_
Definition: TrackingTruthAccumulator.h:155
TrackingTruthAccumulator::mergedOutput_
OutputCollections mergedOutput_
Definition: TrackingTruthAccumulator.h:184
HepMC::GenEvent
Definition: hepmc_rootio.cc:9
edm::Ref< TrackingParticleCollection >
TrackingTruthAccumulator::selectorFlag_
bool selectorFlag_
Definition: TrackingTruthAccumulator.h:151
Vector
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
GenParticle.h
HLTEgPhaseIITestSequence_cff.simVertex
simVertex
Definition: HLTEgPhaseIITestSequence_cff.py:51
config
Definition: config.py:1
TrackingTruthAccumulator::accumulateEvent
void accumulateEvent(const T &event, const edm::EventSetup &setup, const edm::Handle< edm::HepMCProduct > &hepMCproduct)
Both forms of accumulate() delegate to this templated method.
Definition: TrackingTruthAccumulator.cc:443
DetId
Definition: DetId.h:17
TrackerTopology.h
TrackingTruthAccumulator::signalOnly_
bool signalOnly_
Definition: TrackingTruthAccumulator.h:158
PSimHit.h
TrackerTopologyRcd.h
TrackingParticle::numberOfHits
int numberOfHits() const
Gives the total number of hits, including muon hits. Hits on overlaps in the same layer count separat...
Definition: TrackingParticle.h:195
rpcPointValidation_cfi.simHit
simHit
Definition: rpcPointValidation_cfi.py:24
TrackingParticle::setNumberOfTrackerHits
void setNumberOfTrackerHits(int numberOfTrackerHits)
Definition: TrackingParticle.cc:49
TrackingTruthAccumulator::OutputCollections::refTrackingParticles
TrackingParticleRefProd refTrackingParticles
Definition: TrackingTruthAccumulator.h:178
TrackingParticle
Monte Carlo truth information used for tracking validation.
Definition: TrackingParticle.h:29
mps_fire.end
end
Definition: mps_fire.py:242
TrackingTruthAccumulator::createUnmergedCollection_
const bool createUnmergedCollection_
Definition: TrackingTruthAccumulator.h:133
reco::modules::TrackingParticleSelector
SingleObjectSelector< TrackingParticleCollection, ::TrackingParticleSelector > TrackingParticleSelector
Definition: TrackingParticleSelector.cc:17
edm::ESHandle< TrackerTopology >
TrackingVertexRef
edm::Ref< TrackingVertexCollection > TrackingVertexRef
Definition: TrackingVertexContainer.h:9
PileUpEventPrincipal.h
edm::ConsumesCollector::consumes
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
Definition: ConsumesCollector.h:55
TrackingTruthAccumulator::OutputCollections::pTrackingVertices
std::unique_ptr< TrackingVertexCollection > pTrackingVertices
Definition: TrackingTruthAccumulator.h:177
b
double b
Definition: hdecay.h:118
TrackingTruthAccumulator::TrackingTruthAccumulator
TrackingTruthAccumulator(const edm::ParameterSet &config, edm::ProducesCollector, edm::ConsumesCollector &iC)
Definition: TrackingTruthAccumulator.cc:260
DetId::subdetId
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum)
Definition: DetId.h:48
EncodedTruthId.h
TrackingTruthAccumulator::simVertexLabel_
const edm::InputTag simVertexLabel_
Definition: TrackingTruthAccumulator.h:145
cppFunctionSkipper.exception
exception
Definition: cppFunctionSkipper.py:10
TrackingParticle::genParticles
const reco::GenParticleRefVector & genParticles() const
Definition: TrackingParticle.h:88
bphysicsOniaDQM_cfi.vertex
vertex
Definition: bphysicsOniaDQM_cfi.py:7
edm::ParameterSet
Definition: ParameterSet.h:47
math::XYZPoint
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
a
double a
Definition: hdecay.h:119
DetId::Tracker
Definition: DetId.h:25
TrackingTruthAccumulator::messageCategory_
const std::string messageCategory_
Definition: TrackingTruthAccumulator.h:112
duplicaterechits_cfi.trackCollection
trackCollection
Definition: duplicaterechits_cfi.py:4
Event.h
TrackingTruthAccumulator::pInitialVertices_
std::unique_ptr< TrackingVertexCollection > pInitialVertices_
Definition: TrackingTruthAccumulator.h:185
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
edm::getRef
helper::MatcherGetRef< C >::ref_type getRef(const Handle< C > &c, size_t k)
Definition: getRef.h:28
TrackingTruthAccumulator::OutputCollections::refTrackingVertexes
TrackingVertexRefProd refTrackingVertexes
Definition: TrackingTruthAccumulator.h:179
TrackingVertex
Definition: TrackingVertex.h:22
TrackingTruthAccumulator::finalizeEvent
void finalizeEvent(edm::Event &event, const edm::EventSetup &setup) override
Definition: TrackingTruthAccumulator.cc:415
muonSimHitMatcherPSet.simTrack
simTrack
Definition: muonSimHitMatcherPSet.py:4
TrackingTruthAccumulator::collectionTags_
std::vector< edm::InputTag > collectionTags_
Definition: TrackingTruthAccumulator.h:146
trackingTruthProducer_cfi.volumeZ
volumeZ
Definition: trackingTruthProducer_cfi.py:33
position
static int position[264][3]
Definition: ReadPGInfo.cc:289
TrackingTruthAccumulator::fillSimHits
void fillSimHits(std::vector< const PSimHit * > &returnValue, const T &event, const edm::EventSetup &setup)
Fills the supplied vector with pointers to the SimHits, checking for bad modules if required.
Definition: TrackingTruthAccumulator.cc:573
TrackingTruthAccumulator::maximumPreviousBunchCrossing_
const unsigned int maximumPreviousBunchCrossing_
Definition: TrackingTruthAccumulator.h:125
createfilelist.int
int
Definition: createfilelist.py:10
DecayChain
adjacency_list< listS, vecS, directedS, VertexMotherParticleProperty, EdgeParticleClustersProperty > DecayChain
Definition: CaloTruthAccumulator.cc:124
TrackingTruthAccumulator::maximumSubsequentBunchCrossing_
const unsigned int maximumSubsequentBunchCrossing_
Definition: TrackingTruthAccumulator.h:130
TrackingParticle::pdgId
int pdgId() const
PDG ID.
Definition: TrackingParticle.h:61
TrackingTruthAccumulator::initializeEvent
void initializeEvent(const edm::Event &event, const edm::EventSetup &setup) override
Definition: TrackingTruthAccumulator.cc:358
mag2
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
Definition: Basic3DVectorLD.h:124
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
TrackingParticle::setNumberOfHits
void setNumberOfHits(int numberOfHits)
Definition: TrackingParticle.cc:47
EgammaValidation_cff.pdgId
pdgId
Definition: EgammaValidation_cff.py:118
TrackingTruthAccumulator::allowDifferentProcessTypeForDifferentDetectors_
bool allowDifferentProcessTypeForDifferentDetectors_
When counting hits, allows hits in different detectors to have a different process type.
Definition: TrackingTruthAccumulator.h:170
edm::ProducesCollector::produces
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
Definition: ProducesCollector.h:52
edm::EventSetup
Definition: EventSetup.h:57
TrackingTruthAccumulator::selector_
TrackingParticleSelector selector_
Definition: TrackingTruthAccumulator.h:152
edm::LogError
Log< level::Error, false > LogError
Definition: MessageLogger.h:123
CoreSimVertex::position
const math::XYZTLorentzVectorD & position() const
Definition: CoreSimVertex.h:21
get
#define get
TrackingTruthAccumulator::OutputCollections::pTrackingParticles
std::unique_ptr< TrackingParticleCollection > pTrackingParticles
Definition: TrackingTruthAccumulator.h:176
TrackingTruthAccumulator::volumeRadius_
const double volumeRadius_
Definition: TrackingTruthAccumulator.h:115
NULL
#define NULL
Definition: scimark2.h:8
reco::JetExtendedAssociation::LorentzVector
math::PtEtaPhiELorentzVectorF LorentzVector
Definition: JetExtendedAssociation.h:25
TrackingParticle::setParentVertex
void setParentVertex(const TrackingVertexRef &ref)
Definition: TrackingParticle.cc:33
TrackingParticle.h
TrackingTruthAccumulator::simTrackLabel_
const edm::InputTag simTrackLabel_
Definition: TrackingTruthAccumulator.h:144
TrackingTruthAccumulator::genParticleLabel_
edm::InputTag genParticleLabel_
Definition: TrackingTruthAccumulator.h:147
eostools.move
def move(src, dest)
Definition: eostools.py:511
edm::ProducesCollector
Definition: ProducesCollector.h:43
init
Definition: init.py:1
isFinite.h
SimTrack
Definition: SimTrack.h:6
genWeightsTable_cfi.genEvent
genEvent
Definition: genWeightsTable_cfi.py:4
T
long double T
Definition: Basic3DVectorLD.h:48
spclusmultinvestigator_cfi.vertexCollection
vertexCollection
Definition: spclusmultinvestigator_cfi.py:4
LorentzVector
math::XYZTLorentzVector LorentzVector
Definition: HLTMuonMatchAndPlot.h:49
trackingTruthProducer_cfi.volumeRadius
volumeRadius
Definition: trackingTruthProducer_cfi.py:32
TrackingVertex::addDaughterTrack
void addDaughterTrack(const TrackingParticleRef &)
Definition: TrackingVertex.cc:27
trackingTruthProducer_cfi.vertexDistanceCut
vertexDistanceCut
Definition: trackingTruthProducer_cfi.py:34
TrackingTruthAccumulator::unmergedOutput_
OutputCollections unmergedOutput_
Definition: TrackingTruthAccumulator.h:183
TrackingTruthAccumulator::ignoreTracksOutsideVolume_
const bool ignoreTracksOutsideVolume_
Definition: TrackingTruthAccumulator.h:119
TrackingParticleCollection
std::vector< TrackingParticle > TrackingParticleCollection
Definition: TrackingParticleFwd.h:8
EventSetup.h
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
triggerMatcherToHLTDebug_cfi.tags
tags
Definition: triggerMatcherToHLTDebug_cfi.py:9
AlignmentPI::index
index
Definition: AlignmentPayloadInspectorHelper.h:46
ConsumesCollector.h
cms::Exception
Definition: Exception.h:70
DigiAccumulatorMixModFactory.h
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::isFinite
constexpr bool isFinite(T x)
TrackerTopologyRcd
Definition: TrackerTopologyRcd.h:10
ParameterSet.h
GenVertexRef
edm::Ref< edm::HepMCProduct, HepMC::GenVertex > GenVertexRef
Definition: TrackingVertex.cc:6
TrackingTruthAccumulator::volumeZ_
const double volumeZ_
Definition: TrackingTruthAccumulator.h:116
DEFINE_DIGI_ACCUMULATOR
#define DEFINE_DIGI_ACCUMULATOR(type)
Definition: DigiAccumulatorMixModFactory.h:31
TrackingParticleRef
edm::Ref< TrackingParticleCollection > TrackingParticleRef
Definition: TrackingParticleFwd.h:10
PSimHit
Definition: PSimHit.h:15
HepMCProduct.h
PbPb_ZMuSkimMuonDPG_cff.particleType
particleType
Definition: PbPb_ZMuSkimMuonDPG_cff.py:27
event
Definition: event.py:1
edm::Event
Definition: Event.h:73
TrackingParticle::y
double y() const
Same as rapidity().
Definition: TrackingParticle.h:157
StripSubdetector.h
TrackingTruthAccumulator::createMergedCollection_
const bool createMergedCollection_
Definition: TrackingTruthAccumulator.h:134
TrackingParticle::addG4Track
void addG4Track(const SimTrack &t)
Definition: TrackingParticle.cc:23
edm::ConsumesCollector
Definition: ConsumesCollector.h:45
TrackingTruthAccumulator::hepMCproductLabel_
edm::InputTag hepMCproductLabel_
Needed to add HepMC::GenVertex to SimVertex.
Definition: TrackingTruthAccumulator.h:149
findQualityFiles.size
size
Write out results.
Definition: findQualityFiles.py:443
TrackingParticle::g4Tracks
const std::vector< SimTrack > & g4Tracks() const
Definition: TrackingParticle.h:89
TrackingTruthAccumulator::addAncestors_
const bool addAncestors_
Definition: TrackingTruthAccumulator.h:140
TrackingTruthAccumulator::createInitialVertexCollection_
const bool createInitialVertexCollection_
Definition: TrackingTruthAccumulator.h:137
TrackingVertex::addParentTrack
void addParentTrack(const TrackingParticleRef &)
Definition: TrackingVertex.cc:29