CbmRoot
Loading...
Searching...
No Matches
CbmTaskTofClusterizer.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022 Facility for Antiproton and Ion Research in Europe, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Dominik Smith [committer], Pierre-Alain Loizeau, Norbert Herrmann */
4
6
7// TOF Classes and includes
8#include "CbmBmonDigi.h" // in cbmdata/bmon
9#include "CbmDigiManager.h"
10#include "CbmEvent.h"
11#include "CbmMatch.h"
12#include "CbmTofHit.h" // in cbmdata/tof
13#include "CbmTsEventHeader.h"
14
15// FAIR classes and includes
16#include "FairRootFileSink.h"
17#include "FairRootManager.h"
18#include "FairRunAna.h"
19#include "FairRuntimeDb.h"
20
21#include <Logger.h>
22
23// ROOT Classes and includes
24#include "TClonesArray.h"
25#include "TStopwatch.h"
26
27// C++ Classes and includes
28#include "compat/Filesystem.h"
29#include "yaml/Yaml.h"
30
31#include <iomanip>
32#include <vector>
33
34
35/************************************************************************************/
37
38CbmTaskTofClusterizer::CbmTaskTofClusterizer(const char* name, int32_t verbose, bool writeDataInOut)
39 : FairTask(TString(name), verbose)
40 , fTsHeader(NULL)
41 , fDigiMan(nullptr)
42 , fEventsColl(nullptr)
43 , fbWriteHitsInOut(writeDataInOut)
44 , fbWriteDigisInOut(writeDataInOut)
45 , fTofHitsColl(NULL)
46 , fTofDigiMatchColl(NULL)
47 , fTofHitsCollOut(NULL)
48 , fTofDigiMatchCollOut(NULL)
49 , fiNbHits(0)
50 , fdEvent(0)
51 , fbSwapChannelSides(false)
52 , fiOutputTreeEntry(0)
53 , fiFileIndex(0)
54{
55}
56
58
59/************************************************************************************/
60// FairTasks inherited functions
62{
63 LOG(info) << "CbmTaskTofClusterizer initializing... expect Digis in ns units! ";
64 if (false == RegisterInputs()) return kFATAL;
65 if (false == RegisterOutputs()) return kFATAL;
66 if (false == InitAlgos()) return kFATAL;
67 return kSUCCESS;
68}
69
70
71void CbmTaskTofClusterizer::Exec(Option_t* option)
72{
74 if (fEventsColl) {
75 if (NULL != fTsHeader)
76 LOG(info) << "New Ts " << iNbTs << ", size " << fEventsColl->GetSize() << " at " << fTsHeader->GetTsStartTime()
77 << " with " << fEventsColl->GetEntriesFast() << " events, " << fDigiMan->GetNofDigis(ECbmModuleId::kTof)
78 << " TOF digis + " << fDigiMan->GetNofDigis(ECbmModuleId::kBmon) << " Bmon digis ";
79
80 TStopwatch timerTs;
81 timerTs.Start();
82
83 iNbTs++;
84 fiHitStart = 0;
85 int32_t iNbHits = 0;
86 int32_t iNbCalDigis = 0;
87 fTofDigiMatchCollOut->Delete(); // costly, FIXME
88 fTofHitsCollOut->Delete(); // costly, FIXME
89
90 for (int32_t iEvent = 0; iEvent < fEventsColl->GetEntriesFast(); iEvent++) {
91 CbmEvent* tEvent = dynamic_cast<CbmEvent*>(fEventsColl->At(iEvent));
92 fTofDigiVec.clear();
93 LOG(debug) << "TS event " << iEvent << " with " << tEvent->GetNofData(ECbmDataType::kBmonDigi) << " Bmon and "
94 << tEvent->GetNofData(ECbmDataType::kTofDigi) << " Tof digis ";
95
96 for (size_t iDigi = 0; iDigi < tEvent->GetNofData(ECbmDataType::kBmonDigi); iDigi++) {
97 int32_t iDigiIndex = static_cast<int32_t>(tEvent->GetIndex(ECbmDataType::kBmonDigi, iDigi));
98 CbmTofDigi tDigi(fDigiMan->Get<CbmBmonDigi>(iDigiIndex));
99 if (tDigi.GetType() != 5) {
100 tDigi.SetAddress(0, 0, 0, 0, 5); // convert to Tof Address
101 }
102 if (tDigi.GetSide() == 1) { // HACK for May22 setup
103 tDigi.SetAddress(tDigi.GetSm(), tDigi.GetRpc(), tDigi.GetChannel() + 6, 0, tDigi.GetType());
104 }
105 fTofDigiVec.push_back(tDigi);
106 }
107 for (size_t iDigi = 0; iDigi < tEvent->GetNofData(ECbmDataType::kTofDigi); iDigi++) {
108 int32_t iDigiIndex = static_cast<int32_t>(tEvent->GetIndex(ECbmDataType::kTofDigi, iDigi));
109 const CbmTofDigi* tDigi = fDigiMan->Get<CbmTofDigi>(iDigiIndex);
110 fTofDigiVec.push_back(CbmTofDigi(*tDigi));
111 }
112
113 ExecEvent(option);
114
115 // --- In event-by-event mode: copy caldigis, hits and matches to output array and register them to event
116 uint uDigi0 = fTofCalDigiVecOut->size(); //starting index of current event
117 LOG(debug) << "Append " << fTofCalDigiVec->size() << " CalDigis to event " << tEvent->GetNumber();
118 for (uint32_t index = 0; index < fTofCalDigiVec->size(); index++) {
119 CbmTofDigi* tDigi = &(fTofCalDigiVec->at(index));
120 tEvent->AddData(ECbmDataType::kTofCalDigi, iNbCalDigis);
121 fTofCalDigiVecOut->push_back(CbmTofDigi(*tDigi));
122 iNbCalDigis++;
123 }
124
125 int iHit0 = iNbHits; //starting index of current event
126 LOG(debug) << "Assign " << fTofHitsColl->GetEntriesFast() << " hits to event " << tEvent->GetNumber();
127 for (int32_t index = 0; index < fTofHitsColl->GetEntriesFast(); index++) {
128 CbmTofHit* pHit = (CbmTofHit*) fTofHitsColl->At(index);
129 new ((*fTofHitsCollOut)[iNbHits]) CbmTofHit(*pHit);
130 tEvent->AddData(ECbmDataType::kTofHit, iNbHits);
131
132 CbmMatch* pDigiMatch = (CbmMatch*) fTofDigiMatchColl->At(index);
133
134 // update content of match object to TS array
135 CbmMatch* mDigiMatch = new CbmMatch();
136 for (int32_t iLink = 0; iLink < pDigiMatch->GetNofLinks(); iLink++) {
137 CbmLink Link = pDigiMatch->GetLink(iLink);
138 Link.SetIndex(Link.GetIndex() + uDigi0);
139 mDigiMatch->AddLink(Link);
140 }
141
142 new ((*fTofDigiMatchCollOut)[iNbHits]) CbmMatch(*mDigiMatch);
143 delete mDigiMatch;
144 iNbHits++;
145 }
146
147 fiHitStart += iNbHits - iHit0;
148 fTofDigiVec.clear();
149 fTofCalDigiVec->clear();
150 fTofHitsColl->Delete(); //Clear("C");
151 fTofDigiMatchColl->Delete(); //Clear("C");
152 }
153
155 timerTs.Stop();
156 LOG(debug) << GetName() << "::Exec: real time=" << timerTs.RealTime() << " CPU time=" << timerTs.CpuTime();
157 fProcessTime += timerTs.RealTime();
161
162 std::stringstream logOut;
163 logOut << std::setw(20) << std::left << GetName() << " [";
164 logOut << std::fixed << std::setw(8) << std::setprecision(1) << std::right << timerTs.RealTime() * 1000. << " ms] ";
165 logOut << "TS " << iNbTs;
166 logOut << ", events " << fEventsColl->GetEntriesFast();
167 logOut << ", hits " << fiHitStart << ", time/1k-hit " << std::setprecision(4)
168 << timerTs.RealTime() * 1e6 / fiHitStart << " [ms]";
169 LOG(info) << logOut.str();
170 }
171 else {
172 // fTofDigisColl=fTofRawDigisColl;
173 // (VF) This does not work here. The digi manager does not foresee to add
174 // new data to the input array. So, I here copy the input digis into
175 // the array fTofDigisColl. Not very efficient, but temporary only, until
176 // also the internal data representations are changed to std::vectors.
177
178 fTofDigiVec.clear();
179 if (NULL != fBmonDigiVec) { // 2022 data
180 for (int32_t iDigi = 0; iDigi < (int) (fBmonDigiVec->size()); iDigi++) {
181 CbmTofDigi tDigi = fBmonDigiVec->at(iDigi);
182 if (tDigi.GetType() != 5)
183 LOG(fatal) << "Wrong Bmon type " << tDigi.GetType() << ", Addr 0x" << std::hex << tDigi.GetAddress();
184 if (tDigi.GetSide() == 1) { // HACK for May22 setup
185 tDigi.SetAddress(tDigi.GetSm(), tDigi.GetRpc(), tDigi.GetChannel() + 6, 0, tDigi.GetType());
186 }
187 fTofDigiVec.push_back(CbmTofDigi(tDigi));
188 }
189 }
190 for (int32_t iDigi = 0; iDigi < fDigiMan->GetNofDigis(ECbmModuleId::kTof); iDigi++) {
191 const CbmTofDigi* tDigi = fDigiMan->Get<CbmTofDigi>(iDigi);
192 fTofDigiVec.push_back(CbmTofDigi(*tDigi));
193
194 //if (iDigi == 10000) break; // Only use 10000 digis for now. D.Smith
195 }
196 ExecEvent(option);
197 }
198}
199
200void CbmTaskTofClusterizer::ExecEvent(Option_t* /*option*/)
201{
202 // Clear output arrays
203 fTofCalDigiVec->clear();
204 fTofHitsColl->Delete(); // Computationally costly!, but hopefully safe
205 fTofDigiMatchColl->Delete();
206 FairRootFileSink* sink = (FairRootFileSink*) FairRootManager::Instance()->GetSink();
207 if (sink) {
208 fiOutputTreeEntry = sink->GetOutTree()->GetEntries();
209 }
210
211 fiNbHits = 0;
212
214}
215
216/************************************************************************************/
218{
219 LOG(info) << "Finish with " << fdEvent << " processed events";
220
222 LOG(info) << "=====================================";
223 LOG(info) << GetName() << ": Finish run";
224 LOG(info) << GetName() << ": Run summary ";
225 LOG(info) << GetName() << ": Processing time : " << std::fixed << std::setprecision(3) << fProcessTime;
226 LOG(info) << GetName() << ": Nr of events : " << fdEvent;
227 LOG(info) << GetName() << ": Nr of input digis : " << fuNbDigis;
228 LOG(info) << GetName() << ": Nr of produced hits : " << fuNbHits;
229 LOG(info) << GetName() << ": Nr of hits / event : " << std::fixed << std::setprecision(2)
230 << (fdEvent > 0 ? fuNbHits / fdEvent : 0);
231 LOG(info) << GetName() << ": Nr of hits / digis : " << std::fixed << std::setprecision(2)
232 << (fuNbDigis > 0 ? fuNbHits / (double) fuNbDigis : 0);
233 LOG(info) << "=====================================";
234}
235
237{
238 SetCalMode(calMode);
239 Finish();
240}
241
242/************************************************************************************/
243// Functions common for all clusters approximations
245{
246 FairRootManager* fManager = FairRootManager::Instance();
247
248 if (NULL == fManager) {
249 LOG(error) << "CbmTaskTofClusterizer::RegisterInputs => Could not find "
250 "FairRootManager!!!";
251 return false;
252 }
253
254 fEventsColl = dynamic_cast<TClonesArray*>(fManager->GetObject("Event"));
255 if (NULL == fEventsColl) fEventsColl = dynamic_cast<TClonesArray*>(fManager->GetObject("CbmEvent"));
256
257 if (NULL == fEventsColl) LOG(info) << "CbmEvent not found in input file, assume eventwise input";
258
260 fDigiMan->Init();
262 LOG(error) << GetName() << ": No Tof digi input!";
263 return false;
264 }
266 LOG(info) << GetName() << ": separate Bmon digi input!";
267 //fBmonDigiVec = fManager->InitObjectAs<std::vector<CbmTofDigi> const*>("TzdDigi");
268 }
269 else {
270 LOG(info) << "No separate Bmon digi input found.";
271 } // if( ! fBmonDigiVec )
272
273 fTsHeader = fManager->InitObjectAs<CbmTsEventHeader const*>("EventHeader."); //for data
274 if (NULL == fTsHeader) {
275 LOG(info) << "CbmTaskTofClusterizer::RegisterInputs => Could not get TsHeader Object";
276 }
277
278 return true;
279}
281{
282 FairRootManager* rootMgr = FairRootManager::Instance();
283 rootMgr->InitSink();
284
285 fTofCalDigiVec = new std::vector<CbmTofDigi>();
286 fTofHitsColl = new TClonesArray("CbmTofHit", 100);
287 fTofDigiMatchColl = new TClonesArray("CbmMatch", 100);
288
289 if (NULL == fEventsColl) {
290 // Flag check to control whether digis are written in output root file
291 rootMgr->RegisterAny("TofCalDigi", fTofCalDigiVec, fbWriteDigisInOut);
292
293 // Flag check to control whether digis are written in output root file
294 rootMgr->Register("TofHit", "Tof", fTofHitsColl, fbWriteHitsInOut);
296
297 rootMgr->Register("TofHitCalDigiMatch", "Tof", fTofDigiMatchColl, fbWriteHitsInOut);
298 LOG(info) << Form("Register DigiMatch in TS mode at %p with %d", fTofDigiMatchColl, (int) fbWriteHitsInOut);
300 }
301 else { // CbmEvent - mode
302 fTofCalDigiVecOut = new std::vector<CbmTofDigi>();
303 fTofHitsCollOut = new TClonesArray("CbmTofHit", 10000);
304 fTofDigiMatchCollOut = new TClonesArray("CbmMatch", 10000);
305
306 rootMgr->RegisterAny("TofCalDigi", fTofCalDigiVecOut, fbWriteDigisInOut);
307 rootMgr->Register("TofHit", "Tof", fTofHitsCollOut, fbWriteHitsInOut);
308 rootMgr->Register("TofHitCalDigiMatch", "Tof", fTofDigiMatchCollOut, fbWriteHitsInOut);
309 LOG(info) << Form("Register DigiMatch in event mode at %p with %d ", fTofDigiMatchCollOut, (int) fbWriteHitsInOut);
310 }
311 return true;
312}
313
314
316{
317 // Read hitfinder parameters and initialize algo
318 fAlgo = std::make_unique<cbm::algo::tof::Hitfind>(
320
321 // Read calibration parameters initialize algo
322 fCalibrate = std::make_unique<cbm::algo::tof::Calibrate>(
324
325 return true;
326}
327
328
329/************************************************************************************/
331{
332 if (fTofDigiVec.empty()) {
333 LOG(info) << " No RawDigis defined ! Check! ";
334 return false;
335 }
336 LOG(info) << "Build clusters from " << fTofDigiVec.size() << " digis in event " << fdEvent + 1;
337
339 // Duplicate type "5" - digis
340 for (size_t iDigInd = 0; iDigInd < fTofDigiVec.size(); iDigInd++) {
341 CbmTofDigi* pDigi = &(fTofDigiVec.at(iDigInd));
342 if (pDigi->GetType() == 5) { // || pDigi->GetType() == 8) {
343 if (pDigi->GetSide() == 1) {
344 bAddBeamCounterSideDigi = false; // disable for current data set
345 LOG(info) << "Start counter digi duplication disabled";
346 break;
347 }
348 fTofDigiVec.push_back(CbmTofDigi(*pDigi));
349 CbmTofDigi* pDigiN = &(fTofDigiVec.back());
350 pDigiN->SetAddress(pDigi->GetSm(), pDigi->GetRpc(), pDigi->GetChannel(), (0 == pDigi->GetSide()) ? 1 : 0,
351 pDigi->GetType());
352 LOG(debug) << "Duplicated digi " << fTofDigiVec.size() << " with address 0x" << std::hex
353 << pDigiN->GetAddress();
354 }
355 }
356 }
357
358 //Calibrate digis
359 auto [caldigis, calmonitor] = (*fCalibrate)(fTofDigiVec);
360 *fTofCalDigiVec = std::move(caldigis);
361 LOG(info) << calmonitor.print();
362
363 //Call cluster finder
364 auto [clusters, monitor, indices] = (*fAlgo)(*fTofCalDigiVec);
365 LOG(info) << monitor.print();
366
367 //Store hits and match
368 size_t indexOffset = 0;
369 for (auto const& cluster : clusters.Data()) {
370 const int32_t hitIndex = fTofHitsColl->GetEntriesFast();
371 TVector3 hitpos = TVector3(cluster.hitPos.X(), cluster.hitPos.Y(), cluster.hitPos.Z());
372 TVector3 hiterr = TVector3(cluster.hitPosErr.X(), cluster.hitPosErr.Y(), cluster.hitPosErr.Z());
373 new ((*fTofHitsColl)[hitIndex])
374 CbmTofHit(cluster.address, hitpos, hiterr, fiNbHits, cluster.hitTime, cluster.hitTimeErr, cluster.numChan() * 2,
375 int32_t(cluster.weightsSum * 10.));
376
377 fiNbHits++;
378 //if (event) event->AddData(ECbmDataType::kTofHit, hitIndex);
379
380 CbmMatch* digiMatch = new ((*fTofDigiMatchColl)[hitIndex]) CbmMatch();
381 for (int32_t i = 0; i < cluster.numChan() * 2; i++) {
382 size_t digiInd = indices.at(indexOffset + i);
383 double tot = fTofCalDigiVec->at(digiInd).GetTot();
384 digiMatch->AddLink(CbmLink(tot, digiInd, fiOutputTreeEntry, fiFileIndex));
385 }
386 indexOffset += cluster.numChan() * 2;
387 }
388
389 fdEvent++;
390 return true;
391}
@ kTof
Time-of-flight Detector.
static FairRootManager * rootMgr
TClonesArray * fTofHitsColl
TClonesArray * fEventsColl
CbmDigiManager * fDigiMan
Data class for a signal in the t-zero detector.
Definition CbmBmonDigi.h:30
static Int_t GetNofDigis(ECbmModuleId systemId)
static Bool_t IsPresent(ECbmModuleId systemId)
Presence of a digi branch.
InitStatus Init()
Initialisation.
const Digi * Get(Int_t index) const
Get a digi object.
static CbmDigiManager * Instance()
Static instance.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
size_t GetNofData() const
Definition CbmEvent.cxx:58
int32_t GetNumber() const
Definition CbmEvent.h:121
uint32_t GetIndex(ECbmDataType type, uint32_t iData) const
Definition CbmEvent.cxx:42
void AddData(ECbmDataType type, uint32_t index)
Definition CbmEvent.cxx:33
const CbmLink & GetLink(int32_t i) const
Definition CbmMatch.h:39
int32_t GetNofLinks() const
Definition CbmMatch.h:42
void AddLink(const CbmLink &newLink)
Definition CbmMatch.cxx:47
std::unique_ptr< cbm::algo::tof::Calibrate > fCalibrate
virtual void ExecEvent(Option_t *option)
bool RegisterOutputs()
Create and register output TClonesArray of Tof Hits.
std::vector< CbmTofDigi > fTofDigiVec
bool InitAlgos()
Create one algo object for each RPC.
const CbmTsEventHeader * fTsHeader
bool BuildClusters()
Build clusters out of ToF Digis and store the resulting info in a TofHit.
TClonesArray * fTofHitsCollOut
// Calibrated TOF Digis
TClonesArray * fTofHitsColl
// Calibrated TOF Digis
std::vector< CbmTofDigi > * fBmonDigiVec
bool RegisterInputs()
Recover pointer on input TClonesArray: TofPoints, TofDigis...
std::vector< CbmTofDigi > * fTofCalDigiVecOut
virtual void Exec(Option_t *option)
Inherited from FairTask.
virtual InitStatus Init()
Inherited from FairTask.
virtual void Finish()
Inherited from FairTask.
CbmDigiManager * fDigiMan
TOF Digis.
std::vector< CbmTofDigi > * fTofCalDigiVec
virtual ~CbmTaskTofClusterizer()
Destructor.
std::unique_ptr< cbm::algo::tof::Hitfind > fAlgo
Data class for expanded digital TOF information.
Definition CbmTofDigi.h:47
double GetSide() const
Channel Side.
Definition CbmTofDigi.h:160
double GetChannel() const
Channel .
Definition CbmTofDigi.h:156
int32_t GetAddress() const
Inherited from CbmDigi.
Definition CbmTofDigi.h:112
double GetSm() const
Sm.
Definition CbmTofDigi.h:144
double GetType() const
Sm Type .
Definition CbmTofDigi.h:148
double GetRpc() const
Detector aka Module aka RPC .
Definition CbmTofDigi.h:152
void SetAddress(int32_t address)
Definition CbmTofDigi.h:163
uint64_t GetTsStartTime() const
T ReadFromFile(fs::path path)
Definition Yaml.h:51