diff --git a/reco/L1/utils/CbmCaIdealHitProducer.cxx b/reco/L1/utils/CbmCaIdealHitProducer.cxx
index 1daf544d2245a4467fe450bb128d4c8484d9db18..6fd17c889a68cd56f6757dd8520ed2cff9fc29a0 100644
--- a/reco/L1/utils/CbmCaIdealHitProducer.cxx
+++ b/reco/L1/utils/CbmCaIdealHitProducer.cxx
@@ -24,7 +24,7 @@ InitStatus IdealHitProducer::Init()
fbUseDet[ca::EDetectorID::kSts] = CbmSetup::Instance()->IsActive(ECbmModuleId::kSts);
fbUseDet[ca::EDetectorID::kMuch] = CbmSetup::Instance()->IsActive(ECbmModuleId::kMuch);
fbUseDet[ca::EDetectorID::kTrd] = CbmSetup::Instance()->IsActive(ECbmModuleId::kTrd);
- fbUseDet[ca::EDetectorID::kTof] = false; //CbmSetup::Instance()->IsActive(ECbmModuleId::kTof);
+ fbUseDet[ca::EDetectorID::kTof] = CbmSetup::Instance()->IsActive(ECbmModuleId::kTof);
InitStatus ret = kSUCCESS;
diff --git a/reco/L1/utils/CbmCaIdealHitProducerDet.h b/reco/L1/utils/CbmCaIdealHitProducerDet.h
index c233eed55fb236ce71c6a6672a7dea21527192e9..eaff2a8243977e482a2eeb3a10f74ed46269b434 100644
--- a/reco/L1/utils/CbmCaIdealHitProducerDet.h
+++ b/reco/L1/utils/CbmCaIdealHitProducerDet.h
@@ -7,8 +7,7 @@
/// @author S.Zharko
/// @since 30.05.2023
-#ifndef CbmCaIdealHitProducerDet_h
-#define CbmCaIdealHitProducerDet_h 1
+#pragma once
#include "AlgoFairloggerCompat.h"
#include "CaAlgoRandom.h"
@@ -123,6 +122,9 @@ namespace cbm::ca
/// @param opt Function (0 - BoundedGaus, 1 - Uniform)
void SmearValue(double& value, double sigma, int opt);
+ /// @brief Fills map of legit points (inside MC event!)
+ void FillPointIsLegit(int iEvGlob);
+
/// @brief A structure to keep hit adjustment/creation settings for each station
struct HitParameters {
@@ -160,6 +162,7 @@ namespace cbm::ca
CbmMCEventList* fpMCEventList = nullptr; ///< MC event list
CbmMCDataObject* fpMCEventHeader = nullptr; ///< MC event header
CbmMCDataArray* fpBrPoints = nullptr; ///< Branch: array of MC points
+ CbmMCDataArray* fpBrMCTracks = nullptr; ///< Branch: array of MC tracks
TClonesArray* fpBrHits = nullptr; ///< Branch: array of hits
TClonesArray* fpBrHitMatches = nullptr; ///< Branch: array of hit matches
@@ -173,6 +176,8 @@ namespace cbm::ca
std::vector<HitParameters> fvStationPars; ///< Parameters, stored for each station
+ std::vector<unsigned char> fvbPointIsLegit; ///< Map of used point index
+
ca::Random fRandom{1}; ///< Random generator
/// @brief Management flag, which does run the routine if there was a request
@@ -224,9 +229,12 @@ namespace cbm::ca
fpTimeSlice = dynamic_cast<CbmTimeSlice*>(pFairManager->GetObject("TimeSlice."));
fpRecoEvents = dynamic_cast<TClonesArray*>(pFairManager->GetObject("CbmEvent"));
fpMCEventList = dynamic_cast<CbmMCEventList*>(pFairManager->GetObject("MCEventList."));
+
CheckBranch(fpTimeSlice, "TimeSlice.");
CheckBranch(fpMCEventList, "MCEventList.");
fpMCEventHeader = pMcManager->GetObject("MCEventHeader.");
+ fpBrMCTracks = pMcManager->InitBranch("MCTrack");
+ CheckBranch(fpBrMCTracks, "MCTrack");
switch (DetID) {
case ca::EDetectorID::kMvd:
@@ -461,10 +469,6 @@ namespace cbm::ca
std::optional<CbmLink> IdealHitProducerDet<DetID>::GetMatchedPointLink(int iH)
{
const auto* pHitMatch = dynamic_cast<CbmMatch*>(fpBrHitMatchesTmp->At(iH));
- if constexpr (ca::EDetectorID::kTof == DetID) {
- LOG(fatal) << "IdealHitFinder: TOF cannot be used until the new MC points scheme will be introduced";
- }
-
assert(pHitMatch);
if (pHitMatch->GetNofLinks() > 0) {
const auto& link = pHitMatch->GetMatchedLink();
@@ -492,8 +496,6 @@ namespace cbm::ca
template<ca::EDetectorID DetID>
void IdealHitProducerDet<DetID>::Exec(Option_t*)
{
- assert(ca::EDetectorID::kTof != DetID);
-
// ------ Check, if there are any requirement to run the routine for this detector
if (!fbRunTheRoutine) {
return;
@@ -612,7 +614,11 @@ namespace cbm::ca
// TODO: Write point selector for TOF
// NOTE: does not implemented for MVD
+ this->FillPointIsLegit(iE);
for (int iP = 0; iP < nPoints; ++iP) {
+ if (!fvbPointIsLegit[iP]) {
+ continue;
+ }
auto* pPoint = static_cast<Point_t*>(fpBrPoints->Get(fileId, eventId, iP));
int iSt = fpDetInterface->GetTrackingStationIndex(pPoint->GetDetectorID());
const auto& setting = fvStationPars[iSt];
@@ -725,6 +731,106 @@ namespace cbm::ca
}
}
+ // -------------------------------------------------------------------------------------------------------------------
+ //
+ template<ca::EDetectorID DetID>
+ void IdealHitProducerDet<DetID>::FillPointIsLegit(int iEvGlob)
+ {
+ int iFile = fpMCEventList->GetFileIdByIndex(iEvGlob);
+ int iEvent = fpMCEventList->GetEventIdByIndex(iEvGlob);
+ int nPoints = fpBrPoints->Size(iFile, iEvent);
+
+ fvbPointIsLegit.clear();
+ fvbPointIsLegit.resize(nPoints);
+ if constexpr (ca::EDetectorID::kTof == DetID) {
+ constexpr int kNofBitsRpcAddress = 11;
+ std::map<std::pair<int, int>, int> mMatchedPointId; // map (iTr, addr) -> is matched
+ for (int iH = 0; iH < fpBrHitMatches->GetEntriesFast(); ++iH) {
+ auto* pHitMatch = dynamic_cast<CbmMatch*>(fpBrHitMatches->At(iH));
+ LOG_IF(fatal, !pHitMatch) << "CA MC Module: hit match was not found for TOF hit " << iH;
+ double bestWeight = 0;
+ for (int iLink = 0; iLink < pHitMatch->GetNofLinks(); ++iLink) {
+ const auto& link = pHitMatch->GetLink(iLink);
+ if (link.GetFile() != iFile || link.GetEntry() != iEvent) {
+ continue;
+ }
+ int iPext = link.GetIndex();
+ if (iPext < 0) {
+ continue;
+ }
+ auto* pExtPoint = static_cast<CbmTofPoint*>(fpBrPoints->Get(link));
+ int trkId = pExtPoint->GetTrackID();
+ int rpcAddr = pExtPoint->GetDetectorID() << kNofBitsRpcAddress; // FIXME:
+ auto key = std::make_pair(trkId, rpcAddr);
+ auto prev = mMatchedPointId.find(key);
+ if (prev == mMatchedPointId.end()) {
+ bestWeight = link.GetWeight();
+ mMatchedPointId[key] = iPext;
+ }
+ else { // If we find two links for the same interaction, we select the one with the largest weight
+ if (bestWeight < link.GetWeight()) {
+ mMatchedPointId[key] = iPext;
+ }
+ }
+ }
+ } // iH
+
+ // In TOF each RPC contains up to 10 points, and one have to select only
+ // one of them
+ {
+ int iPointSelected = -1;
+ int iTmcCurr = -1;
+ int rpcAddrCurr = -1;
+ bool bTrkHasHits = false;
+ double zDist = std::numeric_limits<double>::max();
+ double zCell = std::numeric_limits<double>::signaling_NaN();
+ for (int iP = 0; iP < nPoints; ++iP) {
+ auto* pExtPoint = dynamic_cast<CbmTofPoint*>(fpBrPoints->Get(iFile, iEvent, iP));
+ LOG_IF(fatal, !pExtPoint) << "NO POINT: TOF: file, event, index = " << iFile << ' ' << iEvent << ' ' << iP;
+
+ int iTmc = pExtPoint->GetTrackID();
+ int rpcAddr = pExtPoint->GetDetectorID() << kNofBitsRpcAddress;
+ // New point
+ if (rpcAddrCurr != rpcAddr || iTmcCurr != iTmc) { // The new interaction of the MC track with the TOF RPC
+ if (iPointSelected != -1) {
+ fvbPointIsLegit[iPointSelected] = true;
+ }
+ iTmcCurr = iTmc;
+ rpcAddrCurr = rpcAddr;
+ auto key = std::make_pair(iTmc, rpcAddr);
+ auto found = mMatchedPointId.find(key);
+ bTrkHasHits = found != mMatchedPointId.end();
+ if (bTrkHasHits) {
+ iPointSelected = found->second;
+ }
+ else {
+ // First iteration
+ zCell = fpDetInterface->GetZrefModule(pExtPoint->GetDetectorID());
+ zDist = std::fabs(zCell - pExtPoint->GetZ());
+ iPointSelected = iP;
+ }
+ }
+ else {
+ if (!bTrkHasHits) {
+ auto newDist = std::fabs(pExtPoint->GetZ() - zCell);
+ if (newDist < zDist) {
+ zDist = newDist;
+ iPointSelected = iP;
+ }
+ }
+ }
+ }
+ // Add the last point
+ if (iPointSelected != -1) {
+ fvbPointIsLegit[iPointSelected] = true;
+ }
+ }
+ }
+ else {
+ // In MVD, STS, MuCh and TRD every MC point is legit
+ std::fill(fvbPointIsLegit.begin(), fvbPointIsLegit.end(), true);
+ }
+ }
+
} // namespace cbm::ca
-#endif // CbmCaIdealHitProducerDet_h