Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:54:36

0001 /**
0002  * \class L1GtDataEmulAnalyzer
0003  * 
0004  * 
0005  * Description: compare hardware records with emulator records for L1 GT record.  
0006  *
0007  * Implementation:
0008  *    Get the L1 GT records from data and from emulator.   
0009  *    Compare every board between data and emulator.
0010  *   
0011  * \author: Vasile Mihai Ghete - HEPHY Vienna
0012  * 
0013  *
0014  */
0015 
0016 // this class header
0017 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtDataEmulAnalyzer.h"
0018 
0019 // system include files
0020 #include <memory>
0021 #include <iostream>
0022 #include <iomanip>
0023 
0024 // user include files
0025 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
0026 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
0027 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0028 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
0029 
0030 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0031 #include "FWCore/ServiceRegistry/interface/Service.h"
0032 #include "CommonTools/UtilAlgos/interface/TFileService.h"
0033 
0034 #include "FWCore/Framework/interface/EventSetup.h"
0035 #include "FWCore/Framework/interface/ESHandle.h"
0036 
0037 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
0038 #include "CondFormats/DataRecord/interface/L1GtTriggerMenuRcd.h"
0039 
0040 #include "CondFormats/L1TObjects/interface/L1GtTriggerMask.h"
0041 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskAlgoTrigRcd.h"
0042 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskTechTrigRcd.h"
0043 
0044 #include "TH1.h"
0045 #include "TH2.h"
0046 #include "TTree.h"
0047 
0048 // constructor(s)
0049 L1GtDataEmulAnalyzer::L1GtDataEmulAnalyzer(const edm::ParameterSet& parSet) {
0050   usesResource(TFileService::kSharedResource);
0051 
0052   // input tag for the L1 GT hardware DAQ/EVM record
0053   m_l1GtDataInputTag = parSet.getParameter<edm::InputTag>("L1GtDataInputTag");
0054 
0055   // input tag for the L1 GT emulator DAQ/EVM record
0056   m_l1GtEmulInputTag = parSet.getParameter<edm::InputTag>("L1GtEmulInputTag");
0057 
0058   // input tag for the L1 GCT hardware record
0059   m_l1GctDataInputTag = parSet.getParameter<edm::InputTag>("L1GctDataInputTag");
0060 
0061   LogDebug("L1GtDataEmulAnalyzer") << "\nInput tag for the L1 GT hardware records:          " << m_l1GtDataInputTag
0062                                    << "\nInput tag for the L1 GT emulator records:          " << m_l1GtEmulInputTag
0063                                    << "\nInput tag for the L1 GCT hardware record:          " << m_l1GctDataInputTag
0064                                    << std::endl;
0065 
0066   // initialize counters
0067   m_nrDataEventError = 0;
0068   m_nrEmulEventError = 0;
0069 
0070   // cache
0071   m_l1GtMenuCacheID = 0ULL;
0072 
0073   m_l1GtTmAlgoCacheID = 0ULL;
0074   m_l1GtTmTechCacheID = 0ULL;
0075 
0076   // book histograms
0077   bookHistograms();
0078 
0079   m_l1GtMenuToken = esConsumes();
0080   m_l1GtTmAlgoToken = esConsumes();
0081   m_l1GtTmTechToken = esConsumes();
0082 }
0083 
0084 // destructor
0085 L1GtDataEmulAnalyzer::~L1GtDataEmulAnalyzer() {
0086   // empty
0087 }
0088 
0089 // member functions
0090 
0091 // method called once each job just before starting event loop
0092 void L1GtDataEmulAnalyzer::beginJob() {
0093   // empty
0094 }
0095 
0096 //compare the GTFE board
0097 void L1GtDataEmulAnalyzer::compareGTFE(const edm::Event& iEvent,
0098                                        const edm::EventSetup& evSetup,
0099                                        const L1GtfeWord& gtfeBlockData,
0100                                        const L1GtfeWord& gtfeBlockEmul) {
0101   if (gtfeBlockData == gtfeBlockEmul) {
0102     m_myCoutStream << "\nData and emulated GTFE blocks: identical.\n";
0103     gtfeBlockData.print(m_myCoutStream);
0104   } else {
0105     m_myCoutStream << "\nData and emulated GTFE blocks: different.\n";
0106 
0107     m_myCoutStream << "\nData: GTFE block\n";
0108     gtfeBlockData.print(m_myCoutStream);
0109 
0110     m_myCoutStream << "\nEmul: GTFE block\n";
0111     gtfeBlockEmul.print(m_myCoutStream);
0112   }
0113 
0114   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0115 
0116   m_myCoutStream.str("");
0117   m_myCoutStream.clear();
0118 
0119   // get BoardId value
0120   const uint16_t boardIdData = gtfeBlockData.boardId();
0121   const uint16_t boardIdEmul = gtfeBlockEmul.boardId();
0122 
0123   if (boardIdData == boardIdEmul) {
0124     m_myCoutStream << "\nData and emulated GTFE boardId identical.";
0125     m_myCoutStream << "\n boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0126                    << std::setfill(' ') << std::dec;
0127     m_myCoutStream << "\n";
0128 
0129   } else {
0130     m_myCoutStream << "\nData and emulated GTFE boardId different.";
0131     m_myCoutStream << "\n Data: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0132                    << std::setfill(' ') << std::dec;
0133     m_myCoutStream << "\n Emul: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdEmul
0134                    << std::setfill(' ') << std::dec;
0135     m_myCoutStream << "\n";
0136     m_gtfeDataEmul->Fill(0);
0137   }
0138 
0139   /// get record length: 3 bx for standard, 5 bx for debug
0140   const uint16_t recordLengthData = gtfeBlockData.recordLength();
0141   const uint16_t recordLengthEmul = gtfeBlockEmul.recordLength();
0142 
0143   if (recordLengthData == recordLengthEmul) {
0144     m_myCoutStream << "\nData and emulated GTFE recordLength identical.";
0145     m_myCoutStream << "\n recordLength() = " << recordLengthData;
0146     m_myCoutStream << "\n";
0147 
0148   } else {
0149     m_myCoutStream << "\nData and emulated GTFE recordLength different.";
0150     m_myCoutStream << "\n Data: recordLength() = " << recordLengthData;
0151     m_myCoutStream << "\n Emul: recordLength() = " << recordLengthEmul;
0152     m_myCoutStream << "\n";
0153     m_gtfeDataEmul->Fill(1);
0154   }
0155 
0156   /// get bunch cross number as counted in the GTFE board
0157   const uint16_t bxNrData = gtfeBlockData.bxNr();
0158   const uint16_t bxNrEmul = gtfeBlockEmul.bxNr();
0159 
0160   if (bxNrData == bxNrEmul) {
0161     m_myCoutStream << "\nData and emulated GTFE bxNr identical.";
0162     m_myCoutStream << "\n bxNr() = " << bxNrData;
0163     m_myCoutStream << "\n";
0164 
0165   } else {
0166     m_myCoutStream << "\nData and emulated GTFE bxNr different.";
0167     m_myCoutStream << "\n Data: bxNr() = " << bxNrData;
0168     m_myCoutStream << "\n Emul: bxNr() = " << bxNrEmul;
0169     m_myCoutStream << "\n";
0170     m_gtfeDataEmul->Fill(2);
0171   }
0172 
0173   /// get setup version
0174   const uint32_t setupVersionData = gtfeBlockData.setupVersion();
0175   const uint32_t setupVersionEmul = gtfeBlockEmul.setupVersion();
0176 
0177   if (setupVersionData == setupVersionEmul) {
0178     m_myCoutStream << "\nData and emulated GTFE setupVersion identical.";
0179     m_myCoutStream << "\n setupVersion() = " << setupVersionData;
0180     m_myCoutStream << "\n";
0181 
0182   } else {
0183     m_myCoutStream << "\nData and emulated GTFE setupVersion different.";
0184     m_myCoutStream << "\n Data: setupVersion() = " << setupVersionData;
0185     m_myCoutStream << "\n Emul: setupVersion() = " << setupVersionEmul;
0186     m_myCoutStream << "\n";
0187     m_gtfeDataEmul->Fill(3);
0188   }
0189 
0190   /// get boards contributing to EVM respectively DAQ record
0191   const uint16_t activeBoardsData = gtfeBlockData.activeBoards();
0192   const uint16_t activeBoardsEmul = gtfeBlockEmul.activeBoards();
0193 
0194   if (activeBoardsData == activeBoardsEmul) {
0195     m_myCoutStream << "\nData and emulated GTFE activeBoards identical.";
0196     m_myCoutStream << "\n activeBoards() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
0197                    << activeBoardsData << std::setfill(' ') << std::dec;
0198     m_myCoutStream << "\n";
0199 
0200   } else {
0201     m_myCoutStream << "\nData and emulated GTFE activeBoards different.";
0202     m_myCoutStream << "\n Data: activeBoards() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
0203                    << activeBoardsData << std::setfill(' ') << std::dec;
0204     m_myCoutStream << "\n Emul: activeBoards() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
0205                    << activeBoardsEmul << std::setfill(' ') << std::dec;
0206     m_myCoutStream << "\n";
0207     m_gtfeDataEmul->Fill(4);
0208   }
0209 
0210   /// get total number of L1A sent since start of run
0211   const uint32_t totalTriggerNrData = gtfeBlockData.totalTriggerNr();
0212   const uint32_t totalTriggerNrEmul = gtfeBlockEmul.totalTriggerNr();
0213 
0214   if (totalTriggerNrData == totalTriggerNrEmul) {
0215     m_myCoutStream << "\nData and emulated GTFE totalTriggerNr identical.";
0216     m_myCoutStream << "\n totalTriggerNr() = " << totalTriggerNrData;
0217     m_myCoutStream << "\n";
0218 
0219   } else {
0220     m_myCoutStream << "\nData and emulated GTFE totalTriggerNr different.";
0221     m_myCoutStream << "\n Data: totalTriggerNr() = " << totalTriggerNrData;
0222     m_myCoutStream << "\n Emul: totalTriggerNr() = " << totalTriggerNrEmul;
0223     m_myCoutStream << "\n";
0224     m_gtfeDataEmul->Fill(5);
0225   }
0226 
0227   edm::LogInfo("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0228   m_myCoutStream.str("");
0229   m_myCoutStream.clear();
0230 }
0231 
0232 //compare the FDL board
0233 void L1GtDataEmulAnalyzer::compareFDL(const edm::Event& iEvent,
0234                                       const edm::EventSetup& evSetup,
0235                                       const L1GtFdlWord& fdlBlockData,
0236                                       const L1GtFdlWord& fdlBlockEmul,
0237                                       const int iRec) {
0238   // index of physics partition
0239   int PhysicsPartition = 0;
0240 
0241   //
0242   std::string recString;
0243   if (iRec == 0) {
0244     recString = "Daq";
0245   } else {
0246     recString = "Evm";
0247   }
0248 
0249   if (fdlBlockData == fdlBlockEmul) {
0250     m_myCoutStream << "\n" << recString << " Data and emulated FDL blocks: identical.\n";
0251     fdlBlockData.print(m_myCoutStream);
0252 
0253   } else {
0254     m_myCoutStream << "\n" << recString << " Data and emulated FDL blocks: different.\n";
0255 
0256     m_myCoutStream << "\nData: FDL block\n";
0257     fdlBlockData.print(m_myCoutStream);
0258 
0259     m_myCoutStream << "\nEmul: FDL block\n";
0260     fdlBlockEmul.print(m_myCoutStream);
0261   }
0262 
0263   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0264 
0265   m_myCoutStream.str("");
0266   m_myCoutStream.clear();
0267 
0268   // get bunch cross in the GT event record -
0269   // move it first as histograms are BxInEvent dependent
0270   const int bxInEventData = fdlBlockData.bxInEvent();
0271   const int bxInEventEmul = fdlBlockEmul.bxInEvent();
0272 
0273   bool matchBxInEvent = false;
0274 
0275   if (bxInEventData == bxInEventEmul) {
0276     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxInEvent identical.";
0277     m_myCoutStream << "\n bxInEvent() = " << bxInEventData;
0278     m_myCoutStream << "\n";
0279     matchBxInEvent = true;
0280 
0281   } else {
0282     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxInEvent different.";
0283     m_myCoutStream << "\n Data: bxInEvent() = " << bxInEventData;
0284     m_myCoutStream << "\n Emul: bxInEvent() = " << bxInEventEmul;
0285     m_myCoutStream << "\n";
0286 
0287     m_fdlDataEmul_Err[iRec]->Fill(1);
0288   }
0289 
0290   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0291   m_myCoutStream.str("");
0292   m_myCoutStream.clear();
0293 
0294   // symmetrize
0295   bool validBxInEvent = false;
0296   int histIndex = bxInEventData + (TotalBxInEvent + 1) / 2 - 1;
0297   if ((histIndex <= TotalBxInEvent) && (histIndex >= 0)) {
0298     validBxInEvent = true;
0299   }
0300 
0301   // get / update the trigger menu from the EventSetup
0302   // local cache & check on cacheIdentifier
0303 
0304   unsigned long long l1GtMenuCacheID = evSetup.get<L1GtTriggerMenuRcd>().cacheIdentifier();
0305 
0306   if (m_l1GtMenuCacheID != l1GtMenuCacheID) {
0307     m_l1GtMenu = &evSetup.getData(m_l1GtMenuToken);
0308 
0309     m_l1GtMenuCacheID = l1GtMenuCacheID;
0310   }
0311   // get / update the trigger mask from the EventSetup
0312   // local cache & check on cacheIdentifier
0313 
0314   unsigned long long l1GtTmAlgoCacheID = evSetup.get<L1GtTriggerMaskAlgoTrigRcd>().cacheIdentifier();
0315 
0316   if (m_l1GtTmAlgoCacheID != l1GtTmAlgoCacheID) {
0317     m_l1GtTmAlgo = &evSetup.getData(m_l1GtTmAlgoToken);
0318 
0319     m_triggerMaskAlgoTrig = m_l1GtTmAlgo->gtTriggerMask();
0320 
0321     m_l1GtTmAlgoCacheID = l1GtTmAlgoCacheID;
0322   }
0323 
0324   unsigned long long l1GtTmTechCacheID = evSetup.get<L1GtTriggerMaskTechTrigRcd>().cacheIdentifier();
0325 
0326   if (m_l1GtTmTechCacheID != l1GtTmTechCacheID) {
0327     m_l1GtTmTech = &evSetup.getData(m_l1GtTmTechToken);
0328 
0329     m_triggerMaskTechTrig = m_l1GtTmTech->gtTriggerMask();
0330 
0331     m_l1GtTmTechCacheID = l1GtTmTechCacheID;
0332   }
0333 
0334   // loop over algorithms and increase the corresponding counters
0335   // FIXME put it back in cache
0336   // FIXME when the menu changes, make a copy of histograms, and clear the old one
0337   //       otherwise the labels are wrong
0338   const AlgorithmMap& algorithmMap = m_l1GtMenu->gtAlgorithmMap();
0339 
0340   for (CItAlgo itAlgo = algorithmMap.begin(); itAlgo != algorithmMap.end(); itAlgo++) {
0341     std::string aName = itAlgo->first;
0342     const char* algName = aName.c_str();
0343     int algBitNumber = (itAlgo->second).algoBitNumber();
0344 
0345     (m_fdlDataAlgoDecision[histIndex][iRec])->GetXaxis()->SetBinLabel(algBitNumber + 1, algName);
0346     m_fdlDataAlgoDecision_Err[iRec]->GetXaxis()->SetBinLabel(algBitNumber + 1, algName);
0347 
0348     m_fdlEmulAlgoDecision[histIndex][iRec]->GetXaxis()->SetBinLabel(algBitNumber + 1, algName);
0349     m_fdlEmulAlgoDecision_Err[iRec]->GetXaxis()->SetBinLabel(algBitNumber + 1, algName);
0350 
0351     m_fdlDataEmulAlgoDecision[histIndex][iRec]->GetXaxis()->SetBinLabel(algBitNumber + 1, algName);
0352     m_fdlDataEmulAlgoDecision_Err[iRec]->GetXaxis()->SetBinLabel(algBitNumber + 1, algName);
0353   }
0354 
0355   // get BoardId value
0356   const uint16_t boardIdData = fdlBlockData.boardId();
0357   const uint16_t boardIdEmul = fdlBlockEmul.boardId();
0358 
0359   if (boardIdData == boardIdEmul) {
0360     m_myCoutStream << "\n" << recString << " Data and emulated FDL boardId identical.";
0361     m_myCoutStream << "\n boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0362                    << std::setfill(' ') << std::dec;
0363     m_myCoutStream << "\n";
0364 
0365   } else {
0366     m_myCoutStream << "\n" << recString << " Data and emulated FDL boardId different.";
0367     m_myCoutStream << "\n Data: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0368                    << std::setfill(' ') << std::dec;
0369     m_myCoutStream << "\n Emul: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdEmul
0370                    << std::setfill(' ') << std::dec;
0371     m_myCoutStream << "\n";
0372 
0373     if (matchBxInEvent && validBxInEvent) {
0374       m_fdlDataEmul[histIndex][iRec]->Fill(0);
0375     } else {
0376       m_fdlDataEmul_Err[iRec]->Fill(0);
0377     }
0378   }
0379 
0380   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0381   m_myCoutStream.str("");
0382   m_myCoutStream.clear();
0383 
0384   // get BxNr - bunch cross number of the actual bx
0385   const uint16_t bxNrData = fdlBlockData.bxNr();
0386   const uint16_t bxNrEmul = fdlBlockEmul.bxNr();
0387 
0388   if (bxNrData == bxNrEmul) {
0389     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxNr identical.";
0390     m_myCoutStream << "\n bxNr() = " << bxNrData;
0391     m_myCoutStream << "\n";
0392 
0393   } else {
0394     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxNr different.";
0395     m_myCoutStream << "\n Data: bxNr() = " << bxNrData;
0396     m_myCoutStream << "\n Emul: bxNr() = " << bxNrEmul;
0397     m_myCoutStream << "\n";
0398 
0399     if (matchBxInEvent && validBxInEvent) {
0400       m_fdlDataEmul[histIndex][iRec]->Fill(2);
0401     } else {
0402       m_fdlDataEmul_Err[iRec]->Fill(2);
0403     }
0404   }
0405 
0406   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0407   m_myCoutStream.str("");
0408   m_myCoutStream.clear();
0409 
0410   // get event number since last L1 reset generated in FDL
0411   const uint32_t eventNrData = fdlBlockData.eventNr();
0412   const uint32_t eventNrEmul = fdlBlockEmul.eventNr();
0413 
0414   if (eventNrData == eventNrEmul) {
0415     m_myCoutStream << "\n" << recString << " Data and emulated FDL eventNr identical.";
0416     m_myCoutStream << "\n eventNr() = " << eventNrData;
0417     m_myCoutStream << "\n";
0418 
0419   } else {
0420     m_myCoutStream << "\n" << recString << " Data and emulated FDL eventNr different.";
0421     m_myCoutStream << "\n Data: eventNr() = " << eventNrData;
0422     m_myCoutStream << "\n Emul: eventNr() = " << eventNrEmul;
0423     m_myCoutStream << "\n";
0424 
0425     if (matchBxInEvent && validBxInEvent) {
0426       m_fdlDataEmul[histIndex][iRec]->Fill(3);
0427     } else {
0428       m_fdlDataEmul_Err[iRec]->Fill(3);
0429     }
0430   }
0431 
0432   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0433   m_myCoutStream.str("");
0434   m_myCoutStream.clear();
0435 
0436   // get  technical trigger bits
0437   const TechnicalTriggerWord& gtTechnicalTriggerWordData = fdlBlockData.gtTechnicalTriggerWord();
0438   const TechnicalTriggerWord& gtTechnicalTriggerWordEmul = fdlBlockEmul.gtTechnicalTriggerWord();
0439 
0440   int nTechBits = gtTechnicalTriggerWordData.size();
0441 
0442   TechnicalTriggerWord gtTechnicalTriggerWordDataMask(nTechBits);
0443   TechnicalTriggerWord gtTechnicalTriggerWordEmulMask(nTechBits);
0444 
0445   unsigned int triggerMask = 0;
0446   unsigned int bitValue = 0;
0447 
0448   if (matchBxInEvent && validBxInEvent) {
0449     for (int iBit = 0; iBit < nTechBits; ++iBit) {
0450       triggerMask = (m_triggerMaskTechTrig.at(iBit)) & (1 << PhysicsPartition);
0451 
0452       if (gtTechnicalTriggerWordData[iBit]) {
0453         m_fdlDataTechDecision[histIndex][iRec]->Fill(iBit);
0454 
0455         bitValue = (triggerMask) ? 0 : 1;
0456         gtTechnicalTriggerWordDataMask[iBit] = bitValue;
0457         if (bitValue) {
0458           m_fdlDataTechDecisionMask[histIndex][iRec]->Fill(iBit);
0459         }
0460       }
0461 
0462       if (gtTechnicalTriggerWordEmul.at(iBit)) {
0463         m_fdlEmulTechDecision[histIndex][iRec]->Fill(iBit);
0464 
0465         bitValue = (triggerMask) ? 0 : 1;
0466         gtTechnicalTriggerWordEmulMask[iBit] = bitValue;
0467         if (bitValue) {
0468           m_fdlEmulTechDecisionMask[histIndex][iRec]->Fill(iBit);
0469         }
0470       }
0471     }
0472   } else {
0473     for (int iBit = 0; iBit < nTechBits; ++iBit) {
0474       if (gtTechnicalTriggerWordData[iBit]) {
0475         m_fdlDataTechDecision_Err[iRec]->Fill(iBit);
0476       }
0477 
0478       if (gtTechnicalTriggerWordEmul.at(iBit)) {
0479         m_fdlEmulTechDecision_Err[iRec]->Fill(iBit);
0480       }
0481     }
0482   }
0483 
0484   if (gtTechnicalTriggerWordData == gtTechnicalTriggerWordEmul) {
0485     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord identical.\n";
0486     fdlBlockData.printGtTechnicalTriggerWord(m_myCoutStream);
0487     m_myCoutStream << "\n";
0488 
0489   } else {
0490     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord different.";
0491     m_myCoutStream << "\n Data: ";
0492     fdlBlockData.printGtTechnicalTriggerWord(m_myCoutStream);
0493     m_myCoutStream << "\n Emul: ";
0494     fdlBlockEmul.printGtTechnicalTriggerWord(m_myCoutStream);
0495     m_myCoutStream << "\n";
0496 
0497     if (matchBxInEvent && validBxInEvent) {
0498       m_fdlDataEmul[histIndex][iRec]->Fill(4);
0499     } else {
0500       m_fdlDataEmul_Err[iRec]->Fill(4);
0501     }
0502 
0503     if (matchBxInEvent && validBxInEvent) {
0504       for (int iBit = 0; iBit < nTechBits; ++iBit) {
0505         if (gtTechnicalTriggerWordData[iBit] != gtTechnicalTriggerWordEmul.at(iBit)) {
0506           m_fdlDataEmulTechDecision[histIndex][iRec]->Fill(iBit);
0507         }
0508       }
0509     } else {
0510       for (int iBit = 0; iBit < nTechBits; ++iBit) {
0511         if (gtTechnicalTriggerWordData[iBit] != gtTechnicalTriggerWordEmul.at(iBit)) {
0512           m_fdlDataEmulTechDecision_Err[iRec]->Fill(iBit);
0513         }
0514       }
0515     }
0516   }
0517 
0518   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0519   m_myCoutStream.str("");
0520   m_myCoutStream.clear();
0521 
0522   if (gtTechnicalTriggerWordDataMask == gtTechnicalTriggerWordEmulMask) {
0523     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord after mask identical.\n";
0524     m_myCoutStream << "\n";
0525 
0526   } else {
0527     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord after mask different.";
0528     m_myCoutStream << "\n Data: ";
0529     m_myCoutStream << "\n Emul: ";
0530     m_myCoutStream << "\n";
0531 
0532     if (matchBxInEvent && validBxInEvent) {
0533       m_fdlDataEmul[histIndex][iRec]->Fill(5);
0534     } else {
0535       m_fdlDataEmul_Err[iRec]->Fill(5);
0536     }
0537 
0538     if (matchBxInEvent && validBxInEvent) {
0539       for (int iBit = 0; iBit < nTechBits; ++iBit) {
0540         if (gtTechnicalTriggerWordData[iBit] != gtTechnicalTriggerWordEmul.at(iBit)) {
0541           m_fdlDataEmulTechDecisionMask[histIndex][iRec]->Fill(iBit);
0542         }
0543       }
0544     }
0545   }
0546 
0547   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0548   m_myCoutStream.str("");
0549   m_myCoutStream.clear();
0550 
0551   // get algorithms bits (decision word)
0552   const DecisionWord& gtDecisionWordData = fdlBlockData.gtDecisionWord();
0553   const DecisionWord& gtDecisionWordEmul = fdlBlockEmul.gtDecisionWord();
0554 
0555   int nAlgoBits = gtDecisionWordData.size();
0556 
0557   DecisionWord gtDecisionWordDataMask(nAlgoBits);
0558   DecisionWord gtDecisionWordEmulMask(nAlgoBits);
0559 
0560   if (matchBxInEvent && validBxInEvent) {
0561     for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
0562       triggerMask = (m_triggerMaskAlgoTrig.at(iBit)) & (1 << PhysicsPartition);
0563 
0564       if (gtDecisionWordData[iBit]) {
0565         m_fdlDataAlgoDecision[histIndex][iRec]->Fill(iBit);
0566 
0567         bitValue = (triggerMask) ? 0 : 1;
0568         gtDecisionWordDataMask[iBit] = bitValue;
0569         if (bitValue) {
0570           m_fdlDataAlgoDecisionMask[histIndex][iRec]->Fill(iBit);
0571         }
0572       }
0573 
0574       if (gtDecisionWordEmul.at(iBit)) {
0575         m_fdlEmulAlgoDecision[histIndex][iRec]->Fill(iBit);
0576 
0577         bitValue = (triggerMask) ? 0 : 1;
0578         gtDecisionWordEmulMask[iBit] = bitValue;
0579         if (bitValue) {
0580           m_fdlEmulAlgoDecisionMask[histIndex][iRec]->Fill(iBit);
0581         }
0582       }
0583     }
0584   } else {
0585     for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
0586       if (gtDecisionWordData[iBit]) {
0587         m_fdlDataAlgoDecision_Err[iRec]->Fill(iBit);
0588       }
0589     }
0590 
0591     for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
0592       if (gtDecisionWordEmul.at(iBit)) {
0593         m_fdlEmulAlgoDecision_Err[iRec]->Fill(iBit);
0594       }
0595     }
0596   }
0597 
0598   if (gtDecisionWordData == gtDecisionWordEmul) {
0599     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord identical.";
0600     fdlBlockData.printGtDecisionWord(m_myCoutStream);
0601     m_myCoutStream << "\n";
0602 
0603   } else {
0604     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord different.";
0605     m_myCoutStream << "\n Data: ";
0606     fdlBlockData.printGtDecisionWord(m_myCoutStream);
0607     m_myCoutStream << "\n Emul: ";
0608     fdlBlockEmul.printGtDecisionWord(m_myCoutStream);
0609     m_myCoutStream << "\n";
0610 
0611     if (matchBxInEvent && validBxInEvent) {
0612       m_fdlDataEmul[histIndex][iRec]->Fill(6);
0613     } else {
0614       m_fdlDataEmul_Err[iRec]->Fill(6);
0615     }
0616 
0617     if (matchBxInEvent && validBxInEvent) {
0618       for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
0619         if (gtDecisionWordData[iBit] != gtDecisionWordEmul.at(iBit)) {
0620           m_fdlDataEmulAlgoDecision[histIndex][iRec]->Fill(iBit);
0621         }
0622       }
0623     } else {
0624       for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
0625         if (gtDecisionWordData[iBit] != gtDecisionWordEmul.at(iBit)) {
0626           m_fdlDataEmulAlgoDecision_Err[iRec]->Fill(iBit);
0627         }
0628       }
0629     }
0630   }
0631 
0632   if (gtDecisionWordDataMask == gtDecisionWordEmulMask) {
0633     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord after mask identical.";
0634     m_myCoutStream << "\n";
0635 
0636   } else {
0637     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord after mask different.";
0638     m_myCoutStream << "\n Data: ";
0639     m_myCoutStream << "\n Emul: ";
0640     m_myCoutStream << "\n";
0641 
0642     if (matchBxInEvent && validBxInEvent) {
0643       m_fdlDataEmul[histIndex][iRec]->Fill(7);
0644     } else {
0645       m_fdlDataEmul_Err[iRec]->Fill(7);
0646     }
0647 
0648     if (matchBxInEvent && validBxInEvent) {
0649       for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
0650         if (gtDecisionWordDataMask[iBit] != gtDecisionWordEmulMask.at(iBit)) {
0651           m_fdlDataEmulAlgoDecisionMask[histIndex][iRec]->Fill(iBit);
0652         }
0653       }
0654     }
0655   }
0656 
0657   // get  extended algorithms bits (extended decision word)
0658   const DecisionWordExtended& gtDecisionWordExtendedData = fdlBlockData.gtDecisionWordExtended();
0659   const DecisionWordExtended& gtDecisionWordExtendedEmul = fdlBlockEmul.gtDecisionWordExtended();
0660 
0661   if (gtDecisionWordExtendedData == gtDecisionWordExtendedEmul) {
0662     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWordExtended identical.\n";
0663     fdlBlockData.printGtDecisionWordExtended(m_myCoutStream);
0664     m_myCoutStream << "\n";
0665 
0666   } else {
0667     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWordExtended different.\n";
0668     m_myCoutStream << "\n Data: ";
0669     fdlBlockData.printGtDecisionWordExtended(m_myCoutStream);
0670     m_myCoutStream << "\n Emul: ";
0671     fdlBlockEmul.printGtDecisionWordExtended(m_myCoutStream);
0672     m_myCoutStream << "\n";
0673 
0674     if (matchBxInEvent && validBxInEvent) {
0675       m_fdlDataEmul[histIndex][iRec]->Fill(8);
0676     } else {
0677       m_fdlDataEmul_Err[iRec]->Fill(8);
0678     }
0679   }
0680 
0681   // get  NoAlgo
0682   const uint16_t noAlgoData = fdlBlockData.noAlgo();
0683   const uint16_t noAlgoEmul = fdlBlockEmul.noAlgo();
0684 
0685   if (noAlgoData == noAlgoEmul) {
0686     m_myCoutStream << "\n" << recString << " Data and emulated FDL noAlgo identical.";
0687     m_myCoutStream << "\n noAlgo() = " << noAlgoData;
0688     m_myCoutStream << "\n";
0689 
0690   } else {
0691     m_myCoutStream << "\n" << recString << " Data and emulated FDL noAlgo different.";
0692     m_myCoutStream << "\n Data: noAlgo() = " << noAlgoData;
0693     m_myCoutStream << "\n Emul: noAlgo() = " << noAlgoEmul;
0694     m_myCoutStream << "\n";
0695 
0696     if (matchBxInEvent && validBxInEvent) {
0697       m_fdlDataEmul[histIndex][iRec]->Fill(9);
0698     } else {
0699       m_fdlDataEmul_Err[iRec]->Fill(9);
0700     }
0701   }
0702 
0703   // get  "Final OR" bits
0704   const uint16_t finalORData = fdlBlockData.finalOR();
0705   const uint16_t finalOREmul = fdlBlockEmul.finalOR();
0706 
0707   if (finalORData == finalOREmul) {
0708     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR identical.";
0709     m_myCoutStream << "\n finalOR() = " << std::hex << "0x" << std::setw(2) << std::setfill('0') << finalORData
0710                    << std::setfill(' ') << std::dec;
0711     m_myCoutStream << "\n";
0712 
0713   } else {
0714     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR different.";
0715     m_myCoutStream << "\n Data: finalOR() = " << std::hex << "0x" << std::setw(2) << std::setfill('0') << finalORData
0716                    << std::setfill(' ') << std::dec;
0717     m_myCoutStream << "\n Emul: finalOR() = " << std::hex << "0x" << std::setw(2) << std::setfill('0') << finalOREmul
0718                    << std::setfill(' ') << std::dec;
0719     m_myCoutStream << "\n";
0720 
0721     if (matchBxInEvent && validBxInEvent) {
0722       m_fdlDataEmul[histIndex][iRec]->Fill(10);
0723     } else {
0724       m_fdlDataEmul_Err[iRec]->Fill(10);
0725     }
0726   }
0727 
0728   // get  "Final OR" for physics partition
0729   const int finalORPhysData = finalORData & (1 << PhysicsPartition);
0730   const int finalORPhysEmul = finalOREmul & (1 << PhysicsPartition);
0731 
0732   if (finalORPhysData == finalORPhysEmul) {
0733     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR for the physics partition identical.";
0734     m_myCoutStream << "\n finalOR() = " << finalORPhysData;
0735     m_myCoutStream << "\n";
0736 
0737   } else {
0738     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR for the physics partition  different.";
0739     m_myCoutStream << "\n Data: finalOR() = " << finalORPhysData;
0740     m_myCoutStream << "\n Emul: finalOR() = " << finalORPhysEmul;
0741     m_myCoutStream << "\n";
0742 
0743     if (matchBxInEvent && validBxInEvent) {
0744       m_fdlDataEmul[histIndex][iRec]->Fill(11);
0745     } else {
0746       m_fdlDataEmul_Err[iRec]->Fill(11);
0747     }
0748   }
0749 
0750   // get  local bunch cross number of the actual bx
0751   const uint16_t localBxNrData = fdlBlockData.localBxNr();
0752   const uint16_t localBxNrEmul = fdlBlockEmul.localBxNr();
0753 
0754   if (localBxNrData == localBxNrEmul) {
0755     m_myCoutStream << "\n" << recString << " Data and emulated FDL localBxNr identical.";
0756     m_myCoutStream << "\n localBxNr() = " << localBxNrData;
0757     m_myCoutStream << "\n";
0758 
0759   } else {
0760     m_myCoutStream << "\n" << recString << " Data and emulated FDL localBxNr different.";
0761     m_myCoutStream << "\n Data: localBxNr() = " << localBxNrData;
0762     m_myCoutStream << "\n Emul: localBxNr() = " << localBxNrEmul;
0763     m_myCoutStream << "\n";
0764 
0765     if (matchBxInEvent && validBxInEvent) {
0766       m_fdlDataEmul[histIndex][iRec]->Fill(12);
0767     } else {
0768       m_fdlDataEmul_Err[iRec]->Fill(12);
0769     }
0770   }
0771 
0772   edm::LogInfo("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0773   m_myCoutStream.str("");
0774   m_myCoutStream.clear();
0775 }
0776 
0777 //compare the PSB board
0778 void L1GtDataEmulAnalyzer::comparePSB(const edm::Event& iEvent,
0779                                       const edm::EventSetup& evSetup,
0780                                       const L1GtPsbWord& psbBlockData,
0781                                       const L1GtPsbWord& psbBlockEmul) {
0782   if (psbBlockData == psbBlockEmul) {
0783     m_myCoutStream << "\nData and emulated PSB blocks: identical.\n";
0784     psbBlockData.print(m_myCoutStream);
0785 
0786   } else {
0787     m_myCoutStream << "\nData and emulated PSB blocks: different.\n";
0788 
0789     m_myCoutStream << "\nData: PSB block\n";
0790     psbBlockData.print(m_myCoutStream);
0791 
0792     m_myCoutStream << "\nEmul: PSB block\n";
0793     psbBlockEmul.print(m_myCoutStream);
0794   }
0795 
0796   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0797 
0798   m_myCoutStream.str("");
0799   m_myCoutStream.clear();
0800 
0801   // get BoardId value
0802   const uint16_t boardIdData = psbBlockData.boardId();
0803   const uint16_t boardIdEmul = psbBlockEmul.boardId();
0804 
0805   if (boardIdData == boardIdEmul) {
0806     m_myCoutStream << "\nData and emulated PSB boardId identical.";
0807     m_myCoutStream << "\n boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0808                    << std::setfill(' ') << std::dec;
0809     m_myCoutStream << "\n";
0810 
0811   } else {
0812     m_myCoutStream << "\nData and emulated PSB boardId different.";
0813     m_myCoutStream << "\n Data: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0814                    << std::setfill(' ') << std::dec;
0815     m_myCoutStream << "\n Emul: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdEmul
0816                    << std::setfill(' ') << std::dec;
0817     m_myCoutStream << "\n";
0818   }
0819 
0820   // get bunch cross in the GT event record
0821   const int bxInEventData = psbBlockData.bxInEvent();
0822   const int bxInEventEmul = psbBlockEmul.bxInEvent();
0823 
0824   if (bxInEventData == bxInEventEmul) {
0825     m_myCoutStream << "\nData and emulated PSB bxInEvent identical.";
0826     m_myCoutStream << "\n bxInEvent() = " << bxInEventData;
0827     m_myCoutStream << "\n";
0828 
0829   } else {
0830     m_myCoutStream << "\nData and emulated PSB bxInEvent different.";
0831     m_myCoutStream << "\n Data: bxInEvent() = " << bxInEventData;
0832     m_myCoutStream << "\n Emul: bxInEvent() = " << bxInEventEmul;
0833     m_myCoutStream << "\n";
0834   }
0835 
0836   // get BxNr - bunch cross number of the actual bx
0837   const uint16_t bxNrData = psbBlockData.bxNr();
0838   const uint16_t bxNrEmul = psbBlockEmul.bxNr();
0839 
0840   if (bxNrData == bxNrEmul) {
0841     m_myCoutStream << "\nData and emulated PSB bxNr identical.";
0842     m_myCoutStream << "\n bxNr() = " << bxNrData;
0843     m_myCoutStream << "\n";
0844 
0845   } else {
0846     m_myCoutStream << "\nData and emulated PSB bxNr different.";
0847     m_myCoutStream << "\n Data: bxNr() = " << bxNrData;
0848     m_myCoutStream << "\n Emul: bxNr() = " << bxNrEmul;
0849     m_myCoutStream << "\n";
0850   }
0851 
0852   // get event number since last L1 reset generated in FDL
0853   const uint32_t eventNrData = psbBlockData.eventNr();
0854   const uint32_t eventNrEmul = psbBlockEmul.eventNr();
0855 
0856   if (eventNrData == eventNrEmul) {
0857     m_myCoutStream << "\nData and emulated PSB eventNr identical.";
0858     m_myCoutStream << "\n eventNr() = " << eventNrData;
0859     m_myCoutStream << "\n";
0860 
0861   } else {
0862     m_myCoutStream << "\nData and emulated PSB eventNr different.";
0863     m_myCoutStream << "\n Data: eventNr() = " << eventNrData;
0864     m_myCoutStream << "\n Emul: eventNr() = " << eventNrEmul;
0865     m_myCoutStream << "\n";
0866   }
0867 
0868   /// get/set A_DATA_CH_IA
0869   uint16_t valData;
0870   uint16_t valEmul;
0871 
0872   for (int iA = 0; iA < psbBlockData.NumberAData; ++iA) {
0873     valData = psbBlockData.aData(iA);
0874     valEmul = psbBlockEmul.aData(iA);
0875 
0876     if (valData == valEmul) {
0877       m_myCoutStream << "\nData and emulated PSB aData(" << iA << ") identical.";
0878       m_myCoutStream << "\n aData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
0879                      << std::setfill(' ') << std::dec;
0880       m_myCoutStream << "\n";
0881 
0882     } else {
0883       m_myCoutStream << "\nData and emulated PSB aData(" << iA << ") different.";
0884       m_myCoutStream << "\n Data: aData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
0885                      << std::setfill(' ') << std::dec;
0886       m_myCoutStream << "\n Emul: aData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valEmul
0887                      << std::setfill(' ') << std::dec;
0888       m_myCoutStream << "\n";
0889     }
0890   }
0891 
0892   /// get/set B_DATA_CH_IB
0893   for (int iB = 0; iB < psbBlockData.NumberBData; ++iB) {
0894     valData = psbBlockData.bData(iB);
0895     valEmul = psbBlockEmul.bData(iB);
0896 
0897     if (valData == valEmul) {
0898       m_myCoutStream << "\nData and emulated PSB bData(" << iB << ") identical.";
0899       m_myCoutStream << "\n bData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
0900                      << std::setfill(' ') << std::dec;
0901       m_myCoutStream << "\n";
0902 
0903     } else {
0904       m_myCoutStream << "\nData and emulated PSB bData(" << iB << ") different.";
0905       m_myCoutStream << "\n Data: bData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
0906                      << std::setfill(' ') << std::dec;
0907       m_myCoutStream << "\n Emul: bData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valEmul
0908                      << std::setfill(' ') << std::dec;
0909       m_myCoutStream << "\n";
0910     }
0911   }
0912 
0913   // get  local bunch cross number of the actual bx
0914   const uint16_t localBxNrData = psbBlockData.localBxNr();
0915   const uint16_t localBxNrEmul = psbBlockEmul.localBxNr();
0916 
0917   if (localBxNrData == localBxNrEmul) {
0918     m_myCoutStream << "\nData and emulated PSB localBxNr identical.";
0919     m_myCoutStream << "\n localBxNr() = " << localBxNrData;
0920     m_myCoutStream << "\n";
0921 
0922   } else {
0923     m_myCoutStream << "\nData and emulated PSB localBxNr different.";
0924     m_myCoutStream << "\n Data: localBxNr() = " << localBxNrData;
0925     m_myCoutStream << "\n Emul: localBxNr() = " << localBxNrEmul;
0926     m_myCoutStream << "\n";
0927   }
0928 
0929   edm::LogInfo("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
0930   m_myCoutStream.str("");
0931   m_myCoutStream.clear();
0932 }
0933 
0934 //compare the TCS board
0935 void L1GtDataEmulAnalyzer::compareTCS(const edm::Event& iEvent,
0936                                       const edm::EventSetup& evSetup,
0937                                       const L1TcsWord&,
0938                                       const L1TcsWord&) {
0939   // empty
0940 }
0941 
0942 //L1 GT DAQ record comparison
0943 void L1GtDataEmulAnalyzer::compareDaqRecord(const edm::Event& iEvent, const edm::EventSetup& evSetup) {
0944   // formal index for DAQ record
0945   int iRec = 0;
0946 
0947   // get the L1 GT hardware DAQ record L1GlobalTriggerReadoutRecord
0948   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecordData;
0949   iEvent.getByLabel(m_l1GtDataInputTag, gtReadoutRecordData);
0950 
0951   bool validData = false;
0952 
0953   if (!gtReadoutRecordData.isValid()) {
0954     m_nrDataEventError++;
0955   } else {
0956     validData = true;
0957   }
0958 
0959   // get the L1 GT emulator DAQ record L1GlobalTriggerReadoutRecord
0960   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecordEmul;
0961   iEvent.getByLabel(m_l1GtEmulInputTag, gtReadoutRecordEmul);
0962 
0963   bool validEmul = false;
0964 
0965   if (!gtReadoutRecordEmul.isValid()) {
0966     m_nrEmulEventError++;
0967   } else {
0968     validEmul = true;
0969   }
0970 
0971   if ((!validData) || (!validEmul)) {
0972     edm::LogWarning("L1GtDataEmulAnalyzer")
0973         << "\n Valid data:" << validData << "\n Valid emulator:" << validEmul << std::endl;
0974   }
0975 
0976   // compare GTFE
0977   const L1GtfeWord& gtfeBlockData = gtReadoutRecordData->gtfeWord();
0978   const L1GtfeWord& gtfeBlockEmul = gtReadoutRecordEmul->gtfeWord();
0979 
0980   compareGTFE(iEvent, evSetup, gtfeBlockData, gtfeBlockEmul);
0981 
0982   // FDL comparison
0983   const std::vector<L1GtFdlWord>& gtFdlVectorData = gtReadoutRecordData->gtFdlVector();
0984   const std::vector<L1GtFdlWord>& gtFdlVectorEmul = gtReadoutRecordEmul->gtFdlVector();
0985 
0986   int gtFdlVectorDataSize = gtFdlVectorData.size();
0987   int gtFdlVectorEmulSize = gtFdlVectorEmul.size();
0988 
0989   if (gtFdlVectorDataSize == gtFdlVectorEmulSize) {
0990     m_myCoutStream << "\nData and emulated FDL vector size: identical.\n";
0991     m_myCoutStream << "  Size: " << gtFdlVectorDataSize << std::endl;
0992 
0993     for (int iFdl = 0; iFdl < gtFdlVectorDataSize; ++iFdl) {
0994       const L1GtFdlWord& fdlBlockData = gtFdlVectorData[iFdl];
0995       const L1GtFdlWord& fdlBlockEmul = gtFdlVectorEmul[iFdl];
0996 
0997       compareFDL(iEvent, evSetup, fdlBlockData, fdlBlockEmul, iRec);
0998     }
0999   } else {
1000     m_myCoutStream << "\nData and emulated FDL vector size: different.\n";
1001     m_myCoutStream << "  Data: size = " << gtFdlVectorDataSize << std::endl;
1002     m_myCoutStream << "  Emul: size = " << gtFdlVectorEmulSize << std::endl;
1003   }
1004 
1005   LogDebug("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
1006 
1007   m_myCoutStream.str("");
1008   m_myCoutStream.clear();
1009 
1010   // PSB comparison
1011   const std::vector<L1GtPsbWord>& gtPsbVectorData = gtReadoutRecordData->gtPsbVector();
1012   const std::vector<L1GtPsbWord>& gtPsbVectorEmul = gtReadoutRecordEmul->gtPsbVector();
1013 
1014   int gtPsbVectorDataSize = gtPsbVectorData.size();
1015   int gtPsbVectorEmulSize = gtPsbVectorEmul.size();
1016 
1017   if (gtPsbVectorDataSize == gtPsbVectorEmulSize) {
1018     m_myCoutStream << "\nData and emulated PSB vector size: identical.\n";
1019     m_myCoutStream << "  Size: " << gtPsbVectorDataSize << std::endl;
1020   } else {
1021     m_myCoutStream << "\nData and emulated PSB vector size: different.\n";
1022     m_myCoutStream << "  Data: size = " << gtPsbVectorDataSize << std::endl;
1023     m_myCoutStream << "  Emul: size = " << gtPsbVectorEmulSize << std::endl;
1024   }
1025 
1026   // the order of PSB block in the gtPsbVector is different in emulator and in data
1027   // in emulator: all active PSB in one BxInEvent, ordered L1A-1, L1A, L1A+1
1028   // in unpacker: every PSB in all BxInEvent
1029   for (int iPsb = 0; iPsb < gtPsbVectorDataSize; ++iPsb) {
1030     const L1GtPsbWord& psbBlockData = gtPsbVectorData[iPsb];
1031     const uint16_t boardIdData = psbBlockData.boardId();
1032     const int bxInEventData = psbBlockData.bxInEvent();
1033 
1034     // search the corresponding PSB in the emulated record using the
1035     // BoardId and the BxInEvent
1036 
1037     bool foundPSB = false;
1038 
1039     for (int iPsbF = 0; iPsbF < gtPsbVectorEmulSize; ++iPsbF) {
1040       const L1GtPsbWord& psbBlockEmul = gtPsbVectorEmul[iPsbF];
1041       const uint16_t boardIdEmul = psbBlockEmul.boardId();
1042       const int bxInEventEmul = psbBlockEmul.bxInEvent();
1043 
1044       if ((boardIdEmul == boardIdData) && (bxInEventData == bxInEventEmul)) {
1045         foundPSB = true;
1046 
1047         // compare the boards
1048         comparePSB(iEvent, evSetup, psbBlockData, psbBlockEmul);
1049       }
1050     }
1051 
1052     if (!foundPSB) {
1053       m_myCoutStream << "\nNo emulated PSB with boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
1054                      << boardIdData << std::setfill(' ') << std::dec << " and BxInEvent = " << bxInEventData
1055                      << " was found";
1056     }
1057   }
1058 
1059   edm::LogInfo("L1GtDataEmulAnalyzer") << m_myCoutStream.str() << std::endl;
1060 
1061   m_myCoutStream.str("");
1062   m_myCoutStream.clear();
1063 }
1064 
1065 // L1 GT EVM record comparison
1066 void L1GtDataEmulAnalyzer::compareEvmRecord(const edm::Event& iEvent, const edm::EventSetup&) {
1067   // FIXME
1068 }
1069 
1070 // compare the GCT collections obtained from L1 GT PSB with the input
1071 // GCT collections
1072 void L1GtDataEmulAnalyzer::compareGt_Gct(const edm::Event& iEvent, const edm::EventSetup&) {
1073   // FIXME
1074 }
1075 
1076 // analyze each event: event loop
1077 void L1GtDataEmulAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& evSetup) {
1078   // L1 GT DAQ record comparison
1079   compareDaqRecord(iEvent, evSetup);
1080 
1081   // L1 GT EVM record comparison
1082   compareEvmRecord(iEvent, evSetup);
1083 
1084   // GCT collections from L1 GT PSB versus unpacked GCT
1085   compareGt_Gct(iEvent, evSetup);
1086 }
1087 
1088 // book all histograms for the module
1089 void L1GtDataEmulAnalyzer::bookHistograms() {
1090   // histogram service
1091   edm::Service<TFileService> histServ;
1092 
1093   // histograms
1094 
1095   // GTFE histograms
1096   TFileDirectory gtfeHist = histServ->mkdir("GTFE");
1097   m_gtfeDataEmul = gtfeHist.make<TH1F>("gtfeDataEmul", "GTFE data vs emul", 6, 0., 6.);
1098   m_gtfeDataEmul->GetXaxis()->SetBinLabel(1, "BoardId");
1099   m_gtfeDataEmul->GetXaxis()->SetBinLabel(2, "RecordLength");
1100   m_gtfeDataEmul->GetXaxis()->SetBinLabel(3, "BxNr");
1101   m_gtfeDataEmul->GetXaxis()->SetBinLabel(4, "SetupVersion");
1102   m_gtfeDataEmul->GetXaxis()->SetBinLabel(5, "DaqActiveBoards");
1103   m_gtfeDataEmul->GetXaxis()->SetBinLabel(6, "TotalTriggerNr");
1104 
1105   // FDL histograms
1106 
1107   TFileDirectory fdlHist = histServ->mkdir("FDL");
1108 
1109   const unsigned int numberTechTriggers = L1GlobalTriggerReadoutSetup::NumberTechnicalTriggers;
1110 
1111   const unsigned int numberAlgoTriggers = L1GlobalTriggerReadoutSetup::NumberPhysTriggers;
1112 
1113   for (int iRec = 0; iRec < 2; ++iRec) {
1114     std::string recString;
1115     if (iRec == 0) {
1116       recString = "Daq";
1117     } else {
1118       recString = "Evm";
1119     }
1120 
1121     std::string hName;
1122     const char* histName;
1123 
1124     for (int iHist = 0; iHist < TotalBxInEvent; ++iHist) {
1125       // convert [0, TotalBxInEvent] to [-X, +X] and add to histogram name
1126       int iIndex = iHist - ((TotalBxInEvent + 1) / 2 - 1);
1127       int hIndex = (iIndex + 16) % 16;
1128 
1129       std::stringstream ss;
1130       std::string str;
1131       ss << std::uppercase << std::hex << hIndex;
1132       ss >> str;
1133 
1134       hName = recString + "FdlDataEmul_" + str;
1135       histName = hName.c_str();
1136 
1137       std::string hTitle = "FDL data vs emul mismatch for BxInEvent = " + str;
1138       const char* histTitle = hTitle.c_str();
1139 
1140       //
1141 
1142       m_fdlDataEmul[iHist][iRec] = fdlHist.make<TH1F>(histName, histTitle, 13, 0., 13.);
1143       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(1, "BoardId");
1144       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(2, "BxInEvent");
1145       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(3, "BxNr");
1146       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(4, "EventNr");
1147       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(5, "TechTrigger");
1148       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(6, "TechTriggerMask");
1149       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(7, "AlgoTrigger");
1150       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(8, "AlgoTriggerMask");
1151       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(9, "AlgoExtend");
1152       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(10, "NoAlgo");
1153       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(11, "FinalORAllParts");
1154       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(12, "FinalORPhysPart");
1155       m_fdlDataEmul[iHist][iRec]->GetXaxis()->SetBinLabel(13, "LocalBxNr");
1156 
1157       // algorithm decision
1158       //   data
1159       hName = recString + "FdlDataAlgoDecision_" + str;
1160       histName = hName.c_str();
1161 
1162       hTitle = "Data: algorithm decision word for BxInEvent = " + str;
1163       histTitle = hTitle.c_str();
1164 
1165       m_fdlDataAlgoDecision[iHist][iRec] =
1166           fdlHist.make<TH1F>(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
1167 
1168       //   emul
1169       hName = recString + "FdlEmulAlgoDecision_" + str;
1170       histName = hName.c_str();
1171 
1172       hTitle = "Emul: algorithm decision word for BxInEvent = " + str;
1173       histTitle = hTitle.c_str();
1174 
1175       m_fdlEmulAlgoDecision[iHist][iRec] =
1176           fdlHist.make<TH1F>(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
1177 
1178       // algorithm decision after masking (partition physics)
1179       //   data
1180       hName = recString + "FdlDataAlgoDecisionMask_" + str;
1181       histName = hName.c_str();
1182 
1183       hTitle = "Data, physics partition: algorithm decision word after mask for BxInEvent = " + str;
1184       histTitle = hTitle.c_str();
1185 
1186       m_fdlDataAlgoDecisionMask[iHist][iRec] =
1187           fdlHist.make<TH1F>(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
1188 
1189       //   emul
1190       hName = recString + "FdlEmulAlgoDecisionMask_" + str;
1191       histName = hName.c_str();
1192 
1193       hTitle = "Emul, physics partition: algorithm decision word after mask for BxInEvent =  " + str;
1194       histTitle = hTitle.c_str();
1195 
1196       m_fdlEmulAlgoDecisionMask[iHist][iRec] =
1197           fdlHist.make<TH1F>(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
1198 
1199       //
1200       hName = recString + "FdlDataEmulAlgoDecision_" + str;
1201       histName = hName.c_str();
1202 
1203       hTitle = "Data vs emul: non-matching algorithm decision word for BxInEvent = " + str;
1204       histTitle = hTitle.c_str();
1205 
1206       m_fdlDataEmulAlgoDecision[iHist][iRec] =
1207           fdlHist.make<TH1F>(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
1208 
1209       //
1210       hName = recString + "FdlDataEmulAlgoDecisionMask_" + str;
1211       histName = hName.c_str();
1212 
1213       hTitle =
1214           "Data vs emul, physics partition: non-matching algorithm decision word after mask for BxInEvent = " + str;
1215       histTitle = hTitle.c_str();
1216 
1217       m_fdlDataEmulAlgoDecisionMask[iHist][iRec] =
1218           fdlHist.make<TH1F>(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
1219 
1220       // technical trigger decision
1221       //   data
1222       hName = recString + "FdlDataTechDecision_" + str;
1223       histName = hName.c_str();
1224 
1225       hTitle = "Data technical trigger decision word for BxInEvent = " + str;
1226       histTitle = hTitle.c_str();
1227 
1228       m_fdlDataTechDecision[iHist][iRec] =
1229           fdlHist.make<TH1F>(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
1230 
1231       //   emul
1232       hName = recString + "FdlEmulTechDecision_" + str;
1233       histName = hName.c_str();
1234 
1235       hTitle = "Emul: technical trigger decision word for BxInEvent = " + str;
1236       histTitle = hTitle.c_str();
1237 
1238       m_fdlEmulTechDecision[iHist][iRec] =
1239           fdlHist.make<TH1F>(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
1240 
1241       // technical trigger decision after masking (partition physics)
1242       hName = recString + "FdlDataTechDecisionMask_" + str;
1243       histName = hName.c_str();
1244 
1245       hTitle = "Data technical trigger decision word after mask for BxInEvent = " + str;
1246       histTitle = hTitle.c_str();
1247 
1248       m_fdlDataTechDecisionMask[iHist][iRec] =
1249           fdlHist.make<TH1F>(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
1250 
1251       //
1252       hName = recString + "FdlEmulTechDecisionMask_" + str;
1253       histName = hName.c_str();
1254 
1255       hTitle = "Emul: technical trigger decision word after mask for BxInEvent = " + str;
1256       histTitle = hTitle.c_str();
1257 
1258       m_fdlEmulTechDecisionMask[iHist][iRec] =
1259           fdlHist.make<TH1F>(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
1260 
1261       //
1262       hName = recString + "FdlDataEmulTechDecision_" + str;
1263       histName = hName.c_str();
1264 
1265       hTitle = "Data vs emul: non-matching technical trigger decision word for BxInEvent = " + str;
1266       histTitle = hTitle.c_str();
1267 
1268       m_fdlDataEmulTechDecision[iHist][iRec] =
1269           fdlHist.make<TH1F>(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
1270 
1271       hName = recString + "FdlDataEmulTechDecisionMask_" + str;
1272       histName = hName.c_str();
1273 
1274       hTitle = "Data vs emul: non-matching technical trigger decision word after mask for BxInEvent = " + str;
1275       histTitle = hTitle.c_str();
1276 
1277       m_fdlDataEmulTechDecisionMask[iHist][iRec] =
1278           fdlHist.make<TH1F>(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
1279     }
1280 
1281     hName = recString + "FdlDataEmul_Err";
1282     histName = hName.c_str();
1283 
1284     m_fdlDataEmul_Err[iRec] = fdlHist.make<TH1F>(histName, "FDL data vs emul: non-matching BxInEvent", 13, 0., 13.);
1285     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(1, "BoardId");
1286     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(2, "BxInEvent");
1287     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(3, "BxNr");
1288     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(4, "EventNr");
1289     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(5, "TechTrigger");
1290     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(6, "TechTriggerMask");
1291     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(7, "AlgoTrigger");
1292     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(8, "AlgoTriggerMask");
1293     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(9, "AlgoExtend");
1294     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(10, "NoAlgo");
1295     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(11, "FinalORAllParts");
1296     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(12, "FinalORPhysPart");
1297     m_fdlDataEmul_Err[iRec]->GetXaxis()->SetBinLabel(13, "LocalBxNr");
1298 
1299     hName = recString + "FdlDataAlgoDecision_Err";
1300     histName = hName.c_str();
1301 
1302     m_fdlDataAlgoDecision_Err[iRec] =
1303         fdlHist.make<TH1F>(histName,
1304                            "Data: algorithm trigger decision word, non-matching BxInEvent",
1305                            numberAlgoTriggers,
1306                            0.,
1307                            numberAlgoTriggers);
1308 
1309     //
1310     hName = recString + "FdlEmulAlgoDecision_Err";
1311     histName = hName.c_str();
1312 
1313     m_fdlEmulAlgoDecision_Err[iRec] =
1314         fdlHist.make<TH1F>(histName,
1315                            "Emul: algorithm trigger decision word, non-matching BxInEvent",
1316                            numberAlgoTriggers,
1317                            0.,
1318                            numberAlgoTriggers);
1319 
1320     hName = recString + "FdlDataEmulAlgoDecision_Err";
1321     histName = hName.c_str();
1322 
1323     m_fdlDataEmulAlgoDecision_Err[iRec] =
1324         fdlHist.make<TH1F>(histName,
1325                            "Data vs emul: algorithm trigger decision word, non-matching BxInEvent",
1326                            numberAlgoTriggers,
1327                            0.,
1328                            numberAlgoTriggers);
1329 
1330     //
1331     hName = recString + "FdlDataTechDecision_Err";
1332     histName = hName.c_str();
1333 
1334     m_fdlDataTechDecision_Err[iRec] =
1335         fdlHist.make<TH1F>(histName,
1336                            "Data: technical trigger decision word, non-matching BxInEvent",
1337                            numberTechTriggers,
1338                            0.,
1339                            numberTechTriggers);
1340 
1341     hName = recString + "FdlEmulTechDecision_Err";
1342     histName = hName.c_str();
1343 
1344     m_fdlEmulTechDecision_Err[iRec] =
1345         fdlHist.make<TH1F>(histName,
1346                            "Emul: technical trigger decision word, non-matching BxInEvent",
1347                            numberTechTriggers,
1348                            0.,
1349                            numberTechTriggers);
1350 
1351     hName = recString + "FdlDataEmulTechDecision_Err";
1352     histName = hName.c_str();
1353 
1354     m_fdlDataEmulTechDecision_Err[iRec] =
1355         fdlHist.make<TH1F>(histName,
1356                            "Data vs emul: technical trigger decision word, non-matching BxInEvent",
1357                            numberTechTriggers,
1358                            0.,
1359                            numberTechTriggers);
1360   }
1361 }
1362 
1363 // method called once each job just after ending the event loop
1364 void L1GtDataEmulAnalyzer::endJob() {
1365   // empty
1366 }