Project
Loading...
Searching...
No Matches
RawToDigitsSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
18
19#include <random>
20#include <iostream>
21#include <fstream>
22#include <stdexcept>
23#include <array>
24#include <functional>
25#include <vector>
26#include <algorithm>
27
30
31#include "TTree.h"
32#include "TFile.h"
33
34#include <gsl/span>
35
36#include "Framework/InputSpec.h"
41#include "Framework/Lifetime.h"
42#include "Framework/Output.h"
43#include "Framework/Task.h"
45#include "Framework/Logger.h"
47
51
53
56#include "HMPIDBase/Geo.h"
59
60namespace o2
61{
62namespace hmpid
63{
64
65using namespace o2;
66using namespace o2::framework;
68using namespace o2::hmpid::raw;
69
70//=======================
71// Data decoder
73{
74 LOG(info) << "[HMPID Write Root File From Raw Files - init()]";
75
76 // get line command options
77 mOutRootFileName = ic.options().get<std::string>("out-file");
78 mBaseFileName = ic.options().get<std::string>("base-file");
79 mInputRawFileName = ic.options().get<std::string>("in-file");
80 mFastAlgorithm = ic.options().get<bool>("fast-decode");
81 mDigitsReceived = 0;
82 mFramesReceived = 0;
83
87 mReader.addFile(mInputRawFileName);
88 mReader.init();
89
91 mDecod->init();
92
93 mExTimer.start();
94 return;
95}
96
98{
99 bool isInLoop = true;
100 int tfID;
101 std::vector<char> dataBuffer; // where to put extracted data
102
103 if (mReader.getNTimeFrames() == 0) {
104 parseNoTF();
105 isInLoop = false;
106 }
107
108 while (isInLoop) {
109 tfID = mReader.getNextTFToRead();
110 if (tfID >= mReader.getNTimeFrames()) {
111 LOG(info) << "nothing left to read after " << tfID << " TFs read";
112 break;
113 }
114 for (int il = 0; il < mReader.getNLinks(); il++) {
115 auto& link = mReader.getLink(il);
116 LOG(info) << "Decoding link " << il;
117 auto sz = link.getNextTFSize(); // size in char needed for the next TF of this link
118 dataBuffer.resize(sz);
119 link.readNextTF(dataBuffer.data());
120 link.rewindToTF(tfID);
121 int nhbf = link.getNHBFinTF();
122 LOG(debug) << " Number of HBF " << nhbf;
123 for (int ib = 0; ib < nhbf; ib++) {
124 auto zs = link.getNextHBFSize(); // size in char needed for the next TF of this link
125 dataBuffer.resize(zs);
126 link.readNextHBF(dataBuffer.data());
127 // Parse
128 uint32_t* ptrBuffer = (uint32_t*)dataBuffer.data();
129 uint32_t* ptrBufferEnd = ptrBuffer + zs / 4;
130 mDecod->setUpStream(ptrBuffer, zs);
131 while (ptrBuffer < ptrBufferEnd) {
132 try {
133 if (mFastAlgorithm) {
134 mDecod->decodePageFast(&ptrBuffer);
135 } else {
136 mDecod->decodePage(&ptrBuffer);
137 }
138 } catch (int e) {
139 // The stream end !
140 LOG(debug) << "End Page decoding !";
141 }
142 int first = mAccumulateDigits.size();
143 mAccumulateDigits.insert(mAccumulateDigits.end(), mDecod->mDigits.begin(), mDecod->mDigits.end());
144 int last = mAccumulateDigits.size();
145 if (last > first) {
146 mEvents.emplace_back(o2::hmpid::Trigger{mDecod->mIntReco, first, last - first});
147 mDigitsReceived += mDecod->mDigits.size();
148 }
149 mFramesReceived++;
150 LOG(debug) << "run() Digits received =" << mDigitsReceived << " frames = " << mFramesReceived << " size=" << sz << " F-L " << first << "," << last << " " << mDecod->mIntReco;
151 mDecod->mDigits.clear();
152 }
153 }
154 }
155 mReader.setNextTFToRead(++tfID);
156 }
157 mTotalDigits += mDigitsReceived;
158 mTotalFrames += mFramesReceived;
159
160 mExTimer.logMes("End of Decoding ! Digits = " + std::to_string(mTotalDigits) + " Frames received = " + std::to_string(mTotalFrames));
161
162 writeResults();
163
164 // pc.services().get<ControlService>().endOfStream();
166 mExTimer.stop();
167 return;
168}
169
171{
172 mExTimer.logMes("Received an End Of Stream !");
173 return;
174}
175
176void RawToDigitsTask::parseNoTF()
177{
178 std::vector<char> dataBuffer; // where to put extracted data
179
180 for (int il = 0; il < mReader.getNLinks(); il++) {
181 auto& link = mReader.getLink(il);
182 LOG(info) << "Decoding link " << il;
183 auto sz = link.getNextTFSize(); // size in char needed for the next TF of this link
184 LOG(info) << " Size TF " << sz;
185 dataBuffer.resize(sz);
186 link.readNextTF(dataBuffer.data());
187
188 uint32_t* ptrBuffer = (uint32_t*)dataBuffer.data();
189 uint32_t* ptrBufferEnd = ptrBuffer + sz / 4;
190 mDecod->setUpStream(ptrBuffer, sz);
191 while (ptrBuffer < ptrBufferEnd) {
192 try {
193 if (mFastAlgorithm) {
194 mDecod->decodePageFast(&ptrBuffer);
195 } else {
196 mDecod->decodePage(&ptrBuffer);
197 }
198 } catch (int e) {
199 // The stream end !
200 LOG(debug) << "End Fast Page decoding !";
201 }
202 int first = mAccumulateDigits.size();
203 mAccumulateDigits.insert(mAccumulateDigits.end(), mDecod->mDigits.begin(), mDecod->mDigits.end());
204 int last = mAccumulateDigits.size();
205 if (last > first) {
206 mEvents.emplace_back(mDecod->mIntReco, first, last - first);
207 mDigitsReceived += mDecod->mDigits.size();
208 }
209 mFramesReceived++;
210 LOG(info) << "run() Digits received =" << mDigitsReceived << " frames = " << mFramesReceived << " size=" << sz << " F-L " << first << "," << last << " " << mDecod->mIntReco;
211 mDecod->mDigits.clear();
212 }
213 }
214 return;
215}
216
217void RawToDigitsTask::writeResults()
218{
219 int numEqui = mDecod->getNumberOfEquipments(); // Update the Stat for the Decoding
220 for (int i = 0; i < numEqui; i++) {
221 if (mDecod->mTheEquipments[i]->mNumberOfEvents > 0) {
222 mDecod->updateStatistics(mDecod->mTheEquipments[i]);
223 }
224 }
225 if (mEvents.size() == 0) { // check if no evwnts
226 LOG(info) << "There are not Event recorded ! Abort. ";
227 mExTimer.stop();
228 return;
229 }
230 for (int i = mEvents.size() - 1; i >= 0; i--) { // remove events that are (0,0) trigger
231 if (mEvents[i].getTriggerID() == 0) {
232 mEvents.erase(mEvents.begin() + i);
233 }
234 }
235 sort(mEvents.begin(), mEvents.end()); // sort the events
236 mExTimer.logMes("Sorted Events = " + std::to_string(mEvents.size()));
237
238 // ---------- ROOT file version 2 ---------------
239 TString filename;
240 TString tit;
241
242 std::vector<o2::hmpid::Digit> digitVec;
243 std::vector<o2::hmpid::Trigger> eventVec;
244
245 filename = TString::Format("%s", mOutRootFileName.c_str());
246 LOG(info) << "Create the ROOT file " << filename.Data();
247 TFile mfileOut(TString::Format("%s", filename.Data()), "RECREATE");
248 tit = TString::Format("HMPID Raw File Decoding");
249 TTree* theTree = new TTree("o2hmp", tit);
250
251 theTree->Branch("InteractionRecords", &eventVec);
252 theTree->Branch("HMPIDDigits", &digitVec);
253
254 // builds the two arranged vectors of objects
255 o2::hmpid::Trigger prevEvent = mEvents[0];
256 uint32_t theFirstDigit = 0;
257 uint32_t theLastDigit = 0;
258 for (int e = 0; e < mEvents.size(); e++) {
259 LOG(debug) << "Manage event " << mEvents[e];
260 if (prevEvent != mEvents[e]) { // changes the event Flush It
261 eventVec.emplace_back(o2::InteractionRecord(prevEvent.getBc(), prevEvent.getOrbit()), theFirstDigit, theLastDigit - theFirstDigit);
262 theFirstDigit = theLastDigit;
263 prevEvent = mEvents[e];
264 }
265 int first = mEvents[e].getFirstEntry();
266 int last = mEvents[e].getLastEntry();
267 for (int idx = first; idx <= last; idx++) {
268 digitVec.push_back(mAccumulateDigits[idx]);
269 theLastDigit++;
270 }
271 }
272 eventVec.emplace_back(o2::InteractionRecord(prevEvent.getBc(), prevEvent.getOrbit()), theFirstDigit, theLastDigit - theFirstDigit);
273 theTree->Fill();
274 theTree->Write();
275 mfileOut.Close();
276 mExTimer.logMes("Register Tree ! ");
277
278 // ---------- Records the statistics -----------------
279 float avgEventSize; //[o2::hmpid::Geo::MAXEQUIPMENTS];
280 float avgBusyTime; //[o2::hmpid::Geo::MAXEQUIPMENTS];
281 float numOfSamples; //[o2::hmpid::Geo::N_MODULES][o2::hmpid::Geo::N_YCOLS][o2::hmpid::Geo::N_XROWS];
282 float sumOfCharges; //[o2::hmpid::Geo::N_MODULES][o2::hmpid::Geo::N_YCOLS][o2::hmpid::Geo::N_XROWS];
283 float squareOfCharges; //[o2::hmpid::Geo::N_MODULES][o2::hmpid::Geo::N_YCOLS][o2::hmpid::Geo::N_XROWS];
284 float xb;
285 float yb;
286
287 filename = TString::Format("%s_stat.root", mBaseFileName.c_str());
288 LOG(info) << "Create the ROOT file " << filename.Data();
289 TFile mfileOutStat(TString::Format("%s", filename.Data()), "RECREATE");
290 TTree* theObj[Geo::N_MODULES + 1];
291 for (int i = 0; i < Geo::N_MODULES; i++) { // Create the TTree array
292 tit = TString::Format("HMPID Data Decoding Statistic results Mod=%d", i);
293 theObj[i] = new TTree("o2hmp", tit);
294 theObj[i]->Branch("x", &xb, "s");
295 theObj[i]->Branch("y", &yb, "s");
296 theObj[i]->Branch("Samples", &numOfSamples, "i");
297 theObj[i]->Branch("Sum_of_charges", &sumOfCharges, "l");
298 theObj[i]->Branch("Sum_of_square", &squareOfCharges, "l");
299 }
300 theObj[Geo::N_MODULES] = new TTree("o2hmp", "HMPID Data Decoding Statistic results");
301 theObj[Geo::N_MODULES]->Branch("Average_Event_Size", &avgEventSize, "F");
302 theObj[Geo::N_MODULES]->Branch("Average_Busy_Time", &avgBusyTime, "F");
303
304 char summaryFileName[254];
305 snprintf(summaryFileName, 254, "%s_stat.txt", mBaseFileName.c_str());
306 mDecod->writeSummaryFile(summaryFileName);
307 for (int e = 0; e < numEqui; e++) {
308 avgEventSize = mDecod->getAverageEventSize(e);
309 avgBusyTime = mDecod->getAverageBusyTime(e);
310 theObj[Geo::N_MODULES]->Fill();
311 }
312 for (int m = 0; m < o2::hmpid::Geo::N_MODULES; m++) {
313 for (int y = 0; y < o2::hmpid::Geo::N_YCOLS; y++) {
314 for (int x = 0; x < o2::hmpid::Geo::N_XROWS; x++) {
315 xb = x;
316 yb = y;
317 numOfSamples = mDecod->getPadSamples(m, x, y);
318 sumOfCharges = mDecod->getPadSum(m, x, y);
319 squareOfCharges = mDecod->getPadSquares(m, x, y);
320 theObj[m]->Fill();
321 }
322 }
323 }
324 for (int i = 0; i <= Geo::N_MODULES; i++) {
325 theObj[i]->Write();
326 }
327
328 mExTimer.logMes("End storing results ! Digits = " + std::to_string(mTotalDigits) + " Frames received = " + std::to_string(mTotalFrames));
329 return;
330}
331
332//_________________________________________________________________________________________________
334{
335 std::vector<o2::framework::InputSpec> inputs;
336 std::vector<o2::framework::OutputSpec> outputs;
337
338 return DataProcessorSpec{
339 "HMP-RawToDigits",
340 inputs,
341 outputs,
342 AlgorithmSpec{adaptFromTask<RawToDigitsTask>()},
343 Options{{"in-file", VariantType::String, "hmpidRaw.raw", {"name of the input Raw file"}},
344 {"fast-decode", VariantType::Bool, false, {"Use the fast algorithm. (error 0.8%)"}},
345 {"out-file", VariantType::String, "hmpReco.root", {"name of the output file"}},
346 {"base-file", VariantType::String, "hmpDecode", {"base name for statistical output file"}}}};
347}
348
349} // namespace hmpid
350} // end namespace o2
A raw page parser for DPL input.
int32_t i
A helper class to iteratate over all parts of all input routes.
Configurable generator for RootTreeWriter processor spec.
Definition of the RAW Data Header.
Reader for (multiple) raw data files.
std::ostringstream debug
ConfigParamRegistry const & options()
Definition InitContext.h:33
ServiceRegistryRef services()
The services registry associated with this processing context.
void stop()
stop : stops the timer
Definition Common.h:73
void start()
start : starts the timer
Definition Common.h:64
void logMes(std::string const message)
Definition Common.h:81
static constexpr int N_XROWS
Definition Geo.h:88
static constexpr int N_MODULES
Definition Geo.h:87
static constexpr int N_YCOLS
Definition Geo.h:89
static constexpr int MAXEQUIPMENTS
Definition Geo.h:79
float getAverageEventSize(int Equipment)
void decodePageFast(uint32_t **streamBuf)
void init()
Init all the members variables.
std::vector< o2::hmpid::Digit > mDigits
void decodePage(uint32_t **streamBuffer)
o2::InteractionRecord mIntReco
bool setUpStream(void *Buffer, long BufferLen)
void writeSummaryFile(char *summaryFileName)
double getPadSum(int Module, int Row, int Column)
HmpidEquipment * mTheEquipments[Geo::MAXEQUIPMENTS]
uint16_t getPadSamples(int Module, int Row, int Column)
void updateStatistics(HmpidEquipment *eq)
float getAverageBusyTime(int Equipment)
double getPadSquares(int Module, int Row, int Column)
void init(framework::InitContext &ic) final
void endOfStream(framework::EndOfStreamContext &ec) override
This is invoked whenever we have an EndOfStream event.
void run(framework::ProcessingContext &pc) final
HMPID Trigger declaration.
Definition Trigger.h:32
uint16_t getBc() const
Definition Trigger.h:44
uint32_t getOrbit() const
Definition Trigger.h:43
uint32_t getNextTFToRead() const
void setNextTFToRead(uint32_t tf)
void setDefaultDataDescription(const std::string &desc)
void setDefaultDataOrigin(const std::string &orig)
uint32_t getNTimeFrames() const
const LinkData & getLink(int i) const
void setDefaultReadoutCardType(ReadoutCardType t=CRU)
bool addFile(const std::string &sname, o2::header::DataOrigin origin, o2::header::DataDescription desc, ReadoutCardType t=CRU)
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
GLint first
Definition glcorearb.h:399
GLint y
Definition glcorearb.h:270
constexpr o2::header::DataOrigin gDataOriginHMP
Definition DataHeader.h:569
constexpr o2::header::DataDescription gDataDescriptionRawData
Definition DataHeader.h:597
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
@ Me
Only quit this data processor.
std::vector< ConfigParamSpec > Options
o2::framework::DataProcessorSpec getRawToDigitsSpec(std::string inputSpec="HMP/RAWDATA")
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::string filename()
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"