Project
Loading...
Searching...
No Matches
DigiParser.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 <TMath.h>
13#include <TROOT.h>
14#include <TPad.h>
15#include <TString.h>
16#include <TAxis.h>
17#include <TStyle.h>
18#include <TPaveStats.h>
19#include "Framework/Logger.h"
23
24namespace o2
25{
26namespace zdc
27{
28
30{
31 LOG(info) << "Initialization of ZDC DigiParser";
32 if (!mModuleConfig) {
33 LOG(fatal) << "Missing ModuleConfig configuration object";
34 return;
35 }
36
37 mTriggerMask = mModuleConfig->getTriggerMask();
38
39 // Update reconstruction parameters
41 ropt.print();
42 mRopt = (o2::zdc::RecoParamZDC*)&ropt;
43
44 // Fill maps channel maps for integration
45 for (int ich = 0; ich < NChannels; ich++) {
46 // If the reconstruction parameters were not manually set
47 if (ropt.amod[ich] < 0 || ropt.ach[ich] < 0) {
48 for (int im = 0; im < NModules; im++) {
49 for (uint32_t ic = 0; ic < NChPerModule; ic++) {
50 if (mModuleConfig->modules[im].channelID[ic] == ich && mModuleConfig->modules[im].readChannel[ic]) {
51 ropt.amod[ich] = im;
52 ropt.ach[ich] = ic;
53 // Fill mask to identify all channels
54 mChMask[ich] = (0x1 << (4 * im + ic));
55 goto next_ich;
56 }
57 }
58 }
59 } else {
60 // Fill mask to identify all channels
61 mChMask[ich] = (0x1 << (4 * ropt.amod[ich] + ropt.ach[ich]));
62 }
63 next_ich:;
64 if (mVerbosity > DbgZero) {
65 LOG(info) << "Channel " << ich << "(" << ChannelNames[ich] << ") mod " << ropt.amod[ich] << " ch " << ropt.ach[ich] << " bit " << (4 * ropt.amod[ich] + ropt.ach[ich]);
66 }
67 }
68
69 double xmin = -3 * NTimeBinsPerBC - 0.5;
70 double xmax = 2 * NTimeBinsPerBC - 0.5;
71 int nbx = std::round(xmax - xmin);
72
73 if (mTransmitted == nullptr) {
74 mTransmitted = std::make_unique<TH1F>("ht", "Transmitted channels", NChannels, -0.5, NChannels - 0.5);
75 }
76 if (mFired == nullptr) {
77 mFired = std::make_unique<TH1F>("hfired", "Fired channels", NChannels, -0.5, NChannels - 0.5);
78 }
79 if (mAlignment == nullptr) {
80 mAlignment = std::make_unique<TH2F>("hmap", "Map of fired channels", o2::constants::lhc::LHCMaxBunches, -0.5, o2::constants::lhc::LHCMaxBunches - 0.5, NChannels, -0.5, NChannels - 0.5);
81 }
82 for (uint32_t ich = 0; ich < NChannels; ich++) {
83 if (mBaseline[ich] == nullptr) {
84 TString hname = TString::Format("hp_%s", ChannelNames[ich].data());
85 TString htit = TString::Format("Baseline %s;Average orbit baseline", ChannelNames[ich].data());
86 mBaseline[ich] = std::make_unique<TH1F>(hname, htit, 65536, -32768.5, 32767.5);
87 }
88 if (mCounts[ich] == nullptr) {
89 TString hname = TString::Format("hc_%s", ChannelNames[ich].data());
90 TString htit = TString::Format("Counts %s; Orbit hits", ChannelNames[ich].data());
91 mCounts[ich] = std::make_unique<TH1F>(hname, htit, o2::constants::lhc::LHCMaxBunches + 1, -0.5, o2::constants::lhc::LHCMaxBunches + 0.5);
92 }
93 if (mSignalTH[ich] == nullptr) {
94 TString hname = TString::Format("hsth_%s", ChannelNames[ich].data());
95 TString htit = TString::Format("Signal %s AUTOT & Hit; Sample; ADC", ChannelNames[ich].data());
96 if (mRejectPileUp) {
97 mSignalTH[ich] = std::make_unique<TH2F>(hname, htit, 3 * NTimeBinsPerBC, -0.5 - 1 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5);
98 } else {
99 mSignalTH[ich] = std::make_unique<TH2F>(hname, htit, 5 * NTimeBinsPerBC, -0.5 - 3 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5);
100 }
101 }
102 if (mBunchH[ich] == nullptr) {
103 TString hname = TString::Format("hbh_%s", ChannelNames[ich].data());
104 TString htit = TString::Format("Bunch %s AUTOT Hit; BC units; - BC hundreds", ChannelNames[ich].data());
105 mBunchH[ich] = std::make_unique<TH2F>(hname, htit, 100, -0.5, 99.5, 36, -35.5, 0.5);
106 }
107 }
108} // init
109
111{
112 TFile* f = new TFile(mOutput.data(), "recreate");
113 if (f->IsZombie()) {
114 LOG(fatal) << "Cannot write to file " << f->GetName();
115 return;
116 }
117 for (uint32_t i = 0; i < NChannels; i++) {
118 setStat(mBunchH[i].get());
119 mBunchH[i]->Write();
120 }
121 for (uint32_t i = 0; i < NChannels; i++) {
122 setStat(mBaseline[i].get());
123 mBaseline[i]->Write();
124 }
125 for (uint32_t i = 0; i < NChannels; i++) {
126 setStat(mCounts[i].get());
127 mCounts[i]->Write();
128 }
129 for (uint32_t i = 0; i < NChannels; i++) {
130 setStat(mSignalTH[i].get());
131 mSignalTH[i]->Write();
132 }
133 setModuleLabel(mTransmitted.get());
134 mTransmitted->SetMinimum(0);
135 mTransmitted->Write();
136 setModuleLabel(mFired.get());
137 mFired->SetMinimum(0);
138 mFired->Write();
139 setModuleLabel((mAlignment.get())->GetYaxis());
140 mAlignment->SetMinimum(0);
141 mAlignment->Write();
142 f->Close();
143}
144
145int DigiParser::process(const gsl::span<const o2::zdc::OrbitData>& orbitdata, const gsl::span<const o2::zdc::BCData>& bcdata, const gsl::span<const o2::zdc::ChannelData>& chdata)
146{
147 // We assume that vectors contain data from a full time frame
148 int norb = orbitdata.size();
149
150 uint32_t scaler[NChannels] = {0};
151 for (int iorb = 0; iorb < norb; iorb++) {
152 for (int ich = 0; ich < NChannels; ich++) {
153 if (orbitdata[iorb].scaler[ich] <= o2::constants::lhc::LHCMaxBunches) {
154 scaler[ich] += orbitdata[iorb].scaler[ich];
155 mCounts[ich]->Fill(orbitdata[iorb].scaler[ich]);
156 auto myped = float(orbitdata[iorb].data[ich]) * mModuleConfig->baselineFactor;
157 if (myped >= ADCMin && myped <= ADCMax) {
158 // Pedestal information is present for this channel
159 mBaseline[ich]->Fill(myped);
160 }
161 } else {
162 LOG(warn) << "Corrupted scaler data for orbit " << orbitdata[iorb].ir.orbit;
163 }
164 }
165 }
166
167 mNBC = bcdata.size();
168 std::vector<std::array<uint32_t, NChannels>> chRef;
169 chRef.resize(mNBC);
170
171 // Assign data references
172 for (int ibc = 0; ibc < mNBC; ibc++) {
173 auto& bcd = bcdata[ibc];
174 int chEnt = bcd.ref.getFirstEntry();
175 for (int ich = 0; ich < NChannels; ich++) {
176 chRef[ibc][ich] = ZDCRefInitVal;
177 }
178 for (int ic = 0; ic < bcd.ref.getEntries(); ic++) {
179 auto& chd = chdata[chEnt];
180 if (chd.id > IdDummy && chd.id < NChannels) {
181 chRef[ibc][chd.id] = chEnt;
182 mTransmitted->Fill(chd.id);
183 if ((bcdata[ibc].triggers & mChMask[chd.id]) != 0) {
184 mFired->Fill(chd.id);
185 }
186 }
187 chEnt++;
188 }
189 }
190
191 for (uint32_t isig = 0; isig < NChannels; isig++) {
192 for (int ibc = 0; ibc < mNBC; ibc++) {
193 auto& ir = bcdata[ibc].ir;
194 // Identify pile-up
195 if (mRejectPileUp) {
196 int nsig = 0;
197 // Check previous bunches
198 for (int ibn = -4; ibn < 5; ibn++) {
199 int ibt = ibc + ibn;
200 if (ibt >= 0) { // Check backward and current bunch
201 if (ibt < mNBC) {
202 auto bcd = bcdata[ibt].ir.differenceInBC(ir);
203 if (bcd == ibn) {
204 if ((bcdata[ibt].triggers & mChMask[isig]) != 0) {
205 nsig++;
206 }
207 }
208 } else {
209 break;
210 }
211 }
212 }
213 if (nsig > 1) {
214 continue;
215 }
216 }
217 // Check previous, current and next bunch crossings
218 for (int ibn = -1; ibn < 4; ibn++) {
219 int ibt = ibc + ibn;
220 if (ibt >= 0) { // Check backward and current bunch
221 if (ibt < mNBC) { // Check forward bunches
222 auto bcd = bcdata[ibt].ir.differenceInBC(ir);
223 if (bcd == 0) {
224 // Fill bunch map
225 if ((bcdata[ibc].triggers & mChMask[isig]) != 0) {
226 double bc_d = uint32_t(ir.bc / 100);
227 double bc_m = uint32_t(ir.bc % 100);
228 mBunchH[isig]->Fill(bc_m, -bc_d);
229 mFired->Fill(isig);
230 mAlignment->Fill(ir.bc, isig);
231 }
232 }
233 if (bcd == ibn) {
234 if ((bcdata[ibt].triggers & mChMask[isig]) != 0) {
235 // Fill waveform
236 auto ref = chRef[ibc][isig];
237 if (ref != ZDCRefInitVal) {
238 for (int is = 0; is < NTimeBinsPerBC; is++) {
239 mSignalTH[isig]->Fill(-ibn * NTimeBinsPerBC + is, chdata[ref].data[is]);
240 }
241 }
242 }
243 }
244 } else {
245 break;
246 }
247 }
248 }
249 }
250 }
251 return 0;
252} // process
253
254void DigiParser::setStat(TH1* h)
255{
256 TString hn = h->GetName();
257 h->Draw();
258 gPad->Update();
259 TPaveStats* st = (TPaveStats*)h->GetListOfFunctions()->FindObject("stats");
260 st->SetFillStyle(1001);
261 st->SetBorderSize(1);
262 if (hn.BeginsWith("hp")) {
263 st->SetOptStat(111111);
264 st->SetX1NDC(0.1);
265 st->SetX2NDC(0.3);
266 st->SetY1NDC(0.640);
267 st->SetY2NDC(0.9);
268 } else if (hn.BeginsWith("hc")) {
269 st->SetOptStat(1111);
270 st->SetX1NDC(0.799);
271 st->SetX2NDC(0.999);
272 st->SetY1NDC(0.829);
273 st->SetY2NDC(0.999);
274 } else if (hn.BeginsWith("hs") || hn.BeginsWith("hb")) {
275 st->SetOptStat(11);
276 st->SetX1NDC(0.799);
277 st->SetX2NDC(0.9995);
278 st->SetY1NDC(0.904);
279 st->SetY2NDC(0.999);
280 }
281}
282
283void DigiParser::setModuleLabel(TH1* h)
284{
285 for (uint32_t isig = 0; isig < NChannels; isig++) {
286 h->GetXaxis()->SetBinLabel(isig + 1, ChannelNames[isig].data());
287 }
288}
289
290void DigiParser::setModuleLabel(TAxis* ax)
291{
292 for (uint32_t isig = 0; isig < NChannels; isig++) {
293 ax->SetBinLabel(isig + 1, ChannelNames[isig].data());
294 }
295}
296
297} // namespace zdc
298} // namespace o2
int32_t i
Header to collect LHC related constants.
ZDC reconstruction parameters.
benchmark::State & st
Class for time synchronization of RawReader instances.
int process(const gsl::span< const o2::zdc::OrbitData > &orbitdata, const gsl::span< const o2::zdc::BCData > &bcdata, const gsl::span< const o2::zdc::ChannelData > &chdata)
GLdouble f
Definition glcorearb.h:310
GLboolean * data
Definition glcorearb.h:298
constexpr int LHCMaxBunches
struct o2::upgrades_utils::@463 zdc
structure to keep FT0 information
constexpr int NModules
Definition Constants.h:68
constexpr int NTimeBinsPerBC
Definition Constants.h:53
constexpr uint32_t ZDCRefInitVal
Definition Constants.h:91
constexpr int NChPerModule
Definition Constants.h:69
constexpr int NChannels
Definition Constants.h:65
constexpr int ADCRange
Definition Constants.h:76
constexpr int DbgZero
Definition Constants.h:207
constexpr int IdDummy
constexpr int ADCMin
Definition Constants.h:76
constexpr std::string_view ChannelNames[]
Definition Constants.h:147
constexpr int ADCMax
Definition Constants.h:76
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint16_t bc
bunch crossing ID of interaction
int64_t differenceInBC(const InteractionRecord &other) const
uint32_t getTriggerMask() const
std::array< Module, MaxNModules > modules
int32_t amod[NChannels]
int32_t ach[NChannels]
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)