Project
Loading...
Searching...
No Matches
DumpRaw.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
12#include <TROOT.h>
13#include <TPad.h>
14#include <TString.h>
15#include <TAxis.h>
16#include <TStyle.h>
17#include <TPaveStats.h>
18#include "ZDCRaw/DumpRaw.h"
21#include "Framework/Logger.h"
22
23using namespace o2::zdc;
24
25void DumpRaw::setStat(TH1* h)
26{
27 TString hn = h->GetName();
28 h->Draw();
29 gPad->Update();
30 TPaveStats* st = (TPaveStats*)h->GetListOfFunctions()->FindObject("stats");
31 st->SetFillStyle(1001);
32 st->SetBorderSize(1);
33 if (hn.BeginsWith("hp")) {
34 st->SetOptStat(111111);
35 st->SetX1NDC(0.1);
36 st->SetX2NDC(0.3);
37 st->SetY1NDC(0.640);
38 st->SetY2NDC(0.9);
39 } else if (hn.BeginsWith("hc")) {
40 st->SetOptStat(1111);
41 st->SetX1NDC(0.799);
42 st->SetX2NDC(0.999);
43 st->SetY1NDC(0.829);
44 st->SetY2NDC(0.999);
45 } else if (hn.BeginsWith("hs") || hn.BeginsWith("hb")) {
46 st->SetOptStat(11);
47 st->SetX1NDC(0.799);
48 st->SetX2NDC(0.9995);
49 st->SetY1NDC(0.904);
50 st->SetY2NDC(0.999);
51 }
52}
53
54void DumpRaw::setModuleLabel(TH1* h)
55{
56 for (int im = 0; im < NModules; im++) {
57 for (int ic = 0; ic < NChPerModule; ic++) {
58 h->GetXaxis()->SetBinLabel(im * NChPerModule + ic + 1, TString::Format("%d%d", im, ic));
59 }
60 }
61}
62
63void DumpRaw::setTriggerYLabel(TH2* h)
64{
65 h->GetYaxis()->SetBinLabel(10, "Alice_3");
66 h->GetYaxis()->SetBinLabel(9, "Alice_2");
67 h->GetYaxis()->SetBinLabel(8, "Alice_1");
68 h->GetYaxis()->SetBinLabel(7, "Alice_0");
69 h->GetYaxis()->SetBinLabel(6, "Auto_3");
70 h->GetYaxis()->SetBinLabel(5, "Auto_2");
71 h->GetYaxis()->SetBinLabel(4, "Auto_1");
72 h->GetYaxis()->SetBinLabel(3, "Auto_0");
73 h->GetYaxis()->SetBinLabel(2, "Auto_m");
74 h->GetYaxis()->SetBinLabel(1, "None");
75}
76
78{
79 gROOT->SetBatch();
80 auto& sopt = ZDCSimParam::Instance();
81 double xmin = -sopt.nBCAheadTrig * NTimeBinsPerBC - 0.5;
82 double xmax = 2 * NTimeBinsPerBC - 0.5;
83 int nbx = std::round(xmax - xmin);
84 if (mTransmitted == nullptr) {
85 mTransmitted = std::make_unique<TH2F>("ht", "Transmitted channels", NModules, -0.5, NModules - 0.5, NChPerModule, -0.5, NChPerModule - 0.5);
86 }
87 if (mFired == nullptr) {
88 mFired = std::make_unique<TH2F>("hfired", "Fired channels", NModules, -0.5, NModules - 0.5, NChPerModule, -0.5, NChPerModule - 0.5);
89 }
90 if (mLoss == nullptr) {
91 mLoss = std::make_unique<TH1F>("hloss", "Data loss", NModules * NChPerModule, -0.5, NModules * NChPerModule - 0.5);
92 setModuleLabel(mLoss.get());
93 }
94 if (mError == nullptr) {
95 mError = std::make_unique<TH1F>("hError", "Error bit", NModules * NChPerModule, -0.5, NModules * NChPerModule - 0.5);
96 setModuleLabel(mError.get());
97 }
98 if (mOve == nullptr) {
99 mOve = std::make_unique<TH1F>("hove", "BC overflow", NModules * NChPerModule, -0.5, NModules * NChPerModule - 0.5);
100 setModuleLabel(mOve.get());
101 }
102 if (mBits == nullptr) {
103 mBits = std::make_unique<TH2F>("hb", "Trigger bits", NModules * NChPerModule, -0.5, NModules * NChPerModule - 0.5, 10, -0.5, 9.5);
104 setTriggerYLabel(mBits.get());
105 setModuleLabel(mBits.get());
106 }
107 if (mBitsH == nullptr) {
108 mBitsH = std::make_unique<TH2F>("hbh", "Trigger bits HIT", NModules * NChPerModule, -0.5, NModules * NChPerModule - 0.5, 10, -0.5, 9.5);
109 setTriggerYLabel(mBitsH.get());
110 setModuleLabel(mBitsH.get());
111 }
112 for (uint32_t i = 0; i < NDigiChannels; i++) {
113 uint32_t imod = i / NChPerModule;
114 uint32_t ich = i % NChPerModule;
115 if (mBaseline[i] == nullptr) {
116 TString hname = TString::Format("hp%d%d", imod, ich);
117 TString htit = TString::Format("Baseline mod. %d ch. %d;Average orbit baseline", imod, ich);
118 // mBaseline[i]=std::make_unique<TH1F>(hname,htit,ADCRange,ADCMin-0.5,ADCMax+0.5);
119 mBaseline[i] = std::make_unique<TH1F>(hname, htit, 65536, -32768.5, 32767.5);
120 }
121 if (mCounts[i] == nullptr) {
122 TString hname = TString::Format("hc%d%d", imod, ich);
123 TString htit = TString::Format("Counts mod. %d ch. %d; Orbit hits", imod, ich);
124 mCounts[i] = std::make_unique<TH1F>(hname, htit, o2::constants::lhc::LHCMaxBunches + 1, -0.5, o2::constants::lhc::LHCMaxBunches + 0.5);
125 }
126 if (mSignalA[i] == nullptr) {
127 TString hname = TString::Format("hsa%d%d", imod, ich);
128 TString htit = TString::Format("Signal mod. %d ch. %d ALICET; Sample; ADC", imod, ich);
129 mSignalA[i] = std::make_unique<TH2F>(hname, htit, nbx, xmin, xmax, ADCRange, ADCMin - 0.5, ADCMax + 0.5);
130 }
131 if (mSignalT[i] == nullptr) {
132 TString hname = TString::Format("hst%d%d", imod, ich);
133 TString htit = TString::Format("Signal mod. %d ch. %d AUTOT; Sample; ADC", imod, ich);
134 mSignalT[i] = std::make_unique<TH2F>(hname, htit, nbx, xmin, xmax, ADCRange, ADCMin - 0.5, ADCMax + 0.5);
135 }
136 if (mSignalTH[i] == nullptr) {
137 TString hname = TString::Format("hsth%d%d", imod, ich);
138 TString htit = TString::Format("Signal mod. %d ch. %d AUTOT & Hit; Sample; ADC", imod, ich);
139 mSignalTH[i] = std::make_unique<TH2F>(hname, htit, 2 * NTimeBinsPerBC, -0.5 - NTimeBinsPerBC, NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5);
140 }
141 if (mBunchA[i] == nullptr) {
142 TString hname = TString::Format("hba%d%d", imod, ich);
143 TString htit = TString::Format("Bunch mod. %d ch. %d ALICET; Sample; ADC", imod, ich);
144 mBunchA[i] = std::make_unique<TH2F>(hname, htit, 100, -0.5, 99.5, 36, -35.5, 0.5);
145 }
146 if (mBunchT[i] == nullptr) {
147 TString hname = TString::Format("hbt%d%d", imod, ich);
148 TString htit = TString::Format("Bunch mod. %d ch. %d AUTOT; Sample; ADC", imod, ich);
149 mBunchT[i] = std::make_unique<TH2F>(hname, htit, 100, -0.5, 99.5, 36, -35.5, 0.5);
150 }
151 if (mBunchH[i] == nullptr) {
152 TString hname = TString::Format("hbh%d%d", imod, ich);
153 TString htit = TString::Format("Bunch mod. %d ch. %d AUTOT Hit; Sample; ADC", imod, ich);
154 mBunchH[i] = std::make_unique<TH2F>(hname, htit, 100, -0.5, 99.5, 36, -35.5, 0.5);
155 }
156 }
157 // Word id not present in payload
158 mCh.f.fixed_0 = Id_wn;
159 mCh.f.fixed_1 = Id_wn;
160 mCh.f.fixed_2 = Id_wn;
161}
162
164{
165 TFile* f = new TFile("ZDCDumpRaw.root", "recreate");
166 if (f->IsZombie()) {
167 LOG(fatal) << "Cannot write to file " << f->GetName();
168 return;
169 }
170 for (uint32_t i = 0; i < NDigiChannels; i++) {
171 if (mBunchA[i] && mBunchA[i]->GetEntries() > 0) {
172 setStat(mBunchA[i].get());
173 mBunchA[i]->Write();
174 }
175 }
176 for (uint32_t i = 0; i < NDigiChannels; i++) {
177 if (mBunchT[i] && mBunchT[i]->GetEntries() > 0) {
178 setStat(mBunchT[i].get());
179 mBunchT[i]->Write();
180 }
181 }
182 for (uint32_t i = 0; i < NDigiChannels; i++) {
183 if (mBunchH[i] && mBunchH[i]->GetEntries() > 0) {
184 setStat(mBunchH[i].get());
185 mBunchH[i]->Write();
186 }
187 }
188 for (uint32_t i = 0; i < NDigiChannels; i++) {
189 if (mBaseline[i] && mBaseline[i]->GetEntries() > 0) {
190 setStat(mBaseline[i].get());
191 mBaseline[i]->Write();
192 }
193 }
194 for (uint32_t i = 0; i < NDigiChannels; i++) {
195 if (mCounts[i] && mCounts[i]->GetEntries() > 0) {
196 setStat(mCounts[i].get());
197 mCounts[i]->Write();
198 }
199 }
200 for (uint32_t i = 0; i < NDigiChannels; i++) {
201 if (mSignalA[i] && mSignalA[i]->GetEntries() > 0) {
202 setStat(mSignalA[i].get());
203 mSignalA[i]->Write();
204 }
205 }
206 for (uint32_t i = 0; i < NDigiChannels; i++) {
207 if (mSignalT[i] && mSignalT[i]->GetEntries() > 0) {
208 setStat(mSignalT[i].get());
209 mSignalT[i]->Write();
210 }
211 if (mSignalTH[i] && mSignalTH[i]->GetEntries() > 0) {
212 setStat(mSignalTH[i].get());
213 mSignalTH[i]->Write();
214 }
215 }
216 mTransmitted->Write();
217 mFired->Write();
218 mBits->Write();
219 mBitsH->Write();
220 mLoss->Write();
221 mError->Write();
222 mOve->Write();
223 f->Close();
224}
225
226inline int DumpRaw::getHPos(uint32_t board, uint32_t ch)
227{
228 int ih = board * 4 + ch;
229 if (ih < NDigiChannels) {
230 return ih;
231 } else {
232 LOG(error) << "Wrong ih " << ih << " board " << board << " ch " << ch;
233 return -1;
234 }
235}
236
237int DumpRaw::processWord(const uint32_t* word)
238{
239 if (word == nullptr) {
240 printf("NULL\n");
241 return 1;
242 }
243 // LOGF(info, "GBT word %04x %08x %08x id=%u", *((uint16_t*)&word[2]), word[1], word[0], word[0] & 0x3);
244 if ((word[0] & 0x3) == Id_w0) {
245 mCh.w[0][NWPerGBTW - 1] = 0;
246 mCh.w[0][NWPerGBTW - 2] = 0;
247 memcpy((void*)&mCh.w[0][0], (const void*)word, PayloadPerGBTW);
248 } else if ((word[0] & 0x3) == Id_w1) {
249 if (mCh.f.fixed_0 == Id_w0) {
250 mCh.w[1][NWPerGBTW - 1] = 0;
251 mCh.w[1][NWPerGBTW - 2] = 0;
252 memcpy((void*)&mCh.w[1][0], (const void*)word, PayloadPerGBTW);
253 } else {
254 LOGF(error, "Wrong word sequence: %04x %08x %08x id=%u *%u*", *((uint16_t*)&word[2]), word[1], word[0], mCh.f.fixed_0, word[0] & 0x3);
255 mCh.f.fixed_0 = Id_wn;
256 mCh.f.fixed_1 = Id_wn;
257 mCh.f.fixed_2 = Id_wn;
258 }
259 } else if ((word[0] & 0x3) == Id_w2) {
260 if (mCh.f.fixed_0 == Id_w0 && mCh.f.fixed_1 == Id_w1) {
261 mCh.w[2][NWPerGBTW - 1] = 0;
262 mCh.w[2][NWPerGBTW - 2] = 0;
263 memcpy((void*)&mCh.w[2][0], (const void*)word, PayloadPerGBTW);
264 process(mCh);
265 } else {
266 LOGF(error, "Wrong word sequence: %04x %08x %08x id=%u %u *%u*", *((uint16_t*)&word[2]), word[1], word[0], mCh.f.fixed_0, mCh.f.fixed_1, word[0] & 0x3);
267 }
268 mCh.f.fixed_0 = Id_wn;
269 mCh.f.fixed_1 = Id_wn;
270 mCh.f.fixed_2 = Id_wn;
271 } else {
272 // Word id not foreseen in payload
273 LOGF(error, "Event format error on word %04x %08x %08x id=%u", *((uint16_t*)&word[2]), word[1], word[0], word[0] & 0x3);
274 return 1;
275 }
276 return 0;
277}
278
280{
281 static constexpr int last_bc = o2::constants::lhc::LHCMaxBunches - 1;
282
283 union {
284 uint16_t uns;
285 int16_t sig;
286 } word16;
287
288 // Not empty event
289 auto f = ch.f;
290 int ih = getHPos(f.board, f.ch);
291 if (ih < 0 || ih >= NDigiChannels) {
292 return -1;
293 }
294
295 if (mVerbosity > 1) {
296 for (int32_t iw = 0; iw < NWPerBc; iw++) {
298 }
299 }
300
301 mTransmitted->Fill(f.board, f.ch);
302 if (f.Hit) {
303 mFired->Fill(f.board, f.ch);
304 }
305
306 static int16_t prev_s[NDigiChannels][NTimeBinsPerBC] = {0};
307 static uint32_t prev_orbit[NDigiChannels] = {0};
308 static uint16_t prev_bc[NDigiChannels] = {0};
309
310 uint16_t us[12];
311 int16_t s[12];
312 us[0] = f.s00;
313 us[1] = f.s01;
314 us[2] = f.s02;
315 us[3] = f.s03;
316 us[4] = f.s04;
317 us[5] = f.s05;
318 us[6] = f.s06;
319 us[7] = f.s07;
320 us[8] = f.s08;
321 us[9] = f.s09;
322 us[10] = f.s10;
323 us[11] = f.s11;
324 for (int32_t i = 0; i < 12; i++) {
325 if (us[i] > ADCMax) {
326 s[i] = us[i] - ADCRange;
327 } else {
328 s[i] = us[i];
329 }
330 // printf("%d %u %d\n",i,us[i],s[i]);
331 }
332 if (f.Alice_3) {
333 mBits->Fill(ih, 9);
334 if (f.Hit) {
335 mBitsH->Fill(ih, 9);
336 }
337 for (int32_t i = 0; i < 12; i++) {
338 mSignalA[ih]->Fill(i - 36., double(s[i]));
339 }
340 }
341 if (f.Alice_2) {
342 mBits->Fill(ih, 8);
343 if (f.Hit) {
344 mBitsH->Fill(ih, 8);
345 }
346 for (int32_t i = 0; i < 12; i++) {
347 mSignalA[ih]->Fill(i - 24., double(s[i]));
348 }
349 }
350 if (f.Alice_1) {
351 mBits->Fill(ih, 7);
352 if (f.Hit) {
353 mBitsH->Fill(ih, 7);
354 }
355 for (int32_t i = 0; i < 12; i++) {
356 mSignalA[ih]->Fill(i - 12., double(s[i]));
357 }
358 }
359 if (f.Alice_0) {
360 mBits->Fill(ih, 6);
361 if (f.Hit) {
362 mBitsH->Fill(ih, 6);
363 }
364 for (int32_t i = 0; i < 12; i++) {
365 mSignalA[ih]->Fill(i + 0., double(s[i]));
366 }
367 double bc_d = uint32_t(f.bc / 100);
368 double bc_m = uint32_t(f.bc % 100);
369 mBunchA[ih]->Fill(bc_m, -bc_d);
370 }
371 if (f.Auto_3) {
372 mBits->Fill(ih, 5);
373 if (f.Hit) {
374 mBitsH->Fill(ih, 5);
375 }
376 for (int32_t i = 0; i < 12; i++) {
377 mSignalT[ih]->Fill(i - 36., double(s[i]));
378 }
379 }
380 if (f.Auto_2) {
381 mBits->Fill(ih, 4);
382 if (f.Hit) {
383 mBitsH->Fill(ih, 4);
384 }
385 for (int32_t i = 0; i < 12; i++) {
386 mSignalT[ih]->Fill(i - 24., double(s[i]));
387 }
388 }
389 if (f.Auto_1) {
390 mBits->Fill(ih, 3);
391 if (f.Hit) {
392 mBitsH->Fill(ih, 3);
393 }
394 for (int32_t i = 0; i < 12; i++) {
395 mSignalT[ih]->Fill(i - 12., double(s[i]));
396 }
397 }
398 if (f.Auto_0) {
399 mBits->Fill(ih, 2);
400 if (f.Hit) {
401 mBitsH->Fill(ih, 2);
402 if ((prev_orbit[ih] == f.orbit && (f.bc - prev_bc[ih]) == 1) || ((f.orbit - prev_orbit[ih]) == 1 && prev_bc[ih] == 3563 && f.bc == 0)) {
403 for (int32_t i = 0; i < 12; i++) {
404 mSignalTH[ih]->Fill(i + 0., double(s[i]));
405 mSignalTH[ih]->Fill(i - NTimeBinsPerBC + 0., double(prev_s[ih][i]));
406 }
407 }
408 }
409 for (int32_t i = 0; i < 12; i++) {
410 mSignalT[ih]->Fill(i + 0., double(s[i]));
411 }
412 double bc_d = uint32_t(f.bc / 100);
413 double bc_m = uint32_t(f.bc % 100);
414 mBunchT[ih]->Fill(bc_m, -bc_d);
415 }
416 if (f.Auto_m) {
417 mBits->Fill(ih, 1);
418 if (f.Hit) {
419 mBitsH->Fill(ih, 1);
420 }
421 for (int32_t i = 0; i < 12; i++) {
422 mSignalT[ih]->Fill(i + 12., double(s[i]));
423 }
424 }
425 if (!(f.Alice_3 || f.Alice_2 || f.Alice_1 || f.Alice_0 || f.Alice_1 || f.Auto_3 || f.Auto_2 || f.Auto_1 || f.Auto_0 || f.Auto_m)) {
426 mBits->Fill(ih, 0);
427 if (f.Hit) {
428 mBitsH->Fill(ih, 0);
429 }
430 }
431 if (f.Hit) {
432 double bc_d = uint32_t(f.bc / 100);
433 double bc_m = uint32_t(f.bc % 100);
434 mBunchH[ih]->Fill(bc_m, -bc_d);
435 }
437 mOve->Fill(ih);
438 }
439
440 if (f.bc == last_bc) {
441 word16.uns = f.offset;
442 mBaseline[ih]->Fill(word16.sig);
443 mCounts[ih]->Fill(f.hits & 0xfff);
444 if (f.dLoss) {
445 mLoss->Fill(ih);
446 }
447 if (f.error) {
448 mError->Fill(ih);
449 }
450 }
451 // Save information to process next bunch crossing
452 prev_orbit[ih] = f.orbit;
453 prev_bc[ih] = f.bc;
454 for (int32_t i = 0; i < 12; i++) {
455 prev_s[ih][i] = s[i];
456 }
457 return 0;
458}
459
461{
462 for (int32_t im = 0; im < NModules; im++) {
463 for (int32_t ic = 0; ic < NChPerModule; ic++) {
464 if (ev.data[im][ic].f.fixed_0 == Id_w0 && ev.data[im][ic].f.fixed_1 == Id_w1 && ev.data[im][ic].f.fixed_2 == Id_w2) {
465 process(ev.data[im][ic]);
466 } else if (ev.data[im][ic].f.fixed_0 == 0 && ev.data[im][ic].f.fixed_1 == 0 && ev.data[im][ic].f.fixed_2 == 0) {
467 // Empty channel
468 } else {
469 LOG(error) << "Data format error";
470 }
471 }
472 }
473 return 0;
474}
int32_t i
Header to collect LHC related constants.
converts digits to raw format
benchmark::State & st
Class for time synchronization of RawReader instances.
static void print_gbt_word(const uint32_t *word, const ModuleConfig *moduleConfig=nullptr)
int process(const EventData &ev)
Definition DumpRaw.cxx:460
int getHPos(uint32_t board, uint32_t ch)
Definition DumpRaw.cxx:226
int processWord(const uint32_t *word)
Definition DumpRaw.cxx:237
GLdouble f
Definition glcorearb.h:310
constexpr int LHCMaxBunches
constexpr int NModules
Definition Constants.h:68
constexpr unsigned short Id_wn
constexpr int NTimeBinsPerBC
Definition Constants.h:53
constexpr int NChPerModule
Definition Constants.h:69
constexpr int NWPerGBTW
constexpr unsigned short Id_w1
constexpr int ADCRange
Definition Constants.h:76
constexpr int PayloadPerGBTW
constexpr int NWPerBc
Definition Constants.h:72
constexpr unsigned short Id_w2
constexpr unsigned short Id_w0
constexpr int ADCMin
Definition Constants.h:76
constexpr int ADCMax
Definition Constants.h:76
constexpr int NDigiChannels
Definition Constants.h:71
EventChData data[NModules][NChPerModule]
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
struct ChannelDataV0 f
UInt_t w[NWPerBc][NWPerGBTW]