CbmRoot
Loading...
Searching...
No Matches
CbmBuildEventsIdeal.cxx
Go to the documentation of this file.
1/* Copyright (C) 2016-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese [committer] */
4
10#include "CbmBuildEventsIdeal.h"
11
12#include "CbmDigiManager.h"
13#include "CbmEvent.h"
14#include "CbmLink.h"
15#include "CbmMCEventList.h"
16#include "CbmModuleList.h"
17#include "CbmTimeSlice.h"
18
19#include <FairRootManager.h>
20#include <Logger.h>
21
22#include <TClonesArray.h>
23#include <TStopwatch.h>
24
25#include <cassert>
26#include <iomanip>
27#include <iostream>
28
29using namespace std;
30
31
32// ===== Constructor =====================================================
33CbmBuildEventsIdeal::CbmBuildEventsIdeal() : FairTask("BuildEventsIdeal") {}
34// ===========================================================================
35
36
37// ===== Destructor ======================================================
39// ===========================================================================
40
41
42// ===== Number if different pairs (input,event) in a match object =======
44{
45 // --- Collect links from different events
46
47 CbmMatch eventMatch;
48 int32_t nLinks = (match != nullptr) ? match->GetNofLinks() : 0;
49
50 for (int32_t iLink = 0; iLink < nLinks; iLink++) {
51 int32_t mcInput = match->GetLink(iLink).GetFile();
52 int32_t mcEvent = match->GetLink(iLink).GetEntry();
53 if (mcInput < 0 || mcEvent < 0) {
54 continue;
55 }
56 eventMatch.AddLink(1., 0, mcEvent, mcInput);
57 }
58 return eventMatch;
59}
60// ===========================================================================
61
62
63// ===== Task execution ==================================================
65{
66
67 // --- Timer and counters
68 TStopwatch timer;
69 timer.Start();
70 uint64_t nDigisTot = 0; // Total number of digis
71 uint64_t nDigisNoise = 0; // Digis without link to MC event
72 uint64_t nDigisAmbig = 0; // Digis with links to multiple MC events
73
74 // --- Clear output array
75 fEvents->Delete();
76 fDigiEvents->clear();
77
78 // --- Timeslice start time
79 double tsStart = fTimeslice->GetStartTime();
80
81 // --- Bookkeeping: Map from (input number, event number) to event
82 map<pair<int32_t, int32_t>, CbmEvent> eventMap;
83 map<pair<int32_t, int32_t>, CbmDigiEvent> digiEventMap;
84
85 // --- Loop over all detector systems
86 for (ECbmModuleId& system : fSystems) {
87
88 // --- Skip system if no data branch or no match match present
89 if (!fDigiMan->IsPresent(system)) continue;
90 if (!fDigiMan->IsMatchPresent(system)) continue;
91
92 // --- Find the digi type
94 switch (system) {
95 case ECbmModuleId::kMvd: digiType = ECbmDataType::kMvdDigi; break;
96 case ECbmModuleId::kSts: digiType = ECbmDataType::kStsDigi; break;
97 case ECbmModuleId::kRich: digiType = ECbmDataType::kRichDigi; break;
98 case ECbmModuleId::kMuch: digiType = ECbmDataType::kMuchDigi; break;
99 case ECbmModuleId::kTrd: digiType = ECbmDataType::kTrdDigi; break;
100 case ECbmModuleId::kTof: digiType = ECbmDataType::kTofDigi; break;
101 case ECbmModuleId::kPsd: digiType = ECbmDataType::kPsdDigi; break;
102 case ECbmModuleId::kFsd: digiType = ECbmDataType::kFsdDigi; break;
103 case ECbmModuleId::kBmon: digiType = ECbmDataType::kBmonDigi; break;
104 default: break;
105 } //? detector
106
107 if (digiType == ECbmDataType::kUnknown) {
108 LOG(fatal) << "unknown type of the module";
109 assert(0);
110 continue;
111 }
112
113 // --- Loop over digis for the current system
114 int64_t nDigis = fDigiMan->GetNofDigis(system);
115 uint64_t nNoise = 0;
116 uint64_t nAmbig = 0;
117 for (int32_t iDigi = 0; iDigi < nDigis; iDigi++) {
118
119 // --- Get the MC input and event numbers through the match object
120 CbmMatch matchedEvents = EventsInMatch(fDigiMan->GetMatch(system, iDigi));
121
122 for (int32_t iLink = 0; iLink < matchedEvents.GetNofLinks(); iLink++) {
123 const auto& link = matchedEvents.GetLink(iLink);
124 auto eventID = make_pair(link.GetFile(), link.GetEntry());
125
126 // --- Get event. If not yet present, create it. Add digi to event.
127 auto eventIt = eventMap.find(eventID);
128 if (eventIt == eventMap.end()) {
129 auto result = eventMap.insert(make_pair(eventID, CbmEvent()));
130 assert(result.second);
131 eventIt = result.first;
132 }
133 eventIt->second.AddData(digiType, iDigi);
134
135 // --- Get digiEvent. If not yet present, create it. Add digi to event.
136 auto digiEventIt = digiEventMap.find(eventID);
137 if (digiEventIt == digiEventMap.end()) {
138 auto result = digiEventMap.insert(make_pair(eventID, CbmDigiEvent()));
139 assert(result.second);
140 digiEventIt = result.first;
141 }
142 // TODO: Restricted to STS for the moment, until CbmDigiEvent is expanded to all
143 // detector systems (digi types)
144 if (system == ECbmModuleId::kSts) {
145 digiEventIt->second.fData.fSts.fDigis.push_back(*(fDigiMan->Get<CbmStsDigi>(iDigi)));
146 }
147
148 } //# links
149
150 // --- Empty match objects or negative event numbers signal noise
151 if (matchedEvents.GetNofLinks() == 0) {
152 nNoise++;
153 }
154
155 // --- Count occurrences of multiple MC events in match
156 if (matchedEvents.GetNofLinks() > 1) {
157 nAmbig++;
158 }
159
160 } //# digis
161
162 LOG(debug) << GetName() << ": Detector " << CbmModuleList::GetModuleNameCaps(system) << ", digis " << nDigis << " ("
163 << nAmbig << " ambiguous), noise " << nNoise;
164 nDigisTot += nDigis;
165 nDigisAmbig += nAmbig;
166 nDigisNoise += nNoise;
167
168 } //# detector systems
169
170 // --- Move CbmEvent objects from map (already ordered) to output branch
171 int32_t nEvents = 0;
172 for (auto& kv : eventMap) {
173
174 // TODO: Retrieving the MC event time from MCEventList currently does not work in case
175 // of multiple MC sources and/or repeat mode.
176 // Until this is fixed, the event time is set to the timeslice start time.
177 /*
178 double eventTime = fMCEvents->GetEventTime(kv.first.second, kv.first.first);
179 if (eventTime < 0.) {
180 LOG(info) << fMCEvents->ToString("long");
181 LOG(fatal) << GetName() << ": MC event " << kv.first.second << " from source " << kv.first.first
182 << " not found in MCEventList!";
183 continue;
184 }
185 eventTime -= tsStart;
186 */
187
188 double eventTime = tsStart;
189 assert(nEvents == fEvents->GetEntriesFast());
190 CbmEvent* store = new ((*fEvents)[nEvents]) CbmEvent();
191 store->Swap(kv.second);
192 store->SetStartTime(eventTime);
193 store->SetEndTime(eventTime);
194 store->SetNumber(nEvents++);
195 }
196
197 // --- Move CbmDigiEvent objects from map (already ordered) to output branch
198 uint64_t evNum = 0;
199 for (auto& kv : digiEventMap) {
200
201 // TODO: Retrieving the MC event time from MCEventList currently does not work in case
202 // of multiple MC sources and/or repeat mode.
203 // Until this is fixed, the event time is set to the timeslice start time.
204 /*
205 double eventTime = fMCEvents->GetEventTime(kv.first.second, kv.first.first);
206 if (eventTime < 0.) {
207 LOG(info) << fMCEvents->ToString("long");
208 LOG(fatal) << GetName() << ": MC event " << kv.first.second << " from source " << kv.first.first
209 << " not found in MCEventList!";
210 continue;
211 }
212 eventTime -= tsStart;
213 */
214
215 double eventTime = tsStart;
216 kv.second.fTime = eventTime;
217 kv.second.fNumber = evNum++;
218 fDigiEvents->push_back(std::move(kv.second));
219 }
220
221 // --- Timeslice log and statistics
222 timer.Stop();
223 stringstream logOut;
224 logOut << setw(20) << left << GetName() << " [";
225 logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] ";
226 logOut << "TS " << fNumEntries;
227 if (fEvents) logOut << ", events " << nEvents;
228 logOut << ", digis " << nDigisTot << " (" << nDigisAmbig << " ambiguous), noise: " << nDigisNoise;
229 LOG(info) << logOut.str();
230 fNumEntries++;
231 fNumEvents += nEvents;
232 fNumDigisTotal += nDigisTot;
233 fNumDigisAmbig += nDigisAmbig;
234 fNumDigisNoise += nDigisNoise;
235 fTime += timer.RealTime();
236
237 // --- For debug: event info
238 if (fair::Logger::Logging(fair::Severity::debug)) {
239 for (int32_t iEvent = 0; iEvent < fEvents->GetEntriesFast(); iEvent++) {
240 CbmEvent* event = (CbmEvent*) fEvents->At(iEvent);
241 LOG(info) << event->ToString();
242 }
243 }
244}
245// ===========================================================================
246
247
248// ===== End-of-timeslice action =========================================
250{
251
252 std::cout << std::endl;
253 LOG(info) << "=====================================";
254 LOG(info) << GetName() << ": Run summary";
255 LOG(info) << "Time slices : " << fNumEntries;
256 LOG(info) << "All digis / TS : " << fixed << setprecision(2) << double(fNumDigisTotal) / double(fNumEntries);
257 LOG(info) << "Ambiguous digis / TS : " << fixed << setprecision(2) << double(fNumDigisAmbig) / double(fNumEntries)
258 << " = " << 100. * double(fNumDigisAmbig) / double(fNumDigisTotal) << " %";
259 LOG(info) << "Noise digis / TS : " << fixed << setprecision(2) << double(fNumDigisNoise) / double(fNumEntries)
260 << " = " << 100. * double(fNumDigisNoise) / double(fNumDigisTotal) << " %";
261 LOG(info) << "Events : " << fNumEvents;
262 LOG(info) << "Time / TS : " << fixed << setprecision(2) << 1000. * fTime / double(fNumEntries) << " ms";
263 LOG(info) << "=====================================";
264}
265// -------------------------------------------------------------------------
266
267
268// ===== Task initialisation =============================================
270{
271
272 // --- Get FairRootManager instance
273 FairRootManager* ioman = FairRootManager::Instance();
274 assert(ioman);
275
276 // --- DigiManager instance
278 fDigiMan->Init();
279
280 std::cout << std::endl;
281 LOG(info) << "==================================================";
282 LOG(info) << GetName() << ": Initialising...";
283
284
285 // --- Check input digis
286 for (ECbmModuleId system = ECbmModuleId::kMvd; system < ECbmModuleId::kNofSystems; ++system) {
287 if (fDigiMan->IsMatchPresent(system)) {
288 LOG(info) << GetName() << ": Found match branch for " << CbmModuleList::GetModuleNameCaps(system);
289 fSystems.push_back(system);
290 }
291 }
292 if (fSystems.empty()) {
293 LOG(fatal) << GetName() << ": No match branch found!";
294 return kFATAL;
295 }
296
297 // --- Time slice meta-data (input)
298 fTimeslice = dynamic_cast<CbmTimeSlice*>(ioman->GetObject("TimeSlice."));
299 if (fTimeslice == nullptr) {
300 LOG(warn) << GetName() << ": No TimeSlice branch found!";
301 return kFATAL;
302 }
303
304 // --- MC event list (input)
305 fMCEvents = dynamic_cast<CbmMCEventList*>(ioman->GetObject("MCEventList."));
306 if (fMCEvents == nullptr) {
307 LOG(warn) << GetName() << ": No MCEventList branch found!";
308 return kFATAL;
309 }
310
311 // --- Register output array (CbmEvent)
312 // TODO: This shall be removed once reconstruction from DigiEvent is established.
313 if (ioman->GetObject("CbmEvent")) {
314 LOG(fatal) << GetName() << ": Branch CbmEvent already exists!";
315 return kFATAL;
316 }
317 fEvents = new TClonesArray("CbmEvent", 100);
318 ioman->Register("CbmEvent", "Cbm_Event", fEvents, IsOutputBranchPersistent("CbmEvent"));
319 if (!fEvents) {
320 LOG(fatal) << GetName() << ": Output branch could not be created!";
321 return kFATAL;
322 }
323
324 // --- Register output array (CbmDigiEvent)
325 if (ioman->GetObject("DigiEvent")) {
326 LOG(fatal) << GetName() << ": Branch DigiEvent already exists!";
327 return kFATAL;
328 }
329 fDigiEvents = new std::vector<CbmDigiEvent>;
330 ioman->RegisterAny("DigiEvent", fDigiEvents, IsOutputBranchPersistent("DigiEvent"));
331 if (!fDigiEvents) {
332 LOG(fatal) << GetName() << ": Output branch could not be created!";
333 return kFATAL;
334 }
335
336
337 LOG(info) << "==================================================";
338 std::cout << std::endl;
339
340 return kSUCCESS;
341}
342// ===========================================================================
343
344
ClassImp(CbmConverterManager)
ECbmDataType
Definition CbmDefs.h:90
ECbmModuleId
Definition CbmDefs.h:39
@ kMvd
Micro-Vertex Detector.
@ kTrd
Transition Radiation Detector.
@ kTof
Time-of-flight Detector.
@ kPsd
Projectile spectator detector.
@ kSts
Silicon Tracking System.
@ kMuch
Muon detection system.
@ kFsd
Forward spectator detector.
@ kNofSystems
For loops over active systems.
@ kRich
Ring-Imaging Cherenkov Detector.
CbmMatch EventsInMatch(const CbmMatch *match)
Number of different MC events in a match object.
CbmBuildEventsIdeal()
Constructor.
virtual void Finish()
Finish timeslice.
CbmDigiManager * fDigiMan
virtual InitStatus Init()
Task initialisation.
virtual void Exec(Option_t *opt)
Task execution.
CbmTimeSlice * fTimeslice
Input (digis)
virtual ~CbmBuildEventsIdeal()
Destructor.
CbmMCEventList * fMCEvents
Input (timeslice meta-data)
std::vector< CbmDigiEvent > * fDigiEvents
Output (CbmEvent)
std::vector< ECbmModuleId > fSystems
Collection of digis from all detector systems within one event.
static Int_t GetNofDigis(ECbmModuleId systemId)
static Bool_t IsPresent(ECbmModuleId systemId)
Presence of a digi branch.
static Bool_t IsMatchPresent(ECbmModuleId systemId)
Presence of a digi match branch.
InitStatus Init()
Initialisation.
const Digi * Get(Int_t index) const
Get a digi object.
static CbmDigiManager * Instance()
Static instance.
const CbmMatch * GetMatch(ECbmModuleId systemId, UInt_t index) const
Get a match object.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
void SetNumber(int32_t number)
Definition CbmEvent.h:152
void Swap(CbmEvent &e)
Definition CbmEvent.cxx:84
void SetStartTime(double startTime)
Definition CbmEvent.h:169
void SetEndTime(double endTime)
Definition CbmEvent.h:157
std::string ToString() const
Definition CbmEvent.cxx:96
Container class for MC events with number, file and start time.
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
static TString GetModuleNameCaps(ECbmModuleId moduleId)
Data class for a single-channel message in the STS.
Definition CbmStsDigi.h:40
Bookkeeping of time-slice content.
double GetStartTime() const
Hash for CbmL1LinkKey.