CbmRoot
Loading...
Searching...
No Matches
CbmCaIdealHitProducerDet.h
Go to the documentation of this file.
1/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergei Zharko [committer] */
4
9
10#pragma once
11
12#include "CaAlgoRandom.h"
13#include "CaDefs.h"
14#include "CaUvConverter.h"
15#include "CbmEvent.h"
16#include "CbmL1DetectorID.h"
17#include "CbmMCDataArray.h"
18#include "CbmMCDataManager.h"
19#include "CbmMCDataObject.h"
20#include "CbmMCEventList.h"
21#include "CbmMatch.h"
22#include "CbmMuchAddress.h"
23#include "CbmMuchPixelHit.h"
24#include "CbmMuchPoint.h"
26#include "CbmMvdHit.h"
27#include "CbmMvdPoint.h"
29#include "CbmStsHit.h"
30#include "CbmStsPoint.h"
32#include "CbmTimeSlice.h"
33#include "CbmTofAddress.h"
34#include "CbmTofHit.h"
35#include "CbmTofPoint.h"
38#include "CbmTrdHit.h"
39#include "CbmTrdPoint.h"
41#include "FairRootManager.h"
42#include "FairTask.h"
43#include "TClonesArray.h"
44#include "TVector3.h"
45
46#include <Logger.h>
47
48#include <array>
49#include <optional>
50#include <sstream>
51#include <string>
52#include <tuple>
53#include <unordered_map>
54
55#include <yaml-cpp/yaml.h>
56
57namespace cbm::ca
58{
60
64 template<ca::EDetectorID DetID>
66 public:
69
72
75
78
81
84
87
89 InitStatus Init();
90
92 InitStatus ReInit() { return Init(); }
93
95 void Exec(Option_t* option);
96
99 void SetRandomSeed(int seed) { fRandom.SetSeed(seed); }
100
103 void SetConfigName(const char* name) { fsConfigName = name; }
104
105 private:
106 static constexpr double kHitWSize = 3.5;
107
111 std::optional<CbmLink> GetMatchedPointLink(int iH);
112
115
118 void PushBackHit(const Hit_t* pHit);
119
124 void SmearValue(double& value, double sigma, int opt);
125
127 void FillPointIsLegit(int iEvGlob);
128
131
134
138
142 short fPdfU = -1;
143 short fPdfV = -1;
144 short fPdfT = -1;
145
150 short fMode = 0;
151
155 bool fbSmear = false;
156 };
157
159
160 // ----- Input branches:
162 TClonesArray* fpRecoEvents = nullptr;
167
168 TClonesArray* fpBrHits = nullptr;
169 TClonesArray* fpBrHitMatches = nullptr;
170
171 TClonesArray* fpBrHitsTmp = nullptr;
172 TClonesArray* fpBrHitMatchesTmp = nullptr;
173
175
176 std::string fsConfigName = "";
177
178 std::vector<HitParameters> fvStationPars;
179
180 std::vector<unsigned char> fvbPointIsLegit;
181
183
185 bool fbRunTheRoutine = true;
186
187
188 int fHitCounter = 0;
189 };
190
191
192 // **********************************************************
193 // ** Template and inline function implementations **
194 // **********************************************************
195
196 // ------------------------------------------------------------------------------------------------------------------
197 //
198 template<ca::EDetectorID DetID>
200 {
201 if (fpBrHitsTmp) {
202 fpBrHitsTmp->Delete();
203 delete fpBrHitsTmp;
204 fpBrHitsTmp = nullptr;
205 }
206
207 if (fpBrHitMatchesTmp) {
208 fpBrHitMatchesTmp->Delete();
209 delete fpBrHitMatchesTmp;
210 fpBrHitMatchesTmp = nullptr;
211 }
212 }
213
214 // ------------------------------------------------------------------------------------------------------------------
215 //
216 template<ca::EDetectorID DetID>
218 try {
219 auto CheckBranch = [](auto pBranch, const char* brName) {
220 if (!pBranch) {
221 throw std::logic_error(Form("Branch %s is not available", brName));
222 }
223 };
224
225 // ------ Input branch initialization
226 auto* pFairManager = FairRootManager::Instance();
227 auto* pMcManager = dynamic_cast<CbmMCDataManager*>(pFairManager->GetObject("MCDataManager"));
228 CheckBranch(pMcManager, "MCDataManager");
229
230 fpTimeSlice = dynamic_cast<CbmTimeSlice*>(pFairManager->GetObject("TimeSlice."));
231 fpRecoEvents = dynamic_cast<TClonesArray*>(pFairManager->GetObject("CbmEvent"));
232 fpMCEventList = dynamic_cast<CbmMCEventList*>(pFairManager->GetObject("MCEventList."));
233
234 CheckBranch(fpTimeSlice, "TimeSlice.");
235 CheckBranch(fpMCEventList, "MCEventList.");
236 fpMCEventHeader = pMcManager->GetObject("MCEventHeader.");
237 fpBrMCTracks = pMcManager->InitBranch("MCTrack");
238 CheckBranch(fpBrMCTracks, "MCTrack");
239
240 switch (DetID) {
241 case ca::EDetectorID::kMvd:
242 fpDetInterface = CbmMvdTrackingInterface::Instance();
243 fpBrPoints = pMcManager->InitBranch("MvdPoint");
244 fpBrHits = dynamic_cast<TClonesArray*>(pFairManager->GetObject("MvdHit"));
245 fpBrHitMatches = dynamic_cast<TClonesArray*>(pFairManager->GetObject("MvdHitMatch"));
246 fHitDataType = ECbmDataType::kMvdHit;
247 CheckBranch(fpBrPoints, "MvdPoint");
248 CheckBranch(fpBrHits, "MvdHit");
249 CheckBranch(fpBrHitMatches, "MvdHitMatch");
250 break;
251 case ca::EDetectorID::kSts:
252 fpDetInterface = CbmStsTrackingInterface::Instance();
253 fpBrPoints = pMcManager->InitBranch("StsPoint");
254 fpBrHits = dynamic_cast<TClonesArray*>(pFairManager->GetObject("StsHit"));
255 fpBrHitMatches = dynamic_cast<TClonesArray*>(pFairManager->GetObject("StsHitMatch"));
256 fHitDataType = ECbmDataType::kStsHit;
257 CheckBranch(fpBrPoints, "StsPoint");
258 CheckBranch(fpBrHits, "StsHit");
259 CheckBranch(fpBrHitMatches, "StsHitMatch");
260 break;
261 case ca::EDetectorID::kMuch:
262 fpDetInterface = CbmMuchTrackingInterface::Instance();
263 fpBrPoints = pMcManager->InitBranch("MuchPoint");
264 fpBrHits = dynamic_cast<TClonesArray*>(pFairManager->GetObject("MuchPixelHit"));
265 fpBrHitMatches = dynamic_cast<TClonesArray*>(pFairManager->GetObject("MuchPixelHitMatch"));
266 fHitDataType = ECbmDataType::kMuchPixelHit;
267 CheckBranch(fpBrPoints, "MuchPoint");
268 CheckBranch(fpBrHits, "MuchPixelHit");
269 CheckBranch(fpBrHitMatches, "MuchPixelHitMatch");
270 break;
271 case ca::EDetectorID::kTrd:
272 fpDetInterface = CbmTrdTrackingInterface::Instance();
273 fpBrPoints = pMcManager->InitBranch("TrdPoint");
274 fpBrHits = dynamic_cast<TClonesArray*>(pFairManager->GetObject("TrdHit"));
275 fpBrHitMatches = dynamic_cast<TClonesArray*>(pFairManager->GetObject("TrdHitMatch"));
276 fHitDataType = ECbmDataType::kTrdHit;
277 CheckBranch(fpBrPoints, "TrdPoint");
278 CheckBranch(fpBrHits, "TrdHit");
279 CheckBranch(fpBrHitMatches, "TrdHitMatch");
280 break;
281 case ca::EDetectorID::kTof:
282 fpDetInterface = CbmTofTrackingInterface::Instance();
283 fpBrPoints = pMcManager->InitBranch("TofPoint");
284 fpBrHits = dynamic_cast<TClonesArray*>(pFairManager->GetObject("TofHit"));
285 fpBrHitMatches = dynamic_cast<TClonesArray*>(pFairManager->GetObject("TofHitMatch"));
286 fHitDataType = ECbmDataType::kTofHit;
287 CheckBranch(fpBrPoints, "TofPoint");
288 CheckBranch(fpBrHits, "TofHit");
289 CheckBranch(fpBrHitMatches, "TofHitMatch");
290 break;
291 case ca::EDetectorID::END:
292 LOG(fatal) << "CA ideal hit producer for " << kDetName[DetID]
293 << ": Wrong template argument is used: ca::EDetectorID::END";
294 break;
295 }
296
297 // ------ Checks of the settings of hit creation/adjustment mode
298 if (fsConfigName.size() != 0) {
299 this->ParseConfig();
300 // Skip event/time slice processing, if there are no requests for hit modification of the detector
301 // (fbRunTheRoutine = true, if there is at least one station with fMode > 0)
302 fbRunTheRoutine =
303 std::any_of(fvStationPars.begin(), fvStationPars.end(), [](const auto& p) { return p.fMode > 0; });
304 }
305 else {
306 fbRunTheRoutine = false;
307 }
308
309 std::stringstream msg;
310 msg << "\033[1;31mATTENTION! IDEAL HIT PRODUCER IS USED FOR " << kDetName[DetID] << "\033[0m";
311 LOG_IF(info, fbRunTheRoutine) << msg.str();
312
313 return kSUCCESS;
314 }
315 catch (const std::logic_error& error) {
316 LOG(error) << "CA ideal hit producer for " << kDetName[DetID]
317 << ": initialization failed. Reason: " << error.what();
318 return kERROR;
319 }
320
321 // -------------------------------------------------------------------------------------------------------------------
322 //
323 template<ca::EDetectorID DetID>
325 {
326 int nStations = fpDetInterface->GetNtrackingStations();
327 fvStationPars.clear();
328 fvStationPars.resize(nStations);
329
330 // Read file
331 YAML::Node config;
332 try {
333 config = YAML::LoadFile(fsConfigName)["ideal_hit_producer"];
334
335 std::string detBranchName = "";
336 if constexpr (ca::EDetectorID::kMvd == DetID) {
337 detBranchName = "mvd";
338 }
339 else if constexpr (ca::EDetectorID::kSts == DetID) {
340 detBranchName = "sts";
341 }
342 else if constexpr (ca::EDetectorID::kMuch == DetID) {
343 detBranchName = "much";
344 }
345 else if constexpr (ca::EDetectorID::kTrd == DetID) {
346 detBranchName = "trd";
347 }
348 else if constexpr (ca::EDetectorID::kTof == DetID) {
349 detBranchName = "tof";
350 }
351
352 const auto& parNode = config["parameters"][detBranchName];
353 const auto& flagNode = config["flags"][detBranchName];
354
355 for (int iSt = 0; iSt < nStations; ++iSt) {
356 auto& par = fvStationPars[iSt];
357 auto& node = parNode[iSt];
358 short mode = flagNode[iSt].as<int>(0);
359 if (mode > 0) {
360 par.fPhiU = node["du"]["angle"].as<double>() * 180. / M_PI;
361 par.fDu = node["du"]["value"].as<double>();
362 switch (node["du"]["pdf"].as<char>()) {
363 case 'g': par.fPdfU = 0; break;
364 case 'u': par.fPdfU = 1; break;
365 default: par.fPdfU = -1; break;
366 }
367 par.fPhiV = node["dv"]["angle"].as<double>() * 180. / M_PI;
368 par.fDv = node["dv"]["value"].as<double>();
369 switch (node["dv"]["pdf"].as<char>()) {
370 case 'g': par.fPdfV = 0; break;
371 case 'u': par.fPdfV = 1; break;
372 default: par.fPdfV = -1; break;
373 }
374 par.fDt = node["dt"]["value"].as<double>();
375 switch (node["dt"]["pdf"].as<char>()) {
376 case 'g': par.fPdfT = 0; break;
377 case 'u': par.fPdfT = 1; break;
378 default: par.fPdfT = -1; break;
379 }
380 switch (mode) {
381 case 1:
382 par.fMode = 1;
383 par.fbSmear = false;
384 break;
385 case 2:
386 par.fMode = 1;
387 par.fbSmear = true;
388 break;
389 case 3:
390 par.fMode = 2;
391 par.fbSmear = false;
392 break;
393 case 4:
394 par.fMode = 2;
395 par.fbSmear = true;
396 break;
397 }
398 }
399 }
400 }
401 catch (const YAML::BadFile& err) {
402 std::stringstream msg;
403 msg << "YAML configuration file " << fsConfigName << " does not exist";
404 throw std::runtime_error(msg.str());
405 }
406 catch (const YAML::ParserException& err) {
407 std::stringstream msg;
408 msg << "YAML configuration file " << fsConfigName << " is formatted improperly";
409 throw std::runtime_error(msg.str());
410 }
411 }
412
413 // -------------------------------------------------------------------------------------------------------------------
414 //
415 template<ca::EDetectorID DetID>
417 {
418 // Common fields for all the subsystems
419 auto pos = TVector3{};
420 auto dpos = TVector3{};
421 pHit->Position(pos);
422 pHit->PositionError(dpos);
423
424 // Fields specific to each detector type
425 if constexpr (ca::EDetectorID::kMvd == DetID) {
426 auto statNr = pHit->GetStationNr();
427 auto iCentrX = pHit->GetIndexCentralX();
428 auto iCentrY = pHit->GetIndexCentralY();
429 auto iClust = pHit->GetClusterIndex();
430 auto flag = pHit->GetFlag();
431 new ((*fpBrHits)[fHitCounter]) CbmMvdHit(statNr, pos, dpos, iCentrX, iCentrY, iClust, flag);
432 }
433 else {
434 auto address = pHit->GetAddress();
435 auto time = pHit->GetTime();
436 auto dtime = pHit->GetTimeError();
437 if constexpr (ca::EDetectorID::kSts == DetID) {
438 auto dxy = pHit->GetDxy();
439 auto iClustF = pHit->GetFrontClusterId();
440 auto iClustB = pHit->GetBackClusterId();
441 auto du = pHit->GetDu();
442 auto dv = pHit->GetDv();
443 new ((*fpBrHits)[fHitCounter]) CbmStsHit(address, pos, dpos, dxy, iClustF, iClustB, time, dtime, du, dv);
444 }
445 else if constexpr (ca::EDetectorID::kMuch == DetID) {
446 auto dxy = pHit->GetDxy();
447 auto refId = pHit->GetRefId();
448 auto planeId = pHit->GetPlaneId();
449 LOG(info) << "MUCH: " << pHit->GetRefId() << ' ' << pHit->GetPlaneId();
450 new ((*fpBrHits)[fHitCounter]) CbmMuchPixelHit(address, pos, dpos, dxy, refId, planeId, time, dtime);
451 }
452 else if constexpr (ca::EDetectorID::kTrd == DetID) {
453 auto dxy = pHit->GetDxy();
454 auto refId = pHit->GetRefId();
455 auto eLoss = pHit->GetELoss();
456 new ((*fpBrHits)[fHitCounter]) CbmTrdHit(address, pos, dpos, dxy, refId, eLoss, time, dtime);
457 }
458 else if constexpr (ca::EDetectorID::kTof == DetID) {
459 auto refId = -1; // pHit->GetRefId(); // -> deprecated
460 auto flag = pHit->GetFlag();
461 auto channel = pHit->GetCh();
462 new ((*fpBrHits)[fHitCounter]) CbmTofHit(address, pos, dpos, refId, time, dtime, flag, channel);
463 }
464 }
465 }
466
467 // -------------------------------------------------------------------------------------------------------------------
468 //
469 template<ca::EDetectorID DetID>
471 {
472 const auto* pHitMatch = dynamic_cast<CbmMatch*>(fpBrHitMatchesTmp->At(iH));
473 assert(pHitMatch);
474 if (pHitMatch->GetNofLinks() > 0) {
475 const auto& link = pHitMatch->GetMatchedLink();
476 if (link.GetIndex() > -1) {
477 return std::make_optional(link);
478 }
479 }
480 return std::nullopt;
481 }
482
483 // -------------------------------------------------------------------------------------------------------------------
484 //
485 template<ca::EDetectorID DetID>
486 void IdealHitProducerDet<DetID>::SmearValue(double& value, double sigma, int opt)
487 {
488 switch (opt) {
489 case 0: value += fRandom.BoundedGaus<double>(0., sigma, kHitWSize); break;
490 case 1: value += fRandom.Uniform<double>(0., sigma); break;
491 default: LOG(fatal) << "IdealHitProducerDet::SmearValue: illegal option: opt = " << opt;
492 }
493 }
494
495 // -------------------------------------------------------------------------------------------------------------------
496 //
497 template<ca::EDetectorID DetID>
499 {
500 // ------ Check, if there are any requirement to run the routine for this detector
501 if (!fbRunTheRoutine) {
502 return;
503 }
504
505 // ------ Copy hit and match branches to the temporary array and clear the main arrays
506 if (fpBrHits) {
507 fpBrHitsTmp = static_cast<TClonesArray*>(fpBrHits->Clone("tmpHit"));
508 fpBrHits->Delete();
509 }
510 if (fpBrHitMatches) {
511 fpBrHitMatchesTmp = static_cast<TClonesArray*>(fpBrHitMatches->Clone("tmpHitMatch"));
512 fpBrHitMatches->Delete();
513 }
514
515 assert(fpBrHits);
516 assert(fpBrHitMatches);
517 assert(fpBrHitsTmp);
518 assert(fpBrHitMatchesTmp);
519
520 std::vector<double> vHitMcEventTime;
521
522 // ------ Fill main hit array
523 fHitCounter = 0;
524 int iCluster = 0;
525 for (int iH = 0; iH < fpBrHitsTmp->GetEntriesFast(); ++iH) {
526 auto* pHit = static_cast<Hit_t*>(fpBrHitsTmp->At(iH));
527 double tMC = pHit->GetTime();
528
529 // Get setting
530 int iSt = fpDetInterface->GetTrackingStationIndex(pHit);
531 if (iSt < 0) {
532 continue;
533 }
534 const auto& setting = fvStationPars[iSt];
535
536 // Skip hits from stations, where new hits are to be created from points
537 if (setting.fMode == 2) {
538 continue;
539 }
540
541 else {
542 if (5 == CbmTofAddress::GetSmType(pHit->GetAddress())) {
543 LOG(info) << "TOF is TZERO!";
544 }
545 }
546
547 // ------ Adjust hit to matched MC point
548 if (setting.fMode == 1) {
549 // Access matched MC point
550 auto oLinkToPoint = GetMatchedPointLink(iH);
551 if (oLinkToPoint == std::nullopt) {
552 continue;
553 } // Hit had no links, so it's fake
554 auto& link = oLinkToPoint.value();
555 auto* pPoint = static_cast<Point_t*>(fpBrPoints->Get(link));
556
557 // Get point position and time
558 auto posIn = TVector3{};
559 auto posOut = TVector3{};
560
561 if constexpr (ca::EDetectorID::kTof == DetID) {
562 pPoint->Position(posIn);
563 pPoint->Position(posOut);
564 }
565 else {
566 pPoint->Position(posIn);
567 pPoint->PositionOut(posOut);
568 }
569 auto pos = 0.5 * (posIn + posOut);
570 double x = pos.X();
571 double y = pos.Y();
572 double z = pos.Z();
573 double t = pPoint->GetTime() + fpMCEventList->GetEventTime(link);
574 tMC = fpMCEventList->GetEventTime(link);
575
576 if (setting.fbSmear) {
577 double dx2 = pHit->GetDx() * pHit->GetDx();
578 double dxy = pHit->GetDxy();
579 double dy2 = pHit->GetDy() * pHit->GetDy();
580
581 CaUvConverter conv(setting.fPhiU, dx2, dxy, dy2);
582
583 auto [u, v] = conv.ConvertXYtoUV(x, y);
584 auto [du2, duv, dv2] = conv.ConvertCovMatrixXYtoUV(dx2, dxy, dy2);
585
586 double dt = pHit->GetTimeError();
587 this->SmearValue(u, sqrt(fabs(du2)), setting.fPdfU);
588 this->SmearValue(v, sqrt(fabs(dv2)), setting.fPdfV);
589 this->SmearValue(t, dt, setting.fPdfT);
590
591 std::tie(x, y) = conv.ConvertUVtoXY(u, v);
592 }
593 pHit->SetX(x);
594 pHit->SetY(y);
595 pHit->SetZ(z);
596 pHit->SetTime(t);
597 } // IF setting.fMode == 1
598
599 // Check out the index of cluster
600 if constexpr (ca::EDetectorID::kSts == DetID) {
601 iCluster = std::max(pHit->GetFrontClusterId(), iCluster);
602 iCluster = std::max(pHit->GetBackClusterId(), iCluster);
603 }
604
605 PushBackHit(pHit);
606 vHitMcEventTime.push_back(tMC);
607 auto* pHitMatchNew = new ((*fpBrHitMatches)[fHitCounter]) CbmMatch();
608 pHitMatchNew->AddLinks(*static_cast<CbmMatch*>(fpBrHitMatchesTmp->At(iH)));
609 ++fHitCounter;
610 }
611
612 // ------ Create hits from points
613 int nEvents = fpMCEventList->GetNofEvents();
614 for (int iE = 0; iE < nEvents; ++iE) {
615 int fileId = fpMCEventList->GetFileIdByIndex(iE);
616 int eventId = fpMCEventList->GetEventIdByIndex(iE);
617 int nPoints = fpBrPoints->Size(fileId, eventId);
618
619 // TODO: Write point selector for TOF
620 // NOTE: does not implemented for MVD
621 this->FillPointIsLegit(iE);
622 for (int iP = 0; iP < nPoints; ++iP) {
623 if (!fvbPointIsLegit[iP]) {
624 continue;
625 }
626 auto* pPoint = static_cast<Point_t*>(fpBrPoints->Get(fileId, eventId, iP));
627 int iSt = fpDetInterface->GetTrackingStationIndex(pPoint->GetDetectorID());
628 if (iSt < 0) {
629 continue;
630 }
631
632 const auto& setting = fvStationPars[iSt];
633 if (setting.fMode != 2) {
634 continue;
635 }
636 double du = setting.fDu;
637 double dv = setting.fDv;
638 double dt = setting.fDt;
639 double dz = 0.;
640
641 CaUvConverter conv(setting.fPhiU, setting.fPhiV);
642 auto [dx2, dxy, dy2] = conv.ConvertCovMatrixUVtoXY(du * du, 0., dv * dv);
643
644 // Get point position and time
645 auto posIn = TVector3{};
646 auto posOut = TVector3{};
647
648 if constexpr (ca::EDetectorID::kTof == DetID) {
649 pPoint->Position(posIn);
650 pPoint->Position(posOut);
651 }
652 else {
653 pPoint->Position(posIn);
654 pPoint->PositionOut(posOut);
655 }
656 auto pos = 0.5 * (posIn + posOut);
657 double x = pos.X();
658 double y = pos.Y();
659 double z = pos.Z();
660 double t = pPoint->GetTime() + fpMCEventList->GetEventTime(eventId, fileId);
661
662 double tMC = fpMCEventList->GetEventTime(eventId, fileId);
663
664 if (setting.fbSmear) { // TODO: Provide more realistic profiles for TRD
665 auto [u, v] = conv.ConvertXYtoUV(x, y);
666 this->SmearValue(u, du, setting.fPdfU);
667 this->SmearValue(v, dv, setting.fPdfV);
668 this->SmearValue(t, dt, setting.fPdfT);
669 std::tie(x, y) = conv.ConvertUVtoXY(u, v);
670 }
671 pos.SetX(x);
672 pos.SetY(y);
673 pos.SetZ(z);
674 auto dpos = TVector3{std::sqrt(dx2), std::sqrt(dy2), dz};
675
676 // Push back a new artificial hit
677 if constexpr (ca::EDetectorID::kMvd == DetID) {
678 new ((*fpBrHits)[fHitCounter]) CbmMvdHit();
679 }
680 else {
681 auto address = pPoint->GetDetectorID();
682 if constexpr (ca::EDetectorID::kSts == DetID) {
683 int32_t iClustF = iCluster;
684 int32_t iClustB = iCluster + 1;
685 new ((*fpBrHits)[fHitCounter]) CbmStsHit(address, pos, dpos, dxy, iClustF, iClustB, t, dt, du, dv);
686 iCluster += 2;
687 }
688 else if constexpr (ca::EDetectorID::kMuch == DetID) {
689 // TODO: What is planeID in MuCh?
690 int32_t refId = -1;
691 int32_t planeId = -1;
692 new ((*fpBrHits)[fHitCounter]) CbmMuchPixelHit(address, pos, dpos, dxy, refId, planeId, t, dt);
693 }
694 else if constexpr (ca::EDetectorID::kTrd == DetID) {
695 int32_t refId = -1;
696 auto eLoss = pPoint->GetEnergyLoss();
697 new ((*fpBrHits)[fHitCounter]) CbmTrdHit(address, pos, dpos, dxy, refId, eLoss, t, dt);
698 }
699 else if constexpr (ca::EDetectorID::kTof == DetID) {
700 int32_t refId = 0;
701 int32_t flag = 0;
702 int32_t channel = 0;
703 new ((*fpBrHits)[fHitCounter]) CbmTofHit(address, pos, dpos, refId, t, dt, flag, channel);
704 }
705 }
706
707 // Update hit match
708 auto* pHitMatchNew = new ((*fpBrHitMatches)[fHitCounter]) CbmMatch();
709 pHitMatchNew->AddLink(1., iP, eventId, fileId);
710 vHitMcEventTime.push_back(tMC);
711 ++fHitCounter;
712 assert(fpBrHitMatches->GetEntriesFast() == fHitCounter);
713 } // iP
714 }
715
716 // ------ Clear temporary hits array
717 fpBrHitsTmp->Delete();
718 delete fpBrHitsTmp;
719 fpBrHitsTmp = nullptr;
720
721 fpBrHitMatchesTmp->Delete();
722 delete fpBrHitMatchesTmp;
723 fpBrHitMatchesTmp = nullptr;
724
725 // --- Set new hit data to the reconstructed events
726 if (fpRecoEvents) {
727 for (Int_t iEvent = 0; iEvent < fpRecoEvents->GetEntriesFast(); iEvent++) {
728 CbmEvent* event = static_cast<CbmEvent*>(fpRecoEvents->At(iEvent));
729 event->ClearData(fHitDataType);
730 double tStart = event->GetStartTime();
731 double tEnd = event->GetEndTime();
732 for (UInt_t iH = 0; iH < vHitMcEventTime.size(); iH++) {
733 double t = vHitMcEventTime[iH];
734 if ((t >= tStart && t <= tEnd) || tStart < 0 || tEnd < 0) {
735 event->AddData(fHitDataType, iH);
736 }
737 }
738 }
739 }
740 }
741
742 // -------------------------------------------------------------------------------------------------------------------
743 //
744 template<ca::EDetectorID DetID>
746 {
747 int iFile = fpMCEventList->GetFileIdByIndex(iEvGlob);
748 int iEvent = fpMCEventList->GetEventIdByIndex(iEvGlob);
749 int nPoints = fpBrPoints->Size(iFile, iEvent);
750
751 fvbPointIsLegit.clear();
752 fvbPointIsLegit.resize(nPoints);
753 if constexpr (ca::EDetectorID::kTof == DetID) {
754 constexpr int kNofBitsRpcAddress = 11;
755 std::map<std::pair<int, int>, int> mMatchedPointId; // map (iTr, addr) -> is matched
756 for (int iH = 0; iH < fpBrHitMatches->GetEntriesFast(); ++iH) {
757 auto* pHitMatch = dynamic_cast<CbmMatch*>(fpBrHitMatches->At(iH));
758 LOG_IF(fatal, !pHitMatch) << "CA MC Module: hit match was not found for TOF hit " << iH;
759 double bestWeight = 0;
760 for (int iLink = 0; iLink < pHitMatch->GetNofLinks(); ++iLink) {
761 const auto& link = pHitMatch->GetLink(iLink);
762 if (link.GetFile() != iFile || link.GetEntry() != iEvent) {
763 continue;
764 }
765 int iPext = link.GetIndex();
766 if (iPext < 0) {
767 continue;
768 }
769 auto* pExtPoint = static_cast<CbmTofPoint*>(fpBrPoints->Get(link));
770 int trkId = pExtPoint->GetTrackID();
771 int rpcAddr = pExtPoint->GetDetectorID() << kNofBitsRpcAddress; // FIXME:
772 auto key = std::make_pair(trkId, rpcAddr);
773 auto prev = mMatchedPointId.find(key);
774 if (prev == mMatchedPointId.end()) {
775 bestWeight = link.GetWeight();
776 mMatchedPointId[key] = iPext;
777 }
778 else { // If we find two links for the same interaction, we select the one with the largest weight
779 if (bestWeight < link.GetWeight()) {
780 mMatchedPointId[key] = iPext;
781 }
782 }
783 }
784 } // iH
785
786 // In TOF each RPC contains up to 10 points, and one have to select only
787 // one of them
788 {
789 int iPointSelected = -1;
790 int iTmcCurr = -1;
791 int rpcAddrCurr = -1;
792 bool bTrkHasHits = false;
793 double zDist = std::numeric_limits<double>::max();
794 double zCell = std::numeric_limits<double>::signaling_NaN();
795 for (int iP = 0; iP < nPoints; ++iP) {
796 auto* pExtPoint = dynamic_cast<CbmTofPoint*>(fpBrPoints->Get(iFile, iEvent, iP));
797 LOG_IF(fatal, !pExtPoint) << "NO POINT: TOF: file, event, index = " << iFile << ' ' << iEvent << ' ' << iP;
798
799 int iTmc = pExtPoint->GetTrackID();
800 int rpcAddr = pExtPoint->GetDetectorID() << kNofBitsRpcAddress;
801 // New point
802 if (rpcAddrCurr != rpcAddr || iTmcCurr != iTmc) { // The new interaction of the MC track with the TOF RPC
803 if (iPointSelected != -1) {
804 fvbPointIsLegit[iPointSelected] = true;
805 }
806 iTmcCurr = iTmc;
807 rpcAddrCurr = rpcAddr;
808 auto key = std::make_pair(iTmc, rpcAddr);
809 auto found = mMatchedPointId.find(key);
810 bTrkHasHits = found != mMatchedPointId.end();
811 if (bTrkHasHits) {
812 iPointSelected = found->second;
813 }
814 else {
815 // First iteration
816 zCell = fpDetInterface->GetZrefModule(pExtPoint->GetDetectorID());
817 zDist = std::fabs(zCell - pExtPoint->GetZ());
818 iPointSelected = iP;
819 }
820 }
821 else {
822 if (!bTrkHasHits) {
823 auto newDist = std::fabs(pExtPoint->GetZ() - zCell);
824 if (newDist < zDist) {
825 zDist = newDist;
826 iPointSelected = iP;
827 }
828 }
829 }
830 }
831 // Add the last point
832 if (iPointSelected != -1) {
833 fvbPointIsLegit[iPointSelected] = true;
834 }
835 }
836 }
837 else {
838 // In MVD, STS, MuCh and TRD every MC point is legit
839 std::fill(fvbPointIsLegit.begin(), fvbPointIsLegit.end(), true);
840 }
841 }
842
843} // namespace cbm::ca
Random generator utility class for CA tracking.
Compile-time constants definition for the CA tracking algorithm.
ECbmDataType
Definition CbmDefs.h:90
Implementation of L1DetectorID enum class for CBM.
Class for pixel hits in MUCH detector.
TVector3 dpos
Data class for a reconstructed hit in the STS.
Base abstract class for tracking detector interface to L1 (implementation of Checker)
Class for hits in TRD detector.
friend fvec sqrt(const fvec &a)
fscal v[fmask::Size]
Definition KfSimdPseudo.h:4
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
void ClearData(ECbmDataType type)
Definition CbmEvent.cxx:37
Access to a MC data branch for time-based analysis.
Task class creating and managing CbmMCDataArray objects.
Access to a MC data branch for time-based analysis.
Container class for MC events with number, file and start time.
void AddLinks(const CbmMatch &match)
Definition CbmMatch.cxx:39
void AddLink(const CbmLink &newLink)
Definition CbmMatch.cxx:47
static CbmMuchTrackingInterface * Instance()
Gets pointer to the instance of the CbmMuchTrackingInterface.
static CbmMvdTrackingInterface * Instance()
Gets pointer to the instance of the CbmMvdTrackingInterface.
data class for a reconstructed 3-d hit in the STS
Definition CbmStsHit.h:35
static CbmStsTrackingInterface * Instance()
Gets pointer to the instance of the CbmStsTrackingInterface class.
Bookkeeping of time-slice content.
static int32_t GetSmType(uint32_t address)
Geometric intersection of a MC track with a TOFb detector.
Definition CbmTofPoint.h:44
static CbmTofTrackingInterface * Instance()
Gets pointer to the instance of the CbmTofTrackingInterface.
Abstract class, which should be inherited by every detecting subsystem tracking interface class.
data class for a reconstructed Energy-4D measurement in the TRD
Definition CbmTrdHit.h:40
static CbmTrdTrackingInterface * Instance()
Gets pointer to the instance of the CbmTrdTrackingInterface.
A class, providing ROOT-free access to randomly generated variables.
void SetSeed(int seed)
Sets seed to the random generator.
A class to convert XY coordinates to UV coordinates.
std::tuple< double, double, double > ConvertCovMatrixUVtoXY(double du2, double duv, double dv2) const
Conversion function (du2, duv, dv2) -> (dx2, dxy, dy2)
std::pair< double, double > ConvertUVtoXY(double u, double v) const
Conversion function (x,y) -> (u,v)
std::tuple< double, double, double > ConvertCovMatrixXYtoUV(double dx2, double dxy, double dy2) const
Conversion function (dx2, dxy, dy2) -> (du2, duv, dv2)
std::pair< double, double > ConvertXYtoUV(double x, double y) const
Conversion function (x,y) -> (u,v)
TClonesArray * fpRecoEvents
Array of reconstructed events.
std::vector< unsigned char > fvbPointIsLegit
Map of used point index.
static constexpr double kHitWSize
half-width for the bounded gaussian [sigma]
TClonesArray * fpBrHitsTmp
Temporary array of hits.
ECbmDataType fHitDataType
Hit data type.
IdealHitProducerDet & operator=(IdealHitProducerDet &&)=delete
Move assignment operator.
PointTypes_t::at< DetID > Point_t
void FillPointIsLegit(int iEvGlob)
Fills map of legit points (inside MC event!)
CbmMCEventList * fpMCEventList
MC event list.
TClonesArray * fpBrHitMatchesTmp
Temporary array of hit matches.
void SetRandomSeed(int seed)
Sets random seed (1 by default)
void SetConfigName(const char *name)
Sets YAML configuration file name.
std::vector< HitParameters > fvStationPars
Parameters, stored for each station.
IdealHitProducerDet(IdealHitProducerDet &&)=delete
Move constructor.
IdealHitProducerDet & operator=(const IdealHitProducerDet &)=delete
Copy assignment operator.
void ParseConfig()
Parses the YAML configuration file.
CbmMCDataObject * fpMCEventHeader
MC event header.
int fHitCounter
Hit counter in a new branch.
CbmTimeSlice * fpTimeSlice
Current time slice.
void PushBackHit(const Hit_t *pHit)
Pushes back a hit into the hits branch.
std::optional< CbmLink > GetMatchedPointLink(int iH)
Gets pointer to matched MC point.
void Exec(Option_t *option)
Execution of the task.
bool fbRunTheRoutine
Management flag, which does run the routine if there was a request.
std::string fsConfigName
Name of configuration file.
CbmMCDataArray * fpBrMCTracks
Branch: array of MC tracks.
ca::Random fRandom
Random generator.
IdealHitProducerDet()=default
Constructor.
InitStatus Init()
Initialization of the task.
InitStatus ReInit()
Re-initialization of the task.
CbmTrackingDetectorInterfaceBase * fpDetInterface
Detector interface.
TClonesArray * fpBrHits
Branch: array of hits.
TClonesArray * fpBrHitMatches
Branch: array of hit matches.
void SmearValue(double &value, double sigma, int opt)
Smears the value by a given standard deviation with a selected function.
CbmMCDataArray * fpBrPoints
Branch: array of MC points.
IdealHitProducerDet(const IdealHitProducerDet &)=delete
Copy constructor.
constexpr double Undef< double >
Definition CaDefs.h:122
constexpr DetIdArr_t< const char * > kDetName
Names of detector subsystems.
std::tuple_element_t< static_cast< std::size_t >(DetID), std::tuple< Types... > > at
A structure to keep hit adjustment/creation settings for each station.
double fDu
Error of u-coordinate measurement [cm].
double fPhiU
Angle of the first independent measured coordinate [rad].
double fPhiV
Angle of the second independent measured coordinate [rad].
double fDt
Error of time measurement [ns].
double fDv
Error of v-coordinate measurement [cm].