Belle II Software  release-05-02-19
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  m_svdShaperDigitListName = storeShaperDigits.getName();
94 
95 }
96 
98 {
99  if (!m_mapping.isValid())
100  B2FATAL("no valid SVD Channel Mapping. We stop here.");
101 
102  m_wrongFTBcrc = 0;
103  if (m_mapping.hasChanged()) { m_map = std::make_unique<SVDOnlineToOfflineMap>(m_mapping->getFileName()); }
104 
105  if (! m_map) { //give up
106  B2ERROR("SVD xml map not loaded." << std::endl <<
107  "No SVDShaperDigit will be produced for this run!");
108  return;
109  }
110 
111  //number of FADC boards
112  nFADCboards = m_map->getFADCboardsNumber();
113 
114  //passing APV<->FADC mapping from SVDOnlineToOfflineMap object
115  APVmap = &(m_map->APVforFADCmap);
116 
117  //setting UnpackerErrorRate factor to use it for BadMapping error suppression
118  m_map->setErrorRate(m_errorRate);
119 
120  nTriggerMatchErrors = -1;
121  nEventMatchErrors = -1;
122  nUpsetAPVsErrors = -1;
123  nErrorFieldErrors = -1;
124  nMissingAPVsErrors = -1;
125  nFADCMatchErrors = -1;
126  nAPVErrors = -1;
127  nFTBFlagsErrors = -1;
129 
131 
132  //get the relative time shift
133  SVDDetectorConfiguration detectorConfig;
134  if (detectorConfig.isValid())
135  m_relativeTimeShift = detectorConfig.getRelativeTimeShift();
136  else {
137  B2ERROR("SVDDetectorConfiguration not valid!! Setting relativeTimeShift to 0 for this reconstruction.");
139  }
140 }
141 
142 #ifndef __clang__
143 #pragma GCC diagnostic push
144 #pragma GCC diagnostic ignored "-Wstack-usage="
145 #endif
147 {
149  if (!rawSVDList || !rawSVDList.getEntries())
150  return;
151 
154 
155  if (!m_silentAppend && shaperDigits && shaperDigits.getEntries())
156  B2WARNING("Unpacking SVDShaperDigits to a non-empty pre-existing \n"
157  << "StoreArray. This can lead to undesired behaviour. At least\n"
158  << "remember to use SVDShaperDigitSorter in your path and \n"
159  << "set the silentlyAppend parameter of SVDUnpacker to true.");
160 
161  SVDDAQDiagnostic* currentDAQDiagnostic;
162  vector<SVDDAQDiagnostic*> vDiagnostic_ptr;
163 
164  map<SVDShaperDigit, SVDDAQDiagnostic*> diagnosticMap;
165  // Store encountered pipeline addresses with APVs in which they were observed
166  map<unsigned short, set<pair<unsigned short, unsigned short> > > apvsByPipeline;
167 
168  if (!m_eventMetaDataPtr.isValid()) { // give up...
169  B2ERROR("Missing valid EventMetaData." << std::endl << "No SVDShaperDigit produced for this event!");
170  return;
171  }
172 
173  bool nFADCmatch = true;
174  bool nAPVmatch = true;
175  bool badMapping = false;
176  bool badHeader = false;
177  bool badTrailer = false;
178  bool missedHeader = false;
179  bool missedTrailer = false;
180 
181  // flag to set SVDEventInfo once per event
182  bool isSetEventInfo = false;
183 
184  //flag to set nAPVsamples in SVDEventInfo once per event
185  bool isSetNAPVsamples = false;
186 
187  unsigned short nAPVheaders = 999;
188  set<short> seenAPVHeaders = {};
189 
190  unsigned short nEntries_rawSVD = rawSVDList.getEntries();
191  auto eventNo = m_eventMetaDataPtr->getEvent();
192 
193  short fadc = 255, apv = 63;
194 
195  if (nEntries_rawSVD != nFADCboards) {
197  if (!(nFADCMatchErrors % m_errorRate)) B2ERROR("Number of RawSVD data objects do not match the number of FADC boards" <<
198  LogVar("#RawSVD",
199  nEntries_rawSVD) << LogVar("#FADCs", nFADCboards) << LogVar("Event number", eventNo));
200 
201  nFADCmatch = false;
202  }
203 
204  for (unsigned int i = 0; i < nEntries_rawSVD; i++) {
205 
206  unsigned int numEntries_rawSVD = rawSVDList[ i ]->GetNumEntries();
207  for (unsigned int j = 0; j < numEntries_rawSVD; j++) {
208 
209  unsigned short nWords[4];
210  nWords[0] = rawSVDList[i]->Get1stDetectorNwords(j);
211  nWords[1] = rawSVDList[i]->Get2ndDetectorNwords(j);
212  nWords[2] = rawSVDList[i]->Get3rdDetectorNwords(j);
213  nWords[3] = rawSVDList[i]->Get4thDetectorNwords(j);
214 
215  uint32_t* data32tab[4]; //vector of pointers
216 
217  data32tab[0] = (uint32_t*)rawSVDList[i]->Get1stDetectorBuffer(j); // points at the begining of the 1st buffer
218  data32tab[1] = (uint32_t*)rawSVDList[i]->Get2ndDetectorBuffer(j);
219  data32tab[2] = (uint32_t*)rawSVDList[i]->Get3rdDetectorBuffer(j);
220  data32tab[3] = (uint32_t*)rawSVDList[i]->Get4thDetectorBuffer(j);
221 
222 
223  unsigned short ftbError = 0;
224  unsigned short trgType = 0;
225  unsigned short trgNumber = 0;
226  unsigned short daqMode = -1;
227  unsigned short daqType = 0;
228  unsigned short cmc1;
229  unsigned short cmc2;
230  unsigned short apvErrors;
231  unsigned short pipAddr;
232  unsigned short ftbFlags = 0;
233  unsigned short apvErrorsOR = 0;
234 
235  bool is3sampleData = false;
236  bool is6sampleData = false;
237 
238  for (unsigned int buf = 0; buf < 4; buf++) { // loop over 4 buffers
239 
240  if (data32tab[buf] == NULL && nWords[buf] == 0) continue;
241  if (m_printRaw) printB2Debug(data32tab[buf], data32tab[buf], &data32tab[buf][nWords[buf] - 1], nWords[buf]);
242 
243  missedHeader = false;
244  missedTrailer = false;
245 
246  uint32_t* data32_it = data32tab[buf];
247  short strip, sample[6];
248  vector<uint32_t> crc16vec;
249 
250  for (; data32_it != &data32tab[buf][nWords[buf]]; data32_it++) {
251  m_data32 = *data32_it; //put current 32-bit frame to union
252 
253  if (m_data32 == 0xffaa0000) { // first part of FTB header
254  crc16vec.clear(); // clear the input container for crc16 calculation
255  crc16vec.push_back(m_data32);
256 
257  seenHeadersAndTrailers++; // we found FTB header
258 
259  data32_it++; // go to 2nd part of FTB header
260  crc16vec.push_back(*data32_it);
261 
262  m_data32 = *data32_it; //put the second 32-bit frame to union
263 
264  ftbError = m_FTBHeader.errorsField;
265 
266  if (ftbError != 240) {
268 
269  if (!(nErrorFieldErrors % m_errorRate) or nErrorFieldErrors < 100) {
270  switch (ftbError - 240) {
271  case 3:
272  B2ERROR("FADC Event Number is different from (FTB & TTD) Event Numbers");
273  break;
274  case 5:
275  B2ERROR("TTD Event Number is different from (FTB & FADC) Event Numbers");
276  break;
277  case 6:
278  B2ERROR("FTB Event Number is different from (TTD & FADC) Event Numbers");
279  break;
280  case 7:
281  B2ERROR("(FTB, TTD & FADC) Event Numbers are different from each other");
282  break;
283  default:
284  B2ERROR("Problem with errorsField variable in FTB Header" << LogVar("abnormal value", ftbError));
285  }
286  }
287  }
288 
289  if (m_FTBHeader.eventNumber !=
290  (eventNo & 0xFFFFFF)) {
293  m_shutUpFTBError -= 1;
294  B2ERROR("Event number mismatch detected! The event number given by EventMetaData object is different from the one in the FTB Header."
295  << LogVar("Expected event number & 0xFFFFFF",
296  (eventNo & 0xFFFFFF)) << LogVar("Event number in the FTB", m_FTBHeader.eventNumber));
297  }
298  }
299 
300  continue;
301  } // is FTB Header
302 
303  crc16vec.push_back(m_data32);
304 
305  if (m_MainHeader.check == 6) { // FADC header
306 
307  seenHeadersAndTrailers += 2; //we found FADC Header
308 
309  fadc = m_MainHeader.FADCnum;
310  trgType = m_MainHeader.trgType;
311  trgNumber = m_MainHeader.trgNumber;
312  daqMode = m_MainHeader.DAQMode;
313  daqType = m_MainHeader.DAQType;
314 
315  //Let's add run-dependent info: daqMode="11" in case of 3-mixed-6 sample acquisition mode.
316  if (daqType) daqMode = 3;
317 
318  nAPVheaders = 0; // start counting APV headers for this FADC
319  nAPVmatch = true; //assume correct # of APV headers
320  badMapping = false; //assume correct mapping
321  badHeader = false;
322  badTrailer = false;
323 
324  is3sampleData = false;
325  is6sampleData = false;
326 
327  if (daqMode == 0) B2ERROR("SVDDataFormatCheck: the event " << eventNo <<
328  " is apparently taken with 1-sample mode, this is not expected.");
329  if (daqMode == 1) is3sampleData = true;
330  if (daqMode == 2) is6sampleData = true;
331 
332  if (
334  ((eventNo - m_FADCTriggerNumberOffset) & 0xFF)) {
335 
338  B2ERROR("Event number mismatch detected! The event number given by EventMetaData object is different from the one in the FADC Header. "
339  << LogVar("Event number", eventNo) << LogVar("FADC", fadc) << LogVar("Trigger number LSByte reported by the FADC",
340  m_MainHeader.trgNumber) << LogVar("+ offset", m_FADCTriggerNumberOffset) << LogVar("expected", (eventNo & 0xFF)));
341  badHeader = true;
342  }
343 
344  // create SVDModeByte object from MainHeader vars
346 
347  // create SVDEventInfo and fill it with SVDModeByte & SVDTriggerType objects
348  if (!isSetEventInfo) {
349  m_SVDTriggerType = SVDTriggerType(trgType);
350  m_svdEventInfoPtr.create();
351  m_svdEventInfoPtr->setModeByte(m_SVDModeByte);
352  m_svdEventInfoPtr->setTriggerType(m_SVDTriggerType);
353 
354  //set relative time shift
355  m_svdEventInfoPtr->setRelativeShift(m_relativeTimeShift);
356  // set X-talk info online from Raw Data
357  m_svdEventInfoPtr->setCrossTalk(m_MainHeader.xTalk);
358 
359  isSetEventInfo = true;
360  } else { // let's check if the current SVDModeByte and SVDTriggerType are consistent with the one stored in SVDEventInfo
361  if (m_SVDModeByte != m_svdEventInfoPtr->getModeByte()) {m_svdEventInfoPtr->setMatchModeByte(false); badHeader = true; nEventInfoMatchErrors++;}
362  if (trgType != (m_svdEventInfoPtr->getTriggerType()).getType()) { m_svdEventInfoPtr->setMatchTriggerType(false); badHeader = true; nEventInfoMatchErrors++;}
363  }
364  } // is FADC header
365 
366  if (m_APVHeader.check == 2) { // APV header
367 
368  nAPVheaders++;
369  apv = m_APVHeader.APVnum;
370  seenAPVHeaders.insert(apv);
371 
372  cmc1 = m_APVHeader.CMC1;
373  cmc2 = m_APVHeader.CMC2;
374  apvErrors = m_APVHeader.apvErr;
375  pipAddr = m_APVHeader.pipelineAddr;
376 
377  if (apvErrors != 0) {
378  nAPVErrors++;
379  if (!(nAPVErrors % m_errorRate)
380  or nAPVErrors < 100) B2ERROR("APV error has been detected." << LogVar("FADC", fadc) << LogVar("APV", apv) << LogVar("Error value",
381  apvErrors));
382  }
383  // temporary SVDDAQDiagnostic object (no info from trailers and APVmatch code)
384  currentDAQDiagnostic = DAQDiagnostics.appendNew(trgNumber, trgType, pipAddr, cmc1, cmc2, apvErrors, ftbError, nFADCmatch, nAPVmatch,
385  badHeader, missedHeader, missedTrailer,
386  fadc, apv);
387  vDiagnostic_ptr.push_back(currentDAQDiagnostic);
388 
389  apvsByPipeline[pipAddr].insert(make_pair(fadc, apv));
390  } //is APV Header
391 
392  if (m_data_A.check == 0) { // data
393  strip = m_data_A.stripNum;
394 
395  sample[0] = m_data_A.sample1;
396  sample[1] = m_data_A.sample2;
397  sample[2] = m_data_A.sample3;
398 
399  sample[3] = 0;
400  sample[4] = 0;
401  sample[5] = 0;
402 
403  // Let's check the next rawdata word to determine if we acquired 3 or 6 sample
404  data32_it++;
405  m_data32 = *data32_it;
406 
407  if (m_data_B.check == 0 && strip == m_data_B.stripNum) { // 2nd data frame with the same strip number -> six samples
408 
409  if (!isSetNAPVsamples) {
410  m_svdEventInfoPtr->setNSamples(6);
411  isSetNAPVsamples = true;
412  } else {
413  if (is3sampleData)
414  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!");
415  }
416 
417  crc16vec.push_back(m_data32);
418 
419  sample[3] = m_data_B.sample4;
420  sample[4] = m_data_B.sample5;
421  sample[5] = m_data_B.sample6;
422  }
423 
424  else { // three samples
425  data32_it--;
426  m_data32 = *data32_it;
427 
428  if (!isSetNAPVsamples) {
429  m_svdEventInfoPtr->setNSamples(3);
430  isSetNAPVsamples = true;
431  } else {
432  if (is6sampleData)
433  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!");
434  }
435  }
436 
437  // Generating SVDShaperDigit object
438  SVDShaperDigit* newShaperDigit = m_map->NewShaperDigit(fadc, apv, strip, sample, 0.0, m_SVDModeByte);
439  if (newShaperDigit) {
440  diagnosticMap.insert(make_pair(*newShaperDigit, currentDAQDiagnostic));
441  delete newShaperDigit;
442  } else if (m_badMappingFatal) {
443  B2FATAL("Respective FADC/APV combination not found -->> incorrect payload in the database! ");
444  } else {
445  badMapping = true;
446  }
447 
448  } //is data frame
449 
450 
451  if (m_FADCTrailer.check == 14) { // FADC trailer
452 
453  seenHeadersAndTrailers += 4; // we found FAD trailer
454 
455  //additional check if we have a faulty/fake FADC that is not in the map
456  if (APVmap->find(fadc) == APVmap->end()) badMapping = true;
457 
458  //comparing number of APV chips and the number of APV headers, for the current FADC
459  unsigned short nAPVs = APVmap->count(fadc);
460 
461  if (nAPVheaders == 0) {
462  currentDAQDiagnostic = DAQDiagnostics.appendNew(0, 0, 0, 0, 0, 0, ftbError, nFADCmatch, nAPVmatch, badHeader, 0, 0, fadc, 0);
463  vDiagnostic_ptr.push_back(currentDAQDiagnostic);
464  }
465 
466  if (nAPVs != nAPVheaders) {
467  // There is an APV missing, detect which it is.
468  for (const auto& fadcApv : *APVmap) {
469  if (fadcApv.first != fadc) continue;
470  if (seenAPVHeaders.find(fadcApv.second) == seenAPVHeaders.end()) {
471  // We have a missing APV. Look if it is a known one.
472  auto missingRec = m_missingAPVs.find(make_pair(fadcApv.first, fadcApv.second));
473  if (missingRec != m_missingAPVs.end()) {
474  // This is known to be missing, so keep quiet and just update event counters
475  if (missingRec->second.first > eventNo)
476  missingRec->second.first = eventNo;
477  if (missingRec->second.second < eventNo)
478  missingRec->second.second = eventNo;
479  } else {
480  // We haven't seen this previously.
482  m_missingAPVs.insert(make_pair(
483  make_pair(fadcApv.first, fadcApv.second),
484  make_pair(eventNo, eventNo)
485  ));
486  if (!(nMissingAPVsErrors % m_errorRate)) B2ERROR("missing APV header! " << LogVar("Event number", eventNo) << LogVar("APV",
487  int(fadcApv.second)) << LogVar("FADC",
488  int(fadcApv.first)));
489  }
490  }
491  }
492  nAPVmatch = false;
493  } // is nAPVs != nAPVheaders
494 
495  seenAPVHeaders.clear();
496 
497  ftbFlags = m_FADCTrailer.FTBFlags;
498  if ((ftbFlags >> 5) != 0) badTrailer = true;
499  if (ftbFlags != 0) {
500  nFTBFlagsErrors++;
501  if (!(nFTBFlagsErrors % m_errorRate) or nFTBFlagsErrors < 100) {
502  B2ERROR(" FTB Flags variable has an active error bit(s)" << LogVar("on FADC number", fadc));
503 
504  if (ftbFlags & 16) B2ERROR("----> CRC error has been detected. Data might be corrupted!");
505  if (ftbFlags & 8) B2ERROR("----> Bad Event indication has been detected. Data might be corrupted!");
506  if (ftbFlags & 4) B2ERROR("----> Double Header has been detected. Data might be corrupted!");
507  if (ftbFlags & 2) B2ERROR("----> Time Out has been detected. Data might be corrupted!");
508  if (ftbFlags & 1) B2ERROR("----> Event Too Long! Data might be corrupted!");
509  }
510  }
511 
512  apvErrorsOR = m_FADCTrailer.apvErrOR;
513 
514 
515  }// is FADC trailer
516 
517  if (m_FTBTrailer.controlWord == 0xff55) {// FTB trailer
518 
519  seenHeadersAndTrailers += 8; // we found FTB trailer
520 
521  //check CRC16
522  crc16vec.pop_back();
523  unsigned short iCRC = crc16vec.size();
524  uint32_t crc16input[iCRC];
525 
526  for (unsigned short icrc = 0; icrc < iCRC; icrc++)
527  crc16input[icrc] = htonl(crc16vec.at(icrc));
528 
529  //verify CRC16
530  boost::crc_basic<16> bcrc(0x8005, 0xffff, 0, false, false);
531  bcrc.process_block(crc16input, crc16input + iCRC);
532  unsigned int checkCRC = bcrc.checksum();
533 
534  if (checkCRC != m_FTBTrailer.crc16) {
535  B2WARNING("FTB CRC16 checksum DOES NOT MATCH" << LogVar("for FADC no.", fadc));
536  m_wrongFTBcrc++;
537  }
538 
539  } // is FTB trailer
540 
541  } // end loop over 32-bit frames in each buffer
542 
543  } // end iteration on 4 data buffers
544 
545  //Let's check if all the headers and trailers were in place in the last frame
546  if (seenHeadersAndTrailers != 0xf) {
547  if (!(seenHeadersAndTrailers & 1)) {B2ERROR("Missing FTB Header is detected. SVD data might be corrupted!" << LogVar("Event number", eventNo) << LogVar("FADC", fadc)); missedHeader = true;}
548  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;}
549  if (!(seenHeadersAndTrailers & 4)) {B2ERROR("Missing FADC Trailer is detected. SVD data might be corrupted!" << LogVar("Event number", eventNo) << LogVar("FADC", fadc)); missedTrailer = true;}
550  if (!(seenHeadersAndTrailers & 8)) {B2ERROR("Missing FTB Trailer is detected. SVD data might be corrupted!" << LogVar("Event number", eventNo) << LogVar("FADC", fadc)); missedTrailer = true;}
551  }
552 
553  //reset value for headers and trailers check
555 
556  for (auto p : vDiagnostic_ptr) {
557  // adding remaining info to Diagnostic object
558  p->setFTBFlags(ftbFlags);
559  p->setApvErrorOR(apvErrorsOR);
560  p->setAPVMatch(nAPVmatch);
561  p->setBadMapping(badMapping);
562  p->setBadTrailer(badTrailer);
563  p->setMissedHeader(missedHeader);
564  p->setMissedTrailer(missedTrailer);
565 
566  vDiagnostic_ptr.clear();
567  }
568 
569  } // end event loop
570 
571  }// end loop over RawSVD objects
572 
573  // Detect upset APVs and report/treat
574  auto major_apv = max_element(apvsByPipeline.begin(), apvsByPipeline.end(),
575  [](const decltype(apvsByPipeline)::value_type & p1,
576  const decltype(apvsByPipeline)::value_type & p2) -> bool
577  { return p1.second.size() < p2.second.size(); }
578  );
579  // We set emuPipelineAddress fields in diagnostics to this.
581  for (auto& p : DAQDiagnostics)
582  p.setEmuPipelineAddress(major_apv->first);
583  // And report any upset apvs or update records
584  if (apvsByPipeline.size() > 1)
585  for (const auto& p : apvsByPipeline) {
586  if (p.first == major_apv->first) continue;
587  for (const auto& fadcApv : p.second) {
588  // We have an upset APV. Look if it is a known one.
589  auto upsetRec = m_upsetAPVs.find(make_pair(fadcApv.first, fadcApv.second));
590  if (upsetRec != m_upsetAPVs.end()) {
591  // This is known to be upset, so keep quiet and update event counters
592  if (upsetRec->second.first > eventNo)
593  upsetRec->second.first = eventNo;
594  if (upsetRec->second.second < eventNo)
595  upsetRec->second.second = eventNo;
596  } else {
597  // We haven't seen this one previously.
599  m_upsetAPVs.insert(make_pair(
600  make_pair(fadcApv.first, fadcApv.second),
601  make_pair(eventNo, eventNo)
602  ));
603  for (auto& pp : DAQDiagnostics) {
604 
605  if (pp.getFADCNumber() == fadcApv.first and pp.getAPVNumber() == fadcApv.second)
606  pp.setUpsetAPV(true);
607  }
608  if (!(nUpsetAPVsErrors % m_errorRate)) B2ERROR("Upset APV detected!!!" << LogVar("APV", int(fadcApv.second)) << LogVar("FADC",
609  int(fadcApv.first)) << LogVar("Event number", eventNo));
610  }
611  }
612  }
613 
614  // Here we can delete digits coming from upset APVs. We detect them by comparing
615  // actual and emulated pipeline address fields in DAQDiagnostics.
616  for (auto& p : diagnosticMap) {
617 
618  if ((m_killUpsetDigits && p.second->getPipelineAddress() != p.second->getEmuPipelineAddress()) || p.second->getFTBError() != 240
619  || p.second->getFTBFlags() || p.second->getAPVError() || !(p.second->getAPVMatch()) || !(p.second->getFADCMatch())
620  || p.second->getBadHeader()
621  || p.second->getBadMapping() || p.second->getUpsetAPV() || p.second->getMissedHeader() || p.second->getMissedTrailer()) continue;
622  shaperDigits.appendNew(p.first);
623  }
624 
625  if (!m_svdEventInfoPtr->getMatchTriggerType()) {if (!(nEventInfoMatchErrors % m_errorRate) or nEventInfoMatchErrors < 200) B2WARNING("Inconsistent SVD Trigger Type value for: " << LogVar("Event number", eventNo));}
626  if (!m_svdEventInfoPtr->getMatchModeByte()) {if (!(nEventInfoMatchErrors % m_errorRate) or nEventInfoMatchErrors < 200) B2WARNING("Inconsistent SVD ModeByte object for: " << LogVar("Event number", eventNo));}
627 
628 
629 } //end event function
630 #ifndef __clang__
631 #pragma GCC diagnostic pop
632 #endif
633 
635 {
636  // Summary report on missing APVs
637  if (m_missingAPVs.size() > 0) {
638  B2WARNING("SVDUnpacker summary 1: Missing APVs");
639  for (const auto& miss : m_missingAPVs)
640  B2WARNING(LogVar("Missing APV", miss.first.second) << LogVar("FADC", miss.first.first) << LogVar("since event",
641  miss.second.first) << LogVar("to event", miss.second.second));
642  }
643  if (m_upsetAPVs.size() > 0) {
644  B2WARNING("SVDUnpacker summary 2: Upset APVs");
645  for (const auto& upst : m_upsetAPVs)
646  B2WARNING(LogVar("Upset APV", upst.first.second) << LogVar("FADC", upst.first.first) <<
647  LogVar("since event", upst.second.first) << LogVar("to event", upst.second.second));
648  }
649 }
650 
651 
652 // additional printing function
653 void SVDUnpackerModule::printB2Debug(uint32_t* data32, uint32_t* data32_min, uint32_t* data32_max, int nWords)
654 {
655 
656  uint32_t* min = std::max((data32 - nWords), data32_min);
657  uint32_t* max = std::min((data32 + nWords), data32_max);
658 
659  size_t counter{0};
660  std::stringstream os;
661  os << std::hex << std::setfill('0');
662  for (uint32_t* ptr = min; ptr <= max; ++ptr) {
663  os << std::setw(8) << *ptr;
664  if (++counter % 10 == 0) os << std::endl;
665  else os << " ";
666  }
667 
668  os << std::endl;
669  B2INFO(os.str());
670  return;
671 
672 }
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::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::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:97
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:653
Belle2::SVD::SVDUnpackerModule::event
virtual void event() override
event
Definition: SVDUnpackerModule.cc:146
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:634
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