CbmRoot
Loading...
Searching...
No Matches
CbmCaMCModule.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022-2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergei Zharko [committer] */
4
9
10#include "CbmCaMCModule.h"
11
12#include "CbmEvent.h"
13#include "CbmL1Constants.h"
14#include "CbmL1DetectorID.h"
15#include "CbmL1HitId.h"
16#include "CbmMCDataManager.h"
17#include "CbmMCDataObject.h"
18#include "CbmMCEventList.h"
19#include "CbmMCTrack.h"
20#include "CbmRecoSetupManager.h"
21#include "CbmRecoSetupUtils.h"
22#include "CbmStsHit.h"
23#include "CbmTimeSlice.h"
24#include "CbmTofCell.h"
25#include "CbmTofDigiPar.h"
26#include "CbmTofPoint.h"
27#include "FairEventHeader.h"
28#include "FairMCEventHeader.h"
29#include "FairRootManager.h"
30#include "FairRunAna.h"
31#include "Logger.h"
32#include "TDatabasePDG.h"
33#include "TLorentzVector.h"
34#include "TVector3.h"
35
36#include <boost/filesystem.hpp>
37
38#include <algorithm>
39#include <cassert>
40#include <fstream> // TODO: SZh 07.12.2022: For debug, should be removed!
41#include <limits>
42#include <map>
43#include <stdexcept> // for std::logic_error
44#include <utility>
45
46#include <fmt/format.h>
47
48// *********************************
49// ** Action definition functions **
50// *********************************
51
53using cbm::algo::ca::constants::clrs::CL; // clear log
54using cbm::algo::ca::constants::clrs::RDb; // red bold log
56
57// ---------------------------------------------------------------------------------------------------------------------
58//
60try {
61
62 if (fVerbose > 0) {
63 LOG(info) << "CA MC Module: initializing CA tracking Monte-Carlo module... ";
64 }
65
66
67 // Validate reco-setup unit
68 const auto& recoSetup = cbm::RecoSetupManager::Instance()->GetSetup();
70 assert(recoSetup.GetMvd());
71 }
73 assert(recoSetup.GetSts());
74 }
76 assert(recoSetup.GetMuch());
77 }
79 assert(recoSetup.GetTrd());
80 }
82 assert(recoSetup.GetTof());
83 }
84
85 auto fairManager = FairRootManager::Instance();
86 assert(fairManager);
87
88 auto mcManager = dynamic_cast<CbmMCDataManager*>(fairManager->GetObject("MCDataManager"));
89 assert(mcManager);
90
91 fpTimeSlice = dynamic_cast<CbmTimeSlice*>(fairManager->GetObject("TimeSlice."));
92 fpMCEventList = dynamic_cast<CbmMCEventList*>(fairManager->GetObject("MCEventList."));
93 fpMCEventHeader = mcManager->GetObject("MCEventHeader.");
94 fpMCTracks = mcManager->InitBranch("MCTrack");
95
96 fvpBrPoints.fill(nullptr);
97 fvpBrHitMatches.fill(nullptr);
98
99 fFileEventIDs.clear();
100
101 auto InitPointBranch = [&](const char* brName, ca::EDetectorID detID) {
102 if (fvbUseDet[detID]) {
103 fvpBrPoints[detID] = mcManager->InitBranch(brName);
104 }
105 };
106
107 auto InitMatchesBranch = [&](const char* brName, ca::EDetectorID detID) {
108 if (fvbUseDet[detID]) {
109 fvpBrHitMatches[detID] = dynamic_cast<TClonesArray*>(fairManager->GetObject(brName));
110 }
111 };
112
113 InitPointBranch("MvdPoint", ca::EDetectorID::kMvd);
114 InitPointBranch("StsPoint", ca::EDetectorID::kSts);
115 InitPointBranch("MuchPoint", ca::EDetectorID::kMuch);
116 InitPointBranch("TrdPoint", ca::EDetectorID::kTrd);
117 InitPointBranch("TofPoint", ca::EDetectorID::kTof);
118
119 InitMatchesBranch("MvdHitMatch", ca::EDetectorID::kMvd);
120 InitMatchesBranch("StsHitMatch", ca::EDetectorID::kSts);
121 InitMatchesBranch("MuchPixelHitMatch", ca::EDetectorID::kMuch);
122 InitMatchesBranch("TrdHitMatch", ca::EDetectorID::kTrd);
123 InitMatchesBranch("TofHitMatch", ca::EDetectorID::kTof);
124
125 // Reco setup manager
126 const auto* pRecoSetupManager = RecoSetupManager::Instance();
127 if (!pRecoSetupManager->IsInitialized()) {
128 return false;
129 }
130
131
132 auto CheckDetector = [&](ca::EDetectorID detID) {
133 if (fvbUseDet[detID] && !pRecoSetupManager->Has(ToCbmModuleId(detID))) {
134 throw std::runtime_error(fmt::format("Det ID {} is not in RecoSetup", static_cast<int>(detID)));
135 }
136 };
137
138 CheckDetector(ca::EDetectorID::kMvd);
139 CheckDetector(ca::EDetectorID::kSts);
140 CheckDetector(ca::EDetectorID::kMuch);
141 CheckDetector(ca::EDetectorID::kTrd);
142 CheckDetector(ca::EDetectorID::kTof);
143
145 if (auto pGeoNodeMap = pRecoSetupManager->GetGeoNodeMap()) {
146 fmTofRpcZpos = std::move(
147 pGeoNodeMap->GetVolumeProperties([](const auto& vol) { return vol.GetCenterZ(); }, ECbmModuleId::kTof));
148 }
149 else {
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 "
152 "to the FairRun");
153 }
154 }
155
156 // Check initialization
157 this->CheckInit();
158
159 // Init monitor
160 fMonitor.SetCounterName(EMonitorKey::kMcTrack, "N MC tracks");
161 fMonitor.SetCounterName(EMonitorKey::kMcTrackReconstructable, "N MC tracks rec-able");
162 fMonitor.SetCounterName(EMonitorKey::kMcPoint, "N MC points");
163 fMonitor.SetCounterName(EMonitorKey::kRecoNevents, "N reco events");
164 fMonitor.SetCounterName(EMonitorKey::kMissedMatchesMvd, "N missed MVD matches");
165 fMonitor.SetCounterName(EMonitorKey::kMissedMatchesSts, "N missed STS matches");
166 fMonitor.SetCounterName(EMonitorKey::kMissedMatchesMuch, "N missed MuCh matches");
167 fMonitor.SetCounterName(EMonitorKey::kMissedMatchesTrd, "N missed TRD matches");
168 fMonitor.SetCounterName(EMonitorKey::kMissedMatchesTof, "N missed TOF matches");
169 fMonitor.SetRatioKeys({EMonitorKey::kRecoNevents});
170
171
172 if (fVerbose > 0) {
173 LOG(info) << "CA MC Module: initializing CA tracking Monte-Carlo module... \033[1;32mDone!\033[0m";
174 }
175 return true;
176}
177catch (const std::exception& error) {
178 LOG(error) << "CA MC Module: initializing CA tracking Monte-Carlo module... \033[1;31mFailed\033[0m\nReason: "
179 << error.what();
180 return false;
181}
182
183// ---------------------------------------------------------------------------------------------------------------------
184//
186{
187 // Fill a set of file and event indexes
188 fFileEventIDs.clear();
189 fBestMcFile = -1;
190 fBestMcEvent = -1;
191 if (pEvent) {
192 CbmMatch* pEvtMatch = pEvent->GetMatch();
193 assert(pEvtMatch);
194 int nLinks = pEvtMatch->GetNofLinks();
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);
198 fFileEventIDs.emplace(link.GetFile(), link.GetEntry());
199 }
200 if (nLinks > 1) {
201 const auto& bestLink = pEvtMatch->GetMatchedLink();
202 fBestMcFile = bestLink.GetFile();
203 fBestMcEvent = bestLink.GetEntry();
204 }
205 }
206 else {
207 int nEvents = fpMCEventList->GetNofEvents();
208 for (int iE = 0; iE < nEvents; ++iE) {
209 int iFile = fpMCEventList->GetFileIdByIndex(iE);
210 int iEvent = fpMCEventList->GetEventIdByIndex(iE);
211 fFileEventIDs.emplace(iFile, iEvent);
212 }
213 }
214
215 // Read data
216 fpMcData->Clear();
217 this->ReadMCTracks();
218 this->ReadMCPoints();
219 fMonitor.IncrementCounter(EMonitorKey::kMcTrack, fpMcData->GetNofPoints());
220 fMonitor.IncrementCounter(EMonitorKey::kMcPoint, fpMcData->GetNofTracks());
221
222 // Prepare tracks: set point indexes and redefine indexes from external to internal containers
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(); });
226 }
227
228 fMonitor.IncrementCounter(EMonitorKey::kRecoNevents);
229}
230
231// ---------------------------------------------------------------------------------------------------------------------
232//
234
235// ---------------------------------------------------------------------------------------------------------------------
236//
238{
239 // FIXME: Reconstructable criteria initialization should be verified!
240
241 // ----- Define reconstructable and additional flags
242 for (auto& aTrk : fpMcData->GetTrackContainer()) {
243 bool isRec = true; // the track can be reconstructed
244
245 // Cut on momentum
246 isRec &= aTrk.GetP() > CbmL1Constants::MinRecoMom;
247
248 // Cut on max number of points on station
249 isRec &= aTrk.GetMaxNofPointsOnStation() <= 3;
250
251 // Suppress MC tracks from complementary MC events
252 if (fBestMcFile >= 0 && (aTrk.GetFileId() != fBestMcFile || aTrk.GetEventId() != fBestMcEvent)) {
253 isRec = false;
254 }
255
256 bool isAdd = isRec; // is track additional
257
258 // Cut on number of stations
259 switch (fPerformanceMode) {
260 case 1: isRec &= aTrk.GetNofConsStationsWithHit() >= CbmL1Constants::MinNStations; break;
261 case 2: isRec &= aTrk.GetTotNofStationsWithHit() >= CbmL1Constants::MinNStations; break;
262 case 3: isRec &= aTrk.GetNofConsStationsWithPoint() >= CbmL1Constants::MinNStations; break;
263 default: LOG(fatal) << "CA MC Module: invalid performance mode " << fPerformanceMode;
264 }
265
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;
272 isAdd &= !isRec;
273 }
274 else {
275 isAdd = false;
276 }
277 aTrk.SetFlagReconstructable(isRec);
278 aTrk.SetFlagAdditional(isAdd);
279 }
280}
281
282// ---------------------------------------------------------------------------------------------------------------------
283//
284void MCModule::Finish() { LOG(info) << '\n' << fMonitor.ToString(); }
285
286
287// **********************************
288// ** Reco and MC matching **
289// **********************************
290
291
292// ---------------------------------------------------------------------------------------------------------------------
293//
295{
301 // ----- Initialize stations arrangement and hit indexes
302 fpMcData->SetMcHitInfo(*fpvQaHits);
303}
304
305// ---------------------------------------------------------------------------------------------------------------------
306//
308{
309 this->MatchRecoAndMCTracks();
310 this->InitMcTrackInfo();
311 for (const auto& trkMC : fpMcData->GetTrackContainer()) {
312 if (trkMC.IsReconstructable()) {
314 }
315 }
316}
317
318
319// ---------------------------------------------------------------------------------------------------------------------
320//
322{
323 for (int iTre = 0; iTre < int(fpvRecoTracks->size()); ++iTre) {
324 auto& trkRe = (*fpvRecoTracks)[iTre];
325
326 // ----- Count number of hits from each MC track belonging to this reconstructed track
327 auto& mNofHitsVsMCTrkID = trkRe.hitMap;
328 mNofHitsVsMCTrkID.clear();
329 for (int iH : trkRe.Hits) {
330 auto& vP = (*fpvQaHits)[iH].GetMcPointIds();
331 for (int iP : vP) {
332 if (iP < 0) {
333 continue;
334 }
335 int iTmc = fpMcData->GetPoint(iP).GetTrackId();
336 mNofHitsVsMCTrkID[iTmc]++;
337 }
338 } // loop over hit ids stored for a reconstructed track: end
339
340
341 // ----- Calculate track max purity
342 // NOTE: Maximal purity is a maximum fraction of hits from a single MC track. A reconstructed track can be matched
343 // to several MC tracks, because it uses hits from different particle. Purity shows, how fully the true track
344 // was reconstructed.
345 int nHitsTrkRe = trkRe.Hits.size(); // number of hits in a given reconstructed track
346 double maxPurity = 0.; // [0, 1]
347 for (auto& item : mNofHitsVsMCTrkID) {
348 int iTmc = item.first;
349 int nHitsTrkMc = item.second;
350
351 if (iTmc < 0) {
352 continue;
353 }
354
355 if (double(nHitsTrkMc) > double(nHitsTrkRe) * maxPurity) {
356 maxPurity = double(nHitsTrkMc) / double(nHitsTrkRe);
357 }
358
359 auto& trkMc = fpMcData->GetTrack(iTmc);
360
361 // Match reconstructed and MC tracks, if purity with this MC track passes the threshold
362 if (double(nHitsTrkMc) >= CbmL1Constants::MinPurity * double(nHitsTrkRe)) {
363 trkMc.AddRecoTrackIndex(iTre);
364 trkRe.AddMCTrackIndex(iTmc);
365 }
366 // If purity is low, but some hits of a given MC track are presented in the reconstructed track
367 else {
368 trkMc.AddTouchTrackIndex(iTre);
369 }
370
371 // Update max purity of the reconstructed track
372 trkRe.SetMaxPurity(maxPurity);
373 } // loop over hit map: end
374 } // loop over reconstructed tracks: end
375}
376
377// *******************************
378// ** Utility functions **
379// *******************************
380
381
382// ---------------------------------------------------------------------------------------------------------------------
383//
385{
386 // Check parameters
387 if (!fpParameters.get()) {
388 throw std::logic_error("Tracking parameters object was not defined");
389 }
390
391 // Check output data containers
392 if (!fpMcData) {
393 throw std::logic_error("MC data object was not registered");
394 }
395 if (!fpvRecoTracks) {
396 throw std::logic_error("Reconstructed track container was not registered");
397 }
398 if (!fpvHitIds) {
399 throw std::logic_error("Hit index container was not registered");
400 }
401 if (!fpvQaHits) {
402 throw std::logic_error("QA hit container was not registered");
403 }
404 if (!fpvFstHitId) {
405 throw std::logic_error("Array of first hit indexes in each detector was not registered");
406 }
407
408 // Check event list
409 if (!fpMCEventList) {
410 throw std::logic_error("MC event list was not found");
411 }
412 if (!fpTimeSlice) {
413 throw std::logic_error("Time slice was not found");
414 }
415
416 // Tracks branch
417 if (!fpMCTracks) {
418 throw std::logic_error("MC tracks branch is unavailable");
419 }
420
421 // Event header
422 if (!fpMCEventHeader) {
423 throw std::logic_error("MC event header is unavailable");
424 }
425
426 // Check detectors initialization
427 for (int iD = 0; iD < static_cast<int>(ca::EDetectorID::END); ++iD) {
428 if (fvbUseDet[iD]) {
429 if (!fvpBrPoints[iD]) {
430 throw std::logic_error(Form("MC points are unavailable for %s", kDetName[iD]));
431 }
432 if (!fvpBrHitMatches[iD]) {
433 throw std::logic_error(Form("Hit matches are unavailable for %s", kDetName[iD]));
434 }
435 }
436 }
437}
438
439// ---------------------------------------------------------------------------------------------------------------------
440//
441template<>
443{
444 if (!fvbUseDet[ca::EDetectorID::kTof]) {
445 return;
446 }
447
448 auto* pBrHitMatches = fvpBrHitMatches[ca::EDetectorID::kTof];
449 auto* pBrPoints = fvpBrPoints[ca::EDetectorID::kTof];
450
451
452 // FIXME: Use mask from CbmTofAddress (but test before!!)
453 constexpr int kNofBitsRpcAddress = 11;
454
455 for (const auto& [iFile, iEvent] : fFileEventIDs) {
456 // Fill map of flags: the external index of the matched point vs. iTrExt and the RPC address
457 int nPoints = pBrPoints->Size(iFile, iEvent);
458 std::map<std::pair<int, int>, int> mMatchedPointId; // map (iTr, addr) -> is matched
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) {
466 continue;
467 }
468 int iPext = link.GetIndex();
469 if (iPext < 0) {
470 continue;
471 }
472 auto* pExtPoint = dynamic_cast<CbmTofPoint*>(pBrPoints->Get(link));
473 if (!pExtPoint) {
474 LOG(error) << "ca::MCModule: MC Point with link=" << link.ToString() << " does not exist in branch";
475 continue;
476 }
477
478 int trkId = pExtPoint->GetTrackID();
479 int rpcAddr = pExtPoint->GetDetectorID() << kNofBitsRpcAddress; // FIXME:
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;
485 }
486 else { // If we find two links for the same interaction, we select the one with the largest weight
487 if (bestWeight < link.GetWeight()) {
488 mMatchedPointId[key] = iPext;
489 }
490 }
491 }
492 } // iH
493
494 // Select one point for the given track ID and RPC address. If at least one of the points for (trackID, RPC address)
495 // produced a hit, the point from the best link is selected. Otherwise the closest point to the RPC z-center is selected
496 {
497 int iPointSelected = -1;
498 int iTmcCurr = -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;
506
507 int iTmc = pExtPoint->GetTrackID();
508 int rpcAddr = CbmTofAddress::GetDetectorId(pExtPoint->GetDetectorID());
509 // New point
510 if (rpcAddrCurr != rpcAddr || iTmcCurr != iTmc) { // The new interaction of the MC track with the TOF RPC
511 if (iPointSelected != -1) {
512 auto oPoint = FillMCPoint<ca::EDetectorID::kTof>(iPointSelected, iEvent, iFile);
513 if (oPoint) {
514 fpMcData->AddPoint(*oPoint);
515 }
516 }
517 iTmcCurr = iTmc;
518 rpcAddrCurr = rpcAddr;
519 auto key = std::make_pair(iTmc, rpcAddr);
520 auto found = mMatchedPointId.find(key);
521 bTrkHasHits = found != mMatchedPointId.end();
522 if (bTrkHasHits) {
523 iPointSelected = found->second;
524 }
525 else {
526 // First iteration
527 zRpc = fmTofRpcZpos.at(CbmTofAddress::GetDetectorId(pExtPoint->GetDetectorID()));
528 zDist = std::fabs(zRpc - pExtPoint->GetZ());
529 iPointSelected = iP;
530 }
531 }
532 else {
533 if (!bTrkHasHits) {
534 auto newDist = std::fabs(pExtPoint->GetZ() - zRpc);
535 if (newDist < zDist) {
536 zDist = newDist;
537 iPointSelected = iP;
538 }
539 }
540 }
541 }
542 // Add the last point
543 if (iPointSelected != -1) {
544 auto oPoint = FillMCPoint<ca::EDetectorID::kTof>(iPointSelected, iEvent, iFile);
545 if (oPoint) {
546 fpMcData->AddPoint(*oPoint);
547 }
548 }
549 }
550 } // [iFile, iEvent]
551}
552
553// ---------------------------------------------------------------------------------------------------------------------
554//
556{
557 int nPointsEstimated = 5 * fpMcData->GetNofTracks() * fpParameters->GetNstationsActive();
558 fpMcData->ReserveNofPoints(nPointsEstimated);
559
560 DetIdArr_t<int> vNofPointsDet = {{0}};
561 for (const auto& [iFile, iEvent] : fFileEventIDs) {
562 for (int iD = 0; iD < static_cast<int>(vNofPointsDet.size()); ++iD) {
563 if (fvbUseDet[iD]) {
564 vNofPointsDet[iD] = fvpBrPoints[iD]->Size(iFile, iEvent);
565 }
566 fpMcData->SetNofPointsOrig(static_cast<ca::EDetectorID>(iD), vNofPointsDet[iD]);
567 }
568 }
569
570 // ----- Read MC points in MVD, STS, MuCh, TRD and TOF
576}
577
578// ---------------------------------------------------------------------------------------------------------------------
579//
581{
582 // ----- Total number of tracks
583 int nTracksTot = 0;
584 for (const auto& [iFile, iEvent] : fFileEventIDs) {
585 if (iFile < 0 || iEvent < 0) {
586 continue;
587 }
588 nTracksTot += fpMCTracks->Size(iFile, iEvent);
589 }
590 fpMcData->ReserveNofTracks(nTracksTot);
591
592 // ----- Loop over MC events
593 for (const auto& [iFile, iEvent] : fFileEventIDs) {
594 if (iFile < 0 || iEvent < 0) {
595 continue;
596 }
597 auto pEvtHeader = dynamic_cast<FairMCEventHeader*>(fpMCEventHeader->Get(iFile, iEvent));
598 if (!pEvtHeader) {
599 LOG(fatal) << "cbm::ca::MCModule: event header is not found for file " << iFile << " and event " << iEvent;
600 }
601 double eventTime = fpMCEventList->GetEventTime(iEvent, iFile);
602
603 // ----- Loop over MC tracks
604 int nTracks = fpMCTracks->Size(iFile, iEvent);
605 for (int iTrkExt = 0; iTrkExt < nTracks; ++iTrkExt) {
606 CbmMCTrack* pExtMCTrk = dynamic_cast<CbmMCTrack*>(fpMCTracks->Get(iFile, iEvent, iTrkExt));
607 if (!pExtMCTrk) {
608 LOG(warn) << "cbm::ca::MCModule: track with (iF, iE, iT) = " << iFile << ' ' << iEvent << ' ' << iTrkExt
609 << " not found";
610 }
611 // Create a CbmL1MCTrack
612 auto aTrk = McTrack{};
613
614 aTrk.SetId(fpMcData->GetNofTracks()); // assign current number of tracks read so far as an ID of a new track
615 aTrk.SetExternalId(iTrkExt); // external index of track is its index from CbmMCTrack objects container
616 aTrk.SetEventId(iEvent);
617 aTrk.SetFileId(iFile);
618
619 aTrk.SetStartT(pExtMCTrk->GetStartT() + eventTime);
620 aTrk.SetStartX(pExtMCTrk->GetStartX());
621 aTrk.SetStartY(pExtMCTrk->GetStartY());
622 aTrk.SetStartZ(pExtMCTrk->GetStartZ());
623
624 aTrk.SetPx(pExtMCTrk->GetPx());
625 aTrk.SetPy(pExtMCTrk->GetPy());
626 aTrk.SetPz(pExtMCTrk->GetPz());
627
628 aTrk.SetFlagSignal(aTrk.IsPrimary() && (aTrk.GetStartZ() > (pEvtHeader->GetZ() + 1.e-10)));
629
630 // In CbmMCTrack mass is defined from ROOT PDG data base. If track is left from ion, and its pdg is not registered
631 // in the data base, its mass is calculated as A times proton mass.
632 aTrk.SetMass(pExtMCTrk->GetMass());
633
634 // The charge in CbmMCTrack is given in the units of e
635 aTrk.SetCharge(pExtMCTrk->GetCharge());
636
637 // Set index of mother track. We assume, that mother track was recorded into the internal array before
638 int extMotherId = pExtMCTrk->GetMotherId();
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));
644 extChainParent = pExtParentTrk->GetMotherId();
645 }
646
647 if (extMotherId < 0) {
648 // This is a primary track, and it's mother ID equals -1 or -2. This value is taken also as an internal mother
649 // ID. The same rules here and below are applied to the chainId
650 aTrk.SetMotherId(extMotherId);
651 aTrk.SetChainId(extChainId);
652 }
653 else {
654 // This is a secondary track, mother ID should be recalculated for the internal track array.
655 int motherId = fpMcData->FindInternalTrackIndex(extMotherId, iEvent, iFile);
656 int chainId = fpMcData->FindInternalTrackIndex(extChainId, iEvent, iFile);
657 if (motherId == -1) {
658 motherId = -3;
659 } // Mother is neutral particle, which is rejected
660 aTrk.SetMotherId(motherId);
661 aTrk.SetChainId(chainId);
662 }
663
664 aTrk.SetProcessId(pExtMCTrk->GetGeantProcessId());
665 aTrk.SetPdgCode(pExtMCTrk->GetPdgCode());
666
667 fpMcData->AddTrack(aTrk);
668 } // Loop over MC tracks: end
669 } // Loop over MC events: end
670}
void MCModule::ReadMCPointsForDetector< ca::EDetectorID::kTof >()
CA Tracking performance interface for CBM (header)
@ kTof
Time-of-flight Detector.
Definition CbmDefs.h:52
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,...
Definition CbmEvent.h:34
CbmMatch * GetMatch() const
Definition CbmEvent.h:98
Task class creating and managing CbmMCDataArray objects.
Container class for MC events with number, file and start time.
double GetPz() const
Definition CbmMCTrack.h:71
double GetStartT() const
Definition CbmMCTrack.h:75
double GetCharge() const
Charge of the associated particle.
double GetPx() const
Definition CbmMCTrack.h:69
uint32_t GetGeantProcessId() const
Definition CbmMCTrack.h:66
double GetStartZ() const
Definition CbmMCTrack.h:74
int32_t GetMotherId() const
Definition CbmMCTrack.h:68
double GetMass() const
Mass of the associated particle.
double GetStartX() const
Definition CbmMCTrack.h:72
int32_t GetPdgCode() const
Definition CbmMCTrack.h:67
double GetStartY() const
Definition CbmMCTrack.h:73
double GetPy() const
Definition CbmMCTrack.h:70
const CbmLink & GetLink(int32_t i) const
Definition CbmMatch.h:39
int32_t GetNofLinks() const
Definition CbmMatch.h:42
const CbmLink & GetMatchedLink() const
Definition CbmMatch.h:41
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.
Definition CbmTofPoint.h:44
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)
Definition CaMcTrack.h:279
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.
const double MinPurity
const int MinNStations
constexpr char RDb[]
bold red
Definition CaDefs.h:161
constexpr char CL[]
clear
Definition CaDefs.h:139
EDetectorID
Enumeration for the tracking detector subsystems in CBM-CA.
Definition CbmDefs.h:216
constexpr ECbmModuleId ToCbmModuleId(EDetectorID detID)
Conversion map from EDetectorID to ECbmModuleId.
Definition CbmDefs.h:228
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.