9 #include <tracking/modules/trackFinderMCTruth/TrackFinderMCTruthRecoTracksModule.h>
11 #include <framework/datastore/StoreArray.h>
12 #include <framework/datastore/RelationArray.h>
13 #include <framework/datastore/StoreObjPtr.h>
14 #include <framework/dataobjects/EventMetaData.h>
15 #include <framework/gearbox/Const.h>
16 #include <mdst/dataobjects/MCParticle.h>
17 #include <cdc/dataobjects/CDCHit.h>
18 #include <cdc/dataobjects/CDCSimHit.h>
19 #include <cdc/geometry/CDCGeometryPar.h>
20 #include <pxd/dataobjects/PXDTrueHit.h>
21 #include <pxd/dataobjects/PXDCluster.h>
22 #include <svd/dataobjects/SVDTrueHit.h>
23 #include <svd/dataobjects/SVDCluster.h>
24 #include <top/dataobjects/TOPBarHit.h>
25 #include <tracking/dataobjects/RecoTrack.h>
26 #include <simulation/monopoles/MonopoleConstants.h>
28 #include <framework/geometry/BFieldManager.h>
29 #include <framework/dataobjects/Helix.h>
53 setDescription(
"Uses the MC information to create genfit::TrackCandidates for primary MCParticles and Relations between them. "
54 "Fills the created genfit::TrackCandidates with all information (start values, hit indices) needed for the fitting.");
55 setPropertyFlags(c_ParallelProcessingCertified);
58 addParam(
"UsePXDHits",
60 "Set true if PXDHits or PXDClusters should be used",
62 addParam(
"UseSVDHits",
64 "Set true if SVDHits or SVDClusters should be used",
66 addParam(
"UseCDCHits",
68 "Set true if CDCHits should be used",
70 addParam(
"UseOnlyAxialCDCHits",
71 m_useOnlyAxialCDCHits,
72 "Set true if only the axial CDCHits should be used",
76 "Set the number of loops whose hits will be marked as priortiy hits. All other hits "
77 "will be marked as auxiliary and therfore not considered for efficiency computations "
78 "By default, all hits will be priority hits.",
80 addParam(
"UseOnlyBeforeTOP",
82 "Mark hits as auxiliary after the track left the CDC and touched the TOP detector "
83 "(only implemented for CDCHits).",
85 addParam(
"UseReassignedHits",
87 "Include hits reassigned from discarded seconardy daughters in the tracks.",
89 addParam(
"UseSecondCDCHits",
91 "Also includes the CDC 2nd hit information in the MC tracks.",
93 addParam(
"MinPXDHits",
95 "Minimum number of PXD hits needed to allow the created of a track candidate",
97 addParam(
"MinSVDHits",
99 "Minimum number of SVD hits needed to allow the created of a track candidate",
101 addParam(
"MinCDCAxialHits",
103 "Minimum number of CDC hits form an axial wire needed to allow the created of a track candidate",
105 addParam(
"MinCDCStereoHits",
107 "Minimum number of CDC hits form a stereo wire needed to allow the created of a track candidate",
109 addParam(
"AllowFirstCDCSuperLayerOnly",
110 m_allowFirstCDCSuperLayerOnly,
111 "Allow tracks to pass the stereo hit requirement if they touched only the first (axial) CDC layer",
114 addParam(
"MinimalNDF",
116 "Minimum number of total hits needed to allow the creation of a track candidate. "
117 "It is called NDF (number of degrees of freedom) because it counts the dimensionality. "
118 "2D hits are counted as 2",
123 addParam(
"WhichParticles",
125 "List of keywords to mark what properties particles must have to get a track candidate. "
126 "If several properties are given all of them must be true: "
127 "\"primary\" particle must come from the generator, "
128 "\"PXD\", \"SVD\", \"CDC\", \"TOP\", \"ARICH\", \"ECL\" or \"KLM\" particle must have hits in the subdetector with that name. "
129 "\"is:X\" where X is a PDG code: particle must have this code. "
130 "\"from:X\" any of the particles's ancestors must have this (X) code",
131 std::vector<std::string>(1,
"primary"));
133 addParam(
"EnergyCut",
135 "Track candidates are only created for MCParticles with energy larger than this cut ",
140 "Set true if track candidates should be created also for neutral particles",
143 addParam(
"MergeDecayInFlight",
144 m_mergeDecayInFlight,
145 "Merge decay in flights that produce a single charged particle to the mother particle",
148 addParam(
"SetTimeSeed",
150 "Set true to forward the production time as time seed of the particles to the RecoTrack",
156 "Smearing of MCMomentum/MCVertex prior to storing it in genfit::TrackCandidate (in %). "
157 "A negative value will switch off smearing. This is also the default.",
160 addParam(
"SmearingCov",
162 "Covariance matrix used to smear the true pos and mom before passed to track candidate. "
163 "This matrix will also passed to Genfit as the initial covarance matrix. "
164 "If any diagonal value is negative this feature will not be used. "
165 "OFF DIAGONAL ELEMENTS DO NOT HAVE AN EFFECT AT THE MOMENT",
166 std::vector<double>(36, -1.0));
168 addParam(
"SplitAfterDeltaT",
170 "Minimal time delay between two sim hits (in ns) after which MC reco track will be "
171 "split into seperate tracks. If < 0, don't do splitting."
172 "This feature was designed to be used in MC cosmics reconstruction to get two MCRecoTracks"
173 "when track pass through empty SVD region, so that number of MCRecoTracks can be compared with"
174 "number of non merged reco tracks. ",
178 addParam(
"RecoTracksStoreArrayName",
179 m_recoTracksStoreArrayName,
180 "Name of store array holding the RecoTracks (output)",
183 addParam(
"TrueHitMustExist",
185 "If set true only cluster hits that have a relation to a TrueHit will be included in the track candidate",
188 addParam(
"discardAuxiliaryHits",
189 m_discardAuxiliaryHits,
190 "If set true hits marked as auxiliary (e.g. hits in higher loops) will not be included in the track candidate.",
191 m_discardAuxiliaryHits);
193 addParam(
"useCDCSuperLayers",
194 m_param_useCDCSuperLayers,
195 "List of CDC super layers to be used.",
196 m_param_useCDCSuperLayers);
198 addParam(
"useCDCLayers",
199 m_param_useCDCLayers,
200 "List of layers to be used. "
201 "If a layer number is given in 'ignoreLayers', too, this will result on a B2FATAL. "
202 "Either use 'useLayers' and provide a set of layers to be used, "
203 "or use 'ignoreLayers' and provide a list of layers to be ignored, but not both at the same time.",
204 m_param_useCDCLayers);
206 addParam(
"ignoreCDCLayers",
207 m_param_ignoreCDCLayers,
208 "List of layers to be ignored. "
209 "If a layer number is given in 'useLayers', too, this will result on a B2FATAL. "
210 "Either use 'useLayers' and provide a set of layers to be used, "
211 "or use 'ignoreLayers' and provide a list of layers to be ignored, but not both at the same time.",
212 m_param_ignoreCDCLayers);
236 for (
int i = 0; i not_eq nProperties; ++i) {
255 std::stringstream(pdgCodeString) >> aPdgCode;
256 B2DEBUG(20,
"PDG code added to m_particlePdgCodes " << aPdgCode <<
" *******");
260 std::stringstream(pdgCodeString) >> aPdgCode;
261 B2DEBUG(20,
"PDG code added to m_fromPdgCodes " << aPdgCode <<
" *******");
264 B2FATAL(
"Invalid values were given to the MCTrackFinder parameter WhichParticles");
273 B2FATAL(
"SmearingCov does not have exactly 36 elements. So 6x6 covariance matrix can be formed from it");
277 for (
int i = 0; i != 6; ++i) {
284 B2FATAL(
"Both relative smearing (Smearing) and using a smearing cov (SmearingCov) is activated but only one of both can be used");
299 if (useLayer == ingoreLayer) {
300 B2FATAL(
"You chose to use and ignore CDC layer " << useLayer <<
" at the same time. "
301 "Please decide to either use or to ignore the layer.");
335 B2DEBUG(20,
"Skipping MC Track Finder as there are no MC Particles registered in the DataStore.");
340 const int eventCounter = eventMetaDataPtr->getEvent();
341 B2DEBUG(20,
"******* MCTrackFinderModule processing event number: " << eventCounter <<
" *******");
345 const int nMcParticles = mcParticles.
getEntries();
346 B2DEBUG(20,
"MCTrackFinder: total Number of MCParticles: " << nMcParticles);
350 const int nPXDHits = pxdTrueHits.
getEntries();
351 B2DEBUG(20,
"MCTrackFinder: Number of PXDTrueHits: " << nPXDHits);
354 const int nMcPartToPXDHits = mcPartToPXDTrueHits.
getEntries();
355 B2DEBUG(20,
"MCTrackFinder: Number of relations between MCParticles and PXDHits: " << nMcPartToPXDHits);
359 const int nPXDClusters = pxdClusters.
getEntries();
360 B2DEBUG(20,
"MCTrackFinder: Number of PXDClusters: " << nPXDClusters);
362 RelationArray pxdClusterToMCParticle(pxdClusters, mcParticles);
363 const int nPxdClusterToMCPart = pxdClusterToMCParticle.
getEntries();
364 B2DEBUG(20,
"MCTrackFinder: Number of relations between PXDCluster and MCParticles: " << nPxdClusterToMCPart);
368 const int nSVDHits = svdTrueHits.
getEntries();
369 B2DEBUG(20,
"MCTrackFinder: Number of SVDDHits: " << nSVDHits);
372 const int nMcPartToSVDHits = mcPartToSVDTrueHits.
getEntries();
373 B2DEBUG(20,
"MCTrackFinder: Number of relations between MCParticles and SVDHits: " << nMcPartToSVDHits);
377 const int nSVDClusters = svdClusters.
getEntries();
378 B2DEBUG(20,
"MCTrackFinder: Number of SVDClusters: " << nSVDClusters);
380 RelationArray svdClusterToMCParticle(svdClusters, mcParticles);
381 const int nSvdClusterToMCPart = svdClusterToMCParticle.
getEntries();
382 B2DEBUG(20,
"MCTrackFinder: Number of relations between SVDCluster and MCParticles: " << nSvdClusterToMCPart);
387 B2DEBUG(20,
"MCTrackFinder: Number of CDCHits: " << nCDCHits);
390 const int nMcPartToCDCHits = mcPartToCDCHits.
getEntries();
391 B2DEBUG(20,
"MCTrackFinder: Number of relations between MCParticles and CDCHits: " << nMcPartToCDCHits);
394 const int nCDCSimHits = cdcSimHits.
getEntries();
395 B2DEBUG(20,
"MCTrackFinder: Number of CDCSimHits: " << nCDCSimHits);
398 const int nCdcSimHitToHitRel = cdcSimHitToHitRel.
getEntries();
399 B2DEBUG(20,
"MCTrackFinder: Number of relations between CDCSimHit and CDCHits: " << nCdcSimHitToHitRel);
408 std::set<int> alreadyConsumedMCParticles;
409 for (
int iPart = 0; iPart < nMcParticles; ++iPart) {
410 if (alreadyConsumedMCParticles.count(iPart))
continue;
411 alreadyConsumedMCParticles.insert(iPart);
413 MCParticle* aMcParticlePtr = mcParticles[iPart];
416 B2DEBUG(20,
"Particle that did not propagate significantly cannot make track.");
421 int mcParticleProperties = 0;
423 mcParticleProperties += 1;
426 mcParticleProperties += 2;
429 mcParticleProperties += 4;
432 mcParticleProperties += 8;
435 mcParticleProperties += 16;
438 mcParticleProperties += 32;
441 mcParticleProperties += 64;
444 mcParticleProperties += 128;
448 B2DEBUG(20,
"PDG: " << aMcParticlePtr->
getPDG() <<
" | property mask of particle " << mcParticleProperties <<
454 B2DEBUG(20,
"particle energy too low. MC particle will be skipped");
461 if (nPdgCodes not_eq 0) {
462 const int currentPdgCode = aMcParticlePtr->
getPDG();
463 int nFalsePdgCodes = 0;
464 for (
int i = 0; i not_eq nPdgCodes; ++i) {
469 if (nFalsePdgCodes == nPdgCodes) {
470 B2DEBUG(20,
"particle does not have one of the user provided pdg codes and will therefore be skipped");
478 if (nFromPdgCodes not_eq 0) {
480 int nFalsePdgCodes = 0;
482 while (currentMother not_eq
nullptr) {
483 int currentMotherPdgCode = currentMother->
getPDG();
484 for (
int i = 0; i not_eq nFromPdgCodes; ++i) {
490 currentMother = currentMother->
getMother();
493 if (nFalsePdgCodes == (nAncestor * nFromPdgCodes)) {
494 B2DEBUG(20,
"particle does not have and ancestor with one of the user provided pdg codes and will therefore be skipped");
501 if (abs(aMcParticlePtr->
getPDG()) > 1000000000
503 B2DEBUG(20,
"Skipped Baryon.");
509 if (!
m_neutrals && (aMcParticlePtr->
getCharge() == 0 && abs(aMcParticlePtr->
getPDG()) != Monopoles::c_monopolePDGCode)) {
510 B2DEBUG(20,
"particle does not have the right charge. MC particle will be skipped");
515 B2DEBUG(20,
"Build a track for the MCParticle with index: " << iPart <<
" (PDG: " << aMcParticlePtr->
getPDG() <<
")");
517 std::vector<const MCParticle*> trackMCParticles;
518 trackMCParticles.push_back(aMcParticlePtr);
521 std::vector<MCParticle*> daughters = aMcParticlePtr->
getDaughters();
522 std::vector<MCParticle*> decayInFlightParticles;
524 if (daughter->getSecondaryPhysicsProcess() > 200 and daughter->getCharge() != 0) {
525 decayInFlightParticles.push_back(daughter);
528 if (decayInFlightParticles.size() == 1) {
529 trackMCParticles.push_back(decayInFlightParticles.front());
530 alreadyConsumedMCParticles.insert(trackMCParticles.back()->getArrayIndex());
539 typedef std::tuple<double, int, RecoHitInformation::OriginTrackFinder, Const::EDetector> TimeHitIDDetector;
540 std::vector<TimeHitIDDetector> hitsWithTimeAndDetectorInformation;
547 for (
const MCParticle* trackMCParticle : trackMCParticles) {
550 for (
size_t i = 0; i < relatedClusters.
size(); ++i) {
551 bool isReassigned = relatedClusters.
weight(i) < 0;
555 auto mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderPriorityHit;
559 mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit;
564 mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit;
568 if (
m_discardAuxiliaryHits and mcFinder == RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit)
continue;
580 for (
const PXDTrueHit& pxdTrueHit : relatedTrueHits) {
584 if (std::find_if(relatedMCParticles.
begin(),
585 relatedMCParticles.
end(),
586 [trackMCParticle](
const MCParticle & mcParticle) {
587 return &mcParticle == trackMCParticle;
588 }) != relatedMCParticles.
end()) {
589 time = pxdTrueHit.getGlobalTime();
593 if (not std::isnan(time)) {
594 hitsWithTimeAndDetectorInformation.emplace_back(time, pxdCluster->
getArrayIndex(), mcFinder, Const::PXD);
600 B2DEBUG(20,
" add " << hitCounter <<
" PXDClusters. " << relatedClusters.
size() - hitCounter <<
601 " PXDClusters were not added because they do not have a corresponding PXDTrueHit");
613 for (
const MCParticle* trackMCParticle : trackMCParticles) {
616 for (
size_t i = 0; i < relatedClusters.
size(); ++i) {
617 bool isReassigned = relatedClusters.
weight(i) < 0;
620 auto mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderPriorityHit;
624 mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit;
629 mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit;
633 if (
m_discardAuxiliaryHits and mcFinder == RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit)
continue;
645 for (
const SVDTrueHit& svdTrueHit : relatedTrueHits) {
649 if (std::find_if(relatedMCParticles.
begin(),
650 relatedMCParticles.
end(),
651 [trackMCParticle](
const MCParticle & mcParticle) {
652 return &mcParticle == trackMCParticle;
653 }) != relatedMCParticles.
end()) {
654 time = svdTrueHit.getGlobalTime();
658 if (not std::isnan(time)) {
659 hitsWithTimeAndDetectorInformation.emplace_back(time, svdCluster->
getArrayIndex(), mcFinder, Const::SVD);
665 B2DEBUG(20,
" add " << hitCounter <<
" SVDClusters. " << relatedClusters.
size() - hitCounter <<
666 " SVDClusters were not added because they do not have a corresponding SVDTrueHit");
676 auto didParticleExitCDC = [](
const CDCHit * hit) {
678 if (not simHit)
return false;
681 if (not mcParticle)
return false;
685 if (topHits.
size() == 0)
return false;
689 return lhs.
getTime() < rhs.getTime();
691 auto itFirstTopHit = std::min_element(topHits.
begin(), topHits.
end(), lessTime);
700 std::array<int, 9> nHitsBySuperLayerId{};
702 for (
const MCParticle* trackMCParticle : trackMCParticles) {
705 for (
size_t i = 0; i < relatedHits.
size(); ++i) {
706 bool isReassigned = relatedHits.
weight(i) < 0;
713 unsigned short layerID = cdcHit->
getICLayer();
721 auto mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderPriorityHit;
725 mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit;
730 mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit;
735 mcFinder = RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit;
739 if (
m_discardAuxiliaryHits and mcFinder == RecoHitInformation::OriginTrackFinder::c_MCTrackFinderAuxiliaryHit)
continue;
743 if (not aCDCSimHitPtr) {
744 B2DEBUG(20,
" Skipping CDCHit without related CDCSimHit.");
751 if (superLayerId % 2 == 0) {
752 hitsWithTimeAndDetectorInformation.emplace_back(time, cdcHit->
getArrayIndex(), mcFinder, Const::CDC);
755 ++nHitsBySuperLayerId[superLayerId];
758 hitsWithTimeAndDetectorInformation.emplace_back(time, cdcHit->
getArrayIndex(), mcFinder, Const::CDC);
761 ++nHitsBySuperLayerId[superLayerId];
766 B2DEBUG(20,
" added " << nAxialHits <<
" axial and " << nStereoHits <<
" stereo CDCHits");
775 nHitsBySuperLayerId[0] == nAxialHits and
795 std::sort(hitsWithTimeAndDetectorInformation.begin(), hitsWithTimeAndDetectorInformation.end(),
796 [](
const TimeHitIDDetector & rhs,
const TimeHitIDDetector & lhs) {
797 return std::get<0>(rhs) < std::get<0>(lhs);
803 std::vector< std::vector<TimeHitIDDetector> > hitsWithTimeAndDetectorInformationVectors;
806 hitsWithTimeAndDetectorInformationVectors.push_back(hitsWithTimeAndDetectorInformation);
809 std::vector<TimeHitIDDetector>::size_type splitFromIdx = 0;
810 for (std::vector<TimeHitIDDetector>::size_type i = 1; i != hitsWithTimeAndDetectorInformation.size(); i++) {
812 double delta_t = (std::get<0>(hitsWithTimeAndDetectorInformation[i])
813 - std::get<0>(hitsWithTimeAndDetectorInformation[i - 1]));
817 hitsWithTimeAndDetectorInformationVectors
818 .emplace_back(hitsWithTimeAndDetectorInformation.begin() + splitFromIdx,
819 hitsWithTimeAndDetectorInformation.begin() + i);
824 hitsWithTimeAndDetectorInformationVectors
825 .emplace_back(hitsWithTimeAndDetectorInformation.begin() + splitFromIdx,
826 hitsWithTimeAndDetectorInformation.end());
831 B2DEBUG(20,
"We came pass all filter of the MCPartile and hit properties. TrackCandidate " << counter <<
832 " will be created from the MCParticle with index: " << iPart <<
" (PDG: " << aMcParticlePtr->
getPDG() <<
")");
838 TVector3 momentumTrue = aMcParticlePtr->
getMomentum();
842 TVector3 momentum = momentumTrue;
843 TVector3 position = positionTrue;
844 double time = timeTrue;
845 TVectorD stateSeed(6);
846 TMatrixDSym covSeed(6);
848 covSeed(0, 0) = 1; covSeed(1, 1) = 1; covSeed(2, 2) = 2 * 2;
849 covSeed(3, 3) = 0.1 * 0.1; covSeed(4, 4) = 0.1 * 0.1; covSeed(5, 5) = 0.2 * 0.2;
857 double smearedX = gRandom->Gaus(positionTrue.x(), smearing * positionTrue.x());
858 double smearedY = gRandom->Gaus(positionTrue.y(), smearing * positionTrue.y());
859 double smearedZ = gRandom->Gaus(positionTrue.z(), smearing * positionTrue.z());
860 position.SetXYZ(smearedX, smearedY, smearedZ);
861 double smearedPX = gRandom->Gaus(momentumTrue.x(), smearing * momentumTrue.x());
862 double smearedPY = gRandom->Gaus(momentumTrue.y(), smearing * momentumTrue.y());
863 double smearedPZ = gRandom->Gaus(momentumTrue.z(), smearing * momentumTrue.z());
864 momentum.SetXYZ(smearedPX, smearedPY, smearedPZ);
871 double smearedX = gRandom->Gaus(positionTrue.x(), sqrt(
m_initialCov(0, 0)));
872 double smearedY = gRandom->Gaus(positionTrue.y(), sqrt(
m_initialCov(1, 1)));
873 double smearedZ = gRandom->Gaus(positionTrue.z(), sqrt(
m_initialCov(2, 2)));
874 position.SetXYZ(smearedX, smearedY, smearedZ);
875 double smearedPX = gRandom->Gaus(momentumTrue.x(), sqrt(
m_initialCov(3, 3)));
876 double smearedPY = gRandom->Gaus(momentumTrue.y(), sqrt(
m_initialCov(4, 4)));
877 double smearedPZ = gRandom->Gaus(momentumTrue.z(), sqrt(
m_initialCov(5, 5)));
878 momentum.SetXYZ(smearedPX, smearedPY, smearedPZ);
884 for (
const auto& hitInformationVector : hitsWithTimeAndDetectorInformationVectors) {
887 short int charge =
static_cast<short int>(aMcParticlePtr->
getCharge());
890 if (hitInformationVector.size() != 0) {
892 time = std::get<0>(hitInformationVector.at(0));
895 TLorentzVector lorentzV;
896 lorentzV.SetVectM(momentum, aMcParticlePtr->
get4Vector().M());
897 const double beta_xy = momentum.Perp() / lorentzV.E();
903 momentum = helix.getMomentumAtArcLength2D(arclength2D, Bz);
904 position = helix.getPositionAtArcLength2D(arclength2D);
916 B2DEBUG(20,
" --- Create relation between genfit::TrackCand " << counter <<
" and MCParticle " << iPart);
919 for (
const TimeHitIDDetector& hitInformation : hitInformationVector) {
922 const int hitID = std::get<1>(hitInformation);
923 const auto hitOriginMCFinderType = std::get<2>(hitInformation);
926 if (detectorInformation == Const::CDC) {
927 const CDCHit* cdcHit = cdcHits[hitID];
933 TVector3 simHitPosOnWire = aCDCSimHitPtr->
getPosWire();
936 const unsigned short isRightHit = cdcGeometry.
getNewLeftRightRaw(simHitPosOnWire, simHitPos, simMom);
939 newRecoTrack->
addCDCHit(cdcHit, hitCounter, RecoHitInformation::RightLeftInformation::c_right, hitOriginMCFinderType);
941 newRecoTrack->
addCDCHit(cdcHit, hitCounter, RecoHitInformation::RightLeftInformation::c_left, hitOriginMCFinderType);
943 B2DEBUG(20,
"CDC hit " << hitID <<
" has reft/right sign " << isRightHit);
944 }
else if (detectorInformation == Const::PXD) {
945 const PXDCluster* pxdCluster = pxdClusters[hitID];
946 newRecoTrack->
addPXDHit(pxdCluster, hitCounter, hitOriginMCFinderType);
947 }
else if (detectorInformation == Const::SVD) {
948 const SVDCluster* svdCluster = svdClusters[hitID];
949 newRecoTrack->
addSVDHit(svdCluster, hitCounter, hitOriginMCFinderType);
954 B2DEBUG(20,
"New RecoTrack: #PXDHits: " << newRecoTrack->
getPXDHitList().size() <<
964 template<
class THit,
class TSimHit>
972 const TSimHit* aSimHit =
nullptr;
973 for (
const auto& thisSimHit : relatedSimHits) {
974 mcParticle = thisSimHit.template getRelated<MCParticle>();
975 aSimHit = &thisSimHit;
976 if (mcParticle)
break;
978 if (not mcParticle or not aSimHit) {
986 const float absMom3D = mcParticle->
getMomentum().Mag();
988 const double loopLength = 2 * M_PI * absMom3D / (Bz * 0.00299792458);
989 const double loopTOF = loopLength / speed;
990 if (tof > loopTOF * nLoops) {
1003 " number of degrees of freedom (NDF). No Track Candidates were created from them so they will not be passed to the track fitter");
1007 " cluster hits did not have a relation to a true hit and were therefore not included in a track candidate");
1009 B2INFO(
"The MCTrackFinder created a total of " <<
m_nRecoTracks <<
" track candidates");
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
bool is2ndHit() const
Getter for 2nd hit flag.
unsigned short getICLayer() const
Getter for iCLayer (0-55).
unsigned short getISuperLayer() const
Getter for iSuperLayer.
TVector3 getPosWire() const
The method to get position on wire.
double getFlightTime() const
The method to get flight time.
float getGlobalTime() const override
The method to get global time.
TVector3 getMomentum() const
The method to get momentum.
TVector3 getPosTrack() const
The method to get position on the track.
The Class for CDC Geometry Parameters.
unsigned short getNewLeftRightRaw(const TVector3 &posOnWire, const TVector3 &posOnTrack, const TVector3 &momentum) const
Returns new left/right_raw.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
int getPDGCode() const
PDG code.
EDetector
Enum for identifying the detector components (detector and subdetector).
static const double speedOfLight
[cm/ns]
static const ChargedStable deuteron
deuteron particle
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
A Class to store the Monte Carlo particle information.
float getEnergy() const
Return particle energy in GeV.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
bool hasSeenInDetector(Const::DetectorSet set) const
Return if the seen-in flag for a specific subdetector is set or not.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
TVector3 getMomentum() const
Return momentum.
TVector3 getDecayVertex() const
Return decay vertex.
float getCharge() const
Return the particle charge defined in TDatabasePDG.
int getPDG() const
Return PDG code of particle.
float getProductionTime() const
Return production time in ns.
TLorentzVector get4Vector() const
Return 4Vector of particle.
TVector3 getProductionVertex() const
Return production vertex position.
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Class PXDTrueHit - Records of tracks that either enter or leave the sensitive volume.
This is the Reconstruction Event-Data Model Track.
bool addCDCHit(const UsedCDCHit *cdcHit, const unsigned int sortingParameter, RightLeftInformation rightLeftInformation=RightLeftInformation::c_undefinedRightLeftInformation, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds a cdc hit with the given information to the reco track.
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
bool addPXDHit(const UsedPXDHit *pxdHit, const unsigned int sortingParameter, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds a pxd hit with the given information to the reco track.
std::vector< Belle2::RecoTrack::UsedPXDHit * > getPXDHitList() const
Return an unsorted list of pxd hits.
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
void setTimeSeed(const double timeSeed)
Set the time seed. ATTENTION: This is not the fitted time.
static void registerRequiredRelations(StoreArray< RecoTrack > &recoTracks, std::string const &pxdHitsStoreArrayName="", std::string const &svdHitsStoreArrayName="", std::string const &cdcHitsStoreArrayName="", std::string const &bklmHitsStoreArrayName="", std::string const &eklmHitsStoreArrayName="", std::string const &recoHitInformationStoreArrayName="")
Convenience method which registers all relations required to fully use a RecoTrack.
bool addSVDHit(const UsedSVDHit *svdHit, const unsigned int sortingParameter, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds a svd hit with the given information to the reco track.
Low-level class to create/modify relations between StoreArrays.
int getEntries() const
Get the number of elements.
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
T * object(int index) const
Get object with index.
iterator end()
Return iterator to last entry +1.
iterator begin()
Return iterator to first entry.
float weight(int index) const
Get weight with index.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
RelationVector< T > getRelationsWith(const std::string &name="", const std::string &namedRelation="") const
Get the relations between this object and another store array.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Type-safe access to single objects in the data store.
Class to store track parameters of incoming MC particles relation to MCParticle filled in top/simulat...
double getTime() const
Returns time of impact.
This module uses the simulated truth information (MCParticles and their relations) to determine which...
bool m_useCDCHits
Boolean to select if CDCHits should be used.
bool m_enforceTrueHit
If set true only cluster hits that have a relation to a TrueHit will be included in the track candida...
std::vector< int > m_fromPdgCodes
if size() is not 0, only for particles having an ancestor (mother or mother of mother etc) with PDG c...
std::vector< int > m_particlePdgCodes
if size() is not 0, only for particles with PDG codes same as in this vector a track candidate will b...
double m_energyCut
Create track candidates only for MCParticles with energy above this cut.
void initialize() override
Initialize the Module.
std::vector< std::string > m_whichParticles
List of keywords to mark what properties particles must have to get a track candidate .
bool m_discardAuxiliaryHits
if true hits marked as auxiliary will not be included in the RecoTrack
void event() override
This method is the core of the module.
int m_minimalNdf
Minimum number of total hits per track to allow track candidate creation.
void endRun() override
This method is called if the current run ends.
int m_particleProperties
Internal encoding of m_whichParticles to avoid string comparisons.
bool m_useReassignedHits
Boolean to select the inclusion of hits form discarded secondary daughters.
std::vector< double > m_smearingCov
Covariance matrix used to smear the true pos and mom before passed to track candidate.
bool m_mcParticlesPresent
This flag is set to false if there are no MC Particles in the data store (probably data run?...
bool m_allowFirstCDCSuperLayerOnly
Boolean to allow tracks to pass the stereo hit requirement if they touched only the first (axial) CDC...
bool m_mergeDecayInFlight
Boolean to merge decay in flight chains that involve a single charged particle.
bool m_setTimeSeed
Boolean to forward the production time as seed time.
float m_useNLoops
Number of loops to include in the MC tracks - effects only CDC.
double m_splitAfterDeltaT
Minimal time delay between two sim hits (in ns) after which MC reco track will be split into seperate...
bool m_useSecondCDCHits
Also includes the CDC 2nd hit information in the mc tracks.
int m_minCDCStereoHits
Minimum number of CDC hits from stereo wires per track to allow track candidate creation.
bool m_usePXDHits
Boolean to select if PXDHits should be used.
void beginRun() override
Called when entering a new run.
std::vector< uint > m_param_useCDCLayers
List of layers to be used.
bool m_useOnlyBeforeTOP
Boolean to select if CDC hits after TOP detector are discarded.
std::vector< uint > m_param_ignoreCDCLayers
List of layers to be ignored in tracking.
std::vector< uint > m_param_useCDCSuperLayers
List of super layers to be used.
int m_minCDCAxialHits
Minimum number of CDC hits from axial wires per track to allow track candidate creation.
int m_noTrueHitCounter
will hold number of cluster hits that do not have a corresponding true hit
int m_minSVDHits
Minimum number of SVD hits per track to allow track candidate creation.
int m_notEnoughtHitsCounter
will hold number of tracks that do not have enough hits to form a track candidate (total NDF less tha...
bool m_useOnlyAxialCDCHits
Boolean to select if only axial CDCHits should be used.
std::array< bool, 56 > m_useCDCLayers
Bits for the used layers ATTENTION: hardcoded value for number of layers.
double m_smearing
Smearing of MCMomentum and MCVertex in %.
std::array< bool, 9 > m_useCDCSuperLayers
Bits for the used super layers ATTENTION: hardcoded value for number of super layers.
std::string m_recoTracksStoreArrayName
RecoTracks StoreArray name.
int m_minPXDHits
Minimum number of PXD hits per track to allow track candidate creation.
bool m_neutrals
Boolean to mark if track candidates should also be created for neutral particles.
TMatrixDSym m_initialCov
The std::vector m_smearingCov will be translated into this TMatrixD.
int m_nRecoTracks
will hold the total number of created track candidates
bool isWithinNLoops(double Bz, const THit *aHit, double nLoops)
helper function which returns true if the current hit is within n loops the template give the hit typ...
bool m_useSVDHits
Boolean to select if SVDHits should be used.
static const double cm
Standard units with the value = 1.
static const double T
[tesla]
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
MCParticle * getMother() const
Returns a pointer to the mother particle.
Abstract base class for different kinds of events.