Belle II Software  release-05-01-25
SVDUnpackerModule.cc
1 /******************************************************************************
2 * BASF2 (Belle Analysis Framework 2) *
3 * Copyright(C) 2010 - Belle II Collaboration *
4 * *
5 * Author: The Belle II Collaboration *
6 * Contributors: Jarek Wiechczynski, Jacek Stypula, Peter Kvasnicka *
7 * Giulia Casarosa, Eugenio Paoloni *
8 * *
9 * This software is provided "as is" without any warranty. *
10 * Beware! Do not expose to open flames it can explode *
11 ******************************************************************************/
12 
13 #include <svd/modules/svdUnpacker/SVDUnpackerModule.h>
14 #include <svd/calibration/SVDDetectorConfiguration.h>
15 
16 #include <framework/datastore/DataStore.h>
17 #include <framework/datastore/StoreObjPtr.h>
18 #include <framework/logging/Logger.h>
19 
20 #include <boost/crc.hpp> // for boost::crc_basic, boost::augmented_crc
21 #define CRC16POLYREV 0x8005 // CRC-16 polynomial, normal representation
22 
23 #include <arpa/inet.h>
24 
25 #include <sstream>
26 #include <iomanip>
27 #include <cstring>
28 #include <vector>
29 #include <set>
30 #include <map>
31 #include <utility>
32 #include <algorithm>
33 
34 using namespace std;
35 using namespace Belle2;
36 using namespace Belle2::SVD;
37 
38 //-----------------------------------------------------------------
39 // Register the Module
40 //-----------------------------------------------------------------
41 REG_MODULE(SVDUnpacker)
42 
43 //-----------------------------------------------------------------
44 // Implementation
45 //-----------------------------------------------------------------
46 
47 std::string Belle2::SVD::SVDUnpackerModule::m_xmlFileName = std::string("SVDChannelMapping.xml");
48 
49 SVDUnpackerModule::SVDUnpackerModule() : Module(),
50  m_mapping(m_xmlFileName),
51  m_shutUpFTBError(0),
52  m_FADCTriggerNumberOffset(0)
53 {
54  //Set module properties
55  setDescription("Produce SVDShaperDigits from RawSVD. NOTE: only zero-suppressed mode is currently supported!");
57 
58  addParam("SVDEventInfo", m_svdEventInfoName, "Name of the SVDEventInfo object", string(""));
59  addParam("rawSVDListName", m_rawSVDListName, "Name of the raw SVD List", string(""));
60  addParam("svdShaperDigitListName", m_svdShaperDigitListName, "Name of the SVDShaperDigits list", string(""));
61  addParam("shutUpFTBError", m_shutUpFTBError,
62  "if >0 is the number of reported FTB header ERRORs before quiet operations. If <0 full log produced.", -1);
63  addParam("FADCTriggerNumberOffset", m_FADCTriggerNumberOffset,
64  "number to be added to the FADC trigger number to match the main trigger number", 0);
65  addParam("svdDAQDiagnosticsListName", m_svdDAQDiagnosticsListName, "Name of the DAQDiagnostics list", string(""));
66  addParam("softwarePipelineAddressEmulation", m_emulatePipelineAddress, "Estimate emulated pipeline address", bool(true));
67  addParam("killDigitsFromUpsetAPVs", m_killUpsetDigits, "Delete digits from upset APVs", bool(false));
68  addParam("silentlyAppend", m_silentAppend, "Append digits to a pre-existing non-empty storeArray", bool(false));
69  addParam("badMappingFatal", m_badMappingFatal, "Throw B2FATAL if there's a wrong payload in the database", bool(false));
70  addParam("UnpackerErrorRate", m_errorRate, "Unpacker will print one error every UnpackerErrorRate", int(1000));
71  addParam("PrintRawData", m_printRaw, "Printing Raw data words for debugging", bool(false));
72 }
73 
75 {
76 }
77 
79 {
80  m_eventMetaDataPtr.isRequired();
81  // Don't panic if no SVD data.
82  m_rawSVD.isOptional(m_rawSVDListName);
83 
84  // Register default SVDEventInfo for unpacking Raw Data
86 
88  storeDAQDiagnostics.registerInDataStore();
89  m_svdDAQDiagnosticsListName = storeDAQDiagnostics.getName();
90 
92  storeShaperDigits.registerInDataStore();
93  storeShaperDigits.registerRelationTo(storeDAQDiagnostics);
94  m_svdShaperDigitListName = storeShaperDigits.getName();
95 
96 }
97 
99 {
100  if (!m_mapping.isValid())
101  B2FATAL("no valid SVD Channel Mapping. We stop here.");
102 
103  m_wrongFTBcrc = 0;
104  if (m_mapping.hasChanged()) { m_map = std::make_unique<SVDOnlineToOfflineMap>(m_mapping->getFileName()); }
105 
106  if (! m_map) { //give up
107  B2ERROR("SVD xml map not loaded." << std::endl <<
108  "No SVDShaperDigit will be produced for this run!");
109  return;
110  }
111 
112  //number of FADC boards
113  nFADCboards = m_map->getFADCboardsNumber();
114 
115  //passing APV<->FADC mapping from SVDOnlineToOfflineMap object
116  APVmap = &(m_map->APVforFADCmap);
117 
118  //setting UnpackerErrorRate factor to use it for BadMapping error suppression
119  m_map->setErrorRate(m_errorRate);
120 
121  nTriggerMatchErrors = -1;
122  nEventMatchErrors = -1;
123  nUpsetAPVsErrors = -1;
124  nErrorFieldErrors = -1;
125  nMissingAPVsErrors = -1;
126  nFADCMatchErrors = -1;
127  nAPVErrors = -1;
128  nFTBFlagsErrors = -1;
130 
132 
133  //get the relative time shift
134  SVDDetectorConfiguration detectorConfig;
135  if (detectorConfig.isValid())
136  m_relativeTimeShift = detectorConfig.getRelativeTimeShift();
137  else {
138  B2ERROR("SVDDetectorConfiguration not valid!! Setting relativeTimeShift to 0 for this reconstruction.");
140  }
141 }
142 
143 #ifndef __clang__
144 #pragma GCC diagnostic push
145 #pragma GCC diagnostic ignored "-Wstack-usage="
146 #endif
148 {
150  if (!rawSVDList || !rawSVDList.getEntries())
151  return;
152 
155 
156  if (!m_silentAppend && shaperDigits && shaperDigits.getEntries())
157  B2WARNING("Unpacking SVDShaperDigits to a non-empty pre-existing \n"
158  << "StoreArray. This can lead to undesired behaviour. At least\n"
159  << "remember to use SVDShaperDigitSorter in your path and \n"
160  << "set the silentlyAppend parameter of SVDUnpacker to true.");
161 
162  SVDDAQDiagnostic* currentDAQDiagnostic;
163  vector<SVDDAQDiagnostic*> vDiagnostic_ptr;
164 
165  map<SVDShaperDigit, SVDDAQDiagnostic*> diagnosticMap;
166  // Store encountered pipeline addresses with APVs in which they were observed
167  map<unsigned short, set<pair<unsigned short, unsigned short> > > apvsByPipeline;
168 
169  if (!m_eventMetaDataPtr.isValid()) { // give up...
170  B2ERROR("Missing valid EventMetaData." << std::endl << "No SVDShaperDigit produced for this event!");
171  return;
172  }
173 
174  bool nFADCmatch = true;
175  bool nAPVmatch = true;
176  bool badMapping = false;
177  bool badHeader = false;
178  bool badTrailer = false;
179  bool missedHeader = false;
180  bool missedTrailer = false;
181 
182  // flag to set SVDEventInfo once per event
183  bool isSetEventInfo = false;
184 
185  //flag to set nAPVsamples in SVDEventInfo once per event
186  bool isSetNAPVsamples = false;
187 
188  unsigned short nAPVheaders = 999;
189  set<short> seenAPVHeaders = {};
190 
191  unsigned short nEntries_rawSVD = rawSVDList.getEntries();
192  auto eventNo = m_eventMetaDataPtr->getEvent();
193 
194  short fadc = 255, apv = 63;
195 
196  if (nEntries_rawSVD != nFADCboards) {
198  if (!(nFADCMatchErrors % m_errorRate)) B2ERROR("Number of RawSVD data objects do not match the number of FADC boards" <<
199  LogVar("#RawSVD",
200  nEntries_rawSVD) << LogVar("#FADCs", nFADCboards) << LogVar("Event number", eventNo));
201 
202  nFADCmatch = false;
203  }
204 
205  for (unsigned int i = 0; i < nEntries_rawSVD; i++) {
206 
207  unsigned int numEntries_rawSVD = rawSVDList[ i ]->GetNumEntries();
208  for (unsigned int j = 0; j < numEntries_rawSVD; j++) {
209 
210  unsigned short nWords[4];
211  nWords[0] = rawSVDList[i]->Get1stDetectorNwords(j);
212  nWords[1] = rawSVDList[i]->Get2ndDetectorNwords(j);
213  nWords[2] = rawSVDList[i]->Get3rdDetectorNwords(j);
214  nWords[3] = rawSVDList[i]->Get4thDetectorNwords(j);
215 
216  uint32_t* data32tab[4]; //vector of pointers
217 
218  data32tab[0] = (uint32_t*)rawSVDList[i]->Get1stDetectorBuffer(j); // points at the begining of the 1st buffer
219  data32tab[1] = (uint32_t*)rawSVDList[i]->Get2ndDetectorBuffer(j);
220  data32tab[2] = (uint32_t*)rawSVDList[i]->Get3rdDetectorBuffer(j);
221  data32tab[3] = (uint32_t*)rawSVDList[i]->Get4thDetectorBuffer(j);
222 
223 
224  unsigned short ftbError = 0;
225  unsigned short trgType = 0;
226  unsigned short trgNumber = 0;
227  unsigned short daqMode = -1;
228  unsigned short daqType = 0;
229  unsigned short cmc1;
230  unsigned short cmc2;
231  unsigned short apvErrors;
232  unsigned short pipAddr;
233  unsigned short ftbFlags = 0;
234  unsigned short apvErrorsOR = 0;
235 
236  bool is3sampleData = false;
237  bool is6sampleData = false;
238 
239  for (unsigned int buf = 0; buf < 4; buf++) { // loop over 4 buffers
240 
241  if (data32tab[buf] == NULL && nWords[buf] == 0) continue;
242  if (m_printRaw) printB2Debug(data32tab[buf], data32tab[buf], &data32tab[buf][nWords[buf] - 1], nWords[buf]);
243 
244  missedHeader = false;
245  missedTrailer = false;
246 
247  uint32_t* data32_it = data32tab[buf];
248  short strip, sample[6];
249  vector<uint32_t> crc16vec;
250 
251  for (; data32_it != &data32tab[buf][nWords[buf]]; data32_it++) {
252  m_data32 = *data32_it; //put current 32-bit frame to union
253 
254  if (m_data32 == 0xffaa0000) { // first part of FTB header
255  crc16vec.clear(); // clear the input container for crc16 calculation
256  crc16vec.push_back(m_data32);
257 
258  seenHeadersAndTrailers++; // we found FTB header
259 
260  data32_it++; // go to 2nd part of FTB header
261  crc16vec.push_back(*data32_it);
262 
263  m_data32 = *data32_it; //put the second 32-bit frame to union
264 
265  ftbError = m_FTBHeader.errorsField;
266 
267  if (ftbError != 240) {
269 
270  if (!(nErrorFieldErrors % m_errorRate) or nErrorFieldErrors < 100) {
271  switch (ftbError - 240) {
272  case 3:
273  B2ERROR("FADC Event Number is different from (FTB & TTD) Event Numbers");
274  break;
275  case 5:
276  B2ERROR("TTD Event Number is different from (FTB & FADC) Event Numbers");
277  break;
278  case 6:
279  B2ERROR("FTB Event Number is different from (TTD & FADC) Event Numbers");
280  break;
281  case 7:
282  B2ERROR("(FTB, TTD & FADC) Event Numbers are different from each other");
283  break;
284  default:
285  B2ERROR("Problem with errorsField variable in FTB Header" << LogVar("abnormal value", ftbError));
286  }
287  }
288  }
289 
290  if (m_FTBHeader.eventNumber !=
291  (eventNo & 0xFFFFFF)) {
294  m_shutUpFTBError -= 1;
295  B2ERROR("Event number mismatch detected! The event number given by EventMetaData object is different from the one in the FTB Header."
296  << LogVar("Expected event number & 0xFFFFFF",
297  (eventNo & 0xFFFFFF)) << LogVar("Event number in the FTB", m_FTBHeader.eventNumber));
298  }
299  }
300 
301  continue;
302  } // is FTB Header
303 
304  crc16vec.push_back(m_data32);
305 
306  if (m_MainHeader.check == 6) { // FADC header
307 
308  seenHeadersAndTrailers += 2; //we found FADC Header
309 
310  fadc = m_MainHeader.FADCnum;
311  trgType = m_MainHeader.trgType;
312  trgNumber = m_MainHeader.trgNumber;
313  daqMode = m_MainHeader.DAQMode;
314  daqType = m_MainHeader.DAQType;
315 
316  //Let's add run-dependent info: daqMode="11" in case of 3-mixed-6 sample acquisition mode.
317  if (daqType) daqMode = 3;
318 
319  nAPVheaders = 0; // start counting APV headers for this FADC
320  nAPVmatch = true; //assume correct # of APV headers
321  badMapping = false; //assume correct mapping
322  badHeader = false;
323  badTrailer = false;
324 
325  is3sampleData = false;
326  is6sampleData = false;
327 
328  if (daqMode == 0) B2ERROR("SVDDataFormatCheck: the event " << eventNo <<
329  " is apparently taken with 1-sample mode, this is not expected.");
330  if (daqMode == 1) is3sampleData = true;
331  if (daqMode == 2) is6sampleData = true;
332 
333  if (
335  ((eventNo - m_FADCTriggerNumberOffset) & 0xFF)) {
336 
339  B2ERROR("Event number mismatch detected! The event number given by EventMetaData object is different from the one in the FADC Header. "
340  << LogVar("Event number", eventNo) << LogVar("FADC", fadc) << LogVar("Trigger number LSByte reported by the FADC",
341  m_MainHeader.trgNumber) << LogVar("+ offset", m_FADCTriggerNumberOffset) << LogVar("expected", (eventNo & 0xFF)));
342  badHeader = true;
343  }
344 
345  // create SVDModeByte object from MainHeader vars
347 
348  // create SVDEventInfo and fill it with SVDModeByte & SVDTriggerType objects
349  if (!isSetEventInfo) {
350  m_SVDTriggerType = SVDTriggerType(trgType);
351  m_svdEventInfoPtr.create();
352  m_svdEventInfoPtr->setModeByte(m_SVDModeByte);
353  m_svdEventInfoPtr->setTriggerType(m_SVDTriggerType);
354 
355  //set relative time shift
356  m_svdEventInfoPtr->setRelativeShift(m_relativeTimeShift);
357  // set X-talk info online from Raw Data
358  m_svdEventInfoPtr->setCrossTalk(m_MainHeader.xTalk);
359 
360  isSetEventInfo = true;
361  } else { // let's check if the current SVDModeByte and SVDTriggerType are consistent with the one stored in SVDEventInfo
362  if (m_SVDModeByte != m_svdEventInfoPtr->getModeByte()) {m_svdEventInfoPtr->setMatchModeByte(false); badHeader = true; nEventInfoMatchErrors++;}
363  if (trgType != (m_svdEventInfoPtr->getTriggerType()).getType()) { m_svdEventInfoPtr->setMatchTriggerType(false); badHeader = true; nEventInfoMatchErrors++;}
364  }
365  } // is FADC header
366 
367  if (m_APVHeader.check == 2) { // APV header
368 
369  nAPVheaders++;
370  apv = m_APVHeader.APVnum;
371  seenAPVHeaders.insert(apv);
372 
373  cmc1 = m_APVHeader.CMC1;
374  cmc2 = m_APVHeader.CMC2;
375  apvErrors = m_APVHeader.apvErr;
376  pipAddr = m_APVHeader.pipelineAddr;
377 
378  if (apvErrors != 0) {
379  nAPVErrors++;
380  if (!(nAPVErrors % m_errorRate)
381  or nAPVErrors < 100) B2ERROR("APV error has been detected." << LogVar("FADC", fadc) << LogVar("APV", apv) << LogVar("Error value",
382  apvErrors));
383  }
384  // temporary SVDDAQDiagnostic object (no info from trailers and APVmatch code)
385  currentDAQDiagnostic = DAQDiagnostics.appendNew(trgNumber, trgType, pipAddr, cmc1, cmc2, apvErrors, ftbError, nFADCmatch, nAPVmatch,
386  badHeader, missedHeader, missedTrailer,
387  fadc, apv);
388  vDiagnostic_ptr.push_back(currentDAQDiagnostic);
389 
390  apvsByPipeline[pipAddr].insert(make_pair(fadc, apv));
391  } //is APV Header
392 
393  if (m_data_A.check == 0) { // data
394  strip = m_data_A.stripNum;
395 
396  sample[0] = m_data_A.sample1;
397  sample[1] = m_data_A.sample2;
398  sample[2] = m_data_A.sample3;
399 
400  sample[3] = 0;
401  sample[4] = 0;
402  sample[5] = 0;
403 
404  // Let's check the next rawdata word to determine if we acquired 3 or 6 sample
405  data32_it++;
406  m_data32 = *data32_it;
407 
408  if (m_data_B.check == 0 && strip == m_data_B.stripNum) { // 2nd data frame with the same strip number -> six samples
409 
410  if (!isSetNAPVsamples) {
411  m_svdEventInfoPtr->setNSamples(6);
412  isSetNAPVsamples = true;
413  } else {
414  if (is3sampleData)
415  B2ERROR("DAQMode value (indicating 3-sample acquisition mode) doesn't correspond to the actual number of samples (6) in the data! The data might be corrupted!");
416  }
417 
418  crc16vec.push_back(m_data32);
419 
420  sample[3] = m_data_B.sample4;
421  sample[4] = m_data_B.sample5;
422  sample[5] = m_data_B.sample6;
423  }
424 
425  else { // three samples
426  data32_it--;
427  m_data32 = *data32_it;
428 
429  if (!isSetNAPVsamples) {
430  m_svdEventInfoPtr->setNSamples(3);
431  isSetNAPVsamples = true;
432  } else {
433  if (is6sampleData)
434  B2ERROR("DAQMode value (indicating 6-sample acquisition mode) doesn't correspond to the actual number of samples (3) in the data! The data might be corrupted!");
435  }
436  }
437 
438  // Generating SVDShaperDigit object
439  SVDShaperDigit* newShaperDigit = m_map->NewShaperDigit(fadc, apv, strip, sample, 0.0, m_SVDModeByte);
440  if (newShaperDigit) {
441  diagnosticMap.insert(make_pair(*newShaperDigit, currentDAQDiagnostic));
442  delete newShaperDigit;
443  } else if (m_badMappingFatal) {
444  B2FATAL("Respective FADC/APV combination not found -->> incorrect payload in the database! ");
445  } else {
446  badMapping = true;
447  }
448 
449  } //is data frame
450 
451 
452  if (m_FADCTrailer.check == 14) { // FADC trailer
453 
454  seenHeadersAndTrailers += 4; // we found FAD trailer
455 
456  //additional check if we have a faulty/fake FADC that is not in the map
457  if (APVmap->find(fadc) == APVmap->end()) badMapping = true;
458 
459  //comparing number of APV chips and the number of APV headers, for the current FADC
460  unsigned short nAPVs = APVmap->count(fadc);
461 
462  if (nAPVheaders == 0) {
463  currentDAQDiagnostic = DAQDiagnostics.appendNew(0, 0, 0, 0, 0, 0, ftbError, nFADCmatch, nAPVmatch, badHeader, 0, 0, fadc, 0);
464  vDiagnostic_ptr.push_back(currentDAQDiagnostic);
465  }
466 
467  if (nAPVs != nAPVheaders) {
468  // There is an APV missing, detect which it is.
469  for (const auto& fadcApv : *APVmap) {
470  if (fadcApv.first != fadc) continue;
471  if (seenAPVHeaders.find(fadcApv.second) == seenAPVHeaders.end()) {
472  // We have a missing APV. Look if it is a known one.
473  auto missingRec = m_missingAPVs.find(make_pair(fadcApv.first, fadcApv.second));
474  if (missingRec != m_missingAPVs.end()) {
475  // This is known to be missing, so keep quiet and just update event counters
476  if (missingRec->second.first > eventNo)
477  missingRec->second.first = eventNo;
478  if (missingRec->second.second < eventNo)
479  missingRec->second.second = eventNo;
480  } else {
481  // We haven't seen this previously.
483  m_missingAPVs.insert(make_pair(
484  make_pair(fadcApv.first, fadcApv.second),
485  make_pair(eventNo, eventNo)
486  ));
487  if (!(nMissingAPVsErrors % m_errorRate)) B2ERROR("missing APV header! " << LogVar("Event number", eventNo) << LogVar("APV",
488  int(fadcApv.second)) << LogVar("FADC",
489  int(fadcApv.first)));
490  }
491  }
492  }
493  nAPVmatch = false;
494  } // is nAPVs != nAPVheaders
495 
496  seenAPVHeaders.clear();
497 
498  ftbFlags = m_FADCTrailer.FTBFlags;
499  if ((ftbFlags >> 5) != 0) badTrailer = true;
500  if (ftbFlags != 0) {
501  nFTBFlagsErrors++;
502  if (!(nFTBFlagsErrors % m_errorRate) or nFTBFlagsErrors < 100) {
503  B2ERROR(" FTB Flags variable has an active error bit(s)" << LogVar("on FADC number", fadc));
504 
505  if (ftbFlags & 16) B2ERROR("----> CRC error has been detected. Data might be corrupted!");
506  if (ftbFlags & 8) B2ERROR("----> Bad Event indication has been detected. Data might be corrupted!");
507  if (ftbFlags & 4) B2ERROR("----> Double Header has been detected. Data might be corrupted!");
508  if (ftbFlags & 2) B2ERROR("----> Time Out has been detected. Data might be corrupted!");
509  if (ftbFlags & 1) B2ERROR("----> Event Too Long! Data might be corrupted!");
510  }
511  }
512 
513  apvErrorsOR = m_FADCTrailer.apvErrOR;
514 
515 
516  }// is FADC trailer
517 
518  if (m_FTBTrailer.controlWord == 0xff55) {// FTB trailer
519 
520  seenHeadersAndTrailers += 8; // we found FTB trailer
521 
522  //check CRC16
523  crc16vec.pop_back();
524  unsigned short iCRC = crc16vec.size();
525  uint32_t crc16input[iCRC];
526 
527  for (unsigned short icrc = 0; icrc < iCRC; icrc++)
528  crc16input[icrc] = htonl(crc16vec.at(icrc));
529 
530  //verify CRC16
531  boost::crc_basic<16> bcrc(0x8005, 0xffff, 0, false, false);
532  bcrc.process_block(crc16input, crc16input + iCRC);
533  unsigned int checkCRC = bcrc.checksum();
534 
535  if (checkCRC != m_FTBTrailer.crc16) {
536  B2WARNING("FTB CRC16 checksum DOES NOT MATCH" << LogVar("for FADC no.", fadc));
537  m_wrongFTBcrc++;
538  }
539 
540  } // is FTB trailer
541 
542  } // end loop over 32-bit frames in each buffer
543 
544  } // end iteration on 4 data buffers
545 
546  //Let's check if all the headers and trailers were in place in the last frame
547  if (seenHeadersAndTrailers != 0xf) {
548  if (!(seenHeadersAndTrailers & 1)) {B2ERROR("Missing FTB Header is detected. SVD data might be corrupted!" << LogVar("Event number", eventNo) << LogVar("FADC", fadc)); missedHeader = true;}
549  if (!(seenHeadersAndTrailers & 2)) {B2ERROR("Missing FADC Header is detected -> related FADC number couldn't be retreived. SVD data might be corrupted! " << LogVar("Event number", eventNo) << LogVar("previous FADC", fadc)); missedHeader = true;}
550  if (!(seenHeadersAndTrailers & 4)) {B2ERROR("Missing FADC Trailer is detected. SVD data might be corrupted!" << LogVar("Event number", eventNo) << LogVar("FADC", fadc)); missedTrailer = true;}
551  if (!(seenHeadersAndTrailers & 8)) {B2ERROR("Missing FTB Trailer is detected. SVD data might be corrupted!" << LogVar("Event number", eventNo) << LogVar("FADC", fadc)); missedTrailer = true;}
552  }
553 
554  //reset value for headers and trailers check
556 
557  for (auto p : vDiagnostic_ptr) {
558  // adding remaining info to Diagnostic object
559  p->setFTBFlags(ftbFlags);
560  p->setApvErrorOR(apvErrorsOR);
561  p->setAPVMatch(nAPVmatch);
562  p->setBadMapping(badMapping);
563  p->setBadTrailer(badTrailer);
564  p->setMissedHeader(missedHeader);
565  p->setMissedTrailer(missedTrailer);
566 
567  vDiagnostic_ptr.clear();
568  }
569 
570  } // end event loop
571 
572  }// end loop over RawSVD objects
573 
574  // Detect upset APVs and report/treat
575  auto major_apv = max_element(apvsByPipeline.begin(), apvsByPipeline.end(),
576  [](const decltype(apvsByPipeline)::value_type & p1,
577  const decltype(apvsByPipeline)::value_type & p2) -> bool
578  { return p1.second.size() < p2.second.size(); }
579  );
580  // We set emuPipelineAddress fields in diagnostics to this.
582  for (auto& p : DAQDiagnostics)
583  p.setEmuPipelineAddress(major_apv->first);
584  // And report any upset apvs or update records
585  if (apvsByPipeline.size() > 1)
586  for (const auto& p : apvsByPipeline) {
587  if (p.first == major_apv->first) continue;
588  for (const auto& fadcApv : p.second) {
589  // We have an upset APV. Look if it is a known one.
590  auto upsetRec = m_upsetAPVs.find(make_pair(fadcApv.first, fadcApv.second));
591  if (upsetRec != m_upsetAPVs.end()) {
592  // This is known to be upset, so keep quiet and update event counters
593  if (upsetRec->second.first > eventNo)
594  upsetRec->second.first = eventNo;
595  if (upsetRec->second.second < eventNo)
596  upsetRec->second.second = eventNo;
597  } else {
598  // We haven't seen this one previously.
600  m_upsetAPVs.insert(make_pair(
601  make_pair(fadcApv.first, fadcApv.second),
602  make_pair(eventNo, eventNo)
603  ));
604  for (auto& pp : DAQDiagnostics) {
605 
606  if (pp.getFADCNumber() == fadcApv.first and pp.getAPVNumber() == fadcApv.second)
607  pp.setUpsetAPV(true);
608  }
609  if (!(nUpsetAPVsErrors % m_errorRate)) B2ERROR("Upset APV detected!!!" << LogVar("APV", int(fadcApv.second)) << LogVar("FADC",
610  int(fadcApv.first)) << LogVar("Event number", eventNo));
611  }
612  }
613  }
614 
615  // Here we can delete digits coming from upset APVs. We detect them by comparing
616  // actual and emulated pipeline address fields in DAQDiagnostics.
617  for (auto& p : diagnosticMap) {
618 
619  if ((m_killUpsetDigits && p.second->getPipelineAddress() != p.second->getEmuPipelineAddress()) || p.second->getFTBError() != 240
620  || p.second->getFTBFlags() || p.second->getAPVError() || !(p.second->getAPVMatch()) || !(p.second->getFADCMatch())
621  || p.second->getBadHeader()
622  || p.second->getBadMapping() || p.second->getUpsetAPV() || p.second->getMissedHeader() || p.second->getMissedTrailer()) continue;
623  shaperDigits.appendNew(p.first)->addRelationTo(p.second);
624  }
625 
626  if (!m_svdEventInfoPtr->getMatchTriggerType()) {if (!(nEventInfoMatchErrors % m_errorRate) or nEventInfoMatchErrors < 200) B2WARNING("Inconsistent SVD Trigger Type value for: " << LogVar("Event number", eventNo));}
627  if (!m_svdEventInfoPtr->getMatchModeByte()) {if (!(nEventInfoMatchErrors % m_errorRate) or nEventInfoMatchErrors < 200) B2WARNING("Inconsistent SVD ModeByte object for: " << LogVar("Event number", eventNo));}
628 
629 
630 } //end event function
631 #ifndef __clang__
632 #pragma GCC diagnostic pop
633 #endif
634 
636 {
637  // Summary report on missing APVs
638  if (m_missingAPVs.size() > 0) {
639  B2WARNING("SVDUnpacker summary 1: Missing APVs");
640  for (const auto& miss : m_missingAPVs)
641  B2WARNING(LogVar("Missing APV", miss.first.second) << LogVar("FADC", miss.first.first) << LogVar("since event",
642  miss.second.first) << LogVar("to event", miss.second.second));
643  }
644  if (m_upsetAPVs.size() > 0) {
645  B2WARNING("SVDUnpacker summary 2: Upset APVs");
646  for (const auto& upst : m_upsetAPVs)
647  B2WARNING(LogVar("Upset APV", upst.first.second) << LogVar("FADC", upst.first.first) <<
648  LogVar("since event", upst.second.first) << LogVar("to event", upst.second.second));
649  }
650 }
651 
652 
653 // additional printing function
654 void SVDUnpackerModule::printB2Debug(uint32_t* data32, uint32_t* data32_min, uint32_t* data32_max, int nWords)
655 {
656 
657  uint32_t* min = std::max((data32 - nWords), data32_min);
658  uint32_t* max = std::min((data32 + nWords), data32_max);
659 
660  size_t counter{0};
661  std::stringstream os;
662  os << std::hex << std::setfill('0');
663  for (uint32_t* ptr = min; ptr <= max; ++ptr) {
664  os << std::setw(8) << *ptr;
665  if (++counter % 10 == 0) os << std::endl;
666  else os << " ";
667  }
668 
669  os << std::endl;
670  B2INFO(os.str());
671  return;
672 
673 }
Belle2::StoreArray::appendNew
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:256
Belle2::SVD::SVDUnpackerModule::m_svdShaperDigitListName
std::string m_svdShaperDigitListName
SVDShaperDigit StoreArray name.
Definition: SVDUnpackerModule.h:79
Belle2::DBAccessorBase::hasChanged
bool hasChanged()
Check whether the object has changed since the last call to hasChanged of the accessor).
Definition: DBAccessorBase.h:92
Belle2::SVD::SVDUnpackerModule::APVHeader::check
unsigned int check
MSB "10" - for APV Header identification.
Definition: SVDUnpackerModule.h:137
Belle2::SVD::SVDUnpackerModule::APVHeader::APVnum
unsigned int APVnum
APV chip number.
Definition: SVDUnpackerModule.h:136
Belle2::SVD::SVDUnpackerModule::m_FTBTrailer
FTBTrailer m_FTBTrailer
Implementation of FTB Trailer.
Definition: SVDUnpackerModule.h:182
Belle2::SVD::SVDUnpackerModule::APVHeader::CMC2
unsigned int CMC2
Common Mode Noise after masking out particle signals.
Definition: SVDUnpackerModule.h:133
Belle2::SVD::SVDUnpackerModule::MainHeader::check
unsigned int check
MSB "110" - for FADC Header identification.
Definition: SVDUnpackerModule.h:127
Belle2::SVD::SVDUnpackerModule::data_A::sample2
unsigned int sample2
2nd data sample
Definition: SVDUnpackerModule.h:143
Belle2::SVDTriggerType
Class to store Trigger Type information.
Definition: SVDTriggerType.h:33
Belle2::SVD::SVDUnpackerModule::m_rawSVDListName
std::string m_rawSVDListName
RawSVD StoreArray name.
Definition: SVDUnpackerModule.h:78
Belle2::SVD::SVDUnpackerModule::m_wrongFTBcrc
int m_wrongFTBcrc
FTB CRC no-Match counter.
Definition: SVDUnpackerModule.h:83
Belle2::SVD::SVDUnpackerModule::m_upsetAPVs
std::map< std::pair< unsigned short, unsigned short >, std::pair< std::size_t, std::size_t > > m_upsetAPVs
Map to store a list of upset APVs.
Definition: SVDUnpackerModule.h:246
Belle2::StoreArray::registerRelationTo
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:150
Belle2::SVD::SVDUnpackerModule::m_FADCTriggerNumberOffset
int m_FADCTriggerNumberOffset
FADC Trigger Offset.
Definition: SVDUnpackerModule.h:192
Belle2::Module::setDescription
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:216
Belle2::SVD::SVDUnpackerModule::nTriggerMatchErrors
int nTriggerMatchErrors
counters for specific ERRORS produced by the Unpacker
Definition: SVDUnpackerModule.h:232
Belle2::DBObjPtr< PayloadFile >::isValid
bool isValid() const
isValid is always true if we have a filename
Definition: PayloadFile.h:74
Belle2::SVDDetectorConfiguration::getRelativeTimeShift
float getRelativeTimeShift()
GLOBAL CONFIGURATION PARAMETERS: Return the relative time shift in units of APV clock /4 between the ...
Definition: SVDDetectorConfiguration.h:187
Belle2::SVD::SVDUnpackerModule::data_B::sample4
unsigned int sample4
4th data sample
Definition: SVDUnpackerModule.h:151
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::Module::c_ParallelProcessingCertified
@ 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:82
Belle2::SVD::SVDUnpackerModule::m_missingAPVs
std::map< std::pair< unsigned short, unsigned short >, std::pair< std::size_t, std::size_t > > m_missingAPVs
Map to store a list of missing APVs.
Definition: SVDUnpackerModule.h:243
Belle2::SVD::SVDUnpackerModule::nFADCboards
unsigned short nFADCboards
how many FADCs we have
Definition: SVDUnpackerModule.h:89
Belle2::SVD::SVDUnpackerModule::data_A::sample3
unsigned int sample3
3rd data sample
Definition: SVDUnpackerModule.h:144
Belle2::SVD::SVDUnpackerModule::data_B::sample5
unsigned int sample5
5th data sample
Definition: SVDUnpackerModule.h:152
Belle2::SVD::SVDUnpackerModule::FTBTrailer::crc16
unsigned int crc16
FTB CRC16 Checksum
Definition: SVDUnpackerModule.h:169
Belle2::SVD::SVDUnpackerModule::m_APVHeader
APVHeader m_APVHeader
Implementation of APV Header.
Definition: SVDUnpackerModule.h:178
Belle2::SVD::SVDUnpackerModule::nErrorFieldErrors
int nErrorFieldErrors
counter of event mismatch errors in FTB's ErrorField
Definition: SVDUnpackerModule.h:235
Belle2::SVD::SVDUnpackerModule::FADCTrailer::apvErrOR
unsigned int apvErrOR
APV Errors Field OR.
Definition: SVDUnpackerModule.h:163
Belle2::SVD::SVDUnpackerModule::FADCTrailer::FTBFlags
unsigned int FTBFlags
FTB Flags Field.
Definition: SVDUnpackerModule.h:160
Belle2::SVD::SVDUnpackerModule::APVmap
std::unordered_multimap< unsigned char, unsigned char > * APVmap
pointer to APVforFADCmap filled by mapping procedure
Definition: SVDUnpackerModule.h:92
Belle2::SVD::SVDUnpackerModule::data_A::check
unsigned int check
MSB "1" - for Data word identification.
Definition: SVDUnpackerModule.h:146
Belle2::RelationsInterface::addRelationTo
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
Definition: RelationsObject.h:144
Belle2::SVD::SVDUnpackerModule::m_data32
uint32_t m_data32
Input 32-bit data word.
Definition: SVDUnpackerModule.h:175
Belle2::SVD::SVDUnpackerModule::beginRun
virtual void beginRun() override
begin run
Definition: SVDUnpackerModule.cc:98
Belle2::SVDModeByte
Class to store SVD mode information.
Definition: SVDModeByte.h:79
Belle2::SVD::SVDUnpackerModule::MainHeader::trgType
unsigned int trgType
Trigger Type.
Definition: SVDUnpackerModule.h:120
Belle2::SVD::SVDUnpackerModule::m_svdEventInfoName
std::string m_svdEventInfoName
SVDEventInfo name.
Definition: SVDUnpackerModule.h:81
Belle2::SVD::SVDUnpackerModule::APVHeader::apvErr
unsigned int apvErr
APV Errors field.
Definition: SVDUnpackerModule.h:134
Belle2::SVD::SVDUnpackerModule::APVHeader::pipelineAddr
unsigned int pipelineAddr
Pipeline Address.
Definition: SVDUnpackerModule.h:135
Belle2::SVD::SVDUnpackerModule::FTBHeader::eventNumber
unsigned int eventNumber
FTB event number.
Definition: SVDUnpackerModule.h:114
Belle2::SVD::SVDUnpackerModule::m_data_B
data_B m_data_B
Implementation of 2nd data word.
Definition: SVDUnpackerModule.h:180
Belle2::SVD::SVDUnpackerModule::FTBHeader::errorsField
unsigned int errorsField
FTB error fields.
Definition: SVDUnpackerModule.h:113
Belle2::SVD::SVDUnpackerModule::nMissingAPVsErrors
int nMissingAPVsErrors
counter of missing APVs errors
Definition: SVDUnpackerModule.h:236
Belle2::SVD::SVDUnpackerModule::data_A::stripNum
unsigned int stripNum
Strip number.
Definition: SVDUnpackerModule.h:145
Belle2::SVD::SVDUnpackerModule::m_rawSVD
StoreArray< RawSVD > m_rawSVD
output for RawSVD
Definition: SVDUnpackerModule.h:189
Belle2::SVDShaperDigit
The SVD ShaperDigit class.
Definition: SVDShaperDigit.h:46
Belle2::SVD::SVDUnpackerModule::m_shutUpFTBError
int m_shutUpFTBError
regulates the number of "Event number mismatch" errors reported
Definition: SVDUnpackerModule.h:191
Belle2::SVD::SVDUnpackerModule::MainHeader::FADCnum
unsigned int FADCnum
FADC number.
Definition: SVDUnpackerModule.h:123
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::SVD::SVDUnpackerModule::m_svdEventInfoPtr
StoreObjPtr< SVDEventInfo > m_svdEventInfoPtr
SVDEventInfo output per event.
Definition: SVDUnpackerModule.h:186
Belle2::SVD::SVDUnpackerModule::seenHeadersAndTrailers
unsigned short seenHeadersAndTrailers
this 4-bits value should be 1111 if no headers/trailers are missing
Definition: SVDUnpackerModule.h:229
Belle2::Module::setPropertyFlags
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:210
Belle2::SVD::SVDUnpackerModule::m_silentAppend
bool m_silentAppend
Silently append new SVDShaperDigits to a pre-existing non-empty SVDShaperDigits storeArray.
Definition: SVDUnpackerModule.h:213
Belle2::SVD::SVDUnpackerModule::nFTBFlagsErrors
int nFTBFlagsErrors
counter of errors in FTBFlags variable
Definition: SVDUnpackerModule.h:239
Belle2::SVD::SVDUnpackerModule::m_map
std::unique_ptr< SVDOnlineToOfflineMap > m_map
Pointer to online-to-offline map.
Definition: SVDUnpackerModule.h:95
Belle2::SVD::SVDUnpackerModule::printB2Debug
void printB2Debug(uint32_t *data32, uint32_t *data32_min, uint32_t *data32_max, int nWords)
additional function that prints raw data words
Definition: SVDUnpackerModule.cc:654
Belle2::SVD::SVDUnpackerModule::event
virtual void event() override
event
Definition: SVDUnpackerModule.cc:147
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::SVD::SVDUnpackerModule::m_MainHeader
MainHeader m_MainHeader
Implementation of FADC Header.
Definition: SVDUnpackerModule.h:177
Belle2::SVD::SVDUnpackerModule::m_FTBHeader
FTBHeader m_FTBHeader
Implementation of FTB Header.
Definition: SVDUnpackerModule.h:176
Belle2::SVD::SVDUnpackerModule::data_A::sample1
unsigned int sample1
1st data sample
Definition: SVDUnpackerModule.h:142
Belle2::SVD::SVDUnpackerModule::m_SVDTriggerType
SVDTriggerType m_SVDTriggerType
SVDTriggerType object.
Definition: SVDUnpackerModule.h:187
LogVar
Class to store variables with their name which were sent to the logging service.
Definition: LogVariableStream.h:24
Belle2::SVD::SVDUnpackerModule::m_data_A
data_A m_data_A
Implementation of 1st data word.
Definition: SVDUnpackerModule.h:179
Belle2::SVD::SVDUnpackerModule::MainHeader::runType
unsigned int runType
Run Type.
Definition: SVDUnpackerModule.h:126
Belle2::SVD
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Definition: GeoSVDCreator.h:35
Belle2::SVD::SVDUnpackerModule::m_emulatePipelineAddress
bool m_emulatePipelineAddress
Software emulation of pipeline address This is a replacement of hardware pipeline address emulation.
Definition: SVDUnpackerModule.h:199
Belle2::SVD::SVDUnpackerModule::MainHeader::trgNumber
unsigned int trgNumber
Trigger Number.
Definition: SVDUnpackerModule.h:119
Belle2::SVD::SVDUnpackerModule::data_B::check
unsigned int check
MSB "1" - for Data word identification.
Definition: SVDUnpackerModule.h:155
Belle2::SVD::SVDUnpackerModule::nEventMatchErrors
int nEventMatchErrors
counter of Event match errors
Definition: SVDUnpackerModule.h:233
Belle2::SVD::SVDUnpackerModule::initialize
virtual void initialize() override
Initializes the Module.
Definition: SVDUnpackerModule.cc:78
Belle2::SVD::SVDUnpackerModule::data_B::sample6
unsigned int sample6
6th data sample
Definition: SVDUnpackerModule.h:153
Belle2::SVD::SVDUnpackerModule::APVHeader::CMC1
unsigned int CMC1
Common Mode Noise w/o masking out particle signals.
Definition: SVDUnpackerModule.h:132
Belle2::SVD::SVDUnpackerModule::nFADCMatchErrors
int nFADCMatchErrors
counter of FADC boards =/= n of RawData objects errors
Definition: SVDUnpackerModule.h:237
Belle2::SVD::SVDUnpackerModule::MainHeader::DAQMode
unsigned int DAQMode
Event type(2:1): "00"…1-sample, "01"…3-sample, "10"…6-sample.
Definition: SVDUnpackerModule.h:125
Belle2::SVD::SVDUnpackerModule::MainHeader::trgTiming
unsigned int trgTiming
Trigger Timing.
Definition: SVDUnpackerModule.h:121
Belle2::SVD::SVDUnpackerModule::nEventInfoMatchErrors
int nEventInfoMatchErrors
counter of inconsistencies in SVDEventInfo within an event
Definition: SVDUnpackerModule.h:240
Belle2::SVD::SVDUnpackerModule::data_B::stripNum
unsigned int stripNum
Strip number.
Definition: SVDUnpackerModule.h:154
Belle2::SVD::SVDUnpackerModule::m_SVDModeByte
SVDModeByte m_SVDModeByte
instance of SVDModeByte for the event
Definition: SVDUnpackerModule.h:104
Belle2::DataStore::c_ErrorIfAlreadyRegistered
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:74
Belle2::Module::addParam
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:562
Belle2::SVD::SVDUnpackerModule::~SVDUnpackerModule
virtual ~SVDUnpackerModule()
Destructor of the module.
Definition: SVDUnpackerModule.cc:74
Belle2::SVD::SVDUnpackerModule::MainHeader::xTalk
unsigned int xTalk
cross talk tag
Definition: SVDUnpackerModule.h:122
Belle2::SVD::SVDUnpackerModule::m_badMappingFatal
bool m_badMappingFatal
Optionally we can stop the unpacking if there is a missing APV/FADC combination in the mapping -> wro...
Definition: SVDUnpackerModule.h:218
Belle2::SVD::SVDUnpackerModule::endRun
virtual void endRun() override
end run
Definition: SVDUnpackerModule.cc:635
Belle2::SVD::SVDUnpackerModule::m_svdDAQDiagnosticsListName
std::string m_svdDAQDiagnosticsListName
SVDDAQDiagnostic StoreArray name.
Definition: SVDUnpackerModule.h:80
Belle2::StoreArray
Accessor to arrays stored in the data store.
Definition: ECLMatchingPerformanceExpertModule.h:33
Belle2::SVDDAQDiagnostic
Class to store SVD DAQ diagnostic information.
Definition: SVDDAQDiagnostic.h:33
Belle2::SVD::SVDUnpackerModule::FADCTrailer::check
unsigned int check
MSB "1110" - for FADC Trailer identification.
Definition: SVDUnpackerModule.h:164
Belle2::SVDDetectorConfiguration::isValid
bool isValid()
returns the unique ID of the payload
Definition: SVDDetectorConfiguration.h:204
Belle2::SVDDetectorConfiguration
This class defines the dbobject and the methods to access the parameters to configure SVD for data ta...
Definition: SVDDetectorConfiguration.h:45
Belle2::SVD::SVDUnpackerModule::m_mapping
DBObjPtr< PayloadFile > m_mapping
pointer to the payload with the mapping
Definition: SVDUnpackerModule.h:101
Belle2::SVD::SVDUnpackerModule::m_relativeTimeShift
int m_relativeTimeShift
latency difference between the 3- and 6-sample acquired events in usint of APV clock / 4,...
Definition: SVDUnpackerModule.h:248
Belle2::SVD::SVDUnpackerModule::FTBTrailer::controlWord
unsigned int controlWord
MSB "ff55" - FADC Trailer ID.
Definition: SVDUnpackerModule.h:170
Belle2::SVD::SVDUnpackerModule::m_FADCTrailer
FADCTrailer m_FADCTrailer
Implementation of FADC Trailer.
Definition: SVDUnpackerModule.h:181
Belle2::StoreArray::getEntries
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:226
Belle2::SVD::SVDUnpackerModule::nAPVErrors
int nAPVErrors
counter of APV errors
Definition: SVDUnpackerModule.h:238
Belle2::SVD::SVDUnpackerModule::m_xmlFileName
static std::string m_xmlFileName
XML filename.
Definition: SVDUnpackerModule.h:98
Belle2::SVD::SVDUnpackerModule::nUpsetAPVsErrors
int nUpsetAPVsErrors
counter of upset APV errors
Definition: SVDUnpackerModule.h:234
Belle2::SVD::SVDUnpackerModule::m_killUpsetDigits
bool m_killUpsetDigits
Optionally, we can kill digits coming from upset APVs right in the unpacker.
Definition: SVDUnpackerModule.h:204
Belle2::SVD::SVDUnpackerModule::m_eventMetaDataPtr
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
Required input for EventMetaData.
Definition: SVDUnpackerModule.h:185
Belle2::SVD::SVDUnpackerModule::m_printRaw
bool m_printRaw
Optionally we can get printout of Raw Data words.
Definition: SVDUnpackerModule.h:221
Belle2::SVD::SVDUnpackerModule::MainHeader::DAQType
unsigned int DAQType
(from 2020c) Event type(0): "0"…3 or …6 acquisition mode, "1"…3-mixed-6 acquisition mode
Definition: SVDUnpackerModule.h:124
Belle2::SVD::SVDUnpackerModule::m_errorRate
int m_errorRate
The parameter that indicates what fraction of B2ERRORs messages should be suppressed to not overload ...
Definition: SVDUnpackerModule.h:226