27#include "FairEventHeader.h"
28#include "FairMCEventHeader.h"
29#include "FairRootManager.h"
30#include "FairRunAna.h"
32#include "TDatabasePDG.h"
33#include "TLorentzVector.h"
36#include <boost/filesystem.hpp>
46#include <fmt/format.h>
63 LOG(info) <<
"CA MC Module: initializing CA tracking Monte-Carlo module... ";
70 assert(recoSetup.GetMvd());
73 assert(recoSetup.GetSts());
76 assert(recoSetup.GetMuch());
79 assert(recoSetup.GetTrd());
82 assert(recoSetup.GetTof());
85 auto fairManager = FairRootManager::Instance();
88 auto mcManager =
dynamic_cast<CbmMCDataManager*
>(fairManager->GetObject(
"MCDataManager"));
101 auto InitPointBranch = [&](
const char* brName,
ca::EDetectorID detID) {
103 fvpBrPoints[detID] = mcManager->InitBranch(brName);
107 auto InitMatchesBranch = [&](
const char* brName,
ca::EDetectorID detID) {
109 fvpBrHitMatches[detID] =
dynamic_cast<TClonesArray*
>(fairManager->GetObject(brName));
127 if (!pRecoSetupManager->IsInitialized()) {
134 throw std::runtime_error(fmt::format(
"Det ID {} is not in RecoSetup",
static_cast<int>(detID)));
145 if (
auto pGeoNodeMap = pRecoSetupManager->GetGeoNodeMap()) {
147 pGeoNodeMap->GetVolumeProperties([](
const auto& vol) { return vol.GetCenterZ(); },
ECbmModuleId::kTof));
150 throw std::runtime_error(
"geo node map was not built in cbm::RecoSetupManager. Please request it with "
151 "cbm::RecoSetupManager::BuildGeoNodeMaps(), when adding the manager as a task "
173 LOG(info) <<
"CA MC Module: initializing CA tracking Monte-Carlo module... \033[1;32mDone!\033[0m";
177catch (
const std::exception& error) {
178 LOG(error) <<
"CA MC Module: initializing CA tracking Monte-Carlo module... \033[1;31mFailed\033[0m\nReason: "
195 LOG(info) <<
"DEBUG: nof linked mc events " << nLinks <<
" of total " <<
fpMCEventList->GetNofEvents();
196 for (
int iLink = 0; iLink < nLinks; ++iLink) {
197 const auto& link = pEvtMatch->
GetLink(iLink);
208 for (
int iE = 0; iE < nEvents; ++iE) {
223 for (
auto& aTrk :
fpMcData->GetTrackContainer()) {
224 aTrk.SortPointIndexes(
225 [&](
const int& iPl,
const int& iPr) {
return fpMcData->GetPoint(iPl).GetZ() <
fpMcData->GetPoint(iPr).GetZ(); });
242 for (
auto& aTrk :
fpMcData->GetTrackContainer()) {
249 isRec &= aTrk.GetMaxNofPointsOnStation() <= 3;
263 default: LOG(fatal) <<
"CA MC Module: invalid performance mode " <<
fPerformanceMode;
266 if (aTrk.GetNofPoints() > 0) {
267 isAdd &= aTrk.GetNofConsStationsWithHit() == aTrk.GetTotNofStationsWithHit();
268 isAdd &= aTrk.GetNofConsStationsWithPoint() == aTrk.GetTotNofStationsWithHit();
269 isAdd &= aTrk.GetTotNofStationsWithHit() == aTrk.GetTotNofStationsWithPoint();
270 isAdd &= aTrk.GetNofConsStationsWithHit() >= 3;
271 isAdd &=
fpMcData->GetPoint(aTrk.GetPointIndexes()[0]).GetActiveStationId() == 0;
277 aTrk.SetFlagReconstructable(isRec);
278 aTrk.SetFlagAdditional(isAdd);
311 for (
const auto& trkMC :
fpMcData->GetTrackContainer()) {
312 if (trkMC.IsReconstructable()) {
323 for (
int iTre = 0; iTre < int(
fpvRecoTracks->size()); ++iTre) {
324 auto& trkRe = (*fpvRecoTracks)[iTre];
327 auto& mNofHitsVsMCTrkID = trkRe.hitMap;
328 mNofHitsVsMCTrkID.clear();
329 for (
int iH : trkRe.Hits) {
330 auto& vP = (*fpvQaHits)[iH].GetMcPointIds();
335 int iTmc =
fpMcData->GetPoint(iP).GetTrackId();
336 mNofHitsVsMCTrkID[iTmc]++;
345 int nHitsTrkRe = trkRe.Hits.size();
346 double maxPurity = 0.;
347 for (
auto& item : mNofHitsVsMCTrkID) {
348 int iTmc = item.first;
349 int nHitsTrkMc = item.second;
355 if (
double(nHitsTrkMc) >
double(nHitsTrkRe) * maxPurity) {
356 maxPurity = double(nHitsTrkMc) / double(nHitsTrkRe);
359 auto& trkMc =
fpMcData->GetTrack(iTmc);
363 trkMc.AddRecoTrackIndex(iTre);
364 trkRe.AddMCTrackIndex(iTmc);
368 trkMc.AddTouchTrackIndex(iTre);
372 trkRe.SetMaxPurity(maxPurity);
388 throw std::logic_error(
"Tracking parameters object was not defined");
393 throw std::logic_error(
"MC data object was not registered");
396 throw std::logic_error(
"Reconstructed track container was not registered");
399 throw std::logic_error(
"Hit index container was not registered");
402 throw std::logic_error(
"QA hit container was not registered");
405 throw std::logic_error(
"Array of first hit indexes in each detector was not registered");
410 throw std::logic_error(
"MC event list was not found");
413 throw std::logic_error(
"Time slice was not found");
418 throw std::logic_error(
"MC tracks branch is unavailable");
423 throw std::logic_error(
"MC event header is unavailable");
430 throw std::logic_error(Form(
"MC points are unavailable for %s",
kDetName[iD]));
433 throw std::logic_error(Form(
"Hit matches are unavailable for %s",
kDetName[iD]));
453 constexpr int kNofBitsRpcAddress = 11;
455 for (
const auto& [iFile, iEvent] : fFileEventIDs) {
457 int nPoints = pBrPoints->Size(iFile, iEvent);
458 std::map<std::pair<int, int>,
int> mMatchedPointId;
459 for (
int iH = 0; iH < pBrHitMatches->GetEntriesFast(); ++iH) {
460 auto* pHitMatch =
dynamic_cast<CbmMatch*
>(pBrHitMatches->At(iH));
461 LOG_IF(fatal, !pHitMatch) <<
"CA MC Module: hit match was not found for TOF hit " << iH;
462 double bestWeight = 0;
463 for (
int iLink = 0; iLink < pHitMatch->GetNofLinks(); ++iLink) {
464 const auto& link = pHitMatch->GetLink(iLink);
465 if (link.GetFile() != iFile || link.GetEntry() != iEvent) {
468 int iPext = link.GetIndex();
472 auto* pExtPoint =
dynamic_cast<CbmTofPoint*
>(pBrPoints->Get(link));
474 LOG(error) <<
"ca::MCModule: MC Point with link=" << link.ToString() <<
" does not exist in branch";
478 int trkId = pExtPoint->GetTrackID();
479 int rpcAddr = pExtPoint->GetDetectorID() << kNofBitsRpcAddress;
480 auto key = std::make_pair(trkId, rpcAddr);
481 auto prev = mMatchedPointId.find(key);
482 if (prev == mMatchedPointId.end()) {
483 bestWeight = link.GetWeight();
484 mMatchedPointId[key] = iPext;
487 if (bestWeight < link.GetWeight()) {
488 mMatchedPointId[key] = iPext;
497 int iPointSelected = -1;
499 int rpcAddrCurr = -1;
500 bool bTrkHasHits =
false;
501 double zDist = std::numeric_limits<double>::max();
502 double zRpc = std::numeric_limits<double>::quiet_NaN();
503 for (
int iP = 0; iP < nPoints; ++iP) {
504 auto* pExtPoint =
dynamic_cast<CbmTofPoint*
>(pBrPoints->Get(iFile, iEvent, iP));
505 LOG_IF(fatal, !pExtPoint) <<
"NO POINT: TOF: file, event, index = " << iFile <<
' ' << iEvent <<
' ' << iP;
507 int iTmc = pExtPoint->GetTrackID();
510 if (rpcAddrCurr != rpcAddr || iTmcCurr != iTmc) {
511 if (iPointSelected != -1) {
512 auto oPoint = FillMCPoint<ca::EDetectorID::kTof>(iPointSelected, iEvent, iFile);
514 fpMcData->AddPoint(*oPoint);
518 rpcAddrCurr = rpcAddr;
519 auto key = std::make_pair(iTmc, rpcAddr);
520 auto found = mMatchedPointId.find(key);
521 bTrkHasHits = found != mMatchedPointId.end();
523 iPointSelected = found->second;
528 zDist = std::fabs(zRpc - pExtPoint->GetZ());
534 auto newDist = std::fabs(pExtPoint->GetZ() - zRpc);
535 if (newDist < zDist) {
543 if (iPointSelected != -1) {
544 auto oPoint = FillMCPoint<ca::EDetectorID::kTof>(iPointSelected, iEvent, iFile);
546 fpMcData->AddPoint(*oPoint);
558 fpMcData->ReserveNofPoints(nPointsEstimated);
562 for (
int iD = 0; iD < static_cast<int>(vNofPointsDet.size()); ++iD) {
564 vNofPointsDet[iD] =
fvpBrPoints[iD]->Size(iFile, iEvent);
585 if (iFile < 0 || iEvent < 0) {
588 nTracksTot +=
fpMCTracks->Size(iFile, iEvent);
590 fpMcData->ReserveNofTracks(nTracksTot);
594 if (iFile < 0 || iEvent < 0) {
597 auto pEvtHeader =
dynamic_cast<FairMCEventHeader*
>(
fpMCEventHeader->Get(iFile, iEvent));
599 LOG(fatal) <<
"cbm::ca::MCModule: event header is not found for file " << iFile <<
" and event " << iEvent;
601 double eventTime =
fpMCEventList->GetEventTime(iEvent, iFile);
604 int nTracks =
fpMCTracks->Size(iFile, iEvent);
605 for (
int iTrkExt = 0; iTrkExt < nTracks; ++iTrkExt) {
608 LOG(warn) <<
"cbm::ca::MCModule: track with (iF, iE, iT) = " << iFile <<
' ' << iEvent <<
' ' << iTrkExt
615 aTrk.SetExternalId(iTrkExt);
616 aTrk.SetEventId(iEvent);
617 aTrk.SetFileId(iFile);
619 aTrk.SetStartT(pExtMCTrk->
GetStartT() + eventTime);
624 aTrk.SetPx(pExtMCTrk->
GetPx());
625 aTrk.SetPy(pExtMCTrk->
GetPy());
626 aTrk.SetPz(pExtMCTrk->
GetPz());
628 aTrk.SetFlagSignal(aTrk.IsPrimary() && (aTrk.GetStartZ() > (pEvtHeader->GetZ() + 1.e-10)));
632 aTrk.SetMass(pExtMCTrk->
GetMass());
639 int extChainId = iTrkExt;
640 int extChainParent = extMotherId;
641 while (extChainParent >= 0) {
642 extChainId = extChainParent;
643 const auto* pExtParentTrk =
dynamic_cast<CbmMCTrack*
>(
fpMCTracks->Get(iFile, iEvent, extChainParent));
647 if (extMotherId < 0) {
650 aTrk.SetMotherId(extMotherId);
651 aTrk.SetChainId(extChainId);
655 int motherId =
fpMcData->FindInternalTrackIndex(extMotherId, iEvent, iFile);
656 int chainId =
fpMcData->FindInternalTrackIndex(extChainId, iEvent, iFile);
657 if (motherId == -1) {
660 aTrk.SetMotherId(motherId);
661 aTrk.SetChainId(chainId);
void MCModule::ReadMCPointsForDetector< ca::EDetectorID::kTof >()
CA Tracking performance interface for CBM (header)
@ kTof
Time-of-flight Detector.
Implementation of L1DetectorID enum class for CBM.
A manager for setup representation in CBM reconstruction.
Different utilities for the CbmOfflineRecoSetup library (source)
Data class for a reconstructed hit in the STS.
Class characterising one event by a collection of links (indices) to data objects,...
CbmMatch * GetMatch() const
Task class creating and managing CbmMCDataArray objects.
Container class for MC events with number, file and start time.
double GetCharge() const
Charge of the associated particle.
uint32_t GetGeantProcessId() const
int32_t GetMotherId() const
double GetMass() const
Mass of the associated particle.
int32_t GetPdgCode() const
const CbmLink & GetLink(int32_t i) const
int32_t GetNofLinks() const
const CbmLink & GetMatchedLink() const
Bookkeeping of time-slice content.
static uint32_t GetDetectorId(uint32_t address)
Gets detectorId - address of minimal alignable volume.
Geometric intersection of a MC track with a TOFb detector.
void ReadMCPointsForDetector()
Reads MC points in particular detector.
bool InitRun()
Defines action on the module in the beginning of the run.
const algo::RecoSetup & GetSetup() const
Setup accessor.
static RecoSetupManager * Instance()
Instance access.
void SetId(int id)
Sets index of track in the CA internal data structure (within event/TS)
Class CbmCaPerformance is an interface to communicate between.
void ReadMCTracks()
Reads MC tracks from external trees and saves them to MCDataObject.
void InitEvent(CbmEvent *pEvent)
Defines performance action in the beginning of each event or time slice.
void Finish()
Defines performance action in the end of the run.
void CheckInit() const
Check class initialization.
CbmMCEventList * fpMCEventList
MC event list.
int fBestMcFile
Index of bestly matched MC file.
void ProcessEvent(CbmEvent *pEvent)
Processes event.
ca::Vector< algo::ca::McHitInfo > * fpvQaHits
Pointer to QA hit container.
ca::Vector< CbmL1HitId > * fpvHitIds
Pointer to hit index container.
void InitMcTrackInfo()
Initializes MC track.
void ReadMCPoints()
Reads MC points from external trees and saves them to MCDataObject.
ca::Monitor< EMonitorKey > fMonitor
Monitor.
DetIdArr_t< bool > fvbUseDet
Flag: is detector subsystem used.
std::unordered_map< uint32_t, double > fmTofRpcZpos
A map of TOF RPC reference z-position vs. address.
const std::array< int, constants::size::MaxNdetectors+1 > * fpvFstHitId
Pointer to array of first hit indexes in the detector subsystem.
algo::ca::McData * fpMcData
MC information (hits and tracks) instance.
int fVerbose
Verbosity level.
DetIdArr_t< CbmMCDataArray * > fvpBrPoints
Array of points vs. detector.
void MatchRecoAndMCTracks()
Matches reconstructed tracks with MC tracks.
CbmMCDataObject * fpMCEventHeader
MC event header.
void ReadMCPointsForDetector()
Reads MC points in particular detector.
@ kMissedMatchesMvd
Number of missed matches in MVD.
@ kMissedMatchesTof
Number of missed TOF matches.
@ kMissedMatchesTrd
Number of missed matches in TRD.
@ kMcPoint
Number of MC points.
@ kMissedMatchesMuch
Number of missed matches in MuCh.
@ kRecoNevents
Number of events.
@ kMissedMatchesSts
Number of missed matches in STS.
@ kMcTrack
Number of MC tracks.
@ kMcTrackReconstructable
Number of reconstructable MC tracks.
void MatchPointsAndHits()
Match sets of MC points and reconstructed hits for a given detector.
std::set< std::pair< int, int > > fFileEventIDs
Set of file and event indexes: first - iFile, second - iEvent.
int fBestMcEvent
Index of bestly matched MC event.
ca::Vector< CbmL1Track > * fpvRecoTracks
Pointer to reconstructed track container.
DetIdArr_t< TClonesArray * > fvpBrHitMatches
Array of hit match branches vs. detector.
CbmMCDataArray * fpMCTracks
MC tracks input.
std::shared_ptr< const ca::Parameters< double > > fpParameters
Pointer to tracking parameters object.
void MatchHits()
Match reconstructed hits and MC points.
const CbmTimeSlice * fpTimeSlice
Current time slice.
void MatchTracks()
Match reconstructed and MC data.
int fPerformanceMode
Mode of performance.
const double MinRecoMom
Performance constants.
constexpr char RDb[]
bold red
EDetectorID
Enumeration for the tracking detector subsystems in CBM-CA.
constexpr ECbmModuleId ToCbmModuleId(EDetectorID detID)
Conversion map from EDetectorID to ECbmModuleId.
constexpr DetIdArr_t< const char * > kDetName
Names of detector subsystems.
cbm::core::EnumArray< ca::EDetectorID, T > DetIdArr_t
Alias to array, indexed by L1DetectorID enum.