CbmRoot
Loading...
Searching...
No Matches
CbmTaskUnpack.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese [committer] */
4
5
6#include "CbmTaskUnpack.h"
7
8#include "CbmDefs.h"
9#include "CbmDigiBranchBase.h"
10#include "CbmDigiEvent.h"
11#include "CbmDigiManager.h"
12#include "CbmDigiTimeslice.h"
13#include "CbmSourceTs.h"
14#include "CbmTimeSlice.h"
15#include "CbmTrdParFasp.h"
16#include "CbmTrdParModAsic.h"
17#include "CbmTrdParModDigi.h"
18#include "CbmTrdParSetAsic.h"
19#include "CbmTrdParSetDigi.h"
20#include "CbmTrdParSpadic.h"
21#include "CbmTsEventHeader.h"
22#include "MicrosliceDescriptor.hpp"
23#include "ParFiles.h"
24#include "System.hpp"
25#include "bmon/ReadoutConfig.h"
26#include "sts/ChannelMaskSet.h"
27#include "tof/ReadoutConfig.h"
28#include "yaml/Yaml.h"
29
30#include <FairParAsciiFileIo.h>
31#include <FairParamList.h>
32#include <FairRunOnline.h>
33#include <Logger.h>
34
35#include <TStopwatch.h>
36
37#include <algorithm>
38#include <cassert>
39#include <cstdint>
40#include <iomanip>
41#include <memory>
42#include <sstream>
43#include <vector>
44
45using namespace std;
46using namespace cbm::algo;
47
48
49// ----- Constructor -----------------------------------------------------
50CbmTaskUnpack::CbmTaskUnpack() : FairTask("Unpack")
51{
52 L_(fatal) << "Instantiated CbmTaskUnpack() without arguments (needs path to parameters and run ID).";
53}
54
55// ----- Constructor -----------------------------------------------------
56CbmTaskUnpack::CbmTaskUnpack(fs::path paramsDir, uint32_t runId) : FairTask("Unpack")
57{
58 ParFiles parFiles(runId);
59 L_(info) << "Using parameter files for setup " << parFiles.setup;
60
62 auto chanMask = yaml::ReadFromFile<sts::ChannelMaskSet>(paramsDir / parFiles.sts.chanMask);
63 auto walkMap = yaml::ReadFromFile<sts::WalkMap>(paramsDir / parFiles.sts.walkMap);
64 sts::ReadoutConfig readout{stsSetup, chanMask};
65 sts::Unpack::Config stsCfg{.readout = readout, .walkMap = walkMap, .bCollectAuxData = false};
66 fStsUnpack = std::make_unique<sts::Unpack>(stsCfg);
67
69 tof::ReadoutConfig tofCfg{tofSetup};
70 fTofUnpack = std::make_unique<tof::Unpack>(tofCfg);
71
73 bmon::ReadoutConfig bmonCfg{bmonSetup};
74 fBmonUnpack = std::make_unique<bmon::Unpack>(bmonCfg);
75
76 auto trdCfg = yaml::ReadFromFile<trd::ReadoutConfig>(paramsDir / parFiles.trd.readout);
77 fTrdUnpack = std::make_unique<trd::Unpack>(trdCfg);
78
81 trd2d::Unpack::Config trd2dCfg{.roSetup = setup, .roCalib = calib};
82 fTrd2dUnpack = std::make_unique<trd2d::Unpack>(trd2dCfg);
83
84 much::ReadoutConfig muchCfg{};
85 fMuchUnpack = std::make_unique<much::Unpack>(muchCfg);
86
87 rich::ReadoutConfig richCfg{};
88 fRichUnpack = std::make_unique<rich::Unpack>(richCfg);
89}
90// ---------------------------------------------------------------------------
91
92
93// ----- Destructor ------------------------------------------------------
95{
97
99 // Clear output vectors
100 fBmonDigis->clear();
101 fStsDigis->clear();
102 fMuchDigis->clear();
103 fTrdDigis->clear();
104 fTofDigis->clear();
105 fRichDigis->clear();
106 }
107}
108// ---------------------------------------------------------------------------
109
110
111// ----- Execution -------------------------------------------------------
112void CbmTaskUnpack::Exec(Option_t*)
113{
114 // --- Get FLES timeslice
115 assert(fSource);
116 fles::Timeslice* timeslice = fSource->GetTimeslice();
117 assert(timeslice);
118
119 // --- Timer and counters
120 TStopwatch timer;
121 timer.Start();
122
123 // --- Unpack the timeslice
124 DigiData digis;
125 Monitor monitor;
126
127 digis.fBmon = RunUnpacker(fBmonUnpack, *timeslice, monitor);
128 digis.fMuch = RunUnpacker(fMuchUnpack, *timeslice, monitor);
129 digis.fRich = RunUnpacker(fRichUnpack, *timeslice, monitor);
130 digis.fSts = RunUnpacker(fStsUnpack, *timeslice, monitor);
131 digis.fTof = RunUnpacker(fTofUnpack, *timeslice, monitor);
132 digis.fTrd = RunUnpacker(fTrdUnpack, *timeslice, monitor);
133 digis.fTrd2d = RunUnpacker(fTrd2dUnpack, *timeslice, monitor);
134
136 // Clear output vectors
137 fBmonDigis->clear();
138 fStsDigis->clear();
139 fMuchDigis->clear();
140 fTrdDigis->clear();
141 fTofDigis->clear();
142 fRichDigis->clear();
143
144 fTsEventHeader->SetTsIndex(timeslice->index());
145 fTsEventHeader->SetTsStartTime(timeslice->start_time());
146
147 fTimeslice->SetStartTime(timeslice->start_time());
148
149 std::move(digis.fBmon.begin(), digis.fBmon.end(), std::back_inserter(*fBmonDigis));
150 std::move(digis.fSts.begin(), digis.fSts.end(), std::back_inserter(*fStsDigis));
151 std::move(digis.fMuch.begin(), digis.fMuch.end(), std::back_inserter(*fMuchDigis));
152 std::move(digis.fTrd2d.begin(), digis.fTrd2d.end(), std::back_inserter(*fTrdDigis));
153 std::move(digis.fTrd.begin(), digis.fTrd.end(), std::back_inserter(*fTrdDigis));
154 std::move(digis.fTof.begin(), digis.fTof.end(), std::back_inserter(*fTofDigis));
155 std::move(digis.fRich.begin(), digis.fRich.end(), std::back_inserter(*fRichDigis));
156
157 // Time-sort the TRD vector as we merged TRD1D and TRD2D (needed for compatibility with legacy unpackers)
159 }
160 else {
161 // --- Reset output branch (CbmDigiTimeslice)
163
164 // Use lines below to combine TRD 1D and 2D
165 //auto& digis1d = digis.fTrd;
166 //auto& digis2d = digis.fTrd2d;
167 //std::copy(digis2d.begin(), digis2d.end(), std::back_inserter(digis1d));
168
170 }
171
172 // --- Timeslice log
173 timer.Stop();
174 stringstream logOut;
175 logOut << setw(15) << left << GetName() << " [";
176 logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] ";
177 logOut << "TS " << fNumTs << " (index " << timeslice->index() << ")";
178 logOut << ", components " << monitor.numCompUsed << " / " << timeslice->num_components();
179 logOut << ", microslices " << monitor.numMs;
180 logOut << ", input rate " << double(monitor.numBytes) / timer.RealTime() / 1.e6 << " MB/s";
181 logOut << ", digis " << monitor.numDigis;
182 LOG(info) << logOut.str();
183
184#if !defined(__CLING__) && !defined(__ROOTCLING__)
185 if (fMonitor) {
186 fMonitor->QueueMetric(GetName(), {{"host", fHostname}},
187 {{"realtime", timer.RealTime()},
188 {"cputime", timer.CpuTime()},
189 {"input_size", monitor.numBytes},
190 {"input_rate", double(monitor.numBytes) / timer.RealTime()},
191 {"digis", monitor.numDigis}});
192 }
193#endif
194
195 // --- Run statistics
196 fNumTs++;
197 fNumMs += monitor.numMs;
198 fNumBytes += monitor.numBytes;
199 fNumDigis += monitor.numDigis;
200 fTime += timer.RealTime();
201}
202// ----------------------------------------------------------------------------
203
204
205// ----- End-of-run action ------------------------------------------------
207{
208 double timePerTs = 1000. * fTime / double(fNumTs); // in ms
209 double rate = fNumBytes / 1.e6 / fTime; // in MB/s
210 LOG(info) << "=====================================";
211 LOG(info) << GetName() << ": Run summary";
212 LOG(info) << "Timeslices : " << fNumTs;
213 LOG(info) << "Microslices : " << fNumMs;
214 LOG(info) << "Digis : " << fNumDigis;
215 LOG(info) << "Av. input rate : " << fixed << setprecision(2) << rate << " MB/s";
216 LOG(info) << "Time / TS : " << fixed << setprecision(2) << timePerTs << " ms";
217 LOG(info) << "=====================================";
218}
219// ----------------------------------------------------------------------------
220
221
222// ----- Initialisation ---------------------------------------------------
223template<typename TVecobj>
224Bool_t CbmTaskUnpack::RegisterVector(FairRootManager* ioman, std::vector<TVecobj>*& vec)
225{
226 if (ioman->GetObject(TVecobj::GetBranchName())) {
227 LOG(fatal) << GetName() << ": Branch " << TVecobj::GetBranchName() << " already exists!";
228 return kFALSE;
229 }
230
231 ioman->RegisterAny(TVecobj::GetBranchName(), vec, kTRUE);
232 LOG(info) << GetName() << ": Registered branch " << TVecobj::GetBranchName() << " at " << vec;
233
234 return kTRUE;
235}
236
238{
239 LOG(info) << "==================================================";
240 LOG(info) << GetName() << ": Initialising...";
241
242 // --- Get hostname
243 fHostname = fles::system::current_hostname();
244
245 // --- Get source instance
246 fSource = dynamic_cast<CbmSourceTs*>(FairRunOnline::Instance()->GetSource());
247 if (fSource == nullptr) {
248 LOG(error) << GetName() << ": No valid source class registered!";
249 return kFATAL;
250 }
251 LOG(info) << "--- Found CbmSourceTs instance";
252
253 // --- Get FairRootManager instance
254 FairRootManager* ioman = FairRootManager::Instance();
255 assert(ioman);
256
257 // --- Register output array (CbmDigiTimeslice)
258 if (ioman->GetObject("DigiTimeslice")) {
259 LOG(fatal) << GetName() << ": Branch DigiTimeslice already exists!";
260 return kFATAL;
261 }
262
264
265 if (!(fTsEventHeader = dynamic_cast<CbmTsEventHeader*>(FairRun::Instance()->GetEventHeader()))) {
266 LOG(fatal) << "CbmSourceDigiTimeslice::Init() no CbmTsEventHeader was added to the run. "
267 "Without it, we can not store the UTC of the Timeslices correctly. "
268 "Hence, this causes a fatal. Please add it to the Run in the steering macro.";
269 return kFATAL;
270 }
271
272 // TimeSlice. branch initialization
273 if (ioman->GetObject("TimeSlice.")) {
274 LOG(fatal) << "Source: Branch TimeSlice. already exists!";
275 return kFATAL;
276 }
277 else {
278 // NOTE: the max time of timeslice is 1.28e8, taken from CbmRecoUnpack.cxx
279 fTimeslice = new CbmTimeSlice(0., 1.28e8 + 1.28e6);
280 ioman->Register("TimeSlice.", "DAQ", fTimeslice, kTRUE);
281 }
282
283 fBmonDigis = new std::vector<CbmBmonDigi>();
284 if (kFALSE == RegisterVector<CbmBmonDigi>(ioman, fBmonDigis)) {
285 return kFATAL;
286 }
287
288
289 fStsDigis = new std::vector<CbmStsDigi>();
290 if (kFALSE == RegisterVector<CbmStsDigi>(ioman, fStsDigis)) {
291 return kFATAL;
292 }
293
294
295 fMuchDigis = new std::vector<CbmMuchDigi>();
296 if (kFALSE == RegisterVector<CbmMuchDigi>(ioman, fMuchDigis)) {
297 return kFATAL;
298 }
299
300
301 fTrdDigis = new std::vector<CbmTrdDigi>();
302 if (kFALSE == RegisterVector<CbmTrdDigi>(ioman, fTrdDigis)) {
303 return kFATAL;
304 }
305
306
307 fTofDigis = new std::vector<CbmTofDigi>();
308 if (kFALSE == RegisterVector<CbmTofDigi>(ioman, fTofDigis)) {
309 return kFATAL;
310 }
311
312
313 fRichDigis = new std::vector<CbmRichDigi>();
314 if (kFALSE == RegisterVector<CbmRichDigi>(ioman, fRichDigis)) {
315 return kFATAL;
316 }
317 }
318 else {
320 ioman->RegisterAny("DigiTimeslice.", fDigiTimeslice, IsOutputBranchPersistent("DigiTimeslice."));
321 LOG(info) << "--- Registered branch DigiTimeslice.";
322 }
323
324 return kSUCCESS;
325}
326// ----------------------------------------------------------------------------
327
328
329template<class Unpacker>
330auto CbmTaskUnpack::RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& timeslice,
332{
333 auto [digis, detmon, detaux] = (*unpacker)(timeslice);
334 monitor.numCompUsed += detmon.numComponents;
335 monitor.numMs += detmon.numMs;
336 monitor.numBytes += detmon.sizeBytesIn;
337 monitor.numDigis += digis.size();
338 return digis;
339}
340
#define L_(level)
ClassImp(CbmConverterManager)
This file contains the definition of the ParFiles class.
bool Bool_t
Collection of digis from all detector systems within one timeslice.
CbmDigiData fData
Timeslice data.
void Clear()
Clear content.
Source class for reading from archived time slice data.
Definition CbmSourceTs.h:26
fles::Timeslice * GetTimeslice()
Pointer to current FLES timeslice.
Definition CbmSourceTs.h:81
Task class for associating digis to events.
Bool_t RegisterVector(FairRootManager *ioman, std::vector< TVecobj > *&vec)
virtual ~CbmTaskUnpack()
Destructor.
virtual void Exec(Option_t *opt)
Task execution.
CbmTaskUnpack()
Constructor.
bool fCbmrootFormatOutput
std::vector< CbmMuchDigi > * fMuchDigis
std::unique_ptr< cbm::algo::sts::Unpack > fStsUnpack
std::unique_ptr< cbm::algo::trd::Unpack > fTrdUnpack
std::string fHostname
std::unique_ptr< cbm::algo::trd2d::Unpack > fTrd2dUnpack
CbmTimeSlice * fTimeslice
=> Time-slice header (old version, class about to be deprecated? one should use only CbmTsEventHeader...
std::vector< CbmTofDigi > * fTofDigis
std::vector< CbmStsDigi > * fStsDigis
CbmTsEventHeader * fTsEventHeader
Time-slice event header.
std::vector< CbmBmonDigi > * fBmonDigis
=> Branch vectors of Digis
virtual InitStatus Init()
Task initialisation.
cbm::Monitor * fMonitor
std::unique_ptr< cbm::algo::rich::Unpack > fRichUnpack
virtual void Finish()
Finish timeslice.
std::vector< CbmRichDigi > * fRichDigis
CbmSourceTs * fSource
std::unique_ptr< cbm::algo::bmon::Unpack > fBmonUnpack
std::unique_ptr< cbm::algo::tof::Unpack > fTofUnpack
std::vector< CbmTrdDigi > * fTrdDigis
auto RunUnpacker(const std::unique_ptr< Unpacker > &unpacker, const fles::Timeslice &ts, Monitor &monitor) -> cbm::algo::algo_traits::Output_t< Unpacker >
std::enable_if< std::is_member_function_pointer< decltype(&TVecobj::GetTime)>::value, void >::type Timesort(std::vector< TVecobj > *vec=nullptr)
CbmDigiTimeslice * fDigiTimeslice
Output data if writing root files "as if rra".
std::unique_ptr< cbm::algo::much::Unpack > fMuchUnpack
Bookkeeping of time-slice content.
void SetStartTime(double time)
Set start time.
void SetTsStartTime(uint64_t value)
Set the Ts Start Time.
void SetTsIndex(uint64_t value)
Set the Ts Start Time.
Provides the hardware-to-software address mapping for the CBM-RICH.
Provides the hardware-to-software address mapping for the CBM-STS.
typename std::tuple_element< 0, ResultOf_t< Algo > >::type Output_t
Type alias for the output type produced by an algorithm.
Definition AlgoTraits.h:53
T ReadFromFile(fs::path path)
Definition Yaml.h:51
Hash for CbmL1LinkKey.
Collection of digis from all detector systems.
Definition DigiData.h:32
PODVector< CbmRichDigi > fRich
Unpacked RICH digis.
Definition DigiData.h:39
PODVector< CbmTrdDigi > fTrd
Unpacked TRD digis.
Definition DigiData.h:37
PODVector< CbmStsDigi > fSts
Unpacked STS digis.
Definition DigiData.h:33
PODVector< CbmTrdDigi > fTrd2d
Unpacked TRD2D digis.
Definition DigiData.h:38
PODVector< CbmTofDigi > fTof
Unpacked TOF digis.
Definition DigiData.h:35
CbmDigiData ToStorable() const
Convert to CbmDigiData for file storage.
Definition DigiData.cxx:56
PODVector< CbmMuchDigi > fMuch
Unpacked MUCH digis.
Definition DigiData.h:34
PODVector< CbmBmonDigi > fBmon
Unpacked Bmon digis.
Definition DigiData.h:36
Class to hold the paths to the parameter files for the different detectors.
Definition ParFiles.h:21
struct cbm::algo::ParFiles::@2 tof
struct cbm::algo::ParFiles::@0 bmon
struct cbm::algo::ParFiles::@1 sts
struct cbm::algo::ParFiles::@3 trd
fs::path readout2d
Definition ParFiles.h:48
fs::path chanMask
Definition ParFiles.h:35
Readout setup / Hardware cabling for BMon Used to create the hardware mapping for the BMon unpacker.
Readout setup / Hardware cabling for STS Used to create the hardware mapping for the STS unpacker.
Readout setup / Hardware cabling for TOF Used to create the hardware mapping for the TOF unpacker.