CMS 3D CMS Logo

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