CbmRoot
Loading...
Searching...
No Matches
CbmDevBuildEvents.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: Pierre-Alain Loizeau[committer], Dominik Smith */
4
5#include "CbmDevBuildEvents.h"
6
8#include "CbmMQDefs.h"
9
11#include "BoostSerializer.h"
12#include "EventBuilderConfig.h"
13#include "FairMQLogger.h"
14#include "FairMQProgOptions.h"
15#include "FairRootFileSink.h"
16#include "FairRootManager.h"
17#include "FairRunOnline.h"
18#include "RootSerializer.h"
19
21#include "TimesliceMetaData.h"
22
23#include <boost/archive/binary_iarchive.hpp>
24#include <boost/serialization/utility.hpp>
25
27#include <array>
28#include <iomanip>
29#include <stdexcept>
30#include <string>
31struct InitTaskError : std::runtime_error {
32 using std::runtime_error::runtime_error;
33};
34
35using namespace std;
36
38
40try {
42 LOG(info) << "Init options for CbmDevBuildEvents.";
43
44 fsOutputFileName = fConfig->GetValue<std::string>("OutFileName"); //For storage of events
45
46 // Event builder algorithm params
47 const std::vector<std::string> vsSetEvbuildWin = fConfig->GetValue<std::vector<std::string>>("SetEvbuildWin");
48
49 fsChannelNameDataInput = fConfig->GetValue<std::string>("TrigNameIn");
50 fsChannelNameDataOutput = fConfig->GetValue<std::string>("EvtNameOut");
52
54 if ("" != fsOutputFileName) {
55 fpRun = new FairRunOnline();
56 fpFairRootMgr = FairRootManager::Instance();
57 fpFairRootMgr->SetSink(new FairRootFileSink(fsOutputFileName));
58 if (nullptr == fpFairRootMgr->GetOutFile()) {
59 throw InitTaskError("Could not open root file");
60 }
61 LOG(info) << "Init Root Output to " << fsOutputFileName;
62 fpFairRootMgr->InitSink();
63
65 fEventsSelOut = new std::vector<CbmDigiEvent>();
66 fpFairRootMgr->RegisterAny("DigiEvent", fEventsSelOut, kTRUE);
67
68 fTimeSliceMetaDataArrayOut = new TClonesArray("TimesliceMetaData", 1);
69 fpFairRootMgr->Register("TimesliceMetaData", "TS Meta Data", fTimeSliceMetaDataArrayOut, kTRUE);
70
71 fpFairRootMgr->WriteFolder();
72 } // if( "" != fsOutputFileName )
73
74 // Get the information about created channels from the device
75 // Check if the defined channels from the topology (by name)
76 // are in the list of channels which are possible/allowed
77 // for the device
78 // The idea is to check at initilization if the devices are
79 // properly connected. For the time beeing this is done with a
80 // nameing convention. It is not avoided that someone sends other
81 // data on this channel.
82 //logger::SetLogLevel("INFO");
83 int noChannel = fChannels.size();
84 LOG(info) << "Number of defined channels: " << noChannel;
85 for (auto const& entry : fChannels) {
86 LOG(info) << "Channel name: " << entry.first;
87 if (std::string::npos != entry.first.find(fsChannelNameDataInput)) {
88 if (!IsChannelNameAllowed(entry.first)) throw InitTaskError("Channel name does not match.");
89 OnData(entry.first, &CbmDevBuildEvents::HandleData);
90 }
91 }
92
94 for (std::vector<std::string>::const_iterator itStrEvbuildWin = vsSetEvbuildWin.begin();
95 itStrEvbuildWin != vsSetEvbuildWin.end(); ++itStrEvbuildWin) {
96 size_t charPosDel = (*itStrEvbuildWin).find(',');
97 if (std::string::npos == charPosDel) {
98 LOG(info) << "CbmDevBuildEvents::InitTask => "
99 << "Trying to set event builder window with invalid option pattern, ignored! "
100 << " (Should be ECbmModuleId,dWinBeg,dWinEnd but instead found " << (*itStrEvbuildWin) << " )";
101 continue;
102 }
103
105 std::string sSelDet = (*itStrEvbuildWin).substr(0, charPosDel);
106 const ECbmModuleId selDet = GetDetectorId(sSelDet);
107
108 if (ECbmModuleId::kNotExist == selDet) {
109 LOG(info) << "CbmDevBuildEvents::InitTask => "
110 << "Trying to set trigger window for unsupported detector, ignored! " << sSelDet;
111 continue;
112 }
113
115 charPosDel++;
116 std::string sNext = (*itStrEvbuildWin).substr(charPosDel);
117 charPosDel = sNext.find(',');
118 if (std::string::npos == charPosDel) {
119 LOG(info) << "CbmDevBuildEvents::InitTask => "
120 << "Trying to set event builder window with invalid option pattern, ignored! "
121 << " (Should be ECbmModuleId,dWinBeg,dWinEnd but instead found " << (*itStrEvbuildWin) << " )";
122 continue;
123 }
124 double dWinBeg = std::stod(sNext.substr(0, charPosDel));
125
127 charPosDel++;
128 double dWinEnd = std::stod(sNext.substr(charPosDel));
130 fEvbuildAlgo = std::make_unique<cbm::algo::evbuild::EventBuilder>(config);
131 }
132}
133catch (InitTaskError& e) {
134 LOG(error) << e.what();
135 // Wrapper defined in CbmMQDefs.h to support different FairMQ versions
137}
138
140{
142 /* clang-format off */
143 ECbmModuleId detId = ("kBmon" == detName ? ECbmModuleId::kBmon
144 : ("kSts" == detName ? ECbmModuleId::kSts
145 : ("kMuch" == detName ? ECbmModuleId::kMuch
146 : ("kTrd" == detName ? ECbmModuleId::kTrd
147 : ("kTrd2d" == detName ? ECbmModuleId::kTrd2d
148 : ("kTof" == detName ? ECbmModuleId::kTof
149 : ("kRich" == detName ? ECbmModuleId::kRich
150 : ("kPsd" == detName ? ECbmModuleId::kPsd
151 : ("kFsd" == detName ? ECbmModuleId::kFsd
152 : ECbmModuleId::kNotExist)))))))));
153 return detId;
155 /* clang-format on */
156}
157
158bool CbmDevBuildEvents::IsChannelNameAllowed(std::string channelName)
159{
160 for (auto const& entry : fsAllowedChannels) {
161 std::size_t pos1 = channelName.find(entry);
162 if (pos1 != std::string::npos) {
163 const vector<std::string>::const_iterator pos =
164 std::find(fsAllowedChannels.begin(), fsAllowedChannels.end(), entry);
165 const vector<std::string>::size_type idx = pos - fsAllowedChannels.begin();
166 LOG(info) << "Found " << entry << " in " << channelName;
167 LOG(info) << "Channel name " << channelName << " found in list of allowed channel names at position " << idx;
168 return true;
169 }
170 }
171 LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names.";
172 LOG(error) << "Stop device.";
173 return false;
174}
175
176// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
177bool CbmDevBuildEvents::HandleData(FairMQParts& parts, int /*index*/)
178{
180 LOG(info) << "Received message number " << fulNumMessages << " with " << parts.Size() << " parts"
181 << ", size0: " << parts.At(0)->GetSize();
182
183 if (0 == fulNumMessages % 10000) LOG(info) << "Received " << fulNumMessages << " messages";
184
186 uint32_t uPartIdx = 0;
187
190 std::string msgStrTS(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize());
191 std::istringstream issTS(msgStrTS);
192 boost::archive::binary_iarchive inputArchiveTS(issTS);
193 inputArchiveTS >> ts;
194 ++uPartIdx;
195
197 TimesliceMetaData* tsMetaData = new TimesliceMetaData();
198 RootSerializer().Deserialize(*parts.At(uPartIdx), tsMetaData);
199 ++uPartIdx;
200
202 std::vector<double> triggers;
203 std::string msgStrTrig(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize());
204 std::istringstream issTrig(msgStrTrig);
205 boost::archive::binary_iarchive inputArchiveTrig(issTrig);
206 inputArchiveTrig >> triggers;
207 ++uPartIdx;
208
209 //if (1 == fulNumMessages) {
211 //fpAlgo->SetTsParameters(0, fTsMetaDataOut->GetDuration(), fTsMetaDataOut->GetOverlapDuration());
212 //}
213
214 LOG(debug) << "Bmon Vector size: " << ts.fData.fBmon.fDigis.size();
215 LOG(debug) << "STS Vector size: " << ts.fData.fSts.fDigis.size();
216 LOG(debug) << "MUCH Vector size: " << ts.fData.fMuch.fDigis.size();
217 LOG(debug) << "TRD Vector size: " << ts.fData.fTrd.fDigis.size();
218 LOG(debug) << "TOF Vector size: " << ts.fData.fTof.fDigis.size();
219 LOG(debug) << "RICH Vector size: " << ts.fData.fRich.fDigis.size();
220 LOG(debug) << "PSD Vector size: " << ts.fData.fPsd.fDigis.size();
221 LOG(debug) << "FSD Vector size: " << ts.fData.fFsd.fDigis.size();
222 LOG(debug) << "triggers: " << triggers.size();
223
225 std::vector<CbmDigiEvent> vEvents = (*fEvbuildAlgo)(ts, triggers).first;
226 LOG(debug) << "vEvents size: " << vEvents.size();
227
229 if (!SendEvents(vEvents, tsMetaData)) {
230 return false;
231 }
232
234 // FIXME: poor man solution with lots of data copy until we undertand how to properly deal
236
237 if ("" != fsOutputFileName) {
238 (*fEventsSelOut) = std::move(vEvents);
239 LOG(debug) << "fEventSel size: " << fEventsSelOut->size();
240
241 new ((*fTimeSliceMetaDataArrayOut)[fTimeSliceMetaDataArrayOut->GetEntriesFast()])
242 TimesliceMetaData(std::move(*tsMetaData));
243
245
247 fEventsSelOut->clear();
248 }
249
250 return true;
251}
252
254{
255 // Unpacked digis + CbmEvent output to root file
256
258 fpFairRootMgr->StoreWriteoutBufferData(fpFairRootMgr->GetEventTime());
259 fpFairRootMgr->Fill();
260 fpFairRootMgr->DeleteOldWriteoutBufferData();
261}
262
263bool CbmDevBuildEvents::SendEvents(const std::vector<CbmDigiEvent>& vEvents, const TimesliceMetaData* tsMetaData)
264{
265 LOG(debug) << "Vector size: " << vEvents.size();
266
267 FairMQParts partsOut;
268
269 // Prepare TS meta data
270 FairMQMessagePtr messTsMeta(NewMessage());
271 RootSerializer().Serialize(*messTsMeta, tsMetaData);
272 partsOut.AddPart(std::move(messTsMeta));
273
274 // Prepare event vector.
275 std::stringstream ossEvt;
276 boost::archive::binary_oarchive oaEvt(ossEvt);
277 oaEvt << vEvents;
278 std::string* strMsgEvt = new std::string(ossEvt.str());
279
280 partsOut.AddPart(NewMessage(
281 const_cast<char*>(strMsgEvt->c_str()), // data
282 strMsgEvt->length(), // size
283 [](void*, void* object) { delete static_cast<std::string*>(object); },
284 strMsgEvt)); // object that manages the data
285
286 if (Send(partsOut, fsChannelNameDataOutput) < 0) {
287 LOG(error) << "Problem sending data to " << fsChannelNameDataOutput;
288 return false;
289 }
290 return true;
291}
292
294{
295 if ("" != fsOutputFileName) {
296 // Clean closure of output to root file
297 fpFairRootMgr->Write();
298 fpFairRootMgr->CloseSink();
299 }
300 fbFinishDone = kTRUE;
301}
302
304{
306 if (!fbFinishDone) Finish();
307 if (fEventsSelOut) {
308 delete fEventsSelOut;
309 }
310 if (fpRun) {
311 delete fpRun;
312 }
315 }
316}
ECbmModuleId
Definition CbmDefs.h:39
@ kTrd
Transition Radiation Detector.
@ kTof
Time-of-flight Detector.
@ kNotExist
If not found.
@ kPsd
Projectile spectator detector.
@ kSts
Silicon Tracking System.
@ kTrd2d
TRD-FASP Detector (FIXME)
@ kMuch
Muon detection system.
@ kFsd
Forward spectator detector.
@ kRich
Ring-Imaging Cherenkov Detector.
bool first
std::vector< CbmBmonDigi > fDigis
Data vector.
std::string fsChannelNameDataInput
Keep track of whether the Finish was already called.
FairRunOnline * fpRun
virtual void InitTask()
std::vector< CbmDigiEvent > * fEventsSelOut
ECbmModuleId GetDetectorId(std::string detName)
std::string fsChannelNameDataOutput
uint64_t fulNumMessages
Statistics & first TS rejection.
bool SendEvents(const std::vector< CbmDigiEvent > &vEvents, const TimesliceMetaData *tsMetaData)
FairRootManager * fpFairRootMgr
bool HandleData(FairMQParts &, int)
bool IsChannelNameAllowed(std::string channelName)
std::unique_ptr< cbm::algo::evbuild::EventBuilder > fEvbuildAlgo
Processing algos.
TClonesArray * fTimeSliceMetaDataArrayOut
std::string fsOutputFileName
Data storage.
std::vector< std::string > fsAllowedChannels
List of MQ channels names.
CbmPsdDigiData fPsd
PSD data.
Definition CbmDigiData.h:42
CbmTrdDigiData fTrd
TRD data.
Definition CbmDigiData.h:39
CbmTofDigiData fTof
TOF data.
Definition CbmDigiData.h:41
CbmStsDigiData fSts
STS data.
Definition CbmDigiData.h:36
CbmFsdDigiData fFsd
FSD data.
Definition CbmDigiData.h:43
CbmRichDigiData fRich
RICH data.
Definition CbmDigiData.h:38
CbmMuchDigiData fMuch
MUCH data.
Definition CbmDigiData.h:37
CbmBmonDigiData fBmon
Beam monitor data.
Definition CbmDigiData.h:35
Collection of digis from all detector systems within one timeslice.
CbmDigiData fData
Timeslice data.
std::vector< CbmFsdDigi > fDigis
Data vector.
std::vector< CbmMuchDigi > fDigis
Data vector.
std::vector< CbmPsdDigi > fDigis
Data vector.
std::vector< CbmRichDigi > fDigis
Data vector.
std::vector< CbmStsDigi > fDigis
Data vector.
std::vector< CbmTofDigi > fDigis
Data vector.
std::vector< CbmTrdDigi > fDigis
Data vector.
Configuration of the EventBuilder class.
void ChangeState(FairMQDevice *device, cbm::mq::Transition transition)
Definition CbmMQDefs.h:26
Hash for CbmL1LinkKey.