CbmRoot
Loading...
Searching...
No Matches
CbmFsdHitProducer.cxx
Go to the documentation of this file.
1/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Lukas Chlad [committer] */
4
5#include "CbmFsdHitProducer.h"
6
7#include "CbmDigiManager.h"
8#include "CbmEvent.h"
9#include "CbmFsdAddress.h"
10#include "CbmFsdDetectorSpecs.h"
11#include "CbmFsdDigi.h"
12#include "CbmFsdGeoHandler.h"
13#include "CbmFsdHit.h"
14
15#include <FairRootManager.h>
16#include <Logger.h>
17
18#include <TClonesArray.h>
19#include <TStopwatch.h>
20#include <TVector3.h>
21
22#include <fstream>
23#include <iomanip>
24#include <iostream>
25#include <map>
26#include <tuple>
27
28using std::cout;
29using std::endl;
30using std::fixed;
31using std::left;
32using std::pair;
33using std::right;
34using std::setprecision;
35using std::setw;
36using std::stringstream;
37
38
39// ----- Default constructor -------------------------------------------
40CbmFsdHitProducer::CbmFsdHitProducer() : FairTask("FsdHitProducer") {}
41// -------------------------------------------------------------------------
42
43
44// ----- Destructor ----------------------------------------------------
46{
47 if (fHitArray) {
48 fHitArray->Delete();
49 delete fHitArray;
50 }
51}
52// -------------------------------------------------------------------------
53
54
55// ----- Public method Init --------------------------------------------
57{
58 std::cout << std::endl << std::endl;
59 LOG(info) << "======= " << GetName() << ": Init =====================";
60
61 // --- Initialize the mapping between loaded Geometry and ModuleData
62 CbmFsdGeoHandler::GetInstance().InitMaps(); // singleton first instance initialization of geometry to maps
63
64 // --- Get RootManager
65 FairRootManager* ioman = FairRootManager::Instance();
66 if (!ioman) {
67 LOG(fatal) << "-W- CbmFsdHitProducer::Init: RootManager not instantised!"; //FLORIAN & SELIM
68 return kFATAL;
69 }
70
71 // --- Get event array, if present
72 fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("Event"));
73 if (fEvents)
74 LOG(info) << GetName() << ": found Event branch, run event-by-event";
75 else {
76 fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent"));
77 if (fEvents) LOG(info) << GetName() << ": found CbmEvent branch, run event-by-event";
78 }
79 if (!fEvents) {
80 LOG(info) << GetName() << ": no event branch found; run in time-based mode";
81 LOG(warn) << "*** Note that the current FSD hit producer is not suited for time-based reconstruction!";
82 LOG(warn) << "*** Unless you have run the simulation event-by-event, it will not produce sensible results.";
83 }
84
85 // --- Initialise digi manager
87 fDigiMan->Init();
89 LOG(error) << GetName() << ": No FsdDigi input array present; "
90 << "task will be inactive.";
91 return kERROR;
92 }
93 LOG(info) << GetName() << ": found FsdDigi branch";
94
95 // --- Create and register output array
96 fHitArray = new TClonesArray("CbmFsdHit", 1000);
97 ioman->Register("FsdHit", "FSD", fHitArray, IsOutputBranchPersistent("FsdHit"));
98 fHitArray->Dump();
99 LOG(info) << GetName() << ": registered branch FsdHit";
100 LOG(info) << GetName() << ": intialisation successfull";
101 LOG(info) << "======================================================\n";
102
103 return kSUCCESS;
104}
105// -------------------------------------------------------------------------
106
107
108// ----- Public method Exec --------------------------------------------
109void CbmFsdHitProducer::Exec(Option_t* /*opt*/)
110{
111
112 // --- Timer
113 TStopwatch timer;
114 timer.Start();
115
116 // --- Reset output array
117 Reset();
118
119 // --- Local variables
120 pair<Int_t, Int_t> result;
121 Int_t nEvents = 0;
122 Int_t nDigis = 0;
123 Int_t nHits = 0;
124 Int_t nDigisAll = fDigiMan->GetNofDigis(ECbmModuleId::kFsd);
125 CbmEvent* event = nullptr;
126
127 // --- Time-slice mode: process entire digi array
128 if (!fEvents) {
129 result = ProcessData(nullptr);
130 nDigis = result.first;
131 nHits = result.second;
132 }
133
134 // --- Event mode: loop over events and process digis within
135 else {
136 assert(fEvents);
137 nEvents = fEvents->GetEntriesFast();
138 for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) {
139 event = static_cast<CbmEvent*>(fEvents->At(iEvent));
140 result = ProcessData(event);
141 LOG(debug) << GetName() << ": Event " << iEvent << " / " << nEvents << ", digis " << result.first << ", hits "
142 << result.second;
143 nDigis += result.first;
144 nHits += result.second;
145 } //# events
146 } //? event mode
147
148 // --- Timeslice log and statistics
149 timer.Stop();
150 stringstream logOut;
151 logOut << setw(20) << left << GetName() << " [";
152 logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] ";
153 logOut << "TS " << fNofTs;
154 if (fEvents) logOut << ", events " << nEvents;
155 logOut << ", digis " << nDigis << " / " << nDigisAll;
156 logOut << ", hits " << nHits;
157 LOG(info) << logOut.str();
158 fNofTs++;
159 fNofEvents += nEvents;
160 fNofDigis += nDigis;
161 fNofHits += nHits;
162 fTimeTot += timer.RealTime();
163}
164// -------------------------------------------------------------------------
165
166
167// ----- End-of-timeslice action ---------------------------------------
169{
170
171 std::cout << std::endl;
172 LOG(info) << "=====================================";
173 LOG(info) << GetName() << ": Run summary";
174 LOG(info) << "Time slices : " << fNofTs;
175 LOG(info) << "Digis / TS : " << fixed << setprecision(2) << Double_t(fNofDigis) / Double_t(fNofTs);
176 LOG(info) << "Hits / TS : " << fixed << setprecision(2) << Double_t(fNofHits) / Double_t(fNofTs);
177 LOG(info) << "Time / TS : " << fixed << setprecision(2) << 1000. * fTimeTot / Double_t(fNofTs) << " ms";
178 if (fEvents) {
179 LOG(info) << "Events : " << fNofEvents;
180 LOG(info) << "Events / TS : " << fixed << setprecision(2) << Double_t(fNofEvents) / Double_t(fNofTs);
181 LOG(info) << "Digis / event : " << fixed << setprecision(2) << Double_t(fNofDigis) / Double_t(fNofEvents);
182 LOG(info) << "Hits / event : " << fixed << setprecision(2) << Double_t(fNofHits) / Double_t(fNofEvents);
183 }
184 LOG(info) << "=====================================\n";
185}
186// -------------------------------------------------------------------------
187
188
189// ----- Data processing -----------------------------------------------
190pair<Int_t, Int_t> CbmFsdHitProducer::ProcessData(CbmEvent* event)
191{
192
193 // --- Local variables
194 std::map<uint32_t, std::tuple<Double_t, Double_t, Int_t>>
195 edeptimemap; // sum of energy deposition, earliest time & digi index per address, key is digi address
196 Int_t nHits = 0;
197 const CbmFsdDigi* digi = nullptr;
198 Int_t nDigis = (event ? event->GetNofData(ECbmDataType::kFsdDigi) : fDigiMan->GetNofDigis(ECbmModuleId::kFsd));
199
200 // --- Loop over FsdDigis. Distribute energy deposition into the modules.
201 Int_t digiIndex = -1;
202 for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
203
204 digiIndex = (event ? event->GetIndex(ECbmDataType::kFsdDigi, iDigi) : iDigi);
205 digi = fDigiMan->Get<const CbmFsdDigi>(digiIndex);
206 assert(digi);
207
208 uint32_t address = digi->GetAddress(); // this contains more information than just module id
209 Double_t eDep = (Double_t) digi->GetEdep();
210 Double_t digiTime = (Double_t) digi->GetTime();
211 auto insert_result = edeptimemap.insert(std::make_pair(address, std::make_tuple(eDep, digiTime, digiIndex)));
212 if (!insert_result.second) { // entry was here before
213 std::get<0>((*insert_result.first).second) = eDep + std::get<0>((*insert_result.first).second);
214 if (digiTime < std::get<1>((*insert_result.first).second)) { // earlier digi => overwrite
215 std::get<1>((*insert_result.first).second) = digiTime;
216 std::get<2>((*insert_result.first).second) = digiIndex;
217 }
218 } // ? exist entry
219 } // # digis
220
221 // --- Create hits, one per activated module
222 UInt_t hitIndex = -1;
223 for (auto entry : edeptimemap) {
224 uint32_t address = entry.first;
225 Double_t sumEdep = std::get<0>(entry.second);
226 Double_t fastestDigiTime = std::get<1>(entry.second);
227 Int_t fastestDigiIndex = std::get<2>(entry.second);
229 CbmFsdAddress::GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::Module)));
230 if (!fsdModSpecs) {
231 LOG(warning) << "FSD module data for address: " << address << " (unitId: "
232 << CbmFsdAddress::GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::Unit))
233 << " ,moduleId: "
234 << CbmFsdAddress::GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::Module))
235 << " ) could not be found! => skip";
236 continue;
237 }
238 TVector3 moduleCenter;
239 moduleCenter.SetXYZ(fsdModSpecs->fX, fsdModSpecs->fY, fsdModSpecs->fZ);
240 TVector3 moduleDimensions;
241 moduleDimensions.SetXYZ(fsdModSpecs->dX, fsdModSpecs->dY, fsdModSpecs->dZ);
242
243 hitIndex = fHitArray->GetEntriesFast();
244 new ((*fHitArray)[hitIndex]) CbmFsdHit(static_cast<int32_t>(address), moduleCenter, moduleDimensions,
245 static_cast<int32_t>(fastestDigiIndex), fastestDigiTime, sumEdep);
246 if (event) event->AddData(ECbmDataType::kFsdHit, hitIndex);
247 nHits++;
248 }
249
250 return std::make_pair(nDigis, nHits);
251}
252// -------------------------------------------------------------------------
253
254
255// ----- Reset: clear output array -------------------------------------
257{
258 if (fHitArray) fHitArray->Delete();
259}
260// -------------------------------------------------------------------------
261
262
ClassImp(CbmConverterManager)
@ kFsd
Forward spectator detector.
Hit Producer for FSD.
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
Data class for FSD digital information.
Definition CbmFsdDigi.h:36
double GetTime() const
Time.
Definition CbmFsdDigi.h:92
uint32_t GetAddress() const
Address.
Definition CbmFsdDigi.h:80
double GetEdep() const
Energy deposit.
Definition CbmFsdDigi.h:106
static CbmFsdGeoHandler & GetInstance()
CbmFsdModuleSpecs * GetModuleSpecsById(Int_t id)
CbmDigiManager * fDigiMan
virtual InitStatus Init()
Virtual method Init.
TClonesArray * fHitArray
TClonesArray * fEvents
CbmFsdHitProducer()
Default constructor.
virtual void Exec(Option_t *opt)
Virtual method Exec.
virtual void Finish()
Virtual method Finish.
std::pair< Int_t, Int_t > ProcessData(CbmEvent *event)
~CbmFsdHitProducer()
Destructor.
uint32_t GetElementId(int32_t address, int32_t level)
Get the index of an element.