147 B2WARNING(
"Unpacking SVDShaperDigits to a non-empty pre-existing \n"
148 <<
"StoreArray. This can lead to undesired behaviour. At least\n"
149 <<
"remember to use SVDShaperDigitSorter in your path and \n"
150 <<
"set the silentlyAppend parameter of SVDUnpacker to true.");
153 vector<SVDDAQDiagnostic*> vDiagnostic_ptr;
155 map<SVDShaperDigit, SVDDAQDiagnostic*> diagnosticMap;
157 map<unsigned short, set<pair<unsigned short, unsigned short> > > apvsByPipeline;
160 B2ERROR(
"Missing valid EventMetaData." << std::endl <<
"No SVDShaperDigit produced for this event!");
164 bool nAPVmatch =
true;
165 bool badMapping =
false;
166 bool badHeader =
false;
167 bool badTrailer =
false;
168 bool missedHeader =
false;
169 bool missedTrailer =
false;
172 bool isSetEventInfo =
false;
175 bool isSetNAPVsamples =
false;
177 unsigned short nAPVheaders = 999;
178 set<short> seenAPVHeaders = {};
180 unsigned short nEntries_rawSVD =
m_rawSVD.getEntries();
183 short fadc = 255, apv = 63;
185 unsigned short cntFADCboards = 0;
186 for (
unsigned int i = 0; i < nEntries_rawSVD; i++) {
188 unsigned int numEntries_rawSVD =
m_rawSVD[ i ]->GetNumEntries();
189 for (
unsigned int j = 0; j < numEntries_rawSVD; j++) {
191 const unsigned short maxNumOfCh =
m_rawSVD[i]->GetMaxNumOfCh(j);
193 std::vector<unsigned short> nWords;
194 nWords.reserve(maxNumOfCh);
195 std::vector<uint32_t*> data32tab(maxNumOfCh);
196 for (
unsigned int k = 0; k < maxNumOfCh; k++) {
197 nWords.push_back(
m_rawSVD[i]->GetDetectorNwords(j, k));
198 data32tab[k] =
reinterpret_cast<uint32_t*
>(
m_rawSVD[i]->GetDetectorBuffer(j, k));
201 unsigned short ftbError = 0;
202 unsigned short trgType = 0;
203 unsigned short trgNumber = 0;
204 unsigned short daqMode = -1;
205 unsigned short daqType = 0;
208 unsigned short apvErrors;
209 unsigned short pipAddr;
210 unsigned short ftbFlags = 0;
211 unsigned short apvErrorsOR = 0;
213 bool is3sampleData =
false;
214 bool is6sampleData =
false;
216 for (
unsigned int buf = 0; buf < maxNumOfCh; buf++) {
218 if (data32tab[buf] ==
nullptr || nWords.at(buf) == 0) {
219 if (data32tab[buf] !=
nullptr || nWords.at(buf) != 0) {
220 B2WARNING(
"Invalid combination of buffer pointer and nWords:" <<
221 LogVar(
"COPPER/PCIe40 ID", i) <<
222 LogVar(
"COPPER/PCIe40 Entry", j) <<
223 LogVar(
"COPPER/PCIe40 Channel", buf) <<
224 LogVar(
"data32tab[buf]", data32tab[buf]) <<
225 LogVar(
"nWords[buf]", nWords.at(buf)));
229 if (
m_printRaw)
printB2Debug(data32tab[buf], data32tab[buf], &data32tab[buf][nWords.at(buf) - 1], nWords.at(buf));
233 missedHeader =
false;
234 missedTrailer =
false;
236 uint32_t* data32_it = data32tab[buf];
237 short strip, sample[6];
238 vector<uint32_t> crc16vec;
243 for (; data32_it != &data32tab[buf][nWords.at(buf)]; data32_it++) {
253 crc16vec.push_back(*data32_it);
259 if (ftbError != 240) {
263 switch (ftbError - 240) {
265 B2ERROR(
"FADC Event Number is different from (FTB & TTD) Event Numbers");
268 B2ERROR(
"TTD Event Number is different from (FTB & FADC) Event Numbers");
271 B2ERROR(
"FTB Event Number is different from (TTD & FADC) Event Numbers");
274 B2ERROR(
"(FTB, TTD & FADC) Event Numbers are different from each other");
277 B2ERROR(
"Problem with errorsField variable in FTB Header" <<
LogVar(
"abnormal value", ftbError));
283 (eventNo & 0xFFFFFF)) {
287 B2ERROR(
"Event number mismatch detected! The event number given by EventMetaData object is different from the one in the FTB Header."
288 <<
LogVar(
"Expected event number & 0xFFFFFF",
289 (eventNo & 0xFFFFFF)) <<
LogVar(
"Event number in the FTB",
m_FTBHeader.eventNumber));
309 if (daqType) daqMode = 3;
317 is3sampleData =
false;
318 is6sampleData =
false;
320 if (daqMode == 0) B2ERROR(
"SVDDataFormatCheck: the event " << eventNo <<
321 " is apparently taken with 1-sample mode, this is not expected.");
322 if (daqMode == 1) is3sampleData =
true;
323 if (daqMode == 2) is6sampleData =
true;
331 B2ERROR(
"Event number mismatch detected! The event number given by EventMetaData object is different from the one in the FADC Header. "
332 <<
LogVar(
"Event number", eventNo) <<
LogVar(
"FADC", fadc) <<
LogVar(
"Trigger number LSByte reported by the FADC",
341 if (!isSetEventInfo) {
353 isSetEventInfo =
true;
364 seenAPVHeaders.insert(apv);
371 if (apvErrors != 0) {
378 currentDAQDiagnostic =
m_storeDAQDiagnostics.appendNew(trgNumber, trgType, pipAddr, cmc1, cmc2, apvErrors, ftbError,
true,
380 badHeader, missedHeader, missedTrailer,
382 vDiagnostic_ptr.push_back(currentDAQDiagnostic);
384 apvsByPipeline[pipAddr].insert(make_pair(fadc, apv));
387 if (pipAddr == 255) {
390 if (
m_data_A.check == 0) B2ERROR(
"The strip data frame is detected for the special SEU recovery mode. " <<
LogVar(
"pipline address",
391 pipAddr) <<
"This is unexpected!");
415 if (!isSetNAPVsamples) {
417 isSetNAPVsamples =
true;
420 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!");
434 if (!isSetNAPVsamples) {
436 isSetNAPVsamples =
true;
439 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!");
445 if (newShaperDigit) {
446 diagnosticMap.insert(make_pair(*newShaperDigit, currentDAQDiagnostic));
447 delete newShaperDigit;
449 B2FATAL(
"Respective FADC/APV combination not found -->> incorrect payload in the database! ");
462 if (
APVmap->find(fadc) ==
APVmap->end()) badMapping =
true;
465 unsigned short nAPVs =
APVmap->count(fadc);
467 if (nAPVheaders == 0) {
468 currentDAQDiagnostic =
m_storeDAQDiagnostics.appendNew(0, 0, 0, 0, 0, 0, ftbError,
true, nAPVmatch, badHeader, 0, 0, fadc, 0);
469 vDiagnostic_ptr.push_back(currentDAQDiagnostic);
472 if (nAPVs != nAPVheaders) {
474 for (
const auto& fadcApv : *
APVmap) {
475 if (fadcApv.first != fadc)
continue;
476 if (seenAPVHeaders.find(fadcApv.second) == seenAPVHeaders.end()) {
478 auto missingRec =
m_missingAPVs.find(make_pair(fadcApv.first, fadcApv.second));
481 if (missingRec->second.first > eventNo)
482 missingRec->second.first = eventNo;
483 if (missingRec->second.second < eventNo)
484 missingRec->second.second = eventNo;
489 make_pair(fadcApv.first, fadcApv.second),
490 make_pair(eventNo, eventNo)
493 int(fadcApv.second)) <<
LogVar(
"FADC",
494 int(fadcApv.first)));
501 seenAPVHeaders.clear();
504 if ((ftbFlags >> 5) != 0) badTrailer =
true;
508 B2ERROR(
" FTB Flags variable has an active error bit(s)" <<
LogVar(
"on FADC number", fadc));
510 if (ftbFlags & 16) B2ERROR(
"----> CRC error has been detected. Data might be corrupted!");
511 if (ftbFlags & 8) B2ERROR(
"----> Bad Event indication has been detected. Data might be corrupted!");
512 if (ftbFlags & 4) B2ERROR(
"----> Double Header has been detected. Data might be corrupted!");
513 if (ftbFlags & 2) B2ERROR(
"----> Time Out has been detected. Data might be corrupted!");
514 if (ftbFlags & 1) B2ERROR(
"----> Event Too Long! Data might be corrupted!");
529 unsigned short iCRC = crc16vec.size();
530 std::vector<uint32_t> crc16input;
531 crc16input.reserve(iCRC);
533 for (
unsigned short icrc = 0; icrc < iCRC; icrc++)
534 crc16input.push_back(htonl(crc16vec.at(icrc)));
537 boost::crc_basic<16> bcrc(0x8005, 0xffff, 0,
false,
false);
538 bcrc.process_bytes(crc16input.data(), crc16input.size() *
sizeof(uint32_t));
539 unsigned int checkCRC = bcrc.checksum();
542 B2WARNING(
"FTB CRC16 checksum DOES NOT MATCH" <<
LogVar(
"for FADC no.", fadc));
552 if (!(
seenHeadersAndTrailers & 1)) {B2ERROR(
"Missing FTB Header is detected. SVD data might be corrupted!" <<
LogVar(
"Event number", eventNo) <<
LogVar(
"FADC", fadc)); missedHeader =
true;}
553 if (!(
seenHeadersAndTrailers & 2)) {B2ERROR(
"Missing FADC Header is detected -> related FADC number couldn't be retrieved. SVD data might be corrupted! " <<
LogVar(
"Event number", eventNo) <<
LogVar(
"previous FADC", fadc)); missedHeader =
true;}
554 if (!(
seenHeadersAndTrailers & 4)) {B2ERROR(
"Missing FADC Trailer is detected. SVD data might be corrupted!" <<
LogVar(
"Event number", eventNo) <<
LogVar(
"FADC", fadc)); missedTrailer =
true;}
555 if (!(
seenHeadersAndTrailers & 8)) {B2ERROR(
"Missing FTB Trailer is detected. SVD data might be corrupted!" <<
LogVar(
"Event number", eventNo) <<
LogVar(
"FADC", fadc)); missedTrailer =
true;}
558 for (
auto p : vDiagnostic_ptr) {
560 p->setFTBFlags(ftbFlags);
561 p->setApvErrorOR(apvErrorsOR);
562 p->setAPVMatch(nAPVmatch);
563 p->setBadMapping(badMapping);
564 p->setBadTrailer(badTrailer);
565 p->setMissedHeader(missedHeader);
566 p->setMissedTrailer(missedTrailer);
569 vDiagnostic_ptr.clear();
581 LogVar(
"# of data objects in rawSVD",
586 p.setFADCMatch(
false);
593 auto itPtr = apvsByPipeline.find(255);
594 if (itPtr != apvsByPipeline.end()) {
595 for (
const auto& fadcApv : itPtr->second) {
597 auto seuRec =
m_seuRecMap.find(make_pair(fadcApv.first, fadcApv.second));
599 if (seuRec->second.first > eventNo)
600 seuRec->second.first = eventNo;
601 if (seuRec->second.second < eventNo)
602 seuRec->second.second = eventNo;
606 make_pair(fadcApv.first, fadcApv.second),
607 make_pair(eventNo, eventNo)
610 B2ERROR(
"Special Recovery Data (Dummy APV Header) found due to the detection of Single Event Upset (SEU)!!!" <<
LogVar(
"APV",
611 int(fadcApv.second)) <<
LogVar(
"FADC",
int(fadcApv.first)) <<
LogVar(
"Event number", eventNo));
615 if (pp.getFADCNumber() == fadcApv.first and pp.getAPVNumber() == fadcApv.second)
616 pp.setSEURecoData(
true);
623 auto majorAPV = max_element(apvsByPipeline.begin(), apvsByPipeline.end(),
624 [](
const decltype(apvsByPipeline)::value_type & p1,
625 const decltype(apvsByPipeline)::value_type & p2) ->
bool
626 { return p1.second.size() < p2.second.size(); }
631 p.setEmuPipelineAddress(majorAPV->first);
633 unsigned short apvsByPipelineSize = apvsByPipeline.size();
634 if (majorAPV->first == 255) apvsByPipelineSize = 1;
637 if (apvsByPipelineSize > 1)
638 for (
const auto& p : apvsByPipeline) {
639 if (p.first == majorAPV->first or p.first == 255)
continue;
640 for (
const auto& fadcApv : p.second) {
642 auto upsetRec =
m_upsetAPVs.find(make_pair(fadcApv.first, fadcApv.second));
645 if (upsetRec->second.first > eventNo)
646 upsetRec->second.first = eventNo;
647 if (upsetRec->second.second < eventNo)
648 upsetRec->second.second = eventNo;
653 make_pair(fadcApv.first, fadcApv.second),
654 make_pair(eventNo, eventNo)
658 int(fadcApv.first)) <<
LogVar(
"Event number", eventNo));
663 if (pp.getFADCNumber() == fadcApv.first and pp.getAPVNumber() == fadcApv.second)
664 pp.setUpsetAPV(
true);
672 for (
auto& p : diagnosticMap) {
674 if ((
m_killUpsetDigits && p.second->getPipelineAddress() != p.second->getEmuPipelineAddress()) || p.second->getFTBError() != 240
675 || p.second->getFTBFlags() || p.second->getAPVError() || !(p.second->getAPVMatch()) || !(p.second->getFADCMatch())
676 || p.second->getBadHeader()
677 || p.second->getBadMapping() || p.second->getUpsetAPV() || p.second->getMissedHeader() || p.second->getMissedTrailer())
continue;