Belle II Software development
SVDUnpackerDQMModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include "svd/modules/svdDQM/SVDUnpackerDQMModule.h"
10#include <svd/online/SVDOnlineToOfflineMap.h>
11
12#include <framework/datastore/StoreObjPtr.h>
13#include <framework/datastore/StoreArray.h>
14
15#include <svd/dataobjects/SVDDAQDiagnostic.h>
16
17#include <TDirectory.h>
18#include <TLine.h>
19#include <TStyle.h>
20
21#include <algorithm>
22#include <string>
23#include <format>
24
25
26using namespace std;
27using namespace Belle2;
28
29//-----------------------------------------------------------------
30// Register the Module
31//-----------------------------------------------------------------
32REG_MODULE(SVDUnpackerDQM);
33
34
35//-----------------------------------------------------------------
36// Implementation
37//-----------------------------------------------------------------
38
39std::string SVDUnpackerDQMModule::m_xmlFileName = std::string("SVDChannelMapping.xml");
40
42{
43 //Set module properties
44 setDescription("DQM Histogram of the SVD Raw Data format.");
45
46 addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of the directory where histograms will be placed.",
47 std::string("SVDUnpacker"));
48 addParam("DAQDiagnostics", m_SVDDAQDiagnosticsName, "Name of DAQDiagnostics Store Array.", std::string(""));
49 addParam("EventInfo", m_SVDEventInfoName, "Name of SVDEventInfo object.", std::string(""));
50
51 setPropertyFlags(c_ParallelProcessingCertified); // specify this flag if you need parallel processing
52}
53
54
55SVDUnpackerDQMModule::~SVDUnpackerDQMModule()
56{
57}
58
59//------------------------------------------------------------------
60// Function to define histograms
61//-----------------------------------------------------------------
62
64{
65
66 // Create a separate histogram directories and cd into it.
67 TDirectory* oldDir = gDirectory;
68 if (m_histogramDirectoryName != "") {
69 oldDir->mkdir(m_histogramDirectoryName.c_str());// do not use return value with ->cd(), its ZERO if dir already exists
70 oldDir->cd(m_histogramDirectoryName.c_str());
71 }
72
73 const unsigned short Bins_FTBFlags = 5;
74 const unsigned short Bins_FTBError = 4;
75 const unsigned short Bins_APVError = 4;
76 const unsigned short Bins_APVMatch = 1;
77 const unsigned short Bins_FADCMatch = 1;
78 const unsigned short Bins_UpsetAPV = 1;
79 const unsigned short Bins_BadMapping = 1;
80 const unsigned short Bins_BadHeader = 1;
81 const unsigned short Bins_MissedTrailer = 1;
82 const unsigned short Bins_MissedHeader = 1;
83 const unsigned short Bins_SEURecoData = 1;
84
85
86 const unsigned short nBins = Bins_FTBFlags + Bins_FTBError + Bins_APVError + Bins_APVMatch + Bins_FADCMatch + Bins_UpsetAPV +
87 Bins_BadMapping + Bins_BadHeader + Bins_MissedTrailer + Bins_MissedHeader + Bins_SEURecoData;
88
89 m_DQMUnpackerHisto = new TH2F("DQMUnpackerHisto", "SVD Data Format Monitor", nBins, 1, nBins + 1, 52, 1, 53);
90 m_DQMErrorEventsHisto = new TH1F("DQMErrorEventsHisto", "SVD Errors Event Counter", 4, 0, 4);
91 m_DQMSeuRecoveryFADCsEventHisto = new TH1F("DQMSeuRecoveryFADCsEventHisto", "Number of FADCs with SEURecovery", 53, 0, 53);
92 m_DQMnSamplesHisto = new TH2F("DQMnSamplesHisto", "nAPVsamples VS DAQMode", 3, 1, 4, 2, 1, 3);
93 m_DQMnSamplesHisto2 = new TH2F("DQMnSamplesHisto2", "nAPVsamples VS DAQMode", 2, 1, 3, 2, 1, 3);
94 m_DQMtrgQuality = new TH2F("DQMtrgQuality", "nAPVsamples VS trgQuality", 4, 1, 5, 2, 1, 3);
95
96 m_SEUonSensors = new SVDSummaryPlots("SEURecoOnSensors@view",
97 "SVD SEU (errAPV or errDET or errSYNC) detected on Sensors for the @view/@side");
98
99 m_DQMUnpackerHisto->GetYaxis()->SetTitle("FADC board");
100 m_DQMUnpackerHisto->GetYaxis()->SetTitleOffset(1.2);
101
102 m_DQMErrorEventsHisto->GetYaxis()->SetTitle("# of Events");
103 m_DQMErrorEventsHisto->GetYaxis()->SetTitleOffset(1.5);
104 m_DQMErrorEventsHisto->SetMinimum(0.7);
105
106 m_DQMSeuRecoveryFADCsEventHisto->GetYaxis()->SetTitle("# of Events");
107 m_DQMSeuRecoveryFADCsEventHisto->GetYaxis()->SetTitleOffset(1.5);
108 m_DQMSeuRecoveryFADCsEventHisto->SetMinimum(0.7);
109 m_DQMSeuRecoveryFADCsEventHisto->SetMaximum(1.0);
110
111 m_DQMnSamplesHisto->GetXaxis()->SetTitle("DAQ Mode");
112 m_DQMnSamplesHisto->GetYaxis()->SetTitle("number of APV samples");
113
114 m_DQMnSamplesHisto2->GetXaxis()->SetTitle("DAQ Mode");
115 m_DQMnSamplesHisto2->GetYaxis()->SetTitle("number of APV samples");
116
117 m_DQMtrgQuality->GetXaxis()->SetTitle("TRG Quality");
118 m_DQMtrgQuality->GetYaxis()->SetTitle("number of APV samples");
119
120 TString Xlabels[nBins] = {"EvTooLong", "TimeOut", "doubleHead", "badEvt", "errCRC", "badFADC", "badTTD", "badFTB", "badALL", "errAPV", "errDET", "errFrame", "errFIFO", "APVmatch", "FADCmatch", "errSYNC", "EVTmatch", "missHead", "missTrail", "badMapping", "EmptyEvts(SEURecovery)"};
121
122 TString Ysamples[2] = {"3", "6"};
123 TString Xsamples[3] = {"3 samples", "6 samples", "3/6 mixed"};
124
125 TString Xquality[4] = {"coarse", "fine", "super fine", "no TRGSummary"};
126
127 //preparing X axis of the DQMUnpacker histograms
128 for (unsigned short i = 0; i < nBins; i++) m_DQMUnpackerHisto->GetXaxis()->SetBinLabel(i + 1, Xlabels[i].Data());
129
130 //preparing X and Y axis of the DQMnSamples histograms
131 for (unsigned short i = 0; i < 3; i++) m_DQMnSamplesHisto->GetXaxis()->SetBinLabel(i + 1, Xsamples[i].Data());
132 for (unsigned short i = 0; i < 2; i++) m_DQMnSamplesHisto2->GetXaxis()->SetBinLabel(i + 1, Xsamples[i].Data());
133
134 for (unsigned short i = 0; i < 2; i++) m_DQMnSamplesHisto->GetYaxis()->SetBinLabel(i + 1, Ysamples[i].Data());
135 for (unsigned short i = 0; i < 2; i++) m_DQMnSamplesHisto2->GetYaxis()->SetBinLabel(i + 1, Ysamples[i].Data());
136
137 //preparing X and Y axis of the DQMtrgQuality histograms
138 for (unsigned short i = 0; i < 4; i++) m_DQMtrgQuality->GetXaxis()->SetBinLabel(i + 1, Xquality[i].Data());
139 for (unsigned short i = 0; i < 2; i++) m_DQMtrgQuality->GetYaxis()->SetBinLabel(i + 1, Ysamples[i].Data());
140
141 m_DQMErrorEventsHisto->GetXaxis()->SetBinLabel(1, "No Errors");
142 m_DQMErrorEventsHisto->GetXaxis()->SetBinLabel(2, "Any Error");
143 m_DQMErrorEventsHisto->GetXaxis()->SetBinLabel(3, "Evts(SEURecovery)");
144 m_DQMErrorEventsHisto->GetXaxis()->SetBinLabel(4, "EmptyEvts(SEURecovery)");
145
146 m_DQMSeuRecoveryFADCsEventHisto->GetXaxis()->SetTitle("number of affected FADCs");
147
148 oldDir->cd();
149}
150
152{
153 m_eventMetaData.isRequired();
156 m_objTrgSummary.isOptional();
157
158 // Register histograms (calls back defineHisto)
159 REG_HISTOGRAM
160}
161
162
164{
165
166 StoreObjPtr<EventMetaData> evtMetaData;
167 m_expNumber = evtMetaData->getExperiment();
168 m_runNumber = evtMetaData->getRun();
169 m_errorFraction = 0;
170
171 std::string runID = std::format(" ~ Exp {:d} Run {:d}", m_expNumber, m_runNumber);
172
173 if (m_DQMUnpackerHisto != nullptr) {
174 TString tmp = m_DQMUnpackerHisto->GetTitle();
175 Int_t pos = tmp.Last('~');
176 if (pos == -1) pos = tmp.Length() + 2;
177 TString title = tmp(0, pos - 2);
178 m_DQMUnpackerHisto->SetTitle(title + runID.c_str());
179 m_DQMUnpackerHisto->Reset();
180 }
181
182 if (m_DQMErrorEventsHisto != nullptr) {
183 TString tmp = m_DQMErrorEventsHisto->GetTitle();
184 Int_t pos = tmp.Last('~');
185 if (pos == -1) pos = tmp.Length() + 2;
186 TString title = tmp(0, pos - 2);
187 m_DQMErrorEventsHisto->SetTitle(title + runID.c_str());
188 m_DQMErrorEventsHisto->Reset();
189 }
190
191 if (m_DQMSeuRecoveryFADCsEventHisto != nullptr) {
192 TString tmp = m_DQMSeuRecoveryFADCsEventHisto->GetTitle();
193 Int_t pos = tmp.Last('~');
194 if (pos == -1) pos = tmp.Length() + 2;
195 TString title = tmp(0, pos - 2);
196 m_DQMSeuRecoveryFADCsEventHisto->SetTitle(title + runID.c_str());
198 }
199
200 if (m_DQMnSamplesHisto != nullptr) {
201 TString tmp = m_DQMnSamplesHisto->GetTitle();
202 Int_t pos = tmp.Last('~');
203 if (pos == -1) pos = tmp.Length() + 2;
204 TString title = tmp(0, pos - 2);
205 m_DQMnSamplesHisto->SetTitle(title + runID.c_str());
206 m_DQMnSamplesHisto->Reset();
207 }
208
209 if (m_DQMnSamplesHisto2 != nullptr) {
210 TString tmp = m_DQMnSamplesHisto2->GetTitle();
211 Int_t pos = tmp.Last('~');
212 if (pos == -1) pos = tmp.Length() + 2;
213 TString title = tmp(0, pos - 2);
214 m_DQMnSamplesHisto2->SetTitle(title + runID.c_str());
215 m_DQMnSamplesHisto2->Reset();
216 }
217
218 if (m_DQMtrgQuality != nullptr) {
219 TString tmp = m_DQMtrgQuality->GetTitle();
220 Int_t pos = tmp.Last('~');
221 if (pos == -1) pos = tmp.Length() + 2;
222 TString title = tmp(0, pos - 2);
223 m_DQMtrgQuality->SetTitle(title + runID.c_str());
224 m_DQMtrgQuality->Reset();
225 }
226
227 m_shutUpNoData = false;
228
229 if (m_mapping.hasChanged()) { m_map = std::make_unique<SVDOnlineToOfflineMap>(m_mapping->getFileName()); }
230
231 m_changeFADCaxis = false;
232
233 //getting fadc numbers from the mapping
234 m_FADCs = &(m_map->FADCnumbers);
235
236 //copy FADC numbers to vector and sort them
237 m_vec_fadc.insert(m_vec_fadc.end(), m_FADCs->begin(), m_FADCs->end());
238 std::sort(m_vec_fadc.begin(), m_vec_fadc.end());
239
240 unsigned short ifadc = 0;
241 for (const auto& fadc : m_vec_fadc) {
242 m_fadc_map.insert(make_pair(fadc, ++ifadc));
243 m_DQMUnpackerHisto->GetYaxis()->SetBinLabel(ifadc, to_string(fadc).c_str());
244 }
245
246 m_nEvents = 0;
247 m_nBadEvents = 0;
248}
249
250
252{
253 if (!m_svdDAQDiagnostics.isValid()) {
254 if (!m_shutUpNoData)
255 B2WARNING("There are no SVDDAQDiagnostic objects saved by the Unpacker! SVD Data Format Monitoring disabled!");
256 m_shutUpNoData = true;
257 return;
258 }
259
260 if (!m_svdEventInfo.isValid()) {
261 if (!m_shutUpNoData)
262 B2WARNING("There is no SVDEventInfo object saved by the Unpacker! SVD Data Format Monitoring disabled!");
263 m_shutUpNoData = true;
264 return;
265 }
266
267 m_badEvent = 0;
268 m_seuEvent = 0;
269 m_seuRecoEvent = 0;
270 m_seuFADCs.clear();
271
272 m_nEvents++;
273
274 // filling nSamplesHisto
275 int daqMode = m_svdEventInfo->getModeByte().getDAQMode();
276 int nSamples = m_svdEventInfo->getNSamples();
277
278 m_DQMnSamplesHisto->Fill(daqMode, nSamples / 3);
279 if (daqMode < 3) m_DQMnSamplesHisto2->Fill(daqMode, nSamples / 3);
280
281
282 //filling TRGqualityHisto
283 if (m_objTrgSummary.isValid()) {
284 int trgQuality = m_objTrgSummary->getTimQuality();
285 m_DQMtrgQuality->Fill(trgQuality, nSamples / 3);
286 } else m_DQMtrgQuality->Fill(4, nSamples / 3);
287
288
289 //filling m_DQMUnpackerHisto
290 unsigned short bin_no = 0;
291 gStyle->SetOptStat(0);
292
293 for (const auto& d : m_svdDAQDiagnostics) {
294
295 m_ftbFlags = d.getFTBFlags();
296 m_ftbError = d.getFTBError();
297 m_apvError = d.getAPVError();
298 m_apvMatch = d.getAPVMatch();
299 m_fadcMatch = d.getFADCMatch();
300 m_upsetAPV = d.getUpsetAPV();
301 m_badMapping = d.getBadMapping();
302 m_badHeader = d.getBadHeader();
303 m_badTrailer = d.getBadTrailer();
304 m_missedHeader = d.getMissedHeader();
305 m_missedTrailer = d.getMissedTrailer();
306 m_seuRecoData = d.getSEURecoData();
307 m_fadcNo = d.getFADCNumber();
308 m_apvNo = d.getAPVNumber();
309
310 // insert FADCnumber into the map (if not already there) and assign the next bin to it.
311 if (m_changeFADCaxis) {
312 if (m_fadc_map.find(m_fadcNo) == m_fadc_map.end()) m_fadc_map.insert(make_pair(m_fadcNo, ++bin_no));
313 }
314
315 if (m_ftbFlags != 0 or m_ftbError != 240 or m_apvError != 0 or !m_apvMatch or !m_fadcMatch or m_upsetAPV or m_badMapping
316 or m_badHeader
318
319 m_badEvent = 1;
320
321 auto ybin = m_fadc_map.find(m_fadcNo);
322
323 if (m_badMapping) {
324 if (!m_changeFADCaxis) {
325 m_changeFADCaxis = true;
326 m_fadc_map.clear();
327 break;
328 } else {
329 m_DQMUnpackerHisto->Fill(20, ybin->second);
330 }
331 }
332
333 if (m_apvError & 8 or m_apvError & 4 or m_upsetAPV) {
334 m_seuEvent = 1;
335
336 //let's retrieve the sensor info for this SEU case
337 SVDOnlineToOfflineMap::SensorInfo theVxdInfo = m_map->getSensorInfo(m_fadcNo, m_apvNo);
338 VxdID::baseType theVxdID = theVxdInfo.m_sensorID;
339 bool side = theVxdInfo.m_uSide;
340
341 m_SEUonSensors->fill(theVxdID, side, 1);
342 }
343
344 if (m_badHeader) m_DQMUnpackerHisto->Fill(17, ybin->second);
345 if (m_missedHeader) m_DQMUnpackerHisto->Fill(18, ybin->second);
346 if (m_badTrailer or m_missedTrailer) m_DQMUnpackerHisto->Fill(19, ybin->second);
347
348 if (m_ftbFlags != 0) {
349 if (m_ftbFlags & 16) m_DQMUnpackerHisto->Fill(5, ybin->second);
350 if (m_ftbFlags & 8) m_DQMUnpackerHisto->Fill(4, ybin->second);
351 if (m_ftbFlags & 4) m_DQMUnpackerHisto->Fill(3, ybin->second);
352 if (m_ftbFlags & 2) m_DQMUnpackerHisto->Fill(2, ybin->second);
353 if (m_ftbFlags & 1) m_DQMUnpackerHisto->Fill(1, ybin->second);
354 }
355 if (m_ftbError != 240) {
356 switch (m_ftbError - 240) {
357 case 3:
358 m_DQMUnpackerHisto->Fill(6, ybin->second); //badFADC
359 break;
360 case 5:
361 m_DQMUnpackerHisto->Fill(7, ybin->second); //badTTD
362 break;
363 case 6:
364 m_DQMUnpackerHisto->Fill(8, ybin->second); //badFTB
365 break;
366 case 7:
367 m_DQMUnpackerHisto->Fill(9, ybin->second);//badALL;
368 break;
369 }
370 }
371
372 if (m_apvError != 0) {
373 if (m_apvError & 8) m_DQMUnpackerHisto->Fill(10, ybin->second);
374 if (m_apvError & 4) m_DQMUnpackerHisto->Fill(11, ybin->second);
375 if (m_apvError & 2) m_DQMUnpackerHisto->Fill(12, ybin->second);
376 if (m_apvError & 1) m_DQMUnpackerHisto->Fill(13, ybin->second);
377 }
378
379 if (!m_apvMatch) m_DQMUnpackerHisto->Fill(14, ybin->second);
380 if (!m_fadcMatch) m_DQMUnpackerHisto->Fill(15, ybin->second);
381 if (m_upsetAPV) m_DQMUnpackerHisto->Fill(16, ybin->second);
382 if (m_seuRecoData) {
383
384 m_DQMUnpackerHisto->Fill(21, ybin->second);
385 m_seuRecoEvent = 1;
386 m_seuFADCs.insert(ybin->first);
387
388 }
389
390 }
391 } //end Diagnostics loop
392
393
394 if (m_changeFADCaxis) {
395 for (auto& iFADC : m_fadc_map) m_DQMUnpackerHisto->GetYaxis()->SetBinLabel(iFADC.second, to_string(iFADC.first).c_str());
396 }
398 m_errorFraction = 100 * float(m_nBadEvents) / float(m_nEvents);
399
400 if (m_DQMErrorEventsHisto != nullptr) {
401 std::string runID = std::format(" ~ Exp {:d} Run {:d}", m_expNumber, m_runNumber);
402 std::string histoErrorTitle = std::format("SVD Events with errors {:s} # Error Fraction: {:6.4e} %%", runID.c_str(),
404 m_DQMErrorEventsHisto->SetTitle(histoErrorTitle.c_str());
405 if (!m_badEvent) m_DQMErrorEventsHisto->Fill(0);
406 else m_DQMErrorEventsHisto->Fill(1);
407 if (m_seuEvent) m_DQMErrorEventsHisto->Fill(2);
409 }
410
411 if (m_DQMSeuRecoveryFADCsEventHisto != nullptr) {
412 if (m_seuFADCs.size() > 0) {
413 m_DQMSeuRecoveryFADCsEventHisto->SetMaximum(-1111);
415 }
416 }
417} // end event function
418
419
421{
422 // Summary report on SVD DQM monitor
423 if (m_nBadEvents) {
424 B2WARNING("=================== SVD DQM Data Format Statistics: =============");
425 B2WARNING(" We found " << m_nBadEvents << "/" << m_nEvents << " corrupted events, which is " << m_errorFraction <<
426 "%");
427 B2WARNING("=================================================================");
428 }
429
430}
HistoModule()
Constructor.
Definition HistoModule.h:32
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
class to summarize SVD quantities per sensor and side
TH1F * m_DQMSeuRecoveryFADCsEventHisto
TH1F histogram showing the number of FADC with SEU recoveries per event.
unsigned int m_nBadEvents
counter of events with any kind of error
void initialize() override final
Module function initialize.
TH2F * m_DQMnSamplesHisto2
TH2F histogram showing number of samples in data VS daqMode (2bins only)
unsigned short m_apvNo
apv number
bool m_seuEvent
indicates if the particular event is SEU case
unsigned int m_nEvents
event counter
bool m_seuRecoData
special SEU recovery data
StoreObjPtr< SVDEventInfo > m_svdEventInfo
SVDEventInfo StoreObjectPointer.
bool m_missedHeader
missed Header error
bool m_shutUpNoData
shut up if no data comes
TH2F * m_DQMUnpackerHisto
TH2F histogram with Unpacking errors.
std::string m_SVDDAQDiagnosticsName
SVD diagnostics module name.
StoreArray< SVDDAQDiagnostic > m_svdDAQDiagnostics
SVDDAQDiagnostic StoreArray.
std::vector< unsigned short > m_vec_fadc
vector of FADC boards
std::unordered_map< unsigned short, unsigned short > m_fadc_map
FADC board number map.
void defineHisto() override final
Histogram definitions such as TH1(), TH2(), TNtuple(), TTree()....
DBObjPtr< PayloadFile > m_mapping
channel map payload
float m_errorFraction
fraction of events with any kind of error
TH2F * m_DQMnSamplesHisto
TH2F histogram showing number of samples in data VS daqMode.
bool m_seuRecoEvent
indicates if the particular event is SEU recovery case
StoreObjPtr< EventMetaData > m_eventMetaData
EvtMetaData StoreObjectPointer.
static std::string m_xmlFileName
xml filename
void event() override final
Module function event.
StoreObjPtr< TRGSummary > m_objTrgSummary
Trigger Summary data object.
std::string m_histogramDirectoryName
Name of the histogram directory in ROOT file.
bool m_missedTrailer
missed Trailer error
std::unordered_set< unsigned char > * m_FADCs
FADC boards number.
TH2F * m_DQMtrgQuality
TH2F histogram showing number of samples in data VS Trigger Quality.
void endRun() override final
Module function endRun.
uint16_t m_apvError
APV error container.
std::string m_SVDEventInfoName
SVDEventInfo name.
unsigned short m_fadcNo
fadc number
std::unordered_set< unsigned char > m_seuFADCs
FADC numbers affected by SEU.
void beginRun() override final
Module function beginRun.
bool m_badEvent
indicates if the particular event has any SVD error
SVDSummaryPlots * m_SEUonSensors
histogram showing SEU Reco events for given sensor
std::unique_ptr< SVDOnlineToOfflineMap > m_map
mapping implementation
TH1F * m_DQMErrorEventsHisto
TH1F histogram showing the events affected by errors.
uint16_t m_ftbError
FTB error container.
uint16_t m_ftbFlags
FTB flags container.
bool m_changeFADCaxis
change FADC (y) axis
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
unsigned short baseType
The base integer type for VxdID.
Definition VxdID.h:35
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.
Struct to hold data about a sensor.
bool m_uSide
True if u-side of the sensor.