Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:07:53

0001 #include "DQM/L1TMonitor/interface/L1TMP7ZeroSupp.h"
0002 
0003 const unsigned int L1TMP7ZeroSupp::maxMasks_ = 16;
0004 
0005 L1TMP7ZeroSupp::L1TMP7ZeroSupp(const edm::ParameterSet& ps)
0006     : fedDataToken_(consumes<FEDRawDataCollection>(ps.getParameter<edm::InputTag>("rawData"))),
0007       zsEnabled_(ps.getUntrackedParameter<bool>("zsEnabled")),
0008       fedIds_(ps.getParameter<std::vector<int>>("fedIds")),
0009       slinkHeaderSize_(ps.getUntrackedParameter<int>("lenSlinkHeader")),
0010       slinkTrailerSize_(ps.getUntrackedParameter<int>("lenSlinkTrailer")),
0011       amc13HeaderSize_(ps.getUntrackedParameter<int>("lenAMC13Header")),
0012       amc13TrailerSize_(ps.getUntrackedParameter<int>("lenAMC13Trailer")),
0013       amcHeaderSize_(ps.getUntrackedParameter<int>("lenAMCHeader")),
0014       amcTrailerSize_(ps.getUntrackedParameter<int>("lenAMCTrailer")),
0015       newZsFlagMask_(ps.getUntrackedParameter<int>("newZsFlagMask")),
0016       zsFlagMask_(ps.getUntrackedParameter<int>("zsFlagMask")),
0017       dataInvFlagMask_(ps.getUntrackedParameter<int>("dataInvFlagMask")),
0018       maxFedReadoutSize_(ps.getUntrackedParameter<int>("maxFEDReadoutSize")),
0019       checkOnlyCapIdsWithMasks_(ps.getUntrackedParameter<bool>("checkOnlyCapIdsWithMasks")),
0020       monitorDir_(ps.getUntrackedParameter<std::string>("monitorDir")),
0021       verbose_(ps.getUntrackedParameter<bool>("verbose")) {
0022   std::vector<int> onesMask(6, 0xffffffff);
0023   masks_.reserve(maxMasks_);
0024   for (unsigned int i = 0; i < maxMasks_; ++i) {
0025     std::string maskCapIdStr{"maskCapId" + std::to_string(i)};
0026     masks_.push_back(ps.getUntrackedParameter<std::vector<int>>(maskCapIdStr, onesMask));
0027     // which masks are defined?
0028     if (ps.exists(maskCapIdStr)) {
0029       definedMaskCapIds_.push_back(i);
0030     }
0031   }
0032   if (verbose_) {
0033     // check masks
0034     std::cout << "masks" << std::endl;
0035     for (unsigned int i = 0; i < maxMasks_; ++i) {
0036       std::cout << "caption ID" << i << ":" << std::endl;
0037       for (const auto& maskIt : masks_.at(i)) {
0038         std::cout << std::hex << std::setw(8) << std::setfill('0') << maskIt << std::dec << std::endl;
0039       }
0040     }
0041     std::cout << "----------" << std::endl;
0042   }
0043 }
0044 
0045 L1TMP7ZeroSupp::~L1TMP7ZeroSupp() = default;
0046 
0047 void L1TMP7ZeroSupp::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0048   edm::ParameterSetDescription desc;
0049   desc.add<edm::InputTag>("rawData");
0050   desc.add<std::vector<int>>("fedIds")->setComment("FED ids to analyze.");
0051   desc.addUntracked<bool>("zsEnabled", true)->setComment("MP7 zero suppression is enabled.");
0052   desc.addUntracked<int>("lenSlinkHeader", 8)->setComment("Number of Slink header bytes.");
0053   desc.addUntracked<int>("lenSlinkTrailer", 8)->setComment("Number of Slink trailer bytes.");
0054   desc.addUntracked<int>("lenAMC13Header", 8)->setComment("Number of AMC13 header bytes.");
0055   desc.addUntracked<int>("lenAMC13Trailer", 8)->setComment("Number of AMC13 trailer bytes.");
0056   desc.addUntracked<int>("lenAMCHeader", 8)->setComment("Number of AMC header bytes.");
0057   desc.addUntracked<int>("lenAMCTrailer", 0)->setComment("Number of AMC trailer bytes.");
0058   desc.addUntracked<int>("zsFlagMask", 0x1)->setComment("Zero suppression flag mask.");
0059   desc.addUntracked<int>("newZsFlagMask", 0x2)->setComment("Per-BX zero suppression flag mask.");
0060   desc.addUntracked<int>("dataInvFlagMask", 0x1)->setComment("Data inversion flag mask.");
0061   desc.addUntracked<int>("maxFEDReadoutSize", 10000)->setComment("Maximal FED readout size histogram x-axis value.");
0062   for (unsigned int i = 0; i < maxMasks_; ++i) {
0063     desc.addOptionalUntracked<std::vector<int>>("maskCapId" + std::to_string(i))
0064         ->setComment("ZS mask for caption id " + std::to_string(i) + ".");
0065   }
0066   desc.addUntracked<bool>("checkOnlyCapIdsWithMasks", true)
0067       ->setComment("Check only blocks that have a CapId for which a mask is defined.");
0068   desc.addUntracked<std::string>("monitorDir", "")
0069       ->setComment("Target directory in the DQM file. Will be created if not existing.");
0070   desc.addUntracked<bool>("verbose", false);
0071   descriptions.add("l1tMP7ZeroSupp", desc);
0072 }
0073 
0074 void L1TMP7ZeroSupp::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, const edm::EventSetup&) {
0075   // overall summary
0076   ibooker.setCurrentFolder(monitorDir_);
0077   bookCapIdHistograms(ibooker, maxMasks_);
0078   capIds_ = ibooker.book1D("capIds", "Caption ids found in data", maxMasks_, 0, maxMasks_);
0079   capIds_->setAxisTitle("caption id", 1);
0080 
0081   // per caption id subdirectories
0082   for (const auto& id : definedMaskCapIds_) {
0083     ibooker.setCurrentFolder(monitorDir_ + "/CapId" + std::to_string(id));
0084     bookCapIdHistograms(ibooker, id);
0085   }
0086 }
0087 
0088 void L1TMP7ZeroSupp::bookCapIdHistograms(DQMStore::IBooker& ibooker, const unsigned int& id) {
0089   std::string summaryTitleText = "Zero suppression validation summary";
0090   std::string sizeTitleText;
0091   if (id == maxMasks_) {
0092     sizeTitleText = "FED readout ";
0093   } else {
0094     summaryTitleText = summaryTitleText + ", caption id " + std::to_string(id);
0095     sizeTitleText = "cumulated caption id " + std::to_string(id) + " block ";
0096   }
0097 
0098   zeroSuppValMap_[id] = ibooker.book1D("zeroSuppVal", summaryTitleText, (int)NBINLABELS, 0, (int)NBINLABELS);
0099   zeroSuppValMap_[id]->setAxisTitle("ZS status", 1);
0100   zeroSuppValMap_[id]->setBinLabel(EVTS + 1, "events", 1);
0101   zeroSuppValMap_[id]->setBinLabel(EVTSGOOD + 1, "good events", 1);
0102   zeroSuppValMap_[id]->setBinLabel(EVTSBAD + 1, "bad events", 1);
0103   zeroSuppValMap_[id]->setBinLabel(BLOCKS + 1, "blocks", 1);
0104   zeroSuppValMap_[id]->setBinLabel(ZSBLKSGOOD + 1, "good blocks", 1);
0105   zeroSuppValMap_[id]->setBinLabel(ZSBLKSBAD + 1, "bad blocks", 1);
0106   zeroSuppValMap_[id]->setBinLabel(ZSBLKSBADFALSEPOS + 1, "false pos.", 1);
0107   zeroSuppValMap_[id]->setBinLabel(ZSBLKSBADFALSENEG + 1, "false neg.", 1);
0108   zeroSuppValMap_[id]->setBinLabel(BXBLOCKS + 1, "BX blocks", 1);
0109   zeroSuppValMap_[id]->setBinLabel(ZSBXBLKSGOOD + 1, "good BX blocks", 1);
0110   zeroSuppValMap_[id]->setBinLabel(ZSBXBLKSBAD + 1, "bad BX blocks", 1);
0111   zeroSuppValMap_[id]->setBinLabel(ZSBXBLKSBADFALSEPOS + 1, "BX false pos.", 1);
0112   zeroSuppValMap_[id]->setBinLabel(ZSBXBLKSBADFALSENEG + 1, "BX false neg.", 1);
0113 
0114   errorSummaryNumMap_[id] = ibooker.book1D("errorSummaryNum", summaryTitleText, (int)RNBINLABELS, 0, (int)RNBINLABELS);
0115   errorSummaryNumMap_[id]->setBinLabel(REVTS + 1, "bad events", 1);
0116   errorSummaryNumMap_[id]->setBinLabel(RBLKS + 1, "bad blocks", 1);
0117   errorSummaryNumMap_[id]->setBinLabel(RBLKSFALSEPOS + 1, "false pos.", 1);
0118   errorSummaryNumMap_[id]->setBinLabel(RBLKSFALSENEG + 1, "false neg.", 1);
0119   errorSummaryNumMap_[id]->setBinLabel(RBXBLKS + 1, "bad BX blocks", 1);
0120   errorSummaryNumMap_[id]->setBinLabel(RBXBLKSFALSEPOS + 1, "BX false pos.", 1);
0121   errorSummaryNumMap_[id]->setBinLabel(RBXBLKSFALSENEG + 1, "BX false neg.", 1);
0122 
0123   errorSummaryDenMap_[id] = ibooker.book1D("errorSummaryDen", "denominators", (int)RNBINLABELS, 0, (int)RNBINLABELS);
0124   errorSummaryDenMap_[id]->setBinLabel(REVTS + 1, "# events", 1);
0125   errorSummaryDenMap_[id]->setBinLabel(RBLKS + 1, "# blocks", 1);
0126   errorSummaryDenMap_[id]->setBinLabel(RBLKSFALSEPOS + 1, "# blocks", 1);
0127   errorSummaryDenMap_[id]->setBinLabel(RBLKSFALSENEG + 1, "# blocks", 1);
0128   errorSummaryDenMap_[id]->setBinLabel(RBXBLKS + 1, "# BX blocks", 1);
0129   errorSummaryDenMap_[id]->setBinLabel(RBXBLKSFALSEPOS + 1, "# BX blocks", 1);
0130   errorSummaryDenMap_[id]->setBinLabel(RBXBLKSFALSENEG + 1, "# BX blocks", 1);
0131   // Setting canExtend to false is needed to get the correct behaviour when running multithreaded.
0132   // Otherwise, when merging the histgrams of the threads, TH1::Merge sums bins that have the same label in one bin.
0133   // This needs to come after the calls to setBinLabel.
0134   errorSummaryDenMap_[id]->getTH1F()->GetXaxis()->SetCanExtend(false);
0135 
0136   readoutSizeNoZSMap_[id] = ibooker.book1D("readoutSize", sizeTitleText + "size", 100, 0, maxFedReadoutSize_);
0137   readoutSizeNoZSMap_[id]->setAxisTitle("size (byte)", 1);
0138   readoutSizeZSMap_[id] =
0139       ibooker.book1D("readoutSizeZS", sizeTitleText + "size with zero suppression", 100, 0, maxFedReadoutSize_);
0140   readoutSizeZSMap_[id]->setAxisTitle("size (byte)", 1);
0141   readoutSizeZSExpectedMap_[id] = ibooker.book1D(
0142       "readoutSizeZSExpected", "Expected " + sizeTitleText + "size with zero suppression", 100, 0, maxFedReadoutSize_);
0143   readoutSizeZSExpectedMap_[id]->setAxisTitle("size (byte)", 1);
0144 }
0145 
0146 void L1TMP7ZeroSupp::analyze(const edm::Event& e, const edm::EventSetup& c) {
0147   if (verbose_)
0148     edm::LogInfo("L1TDQM") << "L1TMP7ZeroSupp: analyze..." << std::endl;
0149 
0150   edm::Handle<FEDRawDataCollection> feds;
0151   e.getByToken(fedDataToken_, feds);
0152 
0153   if (!feds.isValid()) {
0154     edm::LogError("L1TDQM") << "Cannot analyse: no FEDRawDataCollection found";
0155     return;
0156   }
0157 
0158   zeroSuppValMap_[maxMasks_]->Fill(EVTS);
0159   errorSummaryDenMap_[maxMasks_]->Fill(REVTS);
0160   for (const auto& id : definedMaskCapIds_) {
0161     zeroSuppValMap_[id]->Fill(EVTS);
0162     errorSummaryDenMap_[id]->Fill(REVTS);
0163   }
0164 
0165   std::map<unsigned int, bool> evtGood;
0166   evtGood[maxMasks_] = true;
0167   for (const auto& id : definedMaskCapIds_) {
0168     evtGood[id] = true;
0169   }
0170   for (const auto& fedId : fedIds_) {
0171     const FEDRawData& l1tRcd = feds->FEDData(fedId);
0172 
0173     unsigned int fedDataSize = l1tRcd.size();
0174     std::map<unsigned int, unsigned int> readoutSizeNoZSMap;
0175     std::map<unsigned int, unsigned int> readoutSizeZSMap;
0176     std::map<unsigned int, unsigned int> readoutSizeZSExpectedMap;
0177     readoutSizeNoZSMap[maxMasks_] = 0;
0178     readoutSizeZSMap[maxMasks_] = 0;
0179     readoutSizeZSExpectedMap[maxMasks_] = 0;
0180     for (const auto& id : definedMaskCapIds_) {
0181       readoutSizeNoZSMap[id] = 0;
0182       readoutSizeZSMap[id] = 0;
0183       readoutSizeZSExpectedMap[id] = 0;
0184     }
0185 
0186     edm::LogInfo("L1TDQM") << "Found FEDRawDataCollection with ID " << fedId << " and size " << l1tRcd.size();
0187 
0188     if ((int)l1tRcd.size() < slinkHeaderSize_ + slinkTrailerSize_ + amc13HeaderSize_ + amc13TrailerSize_ +
0189                                  amcHeaderSize_ + amcTrailerSize_) {
0190       if (l1tRcd.size() > 0) {
0191         edm::LogError("L1TDQM") << "Cannot analyse: invalid L1T raw data (size = " << l1tRcd.size() << ") for ID "
0192                                 << fedId << ".";
0193       }
0194       continue;
0195     }
0196 
0197     const unsigned char* data = l1tRcd.data();
0198     FEDHeader header(data);
0199 
0200     if (header.check()) {
0201       edm::LogInfo("L1TDQM") << "Found SLink header:"
0202                              << " Trigger type " << header.triggerType() << " L1 event ID " << header.lvl1ID()
0203                              << " BX Number " << header.bxID() << " FED source " << header.sourceID() << " FED version "
0204                              << header.version();
0205     } else {
0206       edm::LogWarning("L1TDQM") << "Did not find a SLink header!";
0207     }
0208 
0209     FEDTrailer trailer(data + (l1tRcd.size() - slinkTrailerSize_));
0210 
0211     if (trailer.check()) {
0212       edm::LogInfo("L1TDQM") << "Found SLink trailer:"
0213                              << " Length " << trailer.fragmentLength() << " CRC " << trailer.crc() << " Status "
0214                              << trailer.evtStatus() << " Throttling bits " << trailer.ttsBits();
0215     } else {
0216       edm::LogWarning("L1TDQM") << "Did not find a SLink trailer!";
0217     }
0218 
0219     amc13::Packet packet;
0220     if (!packet.parse((const uint64_t*)data,
0221                       (const uint64_t*)(data + slinkHeaderSize_),
0222                       (l1tRcd.size() - slinkHeaderSize_ - slinkTrailerSize_) / 8,
0223                       header.lvl1ID(),
0224                       header.bxID())) {
0225       edm::LogError("L1TDQM") << "Could not extract AMC13 Packet.";
0226       return;
0227     }
0228 
0229     for (auto& amc : packet.payload()) {
0230       if (amc.size() == 0)
0231         continue;
0232 
0233       auto payload64 = amc.data();
0234       auto start = (const uint32_t*)payload64.get();
0235       // Want to have payload size in 32 bit words, but AMC measures
0236       // it in 64 bit words -> factor 2.
0237       const uint32_t* end = start + (amc.size() * 2);
0238 
0239       auto payload = std::make_unique<l1t::MP7Payload>(start, end, false);
0240 
0241       // getBlock() returns a non-null unique_ptr on success
0242       std::unique_ptr<l1t::Block> block;
0243       while ((block = payload->getBlock()) != nullptr) {
0244         if (verbose_) {
0245           std::cout << ">>> check zero suppression for block <<<" << std::endl
0246                     << "hdr:  " << std::hex << std::setw(8) << std::setfill('0') << block->header().raw() << std::dec
0247                     << " (ID " << block->header().getID() << ", size " << block->header().getSize() << ", CapID 0x"
0248                     << std::hex << std::setw(2) << std::setfill('0') << block->header().getCapID() << ", flags 0x"
0249                     << std::hex << std::setw(2) << std::setfill('0') << block->header().getFlags() << ")" << std::dec
0250                     << std::endl;
0251           for (const auto& word : block->payload()) {
0252             std::cout << "data: " << std::hex << std::setw(8) << std::setfill('0') << word << std::dec << std::endl;
0253           }
0254         }
0255 
0256         unsigned int blockCapId = block->header().getCapID();
0257         unsigned int blockSize = block->header().getSize() * 4;  // times 4 to get the size in byte
0258         unsigned int blockHeaderSize = sizeof(block->header().raw());
0259         unsigned int blockHeaderFlags = block->header().getFlags();
0260         bool newZsFlagSet = ((blockHeaderFlags & newZsFlagMask_) != 0);  // use the per-BX ZS
0261         bool blockZsFlagSet =
0262             newZsFlagSet ? true : ((blockHeaderFlags & zsFlagMask_) != 0);  // ZS validation flag for whole block
0263         bool dataInvertFlagSet =
0264             newZsFlagSet && ((blockHeaderFlags & dataInvFlagMask_) != 0);  // invert the data before applying the mask
0265 
0266         capIds_->Fill(blockCapId);
0267 
0268         bool capIdDefined = false;
0269         if (zeroSuppValMap_.find(blockCapId) != zeroSuppValMap_.end()) {
0270           capIdDefined = true;
0271         }
0272 
0273         // Only check blocks with a CapId that has a defined ZS mask.
0274         if (checkOnlyCapIdsWithMasks_ and not capIdDefined) {
0275           continue;
0276         }
0277 
0278         // fill the denominator histograms
0279         zeroSuppValMap_[maxMasks_]->Fill(BLOCKS);
0280         errorSummaryDenMap_[maxMasks_]->Fill(RBLKS);
0281         errorSummaryDenMap_[maxMasks_]->Fill(RBLKSFALSEPOS);
0282         errorSummaryDenMap_[maxMasks_]->Fill(RBLKSFALSENEG);
0283         if (capIdDefined) {
0284           zeroSuppValMap_[blockCapId]->Fill(BLOCKS);
0285           errorSummaryDenMap_[blockCapId]->Fill(RBLKS);
0286           errorSummaryDenMap_[blockCapId]->Fill(RBLKSFALSEPOS);
0287           errorSummaryDenMap_[blockCapId]->Fill(RBLKSFALSENEG);
0288         }
0289 
0290         auto totalBlockSize = blockHeaderSize;
0291         if (!newZsFlagSet) {
0292           totalBlockSize += blockSize;
0293         }
0294         auto totalBlockSizeExpected = totalBlockSize;
0295         auto totalBlockSizeNoZS = blockHeaderSize + blockSize;
0296 
0297         auto bxBlocks = block->getBxBlocks(6, newZsFlagSet);  // 6 32 bit MP7 payload words per BX
0298 
0299         // check all BX blocks
0300         bool allToSuppress = true;
0301         for (const auto& bxBlock : bxBlocks) {
0302           bool toSuppress = false;
0303           bool bxZsFlagSet = ((bxBlock.header().getFlags() & zsFlagMask_) != 0);  // ZS validation flag
0304 
0305           // check if this bxblock should be suppressed
0306           unsigned int wordcounter = 0;
0307           unsigned int wordsum = 0;
0308           for (const auto& word : bxBlock.payload()) {
0309             if (dataInvertFlagSet) {
0310               wordsum += masks_[blockCapId].at(wordcounter % 6) & (~word);
0311             } else {
0312               wordsum += masks_[blockCapId].at(wordcounter % 6) & word;
0313             }
0314             if (verbose_) {
0315               std::cout << "word: " << std::hex << std::setw(8) << std::setfill('0') << word << std::dec << ", maskword"
0316                         << wordcounter % 6 << ": " << std::hex << std::setw(8) << std::setfill('0')
0317                         << masks_[blockCapId].at(wordcounter % 6) << std::dec << ", wordsum: " << wordsum << std::endl;
0318             }
0319             if (wordsum > 0) {
0320               if (verbose_) {
0321                 std::cout << "wordsum not 0: this BX block should be kept" << std::endl;
0322               }
0323               break;
0324             }
0325             ++wordcounter;
0326           }
0327           // the sum of payload words must be 0 for correct ZS
0328           if (wordsum == 0 && zsEnabled_) {
0329             toSuppress = true;
0330             if (verbose_) {
0331               std::cout << "wordsum == 0: this BX block should be zero suppressed" << std::endl;
0332             }
0333           }
0334           // update the overall block status
0335           allToSuppress = allToSuppress && toSuppress;
0336 
0337           // only fill the BX related things for the per-BX ZS
0338           if (newZsFlagSet) {
0339             // the ZS flag of the block is the AND of all BX block ZS flags
0340             blockZsFlagSet = blockZsFlagSet && bxZsFlagSet;
0341 
0342             // fill the BX related bins of the denominator histogram
0343             zeroSuppValMap_[maxMasks_]->Fill(BXBLOCKS);
0344             errorSummaryDenMap_[maxMasks_]->Fill(RBXBLKS);
0345             errorSummaryDenMap_[maxMasks_]->Fill(RBXBLKSFALSEPOS);
0346             errorSummaryDenMap_[maxMasks_]->Fill(RBXBLKSFALSENEG);
0347             if (capIdDefined) {
0348               zeroSuppValMap_[blockCapId]->Fill(BXBLOCKS);
0349               errorSummaryDenMap_[blockCapId]->Fill(RBXBLKS);
0350               errorSummaryDenMap_[blockCapId]->Fill(RBXBLKSFALSEPOS);
0351               errorSummaryDenMap_[blockCapId]->Fill(RBXBLKSFALSENEG);
0352             }
0353 
0354             unsigned int totalBxBlockSize =
0355                 bxBlock.getSize() * 4 + sizeof(bxBlock.header().raw());  // times 4 to get the size in byte
0356             // check if zero suppression flag agrees for the BX block
0357             if (toSuppress && bxZsFlagSet) {
0358               if (verbose_)
0359                 std::cout << "GOOD BX block with ZS flag true" << std::endl;
0360               zeroSuppValMap_[maxMasks_]->Fill(ZSBXBLKSGOOD);
0361               if (capIdDefined) {
0362                 zeroSuppValMap_[blockCapId]->Fill(ZSBXBLKSGOOD);
0363               }
0364             } else if (!toSuppress && !bxZsFlagSet) {
0365               if (verbose_)
0366                 std::cout << "GOOD BX block with ZS flag false" << std::endl;
0367               totalBlockSize += totalBxBlockSize;
0368               totalBlockSizeExpected += totalBxBlockSize;
0369               zeroSuppValMap_[maxMasks_]->Fill(ZSBXBLKSGOOD);
0370               if (capIdDefined) {
0371                 zeroSuppValMap_[blockCapId]->Fill(ZSBXBLKSGOOD);
0372               }
0373             } else if (!toSuppress && bxZsFlagSet) {
0374               if (verbose_)
0375                 std::cout << "BAD BX block with ZS flag true" << std::endl;
0376               totalBlockSizeExpected += totalBxBlockSize;
0377               zeroSuppValMap_[maxMasks_]->Fill(ZSBXBLKSBAD);
0378               zeroSuppValMap_[maxMasks_]->Fill(ZSBXBLKSBADFALSEPOS);
0379               errorSummaryNumMap_[maxMasks_]->Fill(RBXBLKS);
0380               errorSummaryNumMap_[maxMasks_]->Fill(RBXBLKSFALSEPOS);
0381               evtGood[maxMasks_] = false;
0382               if (capIdDefined) {
0383                 zeroSuppValMap_[blockCapId]->Fill(ZSBXBLKSBAD);
0384                 zeroSuppValMap_[blockCapId]->Fill(ZSBXBLKSBADFALSEPOS);
0385                 errorSummaryNumMap_[blockCapId]->Fill(RBXBLKS);
0386                 errorSummaryNumMap_[blockCapId]->Fill(RBXBLKSFALSEPOS);
0387                 evtGood[blockCapId] = false;
0388               }
0389             } else {
0390               if (verbose_)
0391                 std::cout << "BAD BX block with ZS flag false" << std::endl;
0392               totalBlockSize += totalBxBlockSize;
0393               zeroSuppValMap_[maxMasks_]->Fill(ZSBXBLKSBAD);
0394               zeroSuppValMap_[maxMasks_]->Fill(ZSBXBLKSBADFALSENEG);
0395               errorSummaryNumMap_[maxMasks_]->Fill(RBXBLKS);
0396               errorSummaryNumMap_[maxMasks_]->Fill(RBXBLKSFALSENEG);
0397               evtGood[maxMasks_] = false;
0398               if (capIdDefined) {
0399                 zeroSuppValMap_[blockCapId]->Fill(ZSBXBLKSBAD);
0400                 zeroSuppValMap_[blockCapId]->Fill(ZSBXBLKSBADFALSENEG);
0401                 errorSummaryNumMap_[blockCapId]->Fill(RBXBLKS);
0402                 errorSummaryNumMap_[blockCapId]->Fill(RBXBLKSFALSENEG);
0403                 evtGood[blockCapId] = false;
0404               }
0405             }
0406           }
0407         }
0408 
0409         readoutSizeNoZSMap[maxMasks_] += totalBlockSizeNoZS;
0410         if (capIdDefined) {
0411           readoutSizeNoZSMap[blockCapId] += totalBlockSizeNoZS;
0412         }
0413 
0414         // check if zero suppression flag agrees for the whole block
0415         if (allToSuppress && blockZsFlagSet) {
0416           if (verbose_)
0417             std::cout << "GOOD block with ZS flag true" << std::endl;
0418           zeroSuppValMap_[maxMasks_]->Fill(ZSBLKSGOOD);
0419           if (capIdDefined) {
0420             zeroSuppValMap_[blockCapId]->Fill(ZSBLKSGOOD);
0421           }
0422         } else if (!allToSuppress && !blockZsFlagSet) {
0423           if (verbose_)
0424             std::cout << "GOOD block with ZS flag false" << std::endl;
0425           zeroSuppValMap_[maxMasks_]->Fill(ZSBLKSGOOD);
0426           readoutSizeZSMap[maxMasks_] += totalBlockSize;
0427           readoutSizeZSExpectedMap[maxMasks_] += totalBlockSizeExpected;
0428           if (capIdDefined) {
0429             zeroSuppValMap_[blockCapId]->Fill(ZSBLKSGOOD);
0430             readoutSizeZSMap[blockCapId] += totalBlockSize;
0431             readoutSizeZSExpectedMap[blockCapId] += totalBlockSizeExpected;
0432           }
0433         } else if (!allToSuppress && blockZsFlagSet) {
0434           if (verbose_)
0435             std::cout << "BAD block with ZS flag true" << std::endl;
0436           zeroSuppValMap_[maxMasks_]->Fill(ZSBLKSBAD);
0437           zeroSuppValMap_[maxMasks_]->Fill(ZSBLKSBADFALSEPOS);
0438           errorSummaryNumMap_[maxMasks_]->Fill(RBLKS);
0439           errorSummaryNumMap_[maxMasks_]->Fill(RBLKSFALSEPOS);
0440           readoutSizeZSExpectedMap[maxMasks_] += totalBlockSizeExpected;
0441           evtGood[maxMasks_] = false;
0442           if (capIdDefined) {
0443             zeroSuppValMap_[blockCapId]->Fill(ZSBLKSBAD);
0444             zeroSuppValMap_[blockCapId]->Fill(ZSBLKSBADFALSEPOS);
0445             errorSummaryNumMap_[blockCapId]->Fill(RBLKS);
0446             errorSummaryNumMap_[blockCapId]->Fill(RBLKSFALSEPOS);
0447             readoutSizeZSExpectedMap[blockCapId] += totalBlockSizeExpected;
0448             evtGood[blockCapId] = false;
0449           }
0450         } else {
0451           if (verbose_)
0452             std::cout << "BAD block with ZS flag false" << std::endl;
0453           zeroSuppValMap_[maxMasks_]->Fill(ZSBLKSBAD);
0454           zeroSuppValMap_[maxMasks_]->Fill(ZSBLKSBADFALSENEG);
0455           errorSummaryNumMap_[maxMasks_]->Fill(RBLKS);
0456           errorSummaryNumMap_[maxMasks_]->Fill(RBLKSFALSENEG);
0457           readoutSizeZSMap[maxMasks_] += totalBlockSize;
0458           evtGood[maxMasks_] = false;
0459           if (capIdDefined) {
0460             zeroSuppValMap_[blockCapId]->Fill(ZSBLKSBAD);
0461             zeroSuppValMap_[blockCapId]->Fill(ZSBLKSBADFALSENEG);
0462             errorSummaryNumMap_[blockCapId]->Fill(RBLKS);
0463             errorSummaryNumMap_[blockCapId]->Fill(RBLKSFALSENEG);
0464             readoutSizeZSMap[blockCapId] += totalBlockSize;
0465             evtGood[blockCapId] = false;
0466           }
0467         }
0468       }
0469     }
0470     if (verbose_) {
0471       std::cout << "FED data size: " << fedDataSize << " bytes" << std::endl;
0472       std::cout << "Payload size no ZS: " << readoutSizeNoZSMap[maxMasks_] << " bytes" << std::endl;
0473       std::cout << "Payload size ZS: " << readoutSizeZSMap[maxMasks_] << " bytes" << std::endl;
0474       std::cout << "Payload size expected ZS: " << readoutSizeZSExpectedMap[maxMasks_] << " bytes" << std::endl;
0475       std::cout << "Filled readout size ZS with headers: "
0476                 << readoutSizeZSMap[maxMasks_] + fedDataSize - readoutSizeNoZSMap[maxMasks_] << " bytes" << std::endl;
0477       std::cout << "Filled expected readout size ZS with headers: "
0478                 << readoutSizeZSExpectedMap[maxMasks_] + fedDataSize - readoutSizeNoZSMap[maxMasks_] << " bytes"
0479                 << std::endl;
0480     }
0481     readoutSizeNoZSMap_[maxMasks_]->Fill(fedDataSize);
0482     readoutSizeZSMap_[maxMasks_]->Fill(readoutSizeZSMap[maxMasks_] + fedDataSize - readoutSizeNoZSMap[maxMasks_]);
0483     readoutSizeZSExpectedMap_[maxMasks_]->Fill(readoutSizeZSExpectedMap[maxMasks_] + fedDataSize -
0484                                                readoutSizeNoZSMap[maxMasks_]);
0485     for (const auto& id : definedMaskCapIds_) {
0486       readoutSizeNoZSMap_[id]->Fill(readoutSizeNoZSMap[id]);
0487       readoutSizeZSMap_[id]->Fill(readoutSizeZSMap[id]);
0488       readoutSizeZSExpectedMap_[id]->Fill(readoutSizeZSExpectedMap[id]);
0489     }
0490   }
0491 
0492   if (evtGood[maxMasks_]) {
0493     zeroSuppValMap_[maxMasks_]->Fill(EVTSGOOD);
0494   } else {
0495     zeroSuppValMap_[maxMasks_]->Fill(EVTSBAD);
0496     errorSummaryNumMap_[maxMasks_]->Fill(REVTS);
0497   }
0498   for (const auto& id : definedMaskCapIds_) {
0499     if (evtGood[id]) {
0500       zeroSuppValMap_[id]->Fill(EVTSGOOD);
0501     } else {
0502       zeroSuppValMap_[id]->Fill(EVTSBAD);
0503       errorSummaryNumMap_[id]->Fill(REVTS);
0504     }
0505   }
0506 }