Belle II Software  release-08-01-10
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 
24 
25 using namespace std;
26 using namespace Belle2;
27 
28 //-----------------------------------------------------------------
29 // Register the Module
30 //-----------------------------------------------------------------
31 REG_MODULE(SVDUnpackerDQM);
32 
33 
34 //-----------------------------------------------------------------
35 // Implementation
36 //-----------------------------------------------------------------
37 
38 std::string SVDUnpackerDQMModule::m_xmlFileName = std::string("SVDChannelMapping.xml");
39 
40 SVDUnpackerDQMModule::SVDUnpackerDQMModule() : HistoModule(), m_mapping(m_xmlFileName), m_FADCs(nullptr)
41 {
42  //Set module properties
43  setDescription("DQM Histogram of the SVD Raw Data format.");
44 
45  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of the directory where histograms will be placed.",
46  std::string("SVDUnpacker"));
47  addParam("DAQDiagnostics", m_SVDDAQDiagnosticsName, "Name of DAQDiagnostics Store Array.", std::string(""));
48  addParam("EventInfo", m_SVDEventInfoName, "Name of SVDEventInfo object.", std::string(""));
49 
50  setPropertyFlags(c_ParallelProcessingCertified); // specify this flag if you need parallel processing
51 }
52 
53 
54 SVDUnpackerDQMModule::~SVDUnpackerDQMModule()
55 {
56 }
57 
58 //------------------------------------------------------------------
59 // Function to define histograms
60 //-----------------------------------------------------------------
61 
63 {
64 
65  // Create a separate histogram directories and cd into it.
66  TDirectory* oldDir = gDirectory;
67  if (m_histogramDirectoryName != "") {
68  oldDir->mkdir(m_histogramDirectoryName.c_str());// do not use return value with ->cd(), its ZERO if dir already exists
69  oldDir->cd(m_histogramDirectoryName.c_str());
70  }
71 
72  const unsigned short Bins_FTBFlags = 5;
73  const unsigned short Bins_FTBError = 4;
74  const unsigned short Bins_APVError = 4;
75  const unsigned short Bins_APVMatch = 1;
76  const unsigned short Bins_FADCMatch = 1;
77  const unsigned short Bins_UpsetAPV = 1;
78  const unsigned short Bins_BadMapping = 1;
79  const unsigned short Bins_BadHeader = 1;
80  const unsigned short Bins_MissedTrailer = 1;
81  const unsigned short Bins_MissedHeader = 1;
82 
83 
84  const unsigned short nBits = Bins_FTBFlags + Bins_FTBError + Bins_APVError + Bins_APVMatch + Bins_FADCMatch + Bins_UpsetAPV +
85  Bins_BadMapping + Bins_BadHeader + Bins_MissedTrailer + Bins_MissedHeader;
86 
87  m_DQMUnpackerHisto = new TH2F("DQMUnpackerHisto", "SVD Data Format Monitor", nBits, 1, nBits + 1, 52, 1, 53);
88  m_DQMEventFractionHisto = new TH1F("DQMEventFractionHisto", "SVD Error Fraction Event Counter", 2, 0, 2);
89  m_DQMnSamplesHisto = new TH2F("DQMnSamplesHisto", "nAPVsamples VS DAQMode", 3, 1, 4, 2, 1, 3);
90  m_DQMnSamplesHisto2 = new TH2F("DQMnSamplesHisto2", "nAPVsamples VS DAQMode", 2, 1, 3, 2, 1, 3);
91  m_DQMtrgQuality = new TH2F("DQMtrgQuality", "nAPVsamples VS trgQuality", 4, 1, 5, 2, 1, 3);
92 
93  m_DQMUnpackerHisto->GetYaxis()->SetTitle("FADC board");
94  m_DQMUnpackerHisto->GetYaxis()->SetTitleOffset(1.2);
95 
96  m_DQMEventFractionHisto->GetYaxis()->SetTitle("# of Events");
97  m_DQMEventFractionHisto->GetYaxis()->SetTitleOffset(1.5);
98  m_DQMEventFractionHisto->SetMinimum(0);
99 
100  m_DQMnSamplesHisto->GetXaxis()->SetTitle("DAQ Mode");
101  m_DQMnSamplesHisto->GetYaxis()->SetTitle("number of APV samples");
102 
103  m_DQMnSamplesHisto2->GetXaxis()->SetTitle("DAQ Mode");
104  m_DQMnSamplesHisto2->GetYaxis()->SetTitle("number of APV samples");
105 
106  m_DQMtrgQuality->GetXaxis()->SetTitle("TRG Quality");
107  m_DQMtrgQuality->GetYaxis()->SetTitle("number of APV samples");
108 
109  TString Xlabels[nBits] = {"EvTooLong", "TimeOut", "doubleHead", "badEvt", "errCRC", "badFADC", "badTTD", "badFTB", "badALL", "errAPV", "errDET", "errFrame", "errFIFO", "APVmatch", "FADCmatch", "upsetAPV", "EVTmatch", "missHead", "missTrail", "badMapping"};
110 
111  TString Ysamples[2] = {"3", "6"};
112  TString Xsamples[3] = {"3 samples", "6 samples", "3/6 mixed"};
113 
114  TString Xquality[4] = {"coarse", "fine", "super fine", "no TRGSummary"};
115 
116  //preparing X axis of the DQMUnpacker histograms
117  for (unsigned short i = 0; i < nBits; i++) m_DQMUnpackerHisto->GetXaxis()->SetBinLabel(i + 1, Xlabels[i].Data());
118 
119  //preparing X and Y axis of the DQMnSamples histograms
120  for (unsigned short i = 0; i < 3; i++) m_DQMnSamplesHisto->GetXaxis()->SetBinLabel(i + 1, Xsamples[i].Data());
121  for (unsigned short i = 0; i < 2; i++) m_DQMnSamplesHisto2->GetXaxis()->SetBinLabel(i + 1, Xsamples[i].Data());
122 
123  for (unsigned short i = 0; i < 2; i++) m_DQMnSamplesHisto->GetYaxis()->SetBinLabel(i + 1, Ysamples[i].Data());
124  for (unsigned short i = 0; i < 2; i++) m_DQMnSamplesHisto2->GetYaxis()->SetBinLabel(i + 1, Ysamples[i].Data());
125 
126  //preparing X and Y axis of the DQMtrgQuality histograms
127  for (unsigned short i = 0; i < 4; i++) m_DQMtrgQuality->GetXaxis()->SetBinLabel(i + 1, Xquality[i].Data());
128  for (unsigned short i = 0; i < 2; i++) m_DQMtrgQuality->GetYaxis()->SetBinLabel(i + 1, Ysamples[i].Data());
129 
130  m_DQMEventFractionHisto->GetXaxis()->SetBinLabel(1, "OK");
131  m_DQMEventFractionHisto->GetXaxis()->SetBinLabel(2, "Error(s)");
132 
133 
134  oldDir->cd();
135 }
136 
138 {
139  m_eventMetaData.isRequired();
142  m_objTrgSummary.isOptional();
143 
144  // Register histograms (calls back defineHisto)
145  REG_HISTOGRAM
146 }
147 
148 
150 {
151 
152  StoreObjPtr<EventMetaData> evtMetaData;
153  m_expNumber = evtMetaData->getExperiment();
154  m_runNumber = evtMetaData->getRun();
155  m_errorFraction = 0;
156 
157  TString runID = TString::Format(" ~ Exp%d Run%d", m_expNumber, m_runNumber);
158 
159  if (m_DQMUnpackerHisto != nullptr) {
160  TString tmp = m_DQMUnpackerHisto->GetTitle();
161  Int_t pos = tmp.Last('~');
162  if (pos == -1) pos = tmp.Length() + 2;
163  TString title = tmp(0, pos - 2);
164  m_DQMUnpackerHisto->SetTitle(title + runID);
165  m_DQMUnpackerHisto->Reset();
166  }
167 
168  if (m_DQMEventFractionHisto != nullptr) {
169  TString tmp = m_DQMEventFractionHisto->GetTitle();
170  Int_t pos = tmp.Last('~');
171  if (pos == -1) pos = tmp.Length() + 2;
172  TString title = tmp(0, pos - 2);
173  m_DQMEventFractionHisto->SetTitle(title + runID);
174  m_DQMEventFractionHisto->Reset();
175  }
176 
177  if (m_DQMnSamplesHisto != nullptr) {
178  TString tmp = m_DQMnSamplesHisto->GetTitle();
179  Int_t pos = tmp.Last('~');
180  if (pos == -1) pos = tmp.Length() + 2;
181  TString title = tmp(0, pos - 2);
182  m_DQMnSamplesHisto->SetTitle(title + runID);
183  m_DQMnSamplesHisto->Reset();
184  }
185 
186  if (m_DQMnSamplesHisto2 != nullptr) {
187  TString tmp = m_DQMnSamplesHisto2->GetTitle();
188  Int_t pos = tmp.Last('~');
189  if (pos == -1) pos = tmp.Length() + 2;
190  TString title = tmp(0, pos - 2);
191  m_DQMnSamplesHisto2->SetTitle(title + runID);
192  m_DQMnSamplesHisto2->Reset();
193  }
194 
195  if (m_DQMtrgQuality != nullptr) {
196  TString tmp = m_DQMtrgQuality->GetTitle();
197  Int_t pos = tmp.Last('~');
198  if (pos == -1) pos = tmp.Length() + 2;
199  TString title = tmp(0, pos - 2);
200  m_DQMtrgQuality->SetTitle(title + runID);
201  m_DQMtrgQuality->Reset();
202  }
203 
204  m_shutUpNoData = false;
205 
206  if (m_mapping.hasChanged()) { m_map = std::make_unique<SVDOnlineToOfflineMap>(m_mapping->getFileName()); }
207 
208  m_changeFADCaxis = false;
209 
210  //getting fadc numbers from the mapping
211  m_FADCs = &(m_map->FADCnumbers);
212 
213  //copy FADC numbers to vector and sort them
214  m_vec_fadc.insert(m_vec_fadc.end(), m_FADCs->begin(), m_FADCs->end());
215  std::sort(m_vec_fadc.begin(), m_vec_fadc.end());
216 
217  unsigned short ifadc = 0;
218  for (const auto& fadc : m_vec_fadc) {
219  m_fadc_map.insert(make_pair(fadc, ++ifadc));
220  m_DQMUnpackerHisto->GetYaxis()->SetBinLabel(ifadc, to_string(fadc).c_str());
221  }
222 
223  m_nEvents = 0;
224  m_nBadEvents = 0;
225 }
226 
227 
229 {
230  if (!m_svdDAQDiagnostics.isValid()) {
231  if (!m_shutUpNoData)
232  B2WARNING("There are no SVDDAQDiagnostic objects saved by the Unpacker! SVD Data Format Monitoring disabled!");
233  m_shutUpNoData = true;
234  return;
235  }
236 
237  if (!m_svdEventInfo.isValid()) {
238  if (!m_shutUpNoData)
239  B2WARNING("There is no SVDEventInfo object saved by the Unpacker! SVD Data Format Monitoring disabled!");
240  m_shutUpNoData = true;
241  return;
242  }
243 
244 
245  m_badEvent = 0;
246  m_nEvents++;
247 
248  // filling nSamplesHisto
249  int daqMode = m_svdEventInfo->getModeByte().getDAQMode();
250  int nSamples = m_svdEventInfo->getNSamples();
251 
252  m_DQMnSamplesHisto->Fill(daqMode, nSamples / 3);
253  if (daqMode < 3) m_DQMnSamplesHisto2->Fill(daqMode, nSamples / 3);
254 
255 
256  //filling TRGqualityHisto
257  if (m_objTrgSummary.isValid()) {
258  int trgQuality = m_objTrgSummary->getTimQuality();
259  m_DQMtrgQuality->Fill(trgQuality, nSamples / 3);
260  } else m_DQMtrgQuality->Fill(4, nSamples / 3);
261 
262 
263  //filling m_DQMUnpackerHisto
264  unsigned int nDiagnostics = m_svdDAQDiagnostics.getEntries();
265 
266  unsigned short bin_no = 0;
267  gStyle->SetOptStat(0);
268 
269  for (unsigned short i = 0; i < nDiagnostics; i++) {
270 
271  m_ftbFlags = m_svdDAQDiagnostics[i]->getFTBFlags();
272  m_ftbError = m_svdDAQDiagnostics[i]->getFTBError();
273  m_apvError = m_svdDAQDiagnostics[i]->getAPVError();
274  m_apvMatch = m_svdDAQDiagnostics[i]->getAPVMatch();
275  m_fadcMatch = m_svdDAQDiagnostics[i]->getFADCMatch();
276  m_upsetAPV = m_svdDAQDiagnostics[i]->getUpsetAPV();
277  m_badMapping = m_svdDAQDiagnostics[i]->getBadMapping();
278  m_badHeader = m_svdDAQDiagnostics[i]->getBadHeader();
279  m_badTrailer = m_svdDAQDiagnostics[i]->getBadTrailer();
280  m_missedHeader = m_svdDAQDiagnostics[i]->getMissedHeader();
281  m_missedTrailer = m_svdDAQDiagnostics[i]->getMissedTrailer();
282 
283  m_fadcNo = m_svdDAQDiagnostics[i]->getFADCNumber();
284  //apvNo = m_svdDAQDiagnostics[i]->getAPVNumber();
285 
286  // insert FADCnumber into the map (if not already there) and assign the next bin to it.
287  if (m_changeFADCaxis) {
288  if (m_fadc_map.find(m_fadcNo) == m_fadc_map.end()) m_fadc_map.insert(make_pair(m_fadcNo, ++bin_no));
289  }
290 
291  if (m_ftbFlags != 0 or m_ftbError != 240 or m_apvError != 0 or !m_apvMatch or !m_fadcMatch or m_upsetAPV or m_badMapping
292  or m_badHeader
294 
295  m_badEvent = 1;
296 
297  auto ybin = m_fadc_map.find(m_fadcNo);
298 
299  if (m_badMapping) {
300  if (!m_changeFADCaxis) {
301  m_changeFADCaxis = true;
302  m_fadc_map.clear();
303  break;
304  } else {
305  m_DQMUnpackerHisto->Fill(20, ybin->second);
306  }
307  }
308 
309  if (m_badHeader) m_DQMUnpackerHisto->Fill(17, ybin->second);
310  if (m_missedHeader) m_DQMUnpackerHisto->Fill(18, ybin->second);
311  if (m_badTrailer or m_missedTrailer) m_DQMUnpackerHisto->Fill(19, ybin->second);
312 
313  if (m_ftbFlags != 0) {
314  if (m_ftbFlags & 16) m_DQMUnpackerHisto->Fill(5, ybin->second);
315  if (m_ftbFlags & 8) m_DQMUnpackerHisto->Fill(4, ybin->second);
316  if (m_ftbFlags & 4) m_DQMUnpackerHisto->Fill(3, ybin->second);
317  if (m_ftbFlags & 2) m_DQMUnpackerHisto->Fill(2, ybin->second);
318  if (m_ftbFlags & 1) m_DQMUnpackerHisto->Fill(1, ybin->second);
319  }
320  if (m_ftbError != 240) {
321  switch (m_ftbError - 240) {
322  case 3:
323  m_DQMUnpackerHisto->Fill(6, ybin->second); //badFADC
324  break;
325  case 5:
326  m_DQMUnpackerHisto->Fill(7, ybin->second); //badTTD
327  break;
328  case 6:
329  m_DQMUnpackerHisto->Fill(8, ybin->second); //badFTB
330  break;
331  case 7:
332  m_DQMUnpackerHisto->Fill(9, ybin->second);//badALL;
333  break;
334  }
335  }
336 
337  if (m_apvError != 0) {
338  if (m_apvError & 1) m_DQMUnpackerHisto->Fill(10, ybin->second);
339  if (m_apvError & 2) m_DQMUnpackerHisto->Fill(11, ybin->second);
340  if (m_apvError & 4) m_DQMUnpackerHisto->Fill(12, ybin->second);
341  if (m_apvError & 8) m_DQMUnpackerHisto->Fill(13, ybin->second);
342  }
343 
344  if (!m_apvMatch) m_DQMUnpackerHisto->Fill(14, ybin->second);
345  if (!m_fadcMatch) m_DQMUnpackerHisto->Fill(15, ybin->second);
346  if (m_upsetAPV) m_DQMUnpackerHisto->Fill(16, ybin->second);
347 
348  }
349  } //end Diagnostics loop
350 
351  if (m_changeFADCaxis) {
352  for (auto& iFADC : m_fadc_map) m_DQMUnpackerHisto->GetYaxis()->SetBinLabel(iFADC.second, to_string(iFADC.first).c_str());
353  }
354  if (m_badEvent) m_nBadEvents++;
355  m_errorFraction = 100 * float(m_nBadEvents) / float(m_nEvents);
356 
357  if (m_DQMEventFractionHisto != nullptr) {
358  TString histoFractionTitle = TString::Format("SVD bad events, Exp %d Run %d", m_expNumber, m_runNumber);
359  m_DQMEventFractionHisto->SetTitle(histoFractionTitle.Data());
360  }
361 
362 
364 
365 } // end event function
366 
367 
369 {
370  // Summary report on SVD DQM monitor
371  if (m_nBadEvents) {
372  B2WARNING("=================== SVD DQM Data Format Statistics: =============");
373  B2WARNING(" We found " << m_nBadEvents << "/" << m_nEvents << " corrupted events, which is " << m_errorFraction <<
374  "%");
375  B2WARNING("=================================================================");
376  }
377 
378 }
bool hasChanged()
Check whether the object has changed since the last call to hasChanged of the accessor).
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
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
std::string getFileName() const
Get the name of the downloaded payload file.
Definition: PayloadFile.h:35
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)
bool m_badTrailer
bad trailer error
unsigned int m_nEvents
event counter
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.
int m_expNumber
experiment number
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.
TH1F * m_DQMEventFractionHisto
TH1F histogram showing the fraction of events affected by errors.
StoreObjPtr< EventMetaData > m_eventMetaData
EvtMetaData StoreObjectPointer.
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.
bool m_badMapping
bad mapping error
uint16_t m_apvError
APV error container.
std::string m_SVDEventInfoName
SVDEventInfo name.
unsigned short m_fadcNo
fadc number
bool m_fadcMatch
fadcc match error
void beginRun() override final
Module function beginRun.
bool m_badEvent
indicates if the particular event has any SVD error
std::unique_ptr< SVDOnlineToOfflineMap > m_map
mapping implementation
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
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.