diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 2d5393ec9cef995525add61f2bd49b7207d9c7e4..00f4b16b20d1807c72a6779121f2d1ccd4b23d0e 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -41,12 +41,15 @@ #include "TClonesArray.h" #include "TH1.h" +#include <boost/functional/hash.hpp> + #include <algorithm> #include <fstream> #include <iostream> #include <map> #include <set> #include <string_view> +#include <unordered_map> #include <utility> #include "L1Algo/L1Algo.h" @@ -67,6 +70,7 @@ class CbmMCDataObject; class CbmEvent; class TProfile2D; +/// TODO: SZh 21.09.2022: Replace instances of this class with L1Hit class CbmL1HitStore { public: int ExtIndex; @@ -81,6 +85,36 @@ public: int Det; }; +/// Internal structure to handle link keys +struct CbmL1LinkKey { + /// Constructor from links + CbmL1LinkKey(int32_t index, int32_t entry, int32_t file) : fIndex(index), fEntry(entry), fFile(file) {} + bool operator==(const CbmL1LinkKey& other) const + { + return fFile == other.fFile && fEntry == other.fEntry && fIndex == other.fIndex; + } + + int32_t fIndex = -1; ///< index of point/track, saved to link + int32_t fEntry = -1; ///< index of link entry + int32_t fFile = -1; ///< index of link file +}; + +/// Hash for CbmL1LinkKey +namespace std +{ + template<> + struct hash<CbmL1LinkKey> { + std::size_t operator()(const CbmL1LinkKey& key) const + { + std::size_t res = 0; + boost::hash_combine(res, key.fFile); + boost::hash_combine(res, key.fEntry); + boost::hash_combine(res, key.fIndex); + return res; + } + }; +} // namespace std + /// Enumeration for the detector subsystems used in L1 tracking /// It is important for the subsystems to be specified in the actual order. The order is used @@ -109,7 +143,6 @@ public: // ********************** using DFSET = std::set<std::pair<int, int>>; // Why std::set<std::pair<>> instead of std::map<>? - using DFEI2I = std::map<Double_t, Int_t>; // ************************** // ** Friends classes list ** @@ -336,7 +369,7 @@ private: // static bool compareZ(const int &a, const int &b ); // bool compareZ(const int &a, const int &b ); - /// Fills the fvMCTracks vector and the dFEI2vMCTracks set + /// Fills the fvMCTracks vector and the fmMCTracksMap void Fill_vMCTracks(); /* @@ -408,8 +441,6 @@ private: static std::istream& eatwhite(std::istream& is); // skip spaces static void writedir2current(TObject* obj); // help procedure - inline Double_t dFEI(int file, int event, int idx) { return (1000 * idx) + file + (0.0001 * event); } - private: std::string fInputDataFilename = ""; ///< File name to read/write input hits @@ -569,8 +600,9 @@ public: // L1Vector<int> vHitMCRef1; // CbmMatch HitMatch; private: - DFEI2I dFEI2vMCPoints = {}; - DFEI2I dFEI2vMCTracks = {}; + std::unordered_map<CbmL1LinkKey, int> fmMCPointsLinksMap = {}; /// Internal MC point index vs. link + std::unordered_map<CbmL1LinkKey, int> fmMCTracksLinksMap = {}; /// Internal MC track index vs. link + // ***************************** // ** Tracking performance QA ** diff --git a/reco/L1/CbmL1ReadEvent.cxx b/reco/L1/CbmL1ReadEvent.cxx index 8e5311961f2c202af4589d51960e6a33cc09d71c..a015b73cf0b565bc5ab3fcbb122d91ae3ea73254 100644 --- a/reco/L1/CbmL1ReadEvent.cxx +++ b/reco/L1/CbmL1ReadEvent.cxx @@ -188,8 +188,9 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int fvRecoTracks.clear(); /* <CbmL1Track> */ // TODO: Move from this function to more suitable place (S.Zharko) fvHitPointIndexes.clear(); /* <int>: indexes of MC-points in fvMCPoints (by index of fpAlgo->vHits) */ fvHitStore.clear(); /* <CbmL1HitStore> */ - dFEI2vMCPoints.clear(); /* dFEI vs MC-point index: dFEI = index * 10000 + fileID + eventID * 0.0001 */ - dFEI2vMCTracks.clear(); /* dFEI vs MC-track index: dFEI = index * 10000 + fileID + eventID * 0.0001 */ + + fmMCPointsLinksMap.clear(); + fmMCTracksLinksMap.clear(); if (fVerbose >= 10) cout << "ReadEvent: clear is done." << endl; @@ -241,10 +242,10 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int */ if (fPerformance) { - // Fill fvMCTracks and dFEI2vMCTracks + // Fill fvMCTracks and fmMCTracksLinksMap Fill_vMCTracks(); - // Fill fvMCPoints and dFEI2vMCPoints + // Fill fvMCPoints and fmMCPointsLinksMap fvMCPoints.clear(); fvMCPoints.reserve(5 * fvMCTracks.size() * fNStations); fvMCPointIndexesTs.clear(); @@ -276,12 +277,11 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int } assert(MC.iStation >= 0); if (fabs(maxDeviation) < fabs(bestDist)) { maxDeviation = bestDist; } - Double_t dtrck = dFEI(iFile, iEvent, MC.ID); - DFEI2I::iterator trk_it = dFEI2vMCTracks.find(dtrck); - assert(trk_it != dFEI2vMCTracks.end()); - MC.ID = trk_it->second; + auto itTrack = fmMCTracksLinksMap.find(CbmL1LinkKey(MC.ID, iEvent, iFile)); + assert(itTrack != fmMCTracksLinksMap.cend()); + MC.ID = itTrack->second; fvMCTracks[MC.ID].Points.push_back_no_warning(fvMCPoints.size()); - dFEI2vMCPoints.insert(DFEI2I::value_type(dFEI(iFile, iEvent, iMC), fvMCPoints.size())); + fmMCPointsLinksMap[CbmL1LinkKey(iMC, iEvent, iFile)] = fvMCPoints.size(); fvMCPoints.push_back(MC); fvMCPointIndexesTs.push_back(0); nMvdPoints++; @@ -315,12 +315,11 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int } assert(MC.iStation >= 0); if (fabs(maxDeviation) < fabs(bestDist)) { maxDeviation = bestDist; } - Double_t dtrck = dFEI(iFile, iEvent, MC.ID); - DFEI2I::iterator trk_it = dFEI2vMCTracks.find(dtrck); - assert(trk_it != dFEI2vMCTracks.end()); - MC.ID = trk_it->second; + auto itTrack = fmMCTracksLinksMap.find(CbmL1LinkKey(MC.ID, iEvent, iFile)); + assert(itTrack != fmMCTracksLinksMap.cend()); + MC.ID = itTrack->second; fvMCTracks[MC.ID].Points.push_back_no_warning(fvMCPoints.size()); - dFEI2vMCPoints.insert(DFEI2I::value_type(dFEI(iFile, iEvent, iMC + nMvdPoints), fvMCPoints.size())); + fmMCPointsLinksMap[CbmL1LinkKey(iMC + nMvdPoints, iEvent, iFile)] = fvMCPoints.size(); fvMCPoints.push_back(MC); fvMCPointIndexesTs.push_back(0); nStsPoints++; @@ -345,13 +344,11 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int if (MC.z > sta[iStActive].z[0] - 2.5) { MC.iStation = iStActive; } } assert(MC.iStation >= 0); - Double_t dtrck = dFEI(iFile, iEvent, MC.ID); - DFEI2I::iterator trk_it = dFEI2vMCTracks.find(dtrck); - assert(trk_it != dFEI2vMCTracks.end()); - MC.ID = trk_it->second; + auto itTrack = fmMCTracksLinksMap.find(CbmL1LinkKey(MC.ID, iEvent, iFile)); + assert(itTrack != fmMCTracksLinksMap.cend()); + MC.ID = itTrack->second; fvMCTracks[MC.ID].Points.push_back_no_warning(fvMCPoints.size()); - dFEI2vMCPoints.insert( - DFEI2I::value_type(dFEI(iFile, iEvent, iMC + nMvdPoints + nStsPoints), fvMCPoints.size())); + fmMCPointsLinksMap[CbmL1LinkKey(iMC + nMvdPoints + nStsPoints, iEvent, iFile)] = fvMCPoints.size(); fvMCPoints.push_back(MC); fvMCPointIndexesTs.push_back(0); nMuchPoints++; @@ -374,13 +371,12 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int } if (MC.iStation < 0) continue; assert(MC.iStation >= 0); - Double_t dtrck = dFEI(iFile, iEvent, MC.ID); - DFEI2I::iterator trk_it = dFEI2vMCTracks.find(dtrck); - assert(trk_it != dFEI2vMCTracks.end()); - MC.ID = trk_it->second; + auto itTrack = fmMCTracksLinksMap.find(CbmL1LinkKey(MC.ID, iEvent, iFile)); + assert(itTrack != fmMCTracksLinksMap.cend()); + MC.ID = itTrack->second; fvMCTracks[MC.ID].Points.push_back_no_warning(fvMCPoints.size()); - dFEI2vMCPoints.insert( - DFEI2I::value_type(dFEI(iFile, iEvent, iMC + nMvdPoints + nStsPoints + nMuchPoints), fvMCPoints.size())); + fmMCPointsLinksMap[CbmL1LinkKey(iMC + nMvdPoints + nStsPoints + nMuchPoints, iEvent, iFile)] = + fvMCPoints.size(); fvMCPoints.push_back(MC); fvMCPointIndexesTs.push_back(0); nTrdPoints++; @@ -424,10 +420,9 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int if (isTofPointMatched[iMC] == 0) continue; CbmL1MCPoint MC; if (!ReadMCPoint(&MC, iMC, iFile, iEvent, 4)) { - Double_t dtrck = dFEI(iFile, iEvent, MC.ID); - auto trk_it = dFEI2vMCTracks.find(dtrck); - if (trk_it == dFEI2vMCTracks.end()) continue; - Int_t iTrack = trk_it->second; + auto itTrack = fmMCTracksLinksMap.find(CbmL1LinkKey(MC.ID, iEvent, iFile)); + if (itTrack == fmMCTracksLinksMap.cend()) { continue; } + int iTrack = itTrack->second; MC.iStation = -1; const L1Station* sta = fpAlgo->GetParameters()->GetStations().begin(); @@ -469,13 +464,9 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int MC.ID = iTrack; - dFEI2vMCPoints.insert(DFEI2I::value_type( - dFEI(iFile, iEvent, - fTofPointToTrack[iTofSta][iTrack] + nMvdPoints + nStsPoints + nMuchPoints + nTrdPoints), - fvMCPoints.size())); - + int iMC = fTofPointToTrack[iTofSta][iTrack] + nMvdPoints + nStsPoints + nMuchPoints + nTrdPoints; + fmMCPointsLinksMap[CbmL1LinkKey(iMC, iEvent, iFile)] = fvMCPoints.size(); fvMCPoints.push_back(MC); - fvMCPointIndexesTs.push_back(0); nTofPoints++; } @@ -488,11 +479,11 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int sort(fvMCTracks[iTr].Points.begin(), fvMCTracks[iTr].Points.end(), compareZ); if (fvMCTracks[iTr].mother_ID >= 0) { - Double_t dtrck = dFEI(fvMCTracks[iTr].iFile, fvMCTracks[iTr].iEvent, fvMCTracks[iTr].mother_ID); - DFEI2I::iterator map_it = dFEI2vMCTracks.find(dtrck); - if (map_it == dFEI2vMCTracks.end()) fvMCTracks[iTr].mother_ID = -2; - else - fvMCTracks[iTr].mother_ID = map_it->second; + auto iFile = fvMCTracks[iTr].iFile; + auto iEvent = fvMCTracks[iTr].iEvent; + auto iMother = fvMCTracks[iTr].mother_ID; + auto itTrack = fmMCTracksLinksMap.find(CbmL1LinkKey(iMother, iEvent, iFile)); + fvMCTracks[iTr].mother_ID = ((itTrack != fmMCTracksLinksMap.cend()) ? itTrack->second : -2); } } //iTr if (fVerbose >= 10) cout << "Points in fvMCTracks are sorted." << endl; @@ -772,10 +763,9 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int Int_t iFile = matchHitMatch->GetLink(0).GetFile(); Int_t iEvent = matchHitMatch->GetLink(0).GetEntry(); - Double_t dtrck = dFEI(iFile, iEvent, iIndex); - DFEI2I::iterator trk_it = dFEI2vMCPoints.find(dtrck); - if (trk_it == dFEI2vMCPoints.end()) continue; - th.iMC = trk_it->second; + auto itPoint = fmMCPointsLinksMap.find(CbmL1LinkKey(iIndex, iEvent, iFile)); + if (itPoint == fmMCPointsLinksMap.cend()) continue; + th.iMC = itPoint->second; if ((1 == fMuchUseMcHit) && (th.iMC > -1)) th.SetHitFromPoint(fvMCPoints[th.iMC], fpAlgo->GetParameters()->GetStation(th.iStation)); } @@ -1006,11 +996,9 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int //CbmTofPoint* pt = L1_DYNAMIC_CAST<CbmTofPoint*>(fTofPoints->Get(iFile, iEvent, iMC)); // pt->GetTrackID(); - Double_t dtrck = dFEI(iFile, iEvent, iIndex); - DFEI2I::iterator trk_it = dFEI2vMCPoints.find(dtrck); - if (trk_it == dFEI2vMCPoints.end()) continue; - - th.iMC = trk_it->second; + auto itPoint = fmMCPointsLinksMap.find(CbmL1LinkKey(iIndex, iEvent, iFile)); + if (itPoint == fmMCPointsLinksMap.cend()) continue; + th.iMC = itPoint->second; if ((1 == fTofUseMcHit) && (th.iMC > -1)) th.SetHitFromPoint(fvMCPoints[th.iMC], fpAlgo->GetParameters()->GetStation(th.iStation)); } @@ -1196,8 +1184,7 @@ void CbmL1::Fill_vMCTracks() T.isSignal = T.IsPrimary() && (T.z > header->GetZ() + 1.e-10); fvMCTracks.push_back(T); - // Double_t dtrck =dFEI(iFile,iEvent,iMCTrack); - dFEI2vMCTracks.insert(DFEI2I::value_type(dFEI(iFile, iEvent, iMCTrack), fvMCTracks.size() - 1)); + fmMCTracksLinksMap[CbmL1LinkKey(iMCTrack, iEvent, iFile)] = fvMCTracks.size() - 1; } //iTracks } //Links @@ -1378,8 +1365,6 @@ void CbmL1::HitMatch() CbmL1Hit& hit = fvExternalHits[iH]; if ((hit.Det == 1) && (2 != fStsUseMcHit)) { - L1_SHOW(iH); - CbmStsHit* sh = L1_DYNAMIC_CAST<CbmStsHit*>(fpStsHits->At(fvExternalHits[iH].extIndex)); int iP = -1; @@ -1416,15 +1401,12 @@ void CbmL1::HitMatch() iEvent = fvFileEvent.begin()->second; } - Double_t dpnt = dFEI(iFile, iEvent, nMvdPoints + iIndex); - DFEI2I::iterator pnt_it = dFEI2vMCPoints.find(dpnt); - - - assert(pnt_it != dFEI2vMCPoints.end()); + auto itPoint = fmMCPointsLinksMap.find(CbmL1LinkKey(iIndex + nMvdPoints, iEvent, iFile)); + assert(itPoint != fmMCPointsLinksMap.cend()); if (link.GetWeight() > bestWeight) { bestWeight = link.GetWeight(); - iP = pnt_it->second; + iP = itPoint->second; } } } //mach cluster diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx index df30f45a903d2364a3158b5945fa216ac6a52b4e..872c344ca481c0dbfdb408b8b35bb8efb0c2d5b6 100644 --- a/reco/L1/L1Algo/L1CATrackFinder.cxx +++ b/reco/L1/L1Algo/L1CATrackFinder.cxx @@ -216,8 +216,12 @@ inline void L1Algo::findSingletsStep1( /// input 1st stage of singlet search fld1.Set(b10, fld1Sta0.z, b11, fld1Sta1.z, b12, fld1Sta2.z); T.chi2 = 0.; - T.NDF = 2.; + T.NDF = 2.; /// Iterations -> Number of parameters - number of measurements, if ((isec == kAllSecIter) || (isec == kAllSecEIter) || (isec == kAllSecJumpIter)) T.NDF = fvec(0.); + // TODO: iteration parameter: "Starting NDF of track parameters" + // NDF = number of track parameters (6: x, y, tx, ty, qp, time) - number of measured parameters (3: x, y, time) on station or (2: x, y) on target + // Alternative: Iteration can find tracks starting from target or from station: -> use a FLAG + T.tx = tx; T.ty = ty; T.t = time; @@ -1648,6 +1652,13 @@ inline void L1Algo::TripletsStaPort( /// creates triplets: void L1Algo::CATrackFinder() { +#ifdef TRACKS_FROM_TRIPLETS + // TODO investigate kAllPrimJumpIter & kAllSecJumpIter + fNFindIterations = TRACKS_FROM_TRIPLETS_ITERATION + 1; +#else + fNFindIterations = fParameters.GetNcaIterations(); +#endif + #ifdef _OPENMP omp_set_num_threads(fNThreads); @@ -1847,12 +1858,6 @@ void L1Algo::CATrackFinder() // ---- Loop over Track Finder iterations ----------------------------------------------------------------// -#ifdef TRACKS_FROM_TRIPLETS - // TODO investigate kAllPrimJumpIter & kAllSecJumpIter - fNFindIterations = TRACKS_FROM_TRIPLETS_ITERATION + 1; -#else - fNFindIterations = fParameters.GetNcaIterations(); -#endif L1ASSERT(0, fNFindIterations == (int) fParameters.GetCAIterations().size()); isec = 0; // TODO: temporary! (S.Zharko) @@ -2075,6 +2080,7 @@ void L1Algo::CATrackFinder() ); if ((isec == kFastPrimJumpIter) || (isec == kAllPrimJumpIter) || (isec == kAllSecJumpIter) || (fMissingHits)) { + // All iterations are "jump"! Tindex nG_2; hitsmG_2.clear(); i1G_2.clear(); @@ -2141,6 +2147,8 @@ void L1Algo::CATrackFinder() if (isec == TRACKS_FROM_TRIPLETS_ITERATION) min_level = 0; #endif + // TODO: Just remove it + // // min_level: lower then this triplets would never start // int min_level = 1; // min level for start triplet. So min track length = min_level+3. // if (isec == kAllPrimJumpIter) min_level = 1; // if ( (isec == kAllSecIter) || (isec == kAllSecJumpIter) ) min_level = 2; // only the long low momentum tracks diff --git a/reco/L1/L1Algo/L1Utils.h b/reco/L1/L1Algo/L1Utils.h index 305d5025806f6d4d0e223940cd604d7bb4d41429..1fb299955b0a714fcc025b65e6c2d2ba9c1745c1 100644 --- a/reco/L1/L1Algo/L1Utils.h +++ b/reco/L1/L1Algo/L1Utils.h @@ -23,8 +23,10 @@ #include <cmath> +#include "CaSimd.h" #include "L1Def.h" + /// Class contains some utility functions for L1Algo namespace L1Utils { @@ -42,10 +44,10 @@ namespace L1Utils || fabs(lhs - rhs) < std::numeric_limits<T>::min(); } - [[gnu::always_inline]] inline void CheckSimdVectorEquality(fvec v, const char* name) + [[gnu::always_inline]] inline void CheckSimdVectorEquality(cbm::algo::ca::fvec v, const char* name) { bool ok = true; - for (size_t i = 1; i < fvec::size(); i++) { + for (size_t i = 1; i < cbm::algo::ca::fvec::size(); i++) { ok = ok && (v[i] == v[0]); } if (!ok) {