4 #include "Fit/Fitter.h"
18 #include <unordered_map>
20 #include "StFwdTrackMaker/include/Tracker/FwdHit.h"
21 #include "StFwdTrackMaker/include/Tracker/FwdDataSource.h"
22 #include "StFwdTrackMaker/include/Tracker/QualityPlotter.h"
23 #include "StFwdTrackMaker/include/Tracker/TrackFitter.h"
24 #include "StFwdTrackMaker/include/Tracker/BDTCriteria.h"
26 #include "Criteria/Criteria.h"
27 #include "Criteria/ICriterion.h"
28 #include "KiTrack/Automaton.h"
29 #include "KiTrack/SegmentBuilder.h"
30 #include "KiTrack/SubsetHopfieldNN.h"
32 #include "StFwdTrackMaker/include/Tracker/CriteriaKeeper.h"
34 #include "GenFit/FitStatus.h"
35 #include "GenFit/GFRaveVertexFactory.h"
37 #include "StFwdTrackMaker/FwdTrackerConfig.h"
38 #include "StFwdTrackMaker/Common.h"
43 static int dominantContribution(
Seed_t hits,
double &qa) {
46 std::unordered_map<int,int> truth;
47 for (
auto hit : hits ) {
49 truth[ fhit->_tid ]++;
53 using P = decltype(truth)::value_type;
54 auto dom = max_element(begin(truth), end(truth), [](P a, P b){
return a.second < b.second; });
58 if ( hits.size() > 0 )
59 qa =
double(dom->second) / double(hits.size()) ;
73 this->trackSeed = seedTrack;
77 this->status = *(this->track->getFitStatus());
78 this->trackRep = this->track->getCardinalRep();
80 this->isFitConverged = this->status.isFitConverged();
81 this->isFitConvergedFully = this->status.isFitConvergedFully();
82 this->isFitConvergedPartially = this->status.isFitConvergedPartially();
83 this->nFailedPoints = this->status.getNFailedPoints();
84 this->charge = this->status.getCharge();
86 this->nPV = this->track->getNumPoints() - (nFTT + nFST);
88 this->momentum = this->trackRep->getMom( this->track->getFittedState(0, this->trackRep) );
89 LOG_DEBUG <<
"GenfitTrackResult::set Track successful" << endm;
91 }
catch ( genfit::Exception &e ) {
92 LOG_ERROR <<
"GenfitTrackResult cannot get track" << endm;
93 this->track =
nullptr;
94 this->trackRep =
nullptr;
96 this->isFitConverged =
false;
97 this->isFitConvergedFully =
false;
98 this->isFitConvergedPartially =
false;
99 this->nFailedPoints = nFST + nFTT;
112 void setFst(
Seed_t &seedFst, genfit::Track *track ){
113 LOG_DEBUG <<
"GenfitTrackResult::setFSt" << endm;
114 nFST = seedFst.size();
118 this->fstTrack =
new genfit::Track(*track);
120 this->fstTrack->setMcTrackId( this->track->getMcTrackId() );
121 this->fstStatus = *(this->fstTrack->getFitStatus());
122 this->fstTrackRep = this->fstTrack->getCardinalRep();
124 this->isFitConverged = this->fstStatus.isFitConverged();
125 this->isFitConvergedFully = this->fstStatus.isFitConvergedFully();
126 this->isFitConvergedPartially = this->fstStatus.isFitConvergedPartially();
127 this->nFailedPoints = this->fstStatus.getNFailedPoints();
128 this->charge = this->fstStatus.getCharge();
129 this->fstMomentum = this->fstTrackRep->getMom( this->fstTrack->getFittedState(0, this->fstTrackRep) );
131 }
catch ( genfit::Exception &e ) {
132 LOG_ERROR <<
"CANNOT GET FST TRACK" << endm;
133 this->fstTrack =
nullptr;
134 this->fstTrackRep =
nullptr;
136 this->fstIsFitConverged =
false;
137 this->fstIsFitConvergedFully =
false;
138 this->fstIsFitConvergedPartially =
false;
139 this->fstNFailedPoints = nFST + nFTT;
151 genfit::FitStatus status;
152 genfit::AbsTrackRep *trackRep =
nullptr;
153 genfit::Track *track =
nullptr;
154 bool isFitConverged =
false;
155 bool isFitConvergedFully =
false;
156 bool isFitConvergedPartially =
false;
157 size_t nFailedPoints = 0;
160 genfit::Track *fstTrack =
nullptr;
161 genfit::AbsTrackRep *fstTrackRep =
nullptr;
162 genfit::FitStatus fstStatus;
163 bool fstIsFitConverged =
false;
164 bool fstIsFitConvergedFully =
false;
165 bool fstIsFitConvergedPartially =
false;
166 size_t fstNFailedPoints = 0;
167 double fstCharge = 0;
168 TVector3 fstMomentum;
171 LOG_INFO << TString::Format(
"TrackResult[p=(%f, %f, %f)/(%f, %f, %f), q=%f, nFTT=%lu, nFST=%lu, nPV=%lu, isFitConvergedFully=%d]", momentum.X(), momentum.Y(), momentum.Z(), momentum.Pt(), momentum.Eta(), momentum.Phi(), charge, nFTT, nFST, nPV, isFitConvergedFully ).Data() << endm;
177 ForwardTrackMaker() : mConfigFile(
"config.xml"), mEventVertex(-999, -999, -999) {
181 const std::vector<GenfitTrackResult> &getTrackResults()
const {
return mTrackResults; }
182 const std::vector<Seed_t> &getRecoTracks()
const {
return mRecoTracks; }
183 const std::vector<TVector3> &getFitMomenta()
const {
return mFitMoms; }
184 const std::vector<unsigned short> &getNumFstHits()
const {
return mNumFstHits; }
185 const std::vector<genfit::FitStatus> &getFitStatus()
const {
return mFitStatus; }
186 const std::vector<genfit::AbsTrackRep *> &globalTrackReps()
const {
return mGlobalTrackReps; }
187 const std::vector<genfit::Track *> &globalTracks()
const {
return mGlobalTracks; }
189 void setConfigFile(std::string cf) {
193 void setSaveCriteriaValues(
bool save) {
194 mSaveCriteriaValues = save;
200 void setData(std::shared_ptr<FwdDataSource>
data) { mDataSource = data; }
202 virtual void initialize( TString geoCache,
bool genHistograms) {
203 mGenHistograms = genHistograms;
204 if (mGenHistograms) setupHistograms();
206 mGeoCache = geoCache;
207 mDoTrackFitting = !(mConfig.get<
bool>(
"TrackFitter:off",
false));
209 if (!mConfig.exists(
"TrackFitter"))
210 mDoTrackFitting =
false;
214 void writeEventHistograms() {
222 TNamed n(
"mConfig", mConfig.dump());
227 gDirectory->mkdir(
"Fit/");
228 gDirectory->cd(
"Fit/");
229 mTrackFitter->writeHistograms();
231 mQualityPlotter->writeHistograms();
242 std::vector<KiTrack::ICriterion *> crits;
243 auto paths = mConfig.childrenOf(path);
245 for (
string p : paths) {
246 string name = mConfig.get<
string>(p +
":name",
"");
247 bool active = mConfig.get<
bool>(p +
":active",
true);
249 if (
false == active) {
253 float vmin = mConfig.get<
float>(p +
":min", 0);
254 float vmax = mConfig.get<
float>(p +
":max", 1);
256 KiTrack::ICriterion * crit =
nullptr;
257 if ( name ==
"Crit2_BDT" ){
260 crit = KiTrack::Criteria::createCriterion(name, vmin, vmax);
263 crit->setSaveValues(mSaveCriteriaValues);
265 if (mSaveCriteriaValues)
268 crits.push_back(crit);
275 std::vector<float> getCriteriaValues(std::string crit_name) {
276 std::vector<float> em;
277 if (mSaveCriteriaValues !=
true) {
281 for (
auto crit : mTwoHitCrit) {
282 if (crit_name == crit->getName()) {
284 return critKeeper->getValues();
288 for (
auto crit : mThreeHitCrit) {
289 if (crit_name == crit->getName()) {
291 return critKeeper->getValues();
298 std::vector<std::map < std::string , float >> getCriteriaAllValues(std::string crit_name) {
299 std::vector<std::map < std::string , float >> em;
300 if (mSaveCriteriaValues !=
true) {
304 for (
auto crit : mTwoHitCrit) {
305 if (crit_name == crit->getName()) {
307 return critKeeper->getAllValues();
311 for (
auto crit : mThreeHitCrit) {
312 if (crit_name == crit->getName()) {
314 return critKeeper->getAllValues();
321 std::vector<int> getCriteriaTrackIds(std::string crit_name) {
323 if (mSaveCriteriaValues !=
true) {
327 for (
auto crit : mTwoHitCrit) {
328 if (crit_name == crit->getName()) {
330 return critKeeper->getTrackIds();
334 for (
auto crit : mThreeHitCrit) {
335 if (crit_name == crit->getName()) {
337 return critKeeper->getTrackIds();
344 void clearSavedCriteriaValues() {
345 if (mSaveCriteriaValues !=
true) {
349 for (
auto crit : mTwoHitCrit) {
354 for (
auto crit : mThreeHitCrit) {
360 size_t nHitsInHitMap(FwdDataSource::HitMap_t &hitmap) {
363 for (
auto kv : hitmap) {
364 n += kv.second.size();
370 size_t countRecoTracks(
size_t nHits) {
373 for (
auto t : mRecoTracks) {
374 if (t.size() == nHits)
381 void setupHistograms() {
383 mHist[
"input_nhits"] =
new TH1I(
"input_nhits",
";# hits", 1000, 0, 1000);
384 mHist[
"nAttemptedFits"] =
new TH1I(
"nAttemptedFits",
";;# attempted fits", 10, 0, 10);
385 mHist[
"nPossibleFits"] =
new TH1I(
"nPossibleFits",
";;# possible fits", 10, 0, 10);
387 mHist[
"nPossibleReFits"] =
new TH1I(
"nPossibleReFits",
";;# possible REfits", 10, 0, 10);
388 mHist[
"nAttemptedReFits"] =
new TH1I(
"nAttemptedReFits",
";;#attempted REfits", 10, 0, 10);
389 mHist[
"nFailedReFits"] =
new TH1I(
"nFailedReFits",
";;# failed REfits", 10, 0, 10);
391 mHist[
"FitStatus"] =
new TH1I(
"FitStatus",
";;# failed REfits", 15, 0, 15);
392 FwdTrackerUtils::labelAxis(mHist[
"FitStatus"]->GetXaxis(), {
"Seeds",
"AttemptFit",
"GoodFit",
"BadFit",
"GoodCardinal",
"PossibleReFit",
"AttemptReFit",
"GoodReFit",
"BadReFit",
"w3Si",
"w2Si",
"w1Si",
"w0Si" });
394 mHist[
"FitDuration"] =
new TH1I(
"FitDuration",
";Duration (ms)", 5000, 0, 50000);
395 mHist[
"nSiHitsFound"] =
new TH2I(
"nSiHitsFound",
";Si Disk; n Hits", 5, 0, 5, 10, 0, 10 );
397 mHist[
"Step1Duration"] =
new TH1I(
"Step1Duration",
";Duration (ms)", 500, 0, 500);
398 mHist[
"Step2Duration"] =
new TH1I(
"Step2Duration",
";Duration (ms)", 500, 0, 500);
399 mHist[
"Step3Duration"] =
new TH1I(
"Step3Duration",
";Duration (ms)", 500, 0, 500);
400 mHist[
"Step4Duration"] =
new TH1I(
"Step4Duration",
";Duration (ms)", 500, 0, 500);
403 void fillHistograms() {
405 if (mGenHistograms && mDataSource !=
nullptr) {
406 auto hm = mDataSource->getFttHits();
408 mHist[
"input_nhits"]->Fill(hp.second.size());
412 void writeHistograms() {
413 if ( !mGenHistograms ){
417 for (
auto nh : mHist) {
418 nh.second->SetDirectory(gDirectory);
426 int single_event = mConfig.get<
int>(
"Input:event", -1);
428 if (single_event >= 0) {
429 doEvent(single_event);
433 unsigned long long firstEvent = mConfig.get<
unsigned long long>(
"Input:first-event", 0);
435 if (mConfig.exists(
"Input:max-events")) {
436 unsigned long long maxEvents = mConfig.get<
unsigned long long>(
"Input:max-events", 0);
438 if (nEvents > maxEvents)
445 for (
unsigned long long iEvent = firstEvent; iEvent < firstEvent + nEvents; iEvent++) {
450 mQualityPlotter->finish();
451 writeEventHistograms();
455 void removeHits(FwdDataSource::HitMap_t &hitmap, std::vector<Seed_t> &tracks) {
457 for (
auto track : tracks) {
459 int sector =
hit->getSector();
461 auto hitit = std::find(hitmap[sector].begin(), hitmap[sector].end(),
hit);
463 if (hitit != hitmap[sector].end()) {
464 hitmap[sector].erase(hitit);
472 void doEvent(
unsigned long long int iEvent = 0) {
477 mRecoTrackQuality.clear();
478 mRecoTrackIdTruth.clear();
485 for (
auto p : mGlobalTrackReps)
488 mGlobalTrackReps.clear();
491 for (
auto p : mGlobalTracks)
494 mGlobalTracks.clear();
496 mTrackResults.clear();
499 if (mGenHistograms ){
500 mQualityPlotter->startEvent();
503 mTotalHitsRemoved = 0;
509 long long itStart = FwdTrackerUtils::nowNanoSecond();
510 FwdDataSource::HitMap_t &hitmap = mDataSource->getFttHits();;
511 FwdDataSource::McTrackMap_t &mcTrackMap = mDataSource->getMcTracks();
514 long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6;
516 mHist[
"Step1Duration"]->Fill( duration );
519 bool mcTrackFinding =
true;
521 if (mConfig.exists(
"TrackFinder"))
522 mcTrackFinding =
false;
526 if (mcTrackFinding) {
527 LOG_DEBUG <<
"MC TRACK FINDING " << endm;
528 doMcTrackFinding(mcTrackMap);
532 if (mConfig.get<
bool>(
"TrackFitter:refitSi",
true)) {
535 LOG_DEBUG <<
"Skipping FST Hits" << endm;
540 if (mConfig.get<
bool>(
"TrackFitter:refitGBL",
true)) {
541 for (
size_t i = 0; i < mGlobalTracks.size(); i++) {
542 mTrackFitter->refitTrackWithGBL(mGlobalTracks[i]);
546 if (mGenHistograms ){
547 mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus);
556 size_t nIterations = mConfig.get<
size_t>(
"TrackFinder:nIterations", 0);
557 for (
size_t iIteration = 0; iIteration < nIterations; iIteration++) {
558 doTrackIteration(iIteration, hitmap);
564 if (mConfig.get<
bool>(
"TrackFitter:refitSi",
true)) {
571 if ( mGenHistograms ){
572 mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus);
576 void fitTrack(
Seed_t &track) {
578 if ( mGenHistograms ){
579 mHist[
"FitStatus"]->Fill(
"Seeds", 1);
585 idt = MCTruthUtils::dominantContribution(track, qual);
592 auto mctm = mDataSource->getMcTracks();
594 if (mctm.count(idt)) {
595 auto mct = mctm[idt];
596 mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi);
601 bool bailout =
false;
602 if (qual < mConfig.get<
float>(
"TrackFitter.McFilter:quality-min", 0.0)) {
606 if (mctm.count(idt)) {
607 auto mct = mctm[idt];
608 mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi);
609 if (mct->mPt < mConfig.get<
float>(
"TrackFitter.McFilter:pt-min", 0.0) ||
610 mct->mPt > mConfig.get<
float>(
"TrackFitter.McFilter:pt-max", 1e10)) {
614 if (mct->mEta < mConfig.get<
float>(
"TrackFitter.McFilter:eta-min", 0) ||
615 mct->mEta > mConfig.get<
float>(
"TrackFitter.McFilter:eta-max", 1e10)) {
627 p.SetPtEtaPhi( 0, -999, 0 );
628 genfit::FitStatus fitStatus;
630 genfit::AbsTrackRep *trackRep =
nullptr;
631 genfit::Track *genTrack =
nullptr;
634 if (mDoTrackFitting && !bailout) {
635 if ( mGenHistograms ){
636 mHist[
"FitStatus"]->Fill(
"AttemptFit", 1);
639 double vertex[3] = { mEventVertex.X(), mEventVertex.Y(), mEventVertex.Z() };
641 double * pVertex = 0;
642 if ( fabs(mEventVertex.X()) < 100 ){
647 if (
true == mConfig.get<
bool>(
"TrackFitter:mcSeed",
false)) {
649 p = mTrackFitter->fitTrack(track, pVertex, &mcSeedMom);
652 p = mTrackFitter->fitTrack(track, pVertex);
655 if ( mGenHistograms ){
656 if (p.Perp() > 1e-3) {
657 mHist[
"FitStatus"]->Fill(
"GoodFit", 1);
659 mHist[
"FitStatus"]->Fill(
"BadFit", 1);
664 genTrack =
new genfit::Track(*mTrackFitter->getTrack());
665 genTrack->setMcTrackId(idt);
669 fitStatus = mTrackFitter->getStatus();
670 trackRep = mTrackFitter->getTrackRep()->clone();
672 if ( mGenHistograms && genTrack->getFitStatus(genTrack->getCardinalRep())->isFitConverged() && p.Perp() > 1e-3) {
673 mHist[
"FitStatus"]->Fill(
"GoodCardinal", 1);
677 mFitMoms.push_back(p);
678 mGlobalTracks.push_back(genTrack);
679 mGlobalTrackReps.push_back(trackRep);
680 mFitStatus.push_back(fitStatus);
681 mRecoTrackQuality.push_back(qual);
682 mRecoTrackIdTruth.push_back(idt);
683 mNumFstHits.push_back(0);
685 mTrackResults.push_back( gtr );
687 LOG_DEBUG <<
"FwdTracker::fitTrack complete" << endm;
691 void doTrackFitting( std::vector<Seed_t> &tracks) {
692 long long itStart = FwdTrackerUtils::nowNanoSecond();
694 for (
auto t : tracks) {
697 long long itEnd = FwdTrackerUtils::nowNanoSecond();
698 long long duration = (itEnd - itStart) * 1e-6;
699 if ( mGenHistograms ){
700 this->mHist[
"FitDuration"]->Fill(duration);
706 void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap) {
708 mQualityPlotter->startIteration();
711 for (
auto kv : mcTrackMap) {
713 auto mc_track = kv.second;
714 if (mc_track->mHits.size() < 4){
718 std::set<size_t> uvid;
721 for (
auto h : mc_track->mHits) {
723 uvid.insert(static_cast<FwdHit *>(h)->_vid);
726 if (uvid.size() == track.size()) {
727 mRecoTracks.push_back(track);
730 idt = MCTruthUtils::dominantContribution(track, qual);
731 mRecoTrackQuality.push_back(qual);
732 mRecoTrackIdTruth.push_back(idt);
738 LOG_DEBUG <<
"McTrackFinding Found: " << mRecoTracks.size() <<
" tracks" << endm;
740 doTrackFitting(mRecoTracks);
742 if ( mGenHistograms ){
743 mQualityPlotter->afterIteration(0, mRecoTracks);
758 size_t sliceHitMapInPhi( FwdDataSource::HitMap_t &inputMap, FwdDataSource::HitMap_t &outputMap,
float phi_min,
float phi_max ){
759 size_t n_hits_kept = 0;
762 for (
auto kv : inputMap ){
763 for ( KiTrack::IHit*
hit : kv.second ){
764 TVector3 vec(hit->getX(), hit->getY(), hit->getZ() );
765 if ( vec.Phi() < phi_min || vec.Phi() > phi_max )
continue;
768 outputMap[kv.first].push_back( hit );
782 long long itStart = FwdTrackerUtils::nowNanoSecond();
784 std::vector<Seed_t> acceptedTracks;
785 std::vector<Seed_t> rejectedTracks;
791 KiTrack::SegmentBuilder builder(hitmap);
795 std::string criteriaPath =
"TrackFinder.Iteration[" + std::to_string(iIteration) +
"].SegmentBuilder";
797 if (
false == mConfig.exists(criteriaPath)) {
800 criteriaPath =
"TrackFinder.SegmentBuilder";
804 mTwoHitCrit = loadCriteria(criteriaPath);
805 builder.addCriteria(mTwoHitCrit);
808 std::string connPath =
"TrackFinder.Iteration[" + std::to_string(iIteration) +
"].Connector";
810 if (
false == mConfig.exists(connPath))
811 connPath =
"TrackFinder.Connector";
813 unsigned int distance = mConfig.get<
unsigned int>(connPath +
":distance", 1);
816 builder.addSectorConnector(&connector);
820 KiTrack::Automaton automaton = builder.get1SegAutomaton();
821 LOG_DEBUG << TString::Format(
"nSegments=%lu", automaton.getSegments().size() ).Data() << endm;
822 LOG_DEBUG << TString::Format(
"nConnections=%u", automaton.getNumberOfConnections() ).Data() << endm;
824 if (automaton.getNumberOfConnections() > 900 ){
825 LOG_ERROR <<
"Got too many connections, bailing out of tracking" << endm;
826 return acceptedTracks;
833 long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6;
835 mHist[
"Step2Duration"]->Fill( duration );
836 itStart = FwdTrackerUtils::nowNanoSecond();
842 automaton.clearCriteria();
843 automaton.resetStates();
844 criteriaPath =
"TrackFinder.Iteration[" + std::to_string(iIteration) +
"].ThreeHitSegments";
846 if (
false == mConfig.exists(criteriaPath))
847 criteriaPath =
"TrackFinder.ThreeHitSegments";
849 mThreeHitCrit.clear();
850 mThreeHitCrit = loadCriteria(criteriaPath);
851 automaton.addCriteria(mThreeHitCrit);
852 automaton.lengthenSegments();
854 bool doAutomation = mConfig.get<
bool>(criteriaPath +
":doAutomation",
true);
855 bool doCleanBadStates = mConfig.get<
bool>(criteriaPath +
":cleanBadStates",
true);
858 automaton.doAutomaton();
863 if (doAutomation && doCleanBadStates) {
864 automaton.cleanBadStates();
867 duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6;
869 mHist[
"Step3Duration"]->Fill( duration );
870 if (duration > 200 || automaton.getNumberOfConnections() > 900){
871 LOG_WARN <<
"The Three Hit Criteria took more than 200ms to process, duration: " << duration <<
" ms" << endm;
872 LOG_WARN <<
"bailing out (skipping subset HNN)" << endm;
873 std::vector<Seed_t> acceptedTracks;
874 std::string subsetPath =
"TrackFinder.Iteration[" + std::to_string(iIteration) +
"].SubsetNN";
875 size_t minHitsOnTrack = mConfig.get<
size_t>(subsetPath +
":min-hits-on-track", FwdSystem::sNFttLayers);
876 acceptedTracks = automaton.getTracks(minHitsOnTrack);
877 return acceptedTracks;
879 itStart = FwdTrackerUtils::nowNanoSecond();
881 LOG_DEBUG << TString::Format(
"nSegments=%lu", automaton.getSegments().size() ).Data() << endm;
882 LOG_DEBUG << TString::Format(
"nConnections=%u", automaton.getNumberOfConnections() ).Data() << endm;
888 std::string subsetPath =
"TrackFinder.Iteration[" + std::to_string(iIteration) +
"].SubsetNN";
890 if (
false == mConfig.exists(subsetPath))
891 subsetPath =
"TrackFinder.SubsetNN";
894 bool findSubsets = mConfig.get<
bool>(subsetPath +
":active",
true);
897 size_t minHitsOnTrack = mConfig.get<
size_t>(subsetPath +
":min-hits-on-track", 7);
899 std::vector<Seed_t> tracks = automaton.getTracks(minHitsOnTrack);
901 float omega = mConfig.get<
float>(subsetPath +
".Omega", 0.75);
902 float stableThreshold = mConfig.get<
float>(subsetPath +
".StableThreshold", 0.1);
903 float Ti = mConfig.get<
float>(subsetPath +
".InitialTemp", 2.1);
904 float Tf = mConfig.get<
float>(subsetPath +
".InfTemp", 0.1);
906 KiTrack::SubsetHopfieldNN<Seed_t> subset;
908 subset.setOmega(omega);
909 subset.setLimitForStable(stableThreshold);
910 subset.setTStart(Ti);
916 subset.calculateBestSet(comparer, quality);
918 acceptedTracks = subset.getAccepted();
925 size_t minHitsOnTrack = mConfig.get<
size_t>(subsetPath +
":min-hits-on-track", FwdSystem::sNFttLayers);
926 acceptedTracks = automaton.getTracks(minHitsOnTrack);
929 duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6;
931 mHist[
"Step4Duration"]->Fill( duration );
933 LOG_WARN <<
"The took more than 500ms to process, duration: " << duration <<
" ms" << endm;
934 LOG_WARN <<
"We got " << acceptedTracks.size() <<
" tracks this round" << endm;
936 LOG_DEBUG <<
"We got " << acceptedTracks.size() <<
" tracks this round" << endm;
937 return acceptedTracks;
940 void doTrackIteration(
size_t iIteration, FwdDataSource::HitMap_t &hitmap) {
943 mRecoTracksThisItertion.clear();
946 size_t nHitsThisIteration = nHitsInHitMap(hitmap);
948 if (nHitsThisIteration < 4) {
954 if ( mGenHistograms ){
955 mQualityPlotter->startIteration();
958 std::string pslPath =
"TrackFinder.Iteration["+ std::to_string(iIteration) +
"]:nPhiSlices";
959 if (
false == mConfig.exists( pslPath ) ) pslPath =
"TrackFinder:nPhiSlices";
960 size_t phi_slice_count = mConfig.get<
size_t>( pslPath, 1 );
962 if ( phi_slice_count <= 1 || phi_slice_count > 100 ) {
963 LOG_DEBUG <<
"Tracking without phi slices" << endm;
967 auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, hitmap );
968 mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() );
971 FwdDataSource::HitMap_t slicedHitMap;
973 if ( phi_slice_count == 0 || phi_slice_count > 100 ){
974 LOG_WARN <<
"Invalid phi_slice_count = " << phi_slice_count <<
", resetting to 1" << endm;
977 float phi_slice = 2 * TMath::Pi() / (float) phi_slice_count;
978 for (
size_t phi_slice_index = 0; phi_slice_index < phi_slice_count; phi_slice_index++ ){
980 float phi_min = phi_slice_index * phi_slice - TMath::Pi();
981 float phi_max = (phi_slice_index + 1) * phi_slice - TMath::Pi();
988 size_t nHitsThisSlice = 0;
989 if ( phi_slice_count > 1 ){
990 nHitsThisSlice = sliceHitMapInPhi( hitmap, slicedHitMap, phi_min, phi_max );
991 if ( nHitsThisSlice < 4 ) {
996 slicedHitMap = hitmap;
1002 auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, slicedHitMap );
1003 mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() );
1011 std::string hrmPath =
"TrackFinder.Iteration["+ std::to_string(iIteration) +
"].HitRemover";
1012 if (
false == mConfig.exists( hrmPath ) ) hrmPath =
"TrackFinder.HitRemover";
1014 if (
true == mConfig.get<
bool>( hrmPath +
":active",
true ) ){
1015 removeHits( hitmap, mRecoTracksThisItertion );
1018 LOG_DEBUG <<
" FITTING " << mRecoTracksThisItertion.size() <<
" now" << endm;
1020 if ( mRecoTracksThisItertion.size() < 201 ){
1021 doTrackFitting( mRecoTracksThisItertion );
1023 LOG_ERROR <<
"BAILING OUT of fit, too many track candidates" << endm;
1026 if ( mGenHistograms ){
1027 mQualityPlotter->afterIteration( iIteration, mRecoTracksThisItertion );
1031 mRecoTracks.insert( mRecoTracks.end(), mRecoTracksThisItertion.begin(), mRecoTracksThisItertion.end() );
1035 void addSiHitsMc() {
1036 FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits();
1038 for (
size_t i = 0; i < mTrackResults.size(); i++) {
1041 if ( gtr.status.isFitConverged() ==
false || gtr.momentum.Perp() < 1e-3) {
1042 LOG_DEBUG <<
"Skipping addSiHitsMc, fit failed" << endm;
1046 if ( mGenHistograms){
1047 mHist[
"FitStatus"]->Fill(
"PossibleReFit", 1);
1050 Seed_t si_hits_for_this_track(3,
nullptr);
1052 for (
size_t j = 0; j < 3; j++) {
1053 for (
auto h0 : hitmap[j]) {
1054 if (dynamic_cast<FwdHit *>(h0)->_tid == gtr.track->getMcTrackId()) {
1055 si_hits_for_this_track[j] = h0;
1061 size_t nSiHitsFound = 0;
1062 if ( si_hits_for_this_track[0] !=
nullptr ) nSiHitsFound++;
1063 if ( si_hits_for_this_track[1] !=
nullptr ) nSiHitsFound++;
1064 if ( si_hits_for_this_track[2] !=
nullptr ) nSiHitsFound++;
1065 LOG_DEBUG <<
"Found " << nSiHitsFound <<
" FST Hits on this track (MC lookup)" << endm;
1067 if ( mGenHistograms ){
1068 this->mHist[
"nSiHitsFound" ]->Fill( 1, ( si_hits_for_this_track[0] !=
nullptr ? 1 : 0 ) );
1069 this->mHist[
"nSiHitsFound" ]->Fill( 2, ( si_hits_for_this_track[1] !=
nullptr ? 1 : 0 ) );
1070 this->mHist[
"nSiHitsFound" ]->Fill( 3, ( si_hits_for_this_track[2] !=
nullptr ? 1 : 0 ) );
1073 if (nSiHitsFound >= 1) {
1074 if ( mGenHistograms ){
1075 mHist[
"FitStatus"]->Fill(
"AttemptReFit", 1);
1077 TVector3 p = mTrackFitter->refitTrackWithSiHits(gtr.track, si_hits_for_this_track);
1079 if ( mGenHistograms ){
1080 if (p.Perp() == mFitMoms[i].Perp()) {
1081 mHist[
"FitStatus"]->Fill(
"BadReFit", 1);
1082 LOG_DEBUG <<
"refitTrackWithSiHits failed refit" << endm;
1084 mHist[
"FitStatus"]->Fill(
"GoodReFit", 1);
1085 gtr.setFst( si_hits_for_this_track, mTrackFitter->getTrack() );
1089 mNumFstHits[i] = nSiHitsFound;
1093 if ( mGenHistograms ){
1094 mHist[
"FitStatus"]->Fill( TString::Format(
"w%luSi", nSiHitsFound ).Data(), 1 );
1101 FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits();
1104 for (
size_t i = 0; i < mGlobalTracks.size(); i++) {
1105 if (mGlobalTracks[i]->getFitStatus(mGlobalTracks[i]->getCardinalRep())->isFitConverged() ==
false) {
1110 if ( mGenHistograms ){
1111 mHist[
"FitStatus"]->Fill(
"PossibleReFit", 1);
1118 auto msp2 = mTrackFitter->projectToFst(2, mGlobalTracks[i]);
1119 auto msp1 = mTrackFitter->projectToFst(1, mGlobalTracks[i]);
1120 auto msp0 = mTrackFitter->projectToFst(0, mGlobalTracks[i]);
1123 hits_near_disk2 = findSiHitsNearMe(hitmap[2], msp2);
1124 hits_near_disk1 = findSiHitsNearMe(hitmap[1], msp1);
1125 hits_near_disk0 = findSiHitsNearMe(hitmap[0], msp0);
1126 }
catch (genfit::Exception &e) {
1130 vector<KiTrack::IHit *> hits_to_add;
1132 size_t nSiHitsFound = 0;
1134 if ( mGenHistograms ){
1135 this->mHist[
"nSiHitsFound" ]->Fill( 1, hits_near_disk0.size() );
1136 this->mHist[
"nSiHitsFound" ]->Fill( 2, hits_near_disk1.size() );
1137 this->mHist[
"nSiHitsFound" ]->Fill( 3, hits_near_disk2.size() );
1141 if ( hits_near_disk0.size() == 1 ) {
1142 hits_to_add.push_back( hits_near_disk0[0] );
1145 hits_to_add.push_back(
nullptr );
1147 if ( hits_near_disk1.size() == 1 ) {
1148 hits_to_add.push_back( hits_near_disk1[0] );
1151 hits_to_add.push_back(
nullptr );
1153 if ( hits_near_disk2.size() == 1 ) {
1154 hits_to_add.push_back( hits_near_disk2[0] );
1157 hits_to_add.push_back(
nullptr );
1160 if (nSiHitsFound >= 1) {
1161 if ( mGenHistograms ){
1162 mHist[
"FitStatus"]->Fill(
"AttemptReFit", 1);
1165 TVector3 p = mTrackFitter->refitTrackWithSiHits(mGlobalTracks[i], hits_to_add);
1166 size_t lengthGTR = mTrackResults.size();
1167 if ( lengthGTR >= 1 ){
1168 mTrackResults[ lengthGTR - 1 ].setFst( hits_to_add, mTrackFitter->getTrack() );
1170 LOG_ERROR <<
"Fit Results not found" << endm;
1173 if ( mGenHistograms ){
1174 if (p.Perp() == mFitMoms[i].Perp()) {
1175 mHist[
"FitStatus"]->Fill(
"BadReFit", 1);
1177 mHist[
"FitStatus"]->Fill(
"GoodReFit", 1);
1182 mNumFstHits[i] = nSiHitsFound;
1189 if ( mGenHistograms ){
1190 mHist[
"FitStatus"]->Fill( TString::Format(
"w%luSi", nSiHitsFound ).Data(), 1 );
1196 Seed_t findSiHitsNearMe(
Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp,
double dphi = 0.004 * 9.5,
double dr = 2.75) {
1197 double probe_phi = TMath::ATan2(msp.getPos().Y(), msp.getPos().X());
1198 double probe_r = sqrt(pow(msp.getPos().X(), 2) + pow(msp.getPos().Y(), 2));
1202 for (
auto h : available_hits) {
1203 double h_phi = TMath::ATan2(h->getY(), h->getX());
1204 double h_r = sqrt(pow(h->getX(), 2) + pow(h->getY(), 2));
1205 double mdphi = fabs(h_phi - probe_phi);
1207 if ( mdphi < dphi && fabs( h_r - probe_r ) < dr) {
1208 found_hits.push_back(h);
1215 bool getSaveCriteriaValues() {
return mSaveCriteriaValues; }
1216 std::vector<KiTrack::ICriterion *> getTwoHitCriteria() {
return mTwoHitCrit; }
1217 std::vector<KiTrack::ICriterion *> getThreeHitCriteria() {
return mThreeHitCrit; }
1219 TrackFitter *getTrackFitter() {
return mTrackFitter; }
1220 void setEventVertex( TVector3 v ) { mEventVertex = v; }
1223 unsigned long long int nEvents;
1225 bool mDoTrackFitting =
true;
1226 bool mSaveCriteriaValues =
true;
1229 std::string mConfigFile;
1230 size_t mTotalHitsRemoved;
1232 std::vector<GenfitTrackResult> mTrackResults;
1234 std::vector<Seed_t> mRecoTracks;
1235 std::vector<Seed_t> mRecoTracksThisItertion;
1238 TVector3 mEventVertex;
1242 std::vector<float> mRecoTrackQuality;
1243 std::vector<int> mRecoTrackIdTruth;
1244 std::vector<TVector3> mFitMoms;
1245 std::vector<unsigned short> mNumFstHits;
1246 std::vector<genfit::FitStatus> mFitStatus;
1247 std::vector<genfit::AbsTrackRep *> mGlobalTrackReps;
1248 std::vector<genfit::Track *> mGlobalTracks;
1251 std::shared_ptr<FwdDataSource> mDataSource;
1255 std::vector<KiTrack::ICriterion *> mTwoHitCrit;
1256 std::vector<KiTrack::ICriterion *> mThreeHitCrit;
1259 bool mGenHistograms =
false;
1261 std::map<std::string, TH1 *> mHist;
std::vector< KiTrack::ICriterion * > loadCriteria(string path)
vector< Seed_t > doTrackingOnHitmapSubset(size_t iIteration, FwdDataSource::HitMap_t &hitmap)
Does track finding steps on a subset of hits (phi slice)
size_t sliceHitMapInPhi(FwdDataSource::HitMap_t &inputMap, FwdDataSource::HitMap_t &outputMap, float phi_min, float phi_max)
Slices a hitmap into a phi section.