CbmRoot
Loading...
Searching...
No Matches
CbmRichMCbmHitProducer.cxx
Go to the documentation of this file.
1/* Copyright (C) 2019-2024 UGiessen/JINR-LIT, Giessen/Dubna
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Adrian Amatus Weber, Semen Lebedev [committer], Martin Beyer */
4
6
7#include "CbmDigiManager.h"
8#include "CbmEvent.h"
9#include "CbmRichDetectorData.h" // for CbmRichPmtData, CbmRichPixelData
10#include "CbmRichDigi.h"
11#include "CbmRichGeoHandler.h"
12#include "CbmRichGeoManager.h"
13#include "CbmRichHit.h"
14#include "CbmRichPoint.h"
15#if HAVE_ONNXRUNTIME
17#endif
18
19#include <FairRootManager.h>
20#include <Logger.h>
21
22#include <TClonesArray.h>
23#include <TStopwatch.h>
24
25#include <iomanip>
26#include <iostream>
27
28using std::fixed;
29using std::right;
30using std::setprecision;
31using std::setw;
32
33using namespace std;
34
35
37 : FairTask("CbmRichMCbmHitProducer")
38 , fRichHits(NULL)
39 , fNofTs(0)
40 , fHitError(0.6 / sqrt(12.))
41 ,
42 //fMappingFile("mRICH_Mapping_vert_20190318.geo")
43 fMappingFile("mRICH_Mapping_vert_20190318_elView.geo")
45{
46}
47
49{
50 FairRootManager* manager = FairRootManager::Instance();
51 manager->Write();
52}
53
55
57{
58 FairRootManager* manager = FairRootManager::Instance();
59
60 fCbmEvents = dynamic_cast<TClonesArray*>(manager->GetObject("CbmEvent"));
61 if (fCbmEvents == nullptr) {
62 LOG(info) << GetName() << "::Init() CbmEvent NOT found \n";
63 }
64 else {
65 LOG(info) << GetName() << "::Init() CbmEvent found";
66 }
67
69 fDigiMan->Init();
70 if (!fDigiMan->IsPresent(ECbmModuleId::kRich)) Fatal("CbmRichMCbmHitProducer::Init", "No RichDigi array!");
71
72 fRichHits = new TClonesArray("CbmRichHit");
73 manager->Register("RichHit", "RICH", fRichHits, IsOutputBranchPersistent("RichHit"));
74
76
77 for (auto& a : fICD_offset_read)
78 a = 0.;
80
81#if HAVE_ONNXRUNTIME
82 if (fUseDenoiseNN) {
83 fDenoiseCnn = std::make_unique<CbmRichMCbmDenoiseCnn>();
84 fDenoiseCnn->Init();
85 fDenoiseCnn->SetClassificationThreshold(fDenoiseCnnThreshold);
86 LOG(info) << "CbmRichMCbmHitProducer: Initialized CbmRichMCbmDenoiseCnn";
87 }
88#endif
89
90 return kSUCCESS;
91}
92
94{
95
96 string line;
97 ifstream file(fMappingFile);
98 if (!file.is_open()) {
99 std::cout << "<CbmRichMCbmHitProducer::InitMapping>: Unable to open mapping file:" << fMappingFile.c_str()
100 << std::endl;
101 }
102
103 fRichMapping.clear();
104
105 while (getline(file, line)) {
106
107 istringstream iss(line);
108 vector<std::string> results(istream_iterator<string>{iss}, std::istream_iterator<string>());
109 if (results.size() != 8) continue;
110
112 data.fTrbId = stoi(results[0], nullptr, 16);
113 data.fChannel = stoi(results[1]);
114 data.fX = stod(results[6]);
115 data.fY = stod(results[7]);
116 data.fZ = 348.;
117
118 data.fX -= 6.3; //Shift by 1Pmt + PmtGap + 1cm
119
120 Int_t adr = ((data.fTrbId << 16) | (data.fChannel & 0x00FF));
121
122 // cout << data.fTrbId << " " << data.fChannel << " " << data.fX << " " << data.fY << " " << adr << endl;
123
124 fRichMapping[adr] = data;
125 }
126 file.close();
127
128 //cout << "Mapping size:" << fRichMapping.size() <<endl;
129}
130
131void CbmRichMCbmHitProducer::Exec(Option_t* /*option*/)
132{
133 fNofDigis = 0;
134 TStopwatch timer;
135 timer.Start();
136 fRichHits->Delete();
137
138 // if CbmEvent does not exist then process standard event.
139 // if CbmEvent exists then proceed all events in time slice.
140 Int_t nUnits = fCbmEvents ? fCbmEvents->GetEntriesFast() : 1;
141 if (fCbmEvents) fNofEvents += nUnits;
142 for (Int_t iUnit = 0; iUnit < nUnits; iUnit++) {
143 CbmEvent* event = fCbmEvents ? static_cast<CbmEvent*>(fCbmEvents->At(iUnit)) : nullptr;
144 ProcessData(event);
145 }
146 timer.Stop();
147 fTotalTime += timer.RealTime();
148
149 std::stringstream logOut;
150 logOut << setw(20) << left << GetName() << "[";
151 logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] ";
152 logOut << "TS " << fNofTs;
153 if (fCbmEvents) logOut << ", events " << nUnits;
154 logOut << ", digis " << fNofDigis;
155 logOut << ", hits " << fRichHits->GetEntriesFast();
156 LOG(info) << logOut.str();
158 fTotalNofHits += fRichHits->GetEntriesFast();
159 fNofTs++;
160}
161
163{
164 TStopwatch timer;
165 timer.Start();
166 if (event != NULL) {
167 LOG(debug) << "CbmRichMCbmHitProducer CbmEvent mode. CbmEvent # " << event->GetNumber();
168 Int_t nofDigis = event->GetNofData(ECbmDataType::kRichDigi);
169 //LOG(info) << "nofDigis: " << nofDigis;
170
171 fNofHits = 0;
172 for (Int_t iDigi = 0; iDigi < nofDigis; iDigi++) {
173 Int_t iDigiIndex = event->GetIndex(ECbmDataType::kRichDigi, iDigi);
174 ProcessDigi(event, iDigiIndex);
175 }
176 LOG(debug) << "nofDigis: " << nofDigis << "\t\t "
177 << "nofHits : " << fNofHits;
178 fNofHits = 0;
179 }
180 else {
181 Int_t nofDigis = fDigiMan->GetNofDigis(ECbmModuleId::kRich);
182 for (Int_t iDigi = 0; iDigi < nofDigis; iDigi++) {
183 ProcessDigi(event, iDigi);
184 }
185 }
186 timer.Stop();
187 fHitProducerTime += timer.RealTime();
188
189// Process all hits with DenoiseNN, setting value RichHit.fIsNoiseNN
190#if HAVE_ONNXRUNTIME
191 if (fUseDenoiseNN) {
192 timer.Start();
193 fDenoiseCnn->Process(event, fRichHits);
194 timer.Stop();
195 fDenoiseCnnTime += timer.RealTime();
196 }
197#endif
198}
199
201{
202 const CbmRichDigi* digi = fDigiMan->Get<CbmRichDigi>(digiIndex);
203 if (digi == nullptr) return;
204 if (digi->GetAddress() < 0) return;
205 Int_t DiRICH_Add = (digi->GetAddress() >> 16) & 0xFFFF;
206 if ((0x7901 <= DiRICH_Add && DiRICH_Add <= 0x7905) || (0x9991 <= DiRICH_Add && DiRICH_Add <= 0x9998)) {
207 // TRBaddresses 0x7901 to 0x7905 are for FSD/NCAL
208 // TRBaddresses 0x9991 to 0x9998 are for PASTA
209 return;
210 }
211 fNofDigis++;
212 if (isInToT(digi->GetToT())) {
213 TVector3 posPoint;
215
216 if (data != nullptr) {
217 posPoint.SetXYZ(data->fX, data->fY, data->fZ);
218 }
219 else {
220 LOG(info) << "CbmRichMCbmHitProducer: No Node for 0x" << std::hex << digi->GetAddress() << std::dec
221 << " found. Using ASCII File! ";
223
224 /* if (dataAscii == NULL) {
225 LOG(error) << "CbmRichMCbmHitProducer: No Position for "<<digi->GetAddress()<<"found! ";
226 return;
227 }*/
228 posPoint.SetXYZ(dataAscii.fX, dataAscii.fY, dataAscii.fZ);
229 }
230
231 //std::cout<<std::hex<<digi->GetAddress()<<std::dec<<" "<<data->fX<<" "<<data->fY<<" "<<data->fZ<<std::endl;
232 if (!RestrictToAcc(posPoint)) return;
233 if (!RestrictToFullAcc(posPoint)) return;
234 if (!RestrictToAerogelAccDec2019(posPoint)) return;
235 AddHit(event, posPoint, digi, digiIndex, data->fPmtId);
236 }
237}
238
239
240void CbmRichMCbmHitProducer::AddHit(CbmEvent* event, TVector3& posHit, const CbmRichDigi* digi, Int_t index,
241 Int_t PmtId)
242{
243 Int_t nofHits = fRichHits->GetEntriesFast();
244
245 int32_t DiRICH_Addr = digi->GetAddress();
246 unsigned int addr = (((DiRICH_Addr >> 24) & 0xF) * 18 * 32) + (((DiRICH_Addr >> 20) & 0xF) * 2 * 32)
247 + (((DiRICH_Addr >> 16) & 0xF) * 32) + ((DiRICH_Addr & 0xFFFF) - 0x1);
248
249 new ((*fRichHits)[nofHits]) CbmRichHit();
250 CbmRichHit* hit = (CbmRichHit*) fRichHits->At(nofHits);
251 hit->SetPosition(posHit);
252 hit->SetDx(fHitError);
253 hit->SetDy(fHitError);
254 hit->SetRefId(index);
255 if (fDoICD) {
256 hit->SetTime(digi->GetTime() - fICD_offset_read.at(addr));
257 }
258 else {
259 hit->SetTime(digi->GetTime());
260 }
261
262 hit->SetToT(digi->GetToT());
263 hit->SetAddress(digi->GetAddress());
264 hit->SetPmtId(PmtId);
265 // Not Implemented in Digi: hit->SetPmtId(digi->GetPmtId());
266
267 if (event != NULL) {
268 event->AddData(ECbmDataType::kRichHit, nofHits);
269 fNofHits++;
270 }
271}
272
273
275{
276 fRichHits->Clear();
277 std::cout << std::endl;
278 LOG(info) << "=====================================";
279 LOG(info) << GetName() << ": Run summary";
280 LOG(info) << "Time slices : " << fNofTs;
281 LOG(info) << "Digis / TS : " << fixed << setprecision(2) << fTotalNofDigis / Double_t(fNofTs);
282 LOG(info) << "Hits / TS : " << fixed << setprecision(2) << fTotalNofHits / Double_t(fNofTs);
283 LOG(info) << "Time / TS : " << fixed << setprecision(2) << 1000. * fTotalTime / Double_t(fNofTs) << " ms";
284 if (fCbmEvents) {
285 LOG(info) << "Events : " << fNofEvents;
286 LOG(info) << "Events / TS : " << fixed << setprecision(2) << fNofEvents / Double_t(fNofTs);
287 if (fNofEvents > 0) {
288 LOG(info) << "Digis / ev : " << fixed << setprecision(2) << fTotalNofDigis / Double_t(fNofEvents);
289 LOG(info) << "Hits / ev : " << fixed << setprecision(2) << fTotalNofHits / Double_t(fNofEvents);
290 LOG(info) << "Time / ev : " << fixed << setprecision(2) << 1000. * fTotalTime / Double_t(fNofEvents)
291 << " ms";
292 }
293 }
294
295 TString eventOrTsStr = fCbmEvents && fNofEvents > 0 ? "ev: " : "TS: ";
296 Double_t eventOrTsValue = Double_t(fCbmEvents && fNofEvents > 0 ? fNofEvents : fNofTs);
297 if (fTotalTime != 0.) {
298 LOG(info) << "===== Time by task (real time) ======";
299 LOG(info) << "HitProducer / " << eventOrTsStr << fixed << setprecision(2) << setw(9) << right
300 << 1000. * fHitProducerTime / eventOrTsValue << " ms [" << setw(5) << right
301 << 100 * fHitProducerTime / fTotalTime << " %]";
302#if HAVE_ONNXRUNTIME
303 if (fUseDenoiseNN)
304 LOG(info) << "Denoise NN / " << eventOrTsStr << fixed << setprecision(2) << setw(9) << right
305 << 1000. * fDenoiseCnnTime / eventOrTsValue << " ms [" << setw(5) << right
306 << 100 * fDenoiseCnnTime / fTotalTime << " %]";
307#endif
308 }
309 LOG(info) << "=====================================\n";
310}
311
312
314{
315
316 if (!fDoToT) return true;
317
318 if ((ToT > fToTLimitLow) && (ToT < fToTLimitHigh)) {
319 return true;
320 }
321 else {
322 return false;
323 }
324}
325
326
328{
329 Double_t x = pos.X();
330 Double_t y = pos.Y();
331
332 return this->RestrictToAcc(x, y);
333}
334
336{ //check if Track is in mRICH acceptance
337 if (fRestrictToAcc == false) return true;
338 bool inside = false;
339 if (x >= -6.25 && x <= -1.05) {
340 // left part of mRICH
341 if (y >= 8 && y <= 15.9) {
342 inside = true;
343 }
344 }
345 else if (x > -1.05 && x <= 4.25) {
346 //right part
347 if (y >= 8 && y <= 13.2) {
348 inside = true;
349 }
350 }
351
352 return inside;
353}
354
356{
357 Double_t x = pos.X();
358 Double_t y = pos.Y();
359
360 return this->RestrictToFullAcc(x, y);
361}
362
364{ //check if Track is in mRICH acceptance
365 if (fRestrictToFullAcc == false) return true;
366 bool inside = false;
367 if (x >= -16.85 && x <= 4.25) { //TODO:check values
368 // left part of mRICH
369 if (y >= -23.8 && y <= 23.8) {
370 inside = true;
371 }
372 }
373
374 return inside;
375}
376
378{
379 Double_t x = pos.X();
380 Double_t y = pos.Y();
381
382 return this->RestrictToAerogelAccDec2019(x, y);
383}
384
386{ //check if Track is in mRICH acceptance
387 if (fRestrictToAerogelAccDec2019 == false) return true;
388 //bool inside = false;
389
390 if (y > 13.5) return false;
391 if (y > 8.0 && x < 12.5) return false;
392
393 return true;
394}
395
396void CbmRichMCbmHitProducer::read_ICD(std::array<Double_t, 2304>& ICD_offsets, unsigned int iteration)
397{
398 std::string line;
399 std::string filename = ("" == fIcdFilenameBase ? "icd_offset_it" : fIcdFilenameBase);
400 filename += Form("_%u.data", iteration);
401 std::ifstream icd_file(filename);
402 unsigned int lineCnt = 0;
403 if (icd_file.is_open()) {
404 while (getline(icd_file, line)) {
405 if (line[0] == '#') continue; // just a comment
406 std::istringstream iss(line);
407 unsigned int addr = 0;
408 Double_t value;
409 if (!(iss >> addr >> value)) {
410 LOG(info) << "A Problem accured in line " << lineCnt;
411 break;
412 } // error
413 lineCnt++;
414 ICD_offsets.at(addr) += value;
415 }
416 icd_file.close();
417 LOG(info) << "Loaded inter channel delay file " << filename << " for RICH.";
418 }
419 else {
420 LOG(info) << "Unable to open inter channel delay file " << filename;
421 }
422}
423
ClassImp(CbmConverterManager)
@ kRich
Ring-Imaging Cherenkov Detector.
Definition CbmDefs.h:49
friend fvec sqrt(const fvec &a)
int Int_t
static CbmDigiManager * Instance()
Static instance.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
void SetAddress(int32_t address)
Definition CbmHit.h:86
void SetRefId(int32_t refId)
Definition CbmHit.h:85
void SetTime(double time)
Definition CbmHit.h:88
void SetDx(double dx)
Definition CbmPixelHit.h:94
void SetDy(double dy)
Definition CbmPixelHit.h:95
void SetPosition(const TVector3 &pos)
Sets position of the hit.
int32_t GetAddress() const
Definition CbmRichDigi.h:43
double GetToT() const
Definition CbmRichDigi.h:78
double GetTime() const
Definition CbmRichDigi.h:72
static CbmRichGeoHandler & GetInstance()
CbmRichPixelData * GetPixelDataByAddress(Int_t address)
virtual void SetPmtId(int32_t det)
Definition CbmRichHit.h:57
void SetToT(double tot)
Definition CbmRichHit.h:60
virtual ~CbmRichMCbmHitProducer()
Destructor.
std::map< Int_t, CbmRichMCbmMappingData > fRichMapping
bool isInToT(const double ToT)
void read_ICD(std::array< Double_t, 2304 > &offsets, unsigned int iteration)
void ProcessDigi(CbmEvent *event, Int_t digiIndex)
bool RestrictToAerogelAccDec2019(TVector3 &pos)
bool RestrictToFullAcc(TVector3 &pos)
void ProcessData(CbmEvent *event)
void AddHit(CbmEvent *event, TVector3 &posHit, const CbmRichDigi *digi, Int_t index, Int_t PmtId)
Add hit to the output array (and) CbmEvent if it is not NULL.
CbmRichMCbmHitProducer()
Default constructor.
virtual void SetParContainers()
Inherited from FairTask.
virtual void Finish()
Inherited from FairTask.
virtual InitStatus Init()
Inherited from FairTask.
std::array< Double_t, 2304 > fICD_offset_read
virtual void Exec(Option_t *option)
Inherited from FairTask.
Hash for CbmL1LinkKey.