77 struct DecayChainTrack {
79 struct DecayChainVertex *pParentVertex;
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() {}
94 struct DecayChainVertex {
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) {}
118 const size_t decayTracksSize;
119 const size_t decayVerticesSize;
121 #if defined(DO_DEBUG_TESTING)
128 void integrityCheck();
130 const SimTrack &getSimTrack(const ::DecayChainTrack *pDecayTrack)
const {
131 return simTrackCollection_.at(pDecayTrack->simTrackIndex);
133 const SimVertex &getSimVertex(const ::DecayChainVertex *pDecayVertex)
const {
134 return simVertexCollection_.at(pDecayVertex->simVertexIndex);
139 std::unique_ptr<::DecayChainTrack[]> decayTracks_;
140 std::unique_ptr<::DecayChainVertex[]> decayVertices_;
144 std::vector<::DecayChainVertex *> rootVertices_;
147 const std::vector<SimTrack> &simTrackCollection_;
148 const std::vector<SimVertex> &simVertexCollection_;
151 const std::unique_ptr<::DecayChainTrack[]> &decayTracks;
152 const std::unique_ptr<::DecayChainVertex[]> &decayVertices;
154 const std::vector<::DecayChainVertex *> &rootVertices;
163 class TrackingParticleFactory {
166 const edm::Handle<std::vector<reco::GenParticle>> &hGenParticles,
168 const edm::Handle<std::vector<int>> &hHepMCGenParticleIndices,
169 const std::vector<const PSimHit *> &
simHits,
173 bool allowDifferentProcessTypes);
175 TrackingVertex createTrackingVertex(
const DecayChainVertex *pVertex)
const;
182 std::vector<int> genParticleIndices_;
183 const std::vector<const PSimHit *> &simHits_;
184 const double volumeRadius_;
185 const double volumeZ_;
186 const double vertexDistanceCut2_;
188 std::multimap<unsigned int, size_t> trackIdToHitIndex_;
189 bool allowDifferentProcessTypeForDifferentDetectors_;
200 class OutputCollectionWrapper {
202 OutputCollectionWrapper(
const DecayChain &decayChain,
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);
217 void associateToExistingObjects(const ::DecayChainVertex *pChainVertex);
218 void associateToExistingObjects(const ::DecayChainTrack *pChainTrack);
220 std::vector<int> trackingParticleIndices_;
221 std::vector<int> trackingVertexIndices_;
231 ::OutputCollectionWrapper *pOutput);
239 void addTrack(::DecayChainTrack *pDecayChainTrack,
241 ::OutputCollectionWrapper *pUnmergedOutput,
242 ::OutputCollectionWrapper *pMergedOutput,
243 const ::TrackingParticleFactory &objectFactory,
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")),
280 allowDifferentProcessTypeForDifferentDetectors_(
config.getParameter<
bool>(
"allowDifferentSimHitProcesses")) {
287 "\"createMergedBremsstrahlung\" have been"
288 <<
"set to false, which means no collections will be created";
292 if (
config.exists(
"select")) {
346 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
348 for (
const auto ¶meterName : parameterNames) {
349 std::vector<edm::InputTag>
tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
354 iC.
consumes<std::vector<PSimHit>>(collectionTag);
436 <<
"Adding " <<
pInitialVertices_->size() <<
" initial TrackingVertexs to the event.";
480 DecayChain decayChain(*hSimTracks, *hSimVertices);
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_);
490 std::vector<const PSimHit *> simHitPointers;
492 TrackingParticleFactory objectFactory(decayChain,
502 #if defined(DO_DEBUG_TESTING)
505 decayChain.integrityCheck();
518 ::DecayChainTrack *pDecayTrack = &decayChain.decayTracks[
index];
534 const SimVertex &
simVertex = hSimVertices->at(pDecayTrack->pParentVertex->simVertexIndex);
535 if (!objectFactory.vectorIsInsideVolume(
simVertex.position()))
543 ::addTrack(pDecayTrack,
545 pUnmergedCollectionWrapper.get(),
546 pMergedCollectionWrapper.get(),
561 for (
const auto &pRootVertex : decayChain.rootVertices) {
562 const SimVertex &
vertex = hSimVertices->at(decayChain.rootVertices[0]->simVertexIndex);
563 if (
vertex.vertexId() != 0)
579 event.getByLabel(collectionTag, hSimHits);
582 for (
const auto &
simHit : *hSimHits) {
583 returnValue.push_back(&
simHit);
591 std::sort(returnValue.begin(), returnValue.end(), [](
const PSimHit *
a,
const PSimHit *
b) {
593 edm::isFinite(
a->timeOfFlight()) ?
a->timeOfFlight() : std::numeric_limits<decltype(
a->timeOfFlight())>::
max();
595 edm::isFinite(
b->timeOfFlight()) ?
b->timeOfFlight() : std::numeric_limits<decltype(
b->timeOfFlight())>::
max();
625 const edm::Handle<std::vector<reco::GenParticle>> &hGenParticles,
627 const edm::Handle<std::vector<int>> &hHepMCGenParticleIndices,
628 const std::vector<const PSimHit *> &
simHits,
632 bool allowDifferentProcessTypes)
633 : decayChain_(decayChain),
634 hGenParticles_(hGenParticles),
635 hepMCproduct_(hepMCproduct),
640 allowDifferentProcessTypeForDifferentDetectors_(allowDifferentProcessTypes) {
644 trackIdToHitIndex_.insert(std::make_pair(simHits_[
index]->trackId(),
index));
647 if (hHepMCGenParticleIndices.isValid())
650 genParticleIndices_.resize(hHepMCGenParticleIndices->size() + 1);
654 for (
size_t recoGenParticleIndex = 0; recoGenParticleIndex < hHepMCGenParticleIndices->size();
655 ++recoGenParticleIndex) {
656 size_t hepMCGenParticleIndex = (*hHepMCGenParticleIndices)[recoGenParticleIndex];
660 if (genParticleIndices_.size() <= hepMCGenParticleIndex)
661 genParticleIndices_.resize(hepMCGenParticleIndex + 1);
663 genParticleIndices_[hepMCGenParticleIndex] = recoGenParticleIndex;
668 TrackingParticle TrackingParticleFactory::createTrackingParticle(const ::DecayChainTrack *pChainTrack,
674 const SimVertex &parentSimVertex = decayChain_.getSimVertex(pChainTrack->pParentVertex);
691 if (
simTrack.eventId().event() == 0 &&
692 simTrack.eventId().bunchCrossing() == 0)
694 int hepMCGenParticleIndex =
simTrack.genpartIndex();
695 if (hepMCGenParticleIndex >= 0 && hepMCGenParticleIndex < static_cast<int>(genParticleIndices_.size()) &&
696 hGenParticles_.isValid()) {
697 int recoGenParticleIndex = genParticleIndices_[hepMCGenParticleIndex];
699 pdgId = generatorParticleRef->pdgId();
710 size_t matchedHits = 0;
712 size_t numberOfHits = 0;
713 size_t numberOfTrackerHits = 0;
729 for (
auto iHitIndex = trackIdToHitIndex_.lower_bound(
simTrack.trackId()),
730 end = trackIdToHitIndex_.upper_bound(
simTrack.trackId());
733 const auto &pSimHit = simHits_[iHitIndex->second];
736 if (pSimHit->particleType() !=
pdgId)
741 processType = pSimHit->processType();
743 newDetector =
DetId(pSimHit->detUnitId());
747 oldDetector = newDetector;
748 newDetector =
DetId(pSimHit->detUnitId());
753 if (allowDifferentProcessTypeForDifferentDetectors_ && newDetector.
det() != oldDetector.
det())
754 processType = pSimHit->processType();
757 if (processType == pSimHit->processType() &&
particleType == pSimHit->particleType()) {
762 ++numberOfTrackerHits;
764 newLayer = tTopo->
layer(newDetector);
767 if ((oldLayer != newLayer || (oldLayer == newLayer && oldDetector.
subdetId() != newDetector.
subdetId())))
780 TrackingVertex TrackingParticleFactory::createTrackingVertex(const ::DecayChainVertex *pChainVertex)
const {
787 bool isInVolume = this->vectorIsInsideVolume(
simVertex.position());
797 hepMCproduct_.isValid())
802 Vector tvPosition(returnValue.position().x(), returnValue.position().
y(), returnValue.position().z());
804 for (HepMC::GenEvent::vertex_const_iterator iGenVertex =
genEvent->vertices_begin();
805 iGenVertex !=
genEvent->vertices_end();
807 HepMC::ThreeVector rawPosition = (*iGenVertex)->position();
809 Vector genPosition(rawPosition.x() * 0.1, rawPosition.y() * 0.1, rawPosition.z() * 0.1);
811 auto distance2 = (tvPosition - genPosition).
mag2();
813 if (distance2 < vertexDistanceCut2_)
814 returnValue.addGenVertex(
GenVertexRef(hepMCproduct_, (*iGenVertex)->barcode()));
836 decayTracks_(new DecayChainTrack[decayTracksSize]),
837 decayVertices_(new DecayChainVertex[decayVerticesSize]),
840 decayTracks(decayTracks_),
842 decayVertices(decayVertices_),
843 rootVertices(rootVertices_) {
845 std::map<int, ::DecayChainTrack *> trackIdToDecayTrack;
846 std::map<int, ::DecayChainVertex *> vertexIdToDecayVertex;
852 size_t decayVertexIndex = 0;
854 ::DecayChainTrack *pDecayTrack = &decayTracks_[
index];
860 pDecayTrack->simTrackIndex =
index;
865 if (parentVertexIndex >= 0) {
868 ::DecayChainVertex *&pParentVertex = vertexIdToDecayVertex[parentVertexIndex];
869 if (pParentVertex ==
nullptr) {
872 pParentVertex = &decayVertices_[decayVertexIndex];
874 pParentVertex->simVertexIndex = parentVertexIndex;
876 pParentVertex->daughterTracks.push_back(pDecayTrack);
877 pDecayTrack->pParentVertex = pParentVertex;
879 throw std::runtime_error(
880 "TrackingTruthAccumulator: Found a track with "
881 "an invalid parent vertex index.");
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());
909 ::DecayChainTrack *pParentTrackHierarchy = iParentTrackMapPair->second;
911 pParentTrackHierarchy->daughterVertices.push_back(pDecayVertex);
912 pDecayVertex->pParentTrack = pParentTrackHierarchy;
914 rootVertices_.push_back(pDecayVertex);
921 #if defined(DO_DEBUG_TESTING)
924 void ::DecayChain::integrityCheck() {
929 const auto &decayTrack = decayTracks[
index];
933 if (decayTrack.pParentVertex ==
NULL)
934 throw std::runtime_error(
935 "TrackingTruthAccumulator.cc integrityCheck(): "
936 "Found DecayChainTrack with no parent vertex.");
942 size_t numberOfTimesListed = 0;
943 for (
const auto pSiblingTrack : decayTrack.pParentVertex->daughterTracks) {
944 if (pSiblingTrack == &decayTrack)
945 ++numberOfTimesListed;
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.");
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 "
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;
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.");
987 const auto &decayVertex = decayVertices[
index];
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 "
1000 pAncestorVertex = pAncestorVertex->pParentTrack->pParentVertex;
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.");
1011 if (decayVertex.pParentTrack !=
NULL) {
1012 size_t numberOfTimesListed = 0;
1013 for (
const auto pSibling : decayVertex.pParentTrack->daughterVertices) {
1014 if (pSibling == &decayVertex)
1015 ++numberOfTimesListed;
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.");
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 "
1036 std::cout <<
"TrackingTruthAccumulator.cc integrityCheck() completed successfully" << std::endl;
1040 void ::DecayChain::findBrem(
const std::vector<SimTrack> &
trackCollection,
1046 if (
vertex.pParentTrack ==
nullptr)
1049 if (
std::abs(parentTrackPDG) != 11)
1052 size_t numberOfElectrons = 0;
1053 size_t numberOfNonElectronsOrPhotons = 0;
1054 for (
auto &pDaughterTrack :
vertex.daughterTracks) {
1057 ++numberOfElectrons;
1059 ++numberOfNonElectronsOrPhotons;
1061 if (numberOfElectrons == 1 && numberOfNonElectronsOrPhotons == 0) {
1064 for (
auto &pDaughterTrack :
vertex.daughterTracks)
1065 pDaughterTrack->pMergedBremSource =
vertex.pParentTrack;
1066 vertex.pMergedBremSource =
vertex.pParentTrack->pParentVertex;
1080 : output_(outputCollections),
1081 trackingParticleIndices_(decayChain.decayTracksSize, -1),
1082 trackingVertexIndices_(decayChain.decayVerticesSize, -1) {
1086 TrackingParticle * ::OutputCollectionWrapper::addTrackingParticle(const ::DecayChainTrack *pDecayTrack,
1088 if (trackingParticleIndices_[pDecayTrack->simTrackIndex] != -1)
1089 throw std::runtime_error(
1090 "OutputCollectionWrapper::addTrackingParticle - "
1091 "trying to add a particle twice");
1093 trackingParticleIndices_[pDecayTrack->simTrackIndex] = output_.pTrackingParticles->size();
1094 output_.pTrackingParticles->push_back(trackingParticle);
1097 output_.pTrackingParticles->back().clearDecayVertices();
1098 output_.pTrackingParticles->back().clearParentVertex();
1101 associateToExistingObjects(pDecayTrack);
1103 return &output_.pTrackingParticles->back();
1106 TrackingVertex * ::OutputCollectionWrapper::addTrackingVertex(const ::DecayChainVertex *pDecayVertex,
1108 if (trackingVertexIndices_[pDecayVertex->simVertexIndex] != -1)
1109 throw std::runtime_error(
1110 "OutputCollectionWrapper::addTrackingVertex - "
1111 "trying to add a vertex twice");
1113 trackingVertexIndices_[pDecayVertex->simVertexIndex] = output_.pTrackingVertices->size();
1114 output_.pTrackingVertices->push_back(trackingVertex);
1118 associateToExistingObjects(pDecayVertex);
1120 return &output_.pTrackingVertices->back();
1123 TrackingParticle * ::OutputCollectionWrapper::getTrackingParticle(const ::DecayChainTrack *pDecayTrack) {
1124 const int index = trackingParticleIndices_[pDecayTrack->simTrackIndex];
1128 return &(*output_.pTrackingParticles)[
index];
1131 TrackingVertex * ::OutputCollectionWrapper::getTrackingVertex(const ::DecayChainVertex *pDecayVertex) {
1132 const int index = trackingVertexIndices_[pDecayVertex->simVertexIndex];
1136 return &(*output_.pTrackingVertices)[
index];
1140 const int index = trackingParticleIndices_[pDecayTrack->simTrackIndex];
1142 throw std::runtime_error(
1143 "OutputCollectionWrapper::getRefTrackingParticle - ref requested for a "
1144 "non existent TrackingParticle");
1150 const int index = trackingVertexIndices_[pDecayVertex->simVertexIndex];
1152 throw std::runtime_error(
1153 "OutputCollectionWrapper::getRefTrackingParticle - ref requested for a "
1154 "non existent TrackingVertex");
1159 void ::OutputCollectionWrapper::setProxy(const ::DecayChainTrack *pOriginalTrack,
1160 const ::DecayChainTrack *pProxyTrack) {
1161 int &
index = trackingParticleIndices_[pOriginalTrack->simTrackIndex];
1163 throw std::runtime_error(
1164 "OutputCollectionWrapper::setProxy() was called for a TrackingParticle "
1165 "that has already been created");
1168 index = trackingParticleIndices_[pProxyTrack->simTrackIndex];
1171 void ::OutputCollectionWrapper::setProxy(const ::DecayChainVertex *pOriginalVertex,
1172 const ::DecayChainVertex *pProxyVertex) {
1173 int &
index = trackingVertexIndices_[pOriginalVertex->simVertexIndex];
1174 const int newIndex = trackingVertexIndices_[pProxyVertex->simVertexIndex];
1177 throw std::runtime_error(
1178 "OutputCollectionWrapper::setProxy() was called for a TrackingVertex "
1179 "that has already been created");
1186 void ::OutputCollectionWrapper::associateToExistingObjects(const ::DecayChainVertex *pChainVertex) {
1189 TrackingVertex *pTrackingVertex = getTrackingVertex(pChainVertex);
1190 if (pTrackingVertex ==
nullptr)
1191 throw std::runtime_error(
"associateToExistingObjects was passed a non existent TrackingVertex");
1196 ::DecayChainTrack *pParentChainTrack = pChainVertex->pParentTrack;
1197 if (pParentChainTrack !=
nullptr)
1201 TrackingParticle *pParentTrackingParticle = getTrackingParticle(pParentChainTrack);
1202 if (pParentTrackingParticle !=
nullptr) {
1219 void ::OutputCollectionWrapper::associateToExistingObjects(const ::DecayChainTrack *pChainTrack) {
1225 if (pTrackingParticle ==
nullptr)
1226 throw std::runtime_error(
1227 "associateToExistingObjects was passed a non "
1228 "existent TrackingParticle");
1232 ::DecayChainVertex *pParentChainVertex = pChainTrack->pParentVertex;
1233 TrackingVertex *pParentTrackingVertex = getTrackingVertex(pParentChainVertex);
1245 for (
auto pDaughterChainVertex : pChainTrack->daughterVertices) {
1246 TrackingVertex *pDaughterTrackingVertex = getTrackingVertex(pDaughterChainVertex);
1247 if (pDaughterTrackingVertex !=
nullptr) {
1256 ::OutputCollectionWrapper *pOutput) {
1260 TrackingParticle *pTrackingParticle = pOutput->getTrackingParticle(pDecayTrack);
1261 if (pTrackingParticle ==
nullptr) {
1263 if (pOutput->getTrackingVertex(pDecayTrack->pParentVertex) ==
nullptr) {
1271 pOutput->addTrackingVertex(pDecayTrack->pParentVertex, *trackingParticle.
parentVertex());
1274 pTrackingParticle = pOutput->addTrackingParticle(pDecayTrack, trackingParticle);
1277 return pTrackingParticle;
1280 void addTrack(::DecayChainTrack *pDecayChainTrack,
1282 ::OutputCollectionWrapper *pUnmergedOutput,
1283 ::OutputCollectionWrapper *pMergedOutput,
1284 const ::TrackingParticleFactory &objectFactory,
1287 if (pDecayChainTrack ==
nullptr)
1296 bool alreadyProcessed =
true;
1297 if (pUnmergedOutput !=
nullptr) {
1298 if (pUnmergedOutput->getTrackingParticle(pDecayChainTrack) ==
nullptr)
1299 alreadyProcessed =
false;
1301 if (pMergedOutput !=
nullptr) {
1302 if (pMergedOutput->getTrackingParticle(pDecayChainTrack) ==
nullptr)
1303 alreadyProcessed =
false;
1305 if (alreadyProcessed)
1310 TrackingParticle newTrackingParticle = objectFactory.createTrackingParticle(pDecayChainTrack, tTopo);
1322 dummyCollection.push_back(objectFactory.createTrackingVertex(pDecayChainTrack->pParentVertex));
1329 if (!(*pSelector)(newTrackingParticle))
1339 addTrack(pDecayChainTrack->pParentVertex->pParentTrack,
1349 if (pUnmergedOutput !=
nullptr)
1350 addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pUnmergedOutput);
1354 if (pMergedOutput !=
nullptr) {
1355 ::DecayChainTrack *pBremParentChainTrack = pDecayChainTrack;
1356 while (pBremParentChainTrack->pMergedBremSource !=
nullptr)
1357 pBremParentChainTrack = pBremParentChainTrack->pMergedBremSource;
1359 if (pBremParentChainTrack != pDecayChainTrack) {
1361 addTrackAndParentVertex(pBremParentChainTrack, newTrackingParticle, pMergedOutput);
1374 pMergedOutput->setProxy(pDecayChainTrack->pParentVertex, pBremParentChainTrack->pParentVertex);
1379 addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pMergedOutput);
1383 for (
const auto &trackSegment : newTrackingParticle.
g4Tracks()) {
1384 pBremParentTrackingParticle->
addG4Track(trackSegment);
1388 for (
const auto &genParticleRef : newTrackingParticle.
genParticles()) {
1402 pMergedOutput->setProxy(pDecayChainTrack, pBremParentChainTrack);
1407 addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pMergedOutput);