75 struct DecayChainTrack {
77 struct DecayChainVertex *pParentVertex;
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() {}
92 struct DecayChainVertex {
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) {}
116 const size_t decayTracksSize;
117 const size_t decayVerticesSize;
119 #if defined(DO_DEBUG_TESTING)
126 void integrityCheck();
128 const SimTrack &getSimTrack(const ::DecayChainTrack *pDecayTrack)
const {
129 return simTrackCollection_.at(pDecayTrack->simTrackIndex);
131 const SimVertex &getSimVertex(const ::DecayChainVertex *pDecayVertex)
const {
132 return simVertexCollection_.at(pDecayVertex->simVertexIndex);
137 std::unique_ptr<::DecayChainTrack[]> decayTracks_;
138 std::unique_ptr<::DecayChainVertex[]> decayVertices_;
142 std::vector<::DecayChainVertex *> rootVertices_;
145 const std::vector<SimTrack> &simTrackCollection_;
146 const std::vector<SimVertex> &simVertexCollection_;
149 const std::unique_ptr<::DecayChainTrack[]> &decayTracks;
150 const std::unique_ptr<::DecayChainVertex[]> &decayVertices;
152 const std::vector<::DecayChainVertex *> &rootVertices;
161 class TrackingParticleFactory {
164 const edm::Handle<std::vector<reco::GenParticle>> &hGenParticles,
166 const edm::Handle<std::vector<int>> &hHepMCGenParticleIndices,
167 const std::vector<const PSimHit *> &
simHits,
171 bool allowDifferentProcessTypes);
173 TrackingVertex createTrackingVertex(
const DecayChainVertex *pVertex)
const;
180 std::vector<int> genParticleIndices_;
181 const std::vector<const PSimHit *> &simHits_;
182 const double volumeRadius_;
183 const double volumeZ_;
184 const double vertexDistanceCut2_;
186 std::multimap<unsigned int, size_t> trackIdToHitIndex_;
187 bool allowDifferentProcessTypeForDifferentDetectors_;
198 class OutputCollectionWrapper {
200 OutputCollectionWrapper(
const DecayChain &decayChain,
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);
215 void associateToExistingObjects(const ::DecayChainVertex *pChainVertex);
216 void associateToExistingObjects(const ::DecayChainTrack *pChainTrack);
218 std::vector<int> trackingParticleIndices_;
219 std::vector<int> trackingVertexIndices_;
229 ::OutputCollectionWrapper *pOutput);
237 void addTrack(::DecayChainTrack *pDecayChainTrack,
239 ::OutputCollectionWrapper *pUnmergedOutput,
240 ::OutputCollectionWrapper *pMergedOutput,
241 const ::TrackingParticleFactory &objectFactory,
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")),
278 allowDifferentProcessTypeForDifferentDetectors_(
config.getParameter<
bool>(
"allowDifferentSimHitProcesses")) {
285 "\"createMergedBremsstrahlung\" have been"
286 <<
"set to false, which means no collections will be created";
290 if (
config.exists(
"select")) {
344 std::vector<std::string> parameterNames = simHitCollectionConfig.getParameterNames();
346 for (
const auto ¶meterName : parameterNames) {
347 std::vector<edm::InputTag>
tags = simHitCollectionConfig.getParameter<std::vector<edm::InputTag>>(parameterName);
352 iC.
consumes<std::vector<PSimHit>>(collectionTag);
434 <<
"Adding " <<
pInitialVertices_->size() <<
" initial TrackingVertexs to the event.";
478 DecayChain decayChain(*hSimTracks, *hSimVertices);
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_));
488 std::vector<const PSimHit *> simHitPointers;
490 TrackingParticleFactory objectFactory(decayChain,
500 #if defined(DO_DEBUG_TESTING)
503 decayChain.integrityCheck();
516 ::DecayChainTrack *pDecayTrack = &decayChain.decayTracks[
index];
532 const SimVertex &
simVertex = hSimVertices->at(pDecayTrack->pParentVertex->simVertexIndex);
533 if (!objectFactory.vectorIsInsideVolume(
simVertex.position()))
541 ::addTrack(pDecayTrack,
543 pUnmergedCollectionWrapper.get(),
544 pMergedCollectionWrapper.get(),
559 for (
const auto &pRootVertex : decayChain.rootVertices) {
560 const SimVertex &
vertex = hSimVertices->at(decayChain.rootVertices[0]->simVertexIndex);
561 if (
vertex.vertexId() != 0)
577 event.getByLabel(collectionTag, hSimHits);
580 for (
const auto &
simHit : *hSimHits) {
581 returnValue.push_back(&
simHit);
589 std::sort(returnValue.begin(), returnValue.end(), [](
const PSimHit *
a,
const PSimHit *
b) {
591 edm::isFinite(
a->timeOfFlight()) ?
a->timeOfFlight() : std::numeric_limits<decltype(
a->timeOfFlight())>::
max();
593 edm::isFinite(
b->timeOfFlight()) ?
b->timeOfFlight() : std::numeric_limits<decltype(
b->timeOfFlight())>::
max();
623 const edm::Handle<std::vector<reco::GenParticle>> &hGenParticles,
625 const edm::Handle<std::vector<int>> &hHepMCGenParticleIndices,
626 const std::vector<const PSimHit *> &
simHits,
630 bool allowDifferentProcessTypes)
631 : decayChain_(decayChain),
632 hGenParticles_(hGenParticles),
633 hepMCproduct_(hepMCproduct),
638 allowDifferentProcessTypeForDifferentDetectors_(allowDifferentProcessTypes) {
642 trackIdToHitIndex_.insert(std::make_pair(simHits_[
index]->trackId(),
index));
645 if (hHepMCGenParticleIndices.isValid())
648 genParticleIndices_.resize(hHepMCGenParticleIndices->size() + 1);
652 for (
size_t recoGenParticleIndex = 0; recoGenParticleIndex < hHepMCGenParticleIndices->size();
653 ++recoGenParticleIndex) {
654 size_t hepMCGenParticleIndex = (*hHepMCGenParticleIndices)[recoGenParticleIndex];
658 if (genParticleIndices_.size() <= hepMCGenParticleIndex)
659 genParticleIndices_.resize(hepMCGenParticleIndex + 1);
661 genParticleIndices_[hepMCGenParticleIndex] = recoGenParticleIndex;
666 TrackingParticle TrackingParticleFactory::createTrackingParticle(const ::DecayChainTrack *pChainTrack,
672 const SimVertex &parentSimVertex = decayChain_.getSimVertex(pChainTrack->pParentVertex);
689 if (
simTrack.eventId().event() == 0 &&
690 simTrack.eventId().bunchCrossing() == 0)
692 int hepMCGenParticleIndex =
simTrack.genpartIndex();
693 if (hepMCGenParticleIndex >= 0 && hepMCGenParticleIndex < static_cast<int>(genParticleIndices_.size()) &&
694 hGenParticles_.isValid()) {
695 int recoGenParticleIndex = genParticleIndices_[hepMCGenParticleIndex];
697 pdgId = generatorParticleRef->pdgId();
708 size_t matchedHits = 0;
710 size_t numberOfHits = 0;
711 size_t numberOfTrackerHits = 0;
727 for (
auto iHitIndex = trackIdToHitIndex_.lower_bound(
simTrack.trackId()),
728 end = trackIdToHitIndex_.upper_bound(
simTrack.trackId());
731 const auto &pSimHit = simHits_[iHitIndex->second];
734 if (pSimHit->particleType() !=
pdgId)
739 processType = pSimHit->processType();
741 newDetector =
DetId(pSimHit->detUnitId());
745 oldDetector = newDetector;
746 newDetector =
DetId(pSimHit->detUnitId());
751 if (allowDifferentProcessTypeForDifferentDetectors_ && newDetector.
det() != oldDetector.
det())
752 processType = pSimHit->processType();
755 if (processType == pSimHit->processType() &&
particleType == pSimHit->particleType()) {
760 ++numberOfTrackerHits;
762 newLayer = tTopo->
layer(newDetector);
765 if ((oldLayer != newLayer || (oldLayer == newLayer && oldDetector.
subdetId() != newDetector.
subdetId())))
778 TrackingVertex TrackingParticleFactory::createTrackingVertex(const ::DecayChainVertex *pChainVertex)
const {
785 bool isInVolume = this->vectorIsInsideVolume(
simVertex.position());
795 hepMCproduct_.isValid())
800 Vector tvPosition(returnValue.position().x(), returnValue.position().
y(), returnValue.position().z());
802 for (HepMC::GenEvent::vertex_const_iterator iGenVertex =
genEvent->vertices_begin();
803 iGenVertex !=
genEvent->vertices_end();
805 HepMC::ThreeVector rawPosition = (*iGenVertex)->position();
807 Vector genPosition(rawPosition.x() * 0.1, rawPosition.y() * 0.1, rawPosition.z() * 0.1);
809 auto distance2 = (tvPosition - genPosition).
mag2();
811 if (distance2 < vertexDistanceCut2_)
812 returnValue.addGenVertex(
GenVertexRef(hepMCproduct_, (*iGenVertex)->barcode()));
821 return (vector.Pt() < volumeRadius_ &&
std::abs(vector.z()) < volumeZ_);
834 decayTracks_(new DecayChainTrack[decayTracksSize]),
835 decayVertices_(new DecayChainVertex[decayVerticesSize]),
838 decayTracks(decayTracks_),
840 decayVertices(decayVertices_),
841 rootVertices(rootVertices_) {
843 std::map<int, ::DecayChainTrack *> trackIdToDecayTrack;
844 std::map<int, ::DecayChainVertex *> vertexIdToDecayVertex;
850 size_t decayVertexIndex = 0;
852 ::DecayChainTrack *pDecayTrack = &decayTracks_[
index];
858 pDecayTrack->simTrackIndex =
index;
863 if (parentVertexIndex >= 0) {
866 ::DecayChainVertex *&pParentVertex = vertexIdToDecayVertex[parentVertexIndex];
867 if (pParentVertex ==
nullptr) {
870 pParentVertex = &decayVertices_[decayVertexIndex];
872 pParentVertex->simVertexIndex = parentVertexIndex;
874 pParentVertex->daughterTracks.push_back(pDecayTrack);
875 pDecayTrack->pParentVertex = pParentVertex;
877 throw std::runtime_error(
878 "TrackingTruthAccumulator: Found a track with "
879 "an invalid parent vertex index.");
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());
907 ::DecayChainTrack *pParentTrackHierarchy = iParentTrackMapPair->second;
909 pParentTrackHierarchy->daughterVertices.push_back(pDecayVertex);
910 pDecayVertex->pParentTrack = pParentTrackHierarchy;
912 rootVertices_.push_back(pDecayVertex);
919 #if defined(DO_DEBUG_TESTING)
922 void ::DecayChain::integrityCheck() {
927 const auto &decayTrack = decayTracks[
index];
931 if (decayTrack.pParentVertex ==
NULL)
932 throw std::runtime_error(
933 "TrackingTruthAccumulator.cc integrityCheck(): "
934 "Found DecayChainTrack with no parent vertex.");
940 size_t numberOfTimesListed = 0;
941 for (
const auto pSiblingTrack : decayTrack.pParentVertex->daughterTracks) {
942 if (pSiblingTrack == &decayTrack)
943 ++numberOfTimesListed;
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.");
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 "
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;
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.");
985 const auto &decayVertex = decayVertices[
index];
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 "
998 pAncestorVertex = pAncestorVertex->pParentTrack->pParentVertex;
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.");
1009 if (decayVertex.pParentTrack !=
NULL) {
1010 size_t numberOfTimesListed = 0;
1011 for (
const auto pSibling : decayVertex.pParentTrack->daughterVertices) {
1012 if (pSibling == &decayVertex)
1013 ++numberOfTimesListed;
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.");
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 "
1034 std::cout <<
"TrackingTruthAccumulator.cc integrityCheck() completed successfully" << std::endl;
1038 void ::DecayChain::findBrem(
const std::vector<SimTrack> &
trackCollection,
1044 if (
vertex.pParentTrack ==
nullptr)
1047 if (
std::abs(parentTrackPDG) != 11)
1050 size_t numberOfElectrons = 0;
1051 size_t numberOfNonElectronsOrPhotons = 0;
1052 for (
auto &pDaughterTrack :
vertex.daughterTracks) {
1055 ++numberOfElectrons;
1057 ++numberOfNonElectronsOrPhotons;
1059 if (numberOfElectrons == 1 && numberOfNonElectronsOrPhotons == 0) {
1062 for (
auto &pDaughterTrack :
vertex.daughterTracks)
1063 pDaughterTrack->pMergedBremSource =
vertex.pParentTrack;
1064 vertex.pMergedBremSource =
vertex.pParentTrack->pParentVertex;
1078 : output_(outputCollections),
1079 trackingParticleIndices_(decayChain.decayTracksSize, -1),
1080 trackingVertexIndices_(decayChain.decayVerticesSize, -1) {
1084 TrackingParticle * ::OutputCollectionWrapper::addTrackingParticle(const ::DecayChainTrack *pDecayTrack,
1086 if (trackingParticleIndices_[pDecayTrack->simTrackIndex] != -1)
1087 throw std::runtime_error(
1088 "OutputCollectionWrapper::addTrackingParticle - "
1089 "trying to add a particle twice");
1091 trackingParticleIndices_[pDecayTrack->simTrackIndex] = output_.pTrackingParticles->size();
1092 output_.pTrackingParticles->push_back(trackingParticle);
1095 output_.pTrackingParticles->back().clearDecayVertices();
1096 output_.pTrackingParticles->back().clearParentVertex();
1099 associateToExistingObjects(pDecayTrack);
1101 return &output_.pTrackingParticles->back();
1104 TrackingVertex * ::OutputCollectionWrapper::addTrackingVertex(const ::DecayChainVertex *pDecayVertex,
1106 if (trackingVertexIndices_[pDecayVertex->simVertexIndex] != -1)
1107 throw std::runtime_error(
1108 "OutputCollectionWrapper::addTrackingVertex - "
1109 "trying to add a vertex twice");
1111 trackingVertexIndices_[pDecayVertex->simVertexIndex] = output_.pTrackingVertices->size();
1112 output_.pTrackingVertices->push_back(trackingVertex);
1116 associateToExistingObjects(pDecayVertex);
1118 return &output_.pTrackingVertices->back();
1121 TrackingParticle * ::OutputCollectionWrapper::getTrackingParticle(const ::DecayChainTrack *pDecayTrack) {
1122 const int index = trackingParticleIndices_[pDecayTrack->simTrackIndex];
1126 return &(*output_.pTrackingParticles)[
index];
1129 TrackingVertex * ::OutputCollectionWrapper::getTrackingVertex(const ::DecayChainVertex *pDecayVertex) {
1130 const int index = trackingVertexIndices_[pDecayVertex->simVertexIndex];
1134 return &(*output_.pTrackingVertices)[
index];
1138 const int index = trackingParticleIndices_[pDecayTrack->simTrackIndex];
1140 throw std::runtime_error(
1141 "OutputCollectionWrapper::getRefTrackingParticle - ref requested for a "
1142 "non existent TrackingParticle");
1148 const int index = trackingVertexIndices_[pDecayVertex->simVertexIndex];
1150 throw std::runtime_error(
1151 "OutputCollectionWrapper::getRefTrackingParticle - ref requested for a "
1152 "non existent TrackingVertex");
1157 void ::OutputCollectionWrapper::setProxy(const ::DecayChainTrack *pOriginalTrack,
1158 const ::DecayChainTrack *pProxyTrack) {
1159 int &
index = trackingParticleIndices_[pOriginalTrack->simTrackIndex];
1161 throw std::runtime_error(
1162 "OutputCollectionWrapper::setProxy() was called for a TrackingParticle "
1163 "that has already been created");
1166 index = trackingParticleIndices_[pProxyTrack->simTrackIndex];
1169 void ::OutputCollectionWrapper::setProxy(const ::DecayChainVertex *pOriginalVertex,
1170 const ::DecayChainVertex *pProxyVertex) {
1171 int &
index = trackingVertexIndices_[pOriginalVertex->simVertexIndex];
1172 const int newIndex = trackingVertexIndices_[pProxyVertex->simVertexIndex];
1175 throw std::runtime_error(
1176 "OutputCollectionWrapper::setProxy() was called for a TrackingVertex "
1177 "that has already been created");
1184 void ::OutputCollectionWrapper::associateToExistingObjects(const ::DecayChainVertex *pChainVertex) {
1187 TrackingVertex *pTrackingVertex = getTrackingVertex(pChainVertex);
1188 if (pTrackingVertex ==
nullptr)
1189 throw std::runtime_error(
"associateToExistingObjects was passed a non existent TrackingVertex");
1194 ::DecayChainTrack *pParentChainTrack = pChainVertex->pParentTrack;
1195 if (pParentChainTrack !=
nullptr)
1199 TrackingParticle *pParentTrackingParticle = getTrackingParticle(pParentChainTrack);
1200 if (pParentTrackingParticle !=
nullptr) {
1217 void ::OutputCollectionWrapper::associateToExistingObjects(const ::DecayChainTrack *pChainTrack) {
1223 if (pTrackingParticle ==
nullptr)
1224 throw std::runtime_error(
1225 "associateToExistingObjects was passed a non "
1226 "existent TrackingParticle");
1230 ::DecayChainVertex *pParentChainVertex = pChainTrack->pParentVertex;
1231 TrackingVertex *pParentTrackingVertex = getTrackingVertex(pParentChainVertex);
1243 for (
auto pDaughterChainVertex : pChainTrack->daughterVertices) {
1244 TrackingVertex *pDaughterTrackingVertex = getTrackingVertex(pDaughterChainVertex);
1245 if (pDaughterTrackingVertex !=
nullptr) {
1254 ::OutputCollectionWrapper *pOutput) {
1258 TrackingParticle *pTrackingParticle = pOutput->getTrackingParticle(pDecayTrack);
1259 if (pTrackingParticle ==
nullptr) {
1261 if (pOutput->getTrackingVertex(pDecayTrack->pParentVertex) ==
nullptr) {
1269 pOutput->addTrackingVertex(pDecayTrack->pParentVertex, *trackingParticle.
parentVertex());
1272 pTrackingParticle = pOutput->addTrackingParticle(pDecayTrack, trackingParticle);
1275 return pTrackingParticle;
1278 void addTrack(::DecayChainTrack *pDecayChainTrack,
1280 ::OutputCollectionWrapper *pUnmergedOutput,
1281 ::OutputCollectionWrapper *pMergedOutput,
1282 const ::TrackingParticleFactory &objectFactory,
1285 if (pDecayChainTrack ==
nullptr)
1294 bool alreadyProcessed =
true;
1295 if (pUnmergedOutput !=
nullptr) {
1296 if (pUnmergedOutput->getTrackingParticle(pDecayChainTrack) ==
nullptr)
1297 alreadyProcessed =
false;
1299 if (pMergedOutput !=
nullptr) {
1300 if (pMergedOutput->getTrackingParticle(pDecayChainTrack) ==
nullptr)
1301 alreadyProcessed =
false;
1303 if (alreadyProcessed)
1308 TrackingParticle newTrackingParticle = objectFactory.createTrackingParticle(pDecayChainTrack, tTopo);
1320 dummyCollection.push_back(objectFactory.createTrackingVertex(pDecayChainTrack->pParentVertex));
1327 if (!(*pSelector)(newTrackingParticle))
1337 addTrack(pDecayChainTrack->pParentVertex->pParentTrack,
1347 if (pUnmergedOutput !=
nullptr)
1348 addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pUnmergedOutput);
1352 if (pMergedOutput !=
nullptr) {
1353 ::DecayChainTrack *pBremParentChainTrack = pDecayChainTrack;
1354 while (pBremParentChainTrack->pMergedBremSource !=
nullptr)
1355 pBremParentChainTrack = pBremParentChainTrack->pMergedBremSource;
1357 if (pBremParentChainTrack != pDecayChainTrack) {
1359 addTrackAndParentVertex(pBremParentChainTrack, newTrackingParticle, pMergedOutput);
1372 pMergedOutput->setProxy(pDecayChainTrack->pParentVertex, pBremParentChainTrack->pParentVertex);
1377 addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pMergedOutput);
1381 for (
const auto &trackSegment : newTrackingParticle.
g4Tracks()) {
1382 pBremParentTrackingParticle->
addG4Track(trackSegment);
1386 for (
const auto &genParticleRef : newTrackingParticle.
genParticles()) {
1400 pMergedOutput->setProxy(pDecayChainTrack, pBremParentChainTrack);
1405 addTrackAndParentVertex(pDecayChainTrack, newTrackingParticle, pMergedOutput);