CbmRoot
Loading...
Searching...
No Matches
CbmTofBuildDigiEvents.cxx
Go to the documentation of this file.
1/* Copyright (C) 2018-2020 Physikalisches Institut, Universitaet Heidelberg, Heidelberg
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Christian Simon [committer] */
4
12
13#include "CbmMCEventList.h"
14#include "CbmMatch.h"
15#include "CbmTimeSlice.h"
16#include "CbmTofDigi.h"
17//#include "CbmTofDef.h" TODO
18
19#include "FairFileSource.h"
20#include "FairRootManager.h"
21#include "TClonesArray.h"
22#include "TMath.h"
23
24#include <Logger.h>
25
26#include <algorithm>
27
28
29// ---------------------------------------------------------------------------
31 : FairTask("TofBuildDigiEvents")
32 , fFileSource(NULL)
33 , fTimeSliceHeader(NULL)
34 , fTofTimeSliceDigis(NULL)
35 , fDigiMatches(nullptr)
36 , fInputMCEventList(NULL)
37 , fOutputMCEventList(NULL)
38 , fTofEventDigis(NULL)
39 , fdEventWindow(0.)
40 , fNominalTriggerCounterMultiplicity()
41 , fiTriggerMultiplicity(0)
42 , fbPreserveMCBacklinks(kFALSE)
43 , fbMCEventBuilding(kFALSE)
44 , fdEventStartTime(DBL_MIN)
45 , fCounterMultiplicity()
46 , fdIdealEventWindow(1000.)
47 , fProcessedIdealEvents()
48 , fIdealEventStartTimes()
49 , fIdealEventDigis()
50 , fiNEvents(0)
51 , fdDigiToTOffset(0.)
52 , fInactiveCounterSides()
53{
54}
55// ---------------------------------------------------------------------------
56
57
58// ---------------------------------------------------------------------------
60// ---------------------------------------------------------------------------
61
62
63// ---------------------------------------------------------------------------
65{
68
69 for (Int_t iDigi = 0; iDigi < fTofTimeSliceDigis->GetEntriesFast(); iDigi++) {
70 CbmTofDigi* tDigi = dynamic_cast<CbmTofDigi*>(fTofTimeSliceDigis->At(iDigi));
71 CbmMatch* match = dynamic_cast<CbmMatch*>(fDigiMatches->At(iDigi));
72 assert(match);
73
74 Int_t iDigiAddress = tDigi->GetAddress();
75 Double_t dDigiTime = tDigi->GetTime();
76 Double_t dDigiToT = tDigi->GetTot();
77
78
79 Int_t iNMCLinks = match->GetNofLinks();
80
81 for (Int_t iLink = 0; iLink < iNMCLinks; iLink++) {
82 const CbmLink& tLink = match->GetLink(iLink);
83
84 // Only consider digis that contain at least one contribution from a
85 // primary source signal. If the digi contains primary signal contributions
86 // from more than one MC event, assign the digi to all MC events found.
87 // TODO: Replace '0' by 'tof::signal_SourcePrimary' upon inclusion of
88 // 'tof/TofTools/CbmTofDef.h' into trunk!
89 if (0 == tLink.GetUniqueID()) {
90 std::pair<Int_t, Int_t> EventID(tLink.GetFile(), tLink.GetEntry());
91
92 // The MC event is already known.
93 if (fIdealEventStartTimes.find(EventID) != fIdealEventStartTimes.end()) {
94 auto& DigiVector = fIdealEventDigis.at(EventID);
95
97 // deep copy construction including 'CbmDigi::fMatch'
98 DigiVector.push_back(new CbmTofDigi(*tDigi));
99 }
100 else {
101 // shallow construction excluding 'CbmDigi::fMatch'
102 DigiVector.push_back(new CbmTofDigi(iDigiAddress, dDigiTime, dDigiToT));
103 }
104 }
105 // The MC event is not known yet.
106 else {
107 // Make sure that a late digi from an event that has already been
108 // processed and written to disk (i.e. the time difference to the
109 // earliest digi in the same event is larger than 'fdIdealEventWindow')
110 // does not trigger separate event processing for itself only
111 // (and possibly a few additional latecomers).
112 if (fProcessedIdealEvents.find(EventID) == fProcessedIdealEvents.end()) {
113 fIdealEventStartTimes.emplace(EventID, dDigiTime);
114 fIdealEventDigis.emplace(EventID, std::vector<CbmTofDigi*>());
115
116 auto& DigiVector = fIdealEventDigis.at(EventID);
117
119 // deep copy construction including 'CbmDigi::fMatch'
120 DigiVector.push_back(new CbmTofDigi(*tDigi));
121 }
122 else {
123 // shallow construction excluding 'CbmDigi::fMatch'
124 DigiVector.push_back(new CbmTofDigi(iDigiAddress, dDigiTime, dDigiToT));
125 }
126 }
127 }
128 }
129 }
130 }
131 }
132 else {
133 for (Int_t iDigi = 0; iDigi < fTofTimeSliceDigis->GetEntriesFast(); iDigi++) {
134 CbmTofDigi* tDigi = dynamic_cast<CbmTofDigi*>(fTofTimeSliceDigis->At(iDigi));
135
136 Int_t iDigiModuleType = tDigi->GetType();
137 Int_t iDigiModuleIndex = tDigi->GetSm();
138 Int_t iDigiCounterIndex = tDigi->GetRpc();
139 Int_t iDigiCounterSide = tDigi->GetSide();
140 Int_t iDigiAddress = tDigi->GetAddress();
141 Double_t dDigiTime = tDigi->GetTime();
142 Double_t dDigiToT = tDigi->GetTot();
143
144
145 if (dDigiTime - fdEventStartTime > fdEventWindow) {
146 std::map<std::tuple<Int_t, Int_t, Int_t>, UChar_t> ActualTriggerCounterMultiplicity;
147
148 std::set_intersection(
151 std::inserter(ActualTriggerCounterMultiplicity, ActualTriggerCounterMultiplicity.begin()));
152
153 if (ActualTriggerCounterMultiplicity.size() >= static_cast<size_t>(fiTriggerMultiplicity)) {
156 }
157
158 FairRootManager::Instance()->Fill();
159 fiNEvents++;
161 fTofEventDigis->Delete();
162 }
163 else {
164 fTofEventDigis->Delete();
165 }
166
167 fCounterMultiplicity.clear();
168
169 fdEventStartTime = dDigiTime;
170 }
171
172
173 fCounterMultiplicity[std::make_tuple(iDigiModuleType, iDigiModuleIndex, iDigiCounterIndex)] |=
174 1 << iDigiCounterSide;
175
176 auto CounterSideTuple = std::make_tuple(iDigiModuleType, iDigiModuleIndex, iDigiCounterIndex, iDigiCounterSide);
177
178 if (fInactiveCounterSides.find(CounterSideTuple) == fInactiveCounterSides.end()) {
179 CbmTofDigi* tEventDigi(NULL);
180
182 // deep copy construction including 'CbmDigi::fMatch'
183 tEventDigi = new ((*fTofEventDigis)[fTofEventDigis->GetEntriesFast()]) CbmTofDigi(*tDigi);
184 }
185 else {
186 // shallow construction excluding 'CbmDigi::fMatch'
187 tEventDigi =
188 new ((*fTofEventDigis)[fTofEventDigis->GetEntriesFast()]) CbmTofDigi(iDigiAddress, dDigiTime, dDigiToT);
189 }
190
191 tEventDigi->SetTot(tEventDigi->GetTot() + fdDigiToTOffset);
192 }
193 }
194 }
195}
196// ---------------------------------------------------------------------------
197
198
199// ---------------------------------------------------------------------------
201{
202 if (!FairRootManager::Instance()) {
203 LOG(error) << "FairRootManager not found.";
204 return kFATAL;
205 }
206
207 fFileSource = dynamic_cast<FairFileSource*>(FairRootManager::Instance()->GetSource());
208 if (!fFileSource) {
209 LOG(error) << "Could not get pointer to FairFileSource.";
210 return kFATAL;
211 }
212
213 fTimeSliceHeader = dynamic_cast<CbmTimeSlice*>(FairRootManager::Instance()->GetObject("TimeSlice."));
214 if (!fTimeSliceHeader) {
215 LOG(error) << "Could not retrieve branch 'TimeSlice.' from FairRootManager.";
216 return kFATAL;
217 }
218
219 fTofTimeSliceDigis = dynamic_cast<TClonesArray*>(FairRootManager::Instance()->GetObject("TofDigiExp"));
220 if (!fTofTimeSliceDigis) {
221 LOG(error) << "Could not retrieve branch 'TofDigiExp' from FairRootManager.";
222 return kFATAL;
223 }
224
225 fDigiMatches = dynamic_cast<TClonesArray*>(FairRootManager::Instance()->GetObject("TofDigiMatch"));
226 if (!fDigiMatches) {
227 LOG(error) << "Could not retrieve branch 'TofDigiMatch' from FairRootManager.";
228 return kFATAL;
229 }
230
231 fInputMCEventList = dynamic_cast<CbmMCEventList*>(FairRootManager::Instance()->GetObject("MCEventList."));
232 if (!fInputMCEventList) {
233 LOG(error) << "Could not retrieve branch 'MCEventList.' from FairRootManager.";
234 return kFATAL;
235 }
236
237 if (FairRootManager::Instance()->GetObject("TofPointTB")) {
238 LOG(error) << "Timeslice branch with MC points found. Event building would "
239 "not work properly.";
240 return kFATAL;
241 }
242
243
245 FairRootManager::Instance()->Register("EventList.", "EventList", fOutputMCEventList,
246 IsOutputBranchPersistent("EventList."));
247
248 fTofEventDigis = new TClonesArray("CbmTofDigi", 100);
249 FairRootManager::Instance()->Register("CbmTofDigi", "TOF event digis", fTofEventDigis,
250 IsOutputBranchPersistent("CbmTofDigi"));
251
252
253 if (0. >= fdEventWindow) {
254 fbMCEventBuilding = kTRUE;
255 }
256
258
259 if (fNominalTriggerCounterMultiplicity.size() < static_cast<size_t>(fiTriggerMultiplicity)) {
261 }
262
263 return kSUCCESS;
264}
265// ---------------------------------------------------------------------------
266
267
268// ---------------------------------------------------------------------------
270{
271 if (fbMCEventBuilding) {
272 // With O(s) of off-spill noise (not eligible for MC event building) stored
273 // in several timeslices (the processing of each causing an 'Exec' call by
274 // the framework) following the final spill there should not be any digis
275 // related to MC events left for processing at this point.
276 ProcessIdealEvents(DBL_MAX);
277 }
278 else {
279 // The remaining digis in the buffer do not cover a time interval of
280 // 'fdEventWindow' and, in consequence, do not qualify for event building.
281 fTofEventDigis->Delete();
282 fCounterMultiplicity.clear();
283 }
284}
285// ---------------------------------------------------------------------------
286
287
288// ---------------------------------------------------------------------------
289void CbmTofBuildDigiEvents::SetTriggerCounter(Int_t iModuleType, Int_t iModuleIndex, Int_t iCounterIndex,
290 Int_t iNCounterSides)
291{
292 fNominalTriggerCounterMultiplicity.emplace(std::make_tuple(iModuleType, iModuleIndex, iCounterIndex),
293 (1 == iNCounterSides) ? 1 : 3);
294}
295// ---------------------------------------------------------------------------
296
297
298// ---------------------------------------------------------------------------
299void CbmTofBuildDigiEvents::ProcessIdealEvents(Double_t dProcessingTime)
300{
301 for (auto itEvent = fIdealEventStartTimes.cbegin(); itEvent != fIdealEventStartTimes.cend();) {
302 auto EventID = itEvent->first;
303 Double_t dEventStartTime = itEvent->second;
304
305 if (dProcessingTime - dEventStartTime > fdIdealEventWindow) {
306 for (auto& tDigi : fIdealEventDigis.at(EventID)) {
307 Int_t iDigiModuleType = tDigi->GetType();
308 Int_t iDigiModuleIndex = tDigi->GetSm();
309 Int_t iDigiCounterIndex = tDigi->GetRpc();
310 Int_t iDigiCounterSide = tDigi->GetSide();
311
312 fCounterMultiplicity[std::make_tuple(iDigiModuleType, iDigiModuleIndex, iDigiCounterIndex)] |=
313 1 << iDigiCounterSide;
314
315 auto CounterSideTuple = std::make_tuple(iDigiModuleType, iDigiModuleIndex, iDigiCounterIndex, iDigiCounterSide);
316
317 if (fInactiveCounterSides.find(CounterSideTuple) == fInactiveCounterSides.end()) {
318 // deep copy construction including 'CbmDigi::fMatch' (only if already deep-copied in 'Exec')
319 CbmTofDigi* tEventDigi = new ((*fTofEventDigis)[fTofEventDigis->GetEntriesFast()]) CbmTofDigi(*tDigi);
320 tEventDigi->SetTot(tEventDigi->GetTot() + fdDigiToTOffset);
321 }
322
323 delete tDigi;
324 }
325
326 std::map<std::tuple<Int_t, Int_t, Int_t>, UChar_t> ActualTriggerCounterMultiplicity;
327
328 std::set_intersection(fCounterMultiplicity.begin(), fCounterMultiplicity.end(),
330 std::inserter(ActualTriggerCounterMultiplicity, ActualTriggerCounterMultiplicity.begin()));
331
332 if (ActualTriggerCounterMultiplicity.size() >= static_cast<size_t>(fiTriggerMultiplicity)) {
335 }
336
337 FairRootManager::Instance()->Fill();
338 fiNEvents++;
340 fTofEventDigis->Delete();
341 }
342 else {
343 fTofEventDigis->Delete();
344 }
345
346 fCounterMultiplicity.clear();
347 fIdealEventDigis.erase(EventID);
348 fProcessedIdealEvents.emplace(EventID);
349
350 itEvent = fIdealEventStartTimes.erase(itEvent);
351 }
352 else {
353 ++itEvent;
354 }
355 }
356}
357// ---------------------------------------------------------------------------
358
359
360// ---------------------------------------------------------------------------
362{
363 std::set<std::pair<Int_t, Int_t>> MCEventSet;
364
365 for (Int_t iDigi = 0; iDigi < fTofEventDigis->GetEntriesFast(); iDigi++) {
366 //CbmTofDigi* tDigi = dynamic_cast<CbmTofDigi*>(fTofEventDigis->At(iDigi)); (VF) not used
367 CbmMatch* match = dynamic_cast<CbmMatch*>(fDigiMatches->At(iDigi));
368 Int_t iNMCLinks = match->GetNofLinks();
369
370 for (Int_t iLink = 0; iLink < iNMCLinks; iLink++) {
371 const CbmLink& tLink = match->GetLink(iLink);
372
373 Int_t iFileIndex = tLink.GetFile();
374 Int_t iEventIndex = tLink.GetEntry();
375
376 // Collect original MC event affiliations of digis attributed to
377 // the current reconstructed event.
378 if (-1 < iFileIndex && -1 < iEventIndex) {
379 MCEventSet.emplace(iFileIndex, iEventIndex);
380 }
381 }
382 }
383
384 // Read the respective start times of the original MC events contributing to
385 // the reconstructed event from the input MC event list and make them
386 // available in the output MC event list.
387 for (auto const& MCEvent : MCEventSet) {
388 Int_t iFileIndex = MCEvent.first;
389 Int_t iEventIndex = MCEvent.second;
390
391 Double_t dStartTime = fInputMCEventList->GetEventTime(iEventIndex, iFileIndex);
392
393 if (-1. != dStartTime) {
394 fOutputMCEventList->Insert(iEventIndex, iFileIndex, dStartTime);
395 }
396 else {
397 LOG(fatal) << Form("Could not find MC event (%d, %d) in the input MC event list.", iFileIndex, iEventIndex);
398 }
399 }
400
402}
403// ---------------------------------------------------------------------------
404
405
406// ---------------------------------------------------------------------------
407void CbmTofBuildDigiEvents::SetIgnoreCounterSide(Int_t iModuleType, Int_t iModuleIndex, Int_t iCounterIndex,
408 Int_t iCounterSide)
409{
410 fInactiveCounterSides.emplace(std::make_tuple(iModuleType, iModuleIndex, iCounterIndex, iCounterSide));
411}
412// ---------------------------------------------------------------------------
413
414
ClassImp(CbmConverterManager)
Container class for MC events with number, file and start time.
void Sort()
Sort the list.
virtual void Clear(Option_t *)
Delete all event entries.
double GetEventTime(uint32_t event, uint32_t file)
Event start time.
bool Insert(uint32_t event, uint32_t file, double time)
const CbmLink & GetLink(int32_t i) const
Definition CbmMatch.h:39
int32_t GetNofLinks() const
Definition CbmMatch.h:42
Bookkeeping of time-slice content.
double GetStartTime() const
std::map< std::pair< Int_t, Int_t >, std::vector< CbmTofDigi * > > fIdealEventDigis
std::map< std::tuple< Int_t, Int_t, Int_t >, UChar_t > fCounterMultiplicity
std::set< std::tuple< Int_t, Int_t, Int_t, Int_t > > fInactiveCounterSides
void ProcessIdealEvents(Double_t dProcessingTime)
std::set< std::pair< Int_t, Int_t > > fProcessedIdealEvents
void SetTriggerCounter(Int_t iModuleType, Int_t iModuleIndex, Int_t iCounterIndex, Int_t iNCounterSides)
std::map< std::tuple< Int_t, Int_t, Int_t >, UChar_t > fNominalTriggerCounterMultiplicity
void SetIgnoreCounterSide(Int_t iModuleType, Int_t iModuleIndex, Int_t iCounterIndex, Int_t iCounterSide)
std::map< std::pair< Int_t, Int_t >, Double_t > fIdealEventStartTimes
virtual void Exec(Option_t *option)
CbmMCEventList * fInputMCEventList
CbmMCEventList * fOutputMCEventList
Data class for expanded digital TOF information.
Definition CbmTofDigi.h:47
double GetSide() const
Channel Side.
Definition CbmTofDigi.h:160
void SetTot(double tot)
Definition CbmTofDigi.h:166
int32_t GetAddress() const
Inherited from CbmDigi.
Definition CbmTofDigi.h:112
double GetSm() const
Sm.
Definition CbmTofDigi.h:144
double GetTime() const
Inherited from CbmDigi.
Definition CbmTofDigi.h:131
double GetType() const
Sm Type .
Definition CbmTofDigi.h:148
double GetRpc() const
Detector aka Module aka RPC .
Definition CbmTofDigi.h:152
double GetTot() const
Alias for GetCharge.
Definition CbmTofDigi.h:140