Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-06-24 22:38:20

0001 /**
0002  * \class L1GtHwValidation
0003  * 
0004  * 
0005  * Description: compare hardware records with emulator records for L1 GT records.
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 "DQM/L1TMonitor/interface/L1GtHwValidation.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/L1GlobalTriggerReadoutSetup.h"
0026 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0027 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
0028 
0029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0030 #include "FWCore/ServiceRegistry/interface/Service.h"
0031 
0032 #include "FWCore/Framework/interface/EventSetup.h"
0033 #include "FWCore/Framework/interface/ESHandle.h"
0034 #include "FWCore/Framework/interface/Run.h"
0035 
0036 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
0037 #include "CondFormats/DataRecord/interface/L1GtTriggerMenuRcd.h"
0038 
0039 #include "CondFormats/L1TObjects/interface/L1GtPrescaleFactors.h"
0040 #include "CondFormats/DataRecord/interface/L1GtPrescaleFactorsAlgoTrigRcd.h"
0041 #include "CondFormats/DataRecord/interface/L1GtPrescaleFactorsTechTrigRcd.h"
0042 
0043 #include "CondFormats/L1TObjects/interface/L1GtTriggerMask.h"
0044 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskAlgoTrigRcd.h"
0045 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskTechTrigRcd.h"
0046 
0047 #include "TH1.h"
0048 #include "TH2.h"
0049 #include "TTree.h"
0050 
0051 // constructor(s)
0052 L1GtHwValidation::L1GtHwValidation(const edm::ParameterSet& paramSet)
0053     :  //
0054       // input tag for the L1 GT hardware DAQ record
0055       m_l1GtDataDaqInputTag(paramSet.getParameter<edm::InputTag>("L1GtDataDaqInputTag")),
0056       // input tag for the L1 GT hardware EVM record
0057       m_l1GtDataEvmInputTag(paramSet.getParameter<edm::InputTag>("L1GtDataEvmInputTag")),
0058       // input tag for the L1 GT emulator DAQ record
0059       m_l1GtEmulDaqInputTag(paramSet.getParameter<edm::InputTag>("L1GtEmulDaqInputTag")),
0060       // input tag for the L1 GT emulator EVM record
0061       m_l1GtEmulEvmInputTag(paramSet.getParameter<edm::InputTag>("L1GtEmulEvmInputTag")),
0062       // input tag for the L1 GCT hardware record
0063       m_l1GctDataInputTag(paramSet.getParameter<edm::InputTag>("L1GctDataInputTag")),
0064       //
0065       m_dirName(paramSet.getUntrackedParameter("DirName", std::string("L1TEMU/GTexpert"))),
0066       //
0067       m_excludeCondCategTypeObject(
0068           paramSet.getParameter<std::vector<edm::ParameterSet> >("ExcludeCondCategTypeObject")),
0069       //
0070       m_excludeAlgoTrigByName(paramSet.getParameter<std::vector<std::string> >("ExcludeAlgoTrigByName")),
0071       //
0072       m_excludeAlgoTrigByBit(paramSet.getParameter<std::vector<int> >("ExcludeAlgoTrigByBit")),
0073       //
0074       // initialize counters
0075       m_nrDataEventError(0),
0076       m_nrEmulEventError(0),
0077       // cache
0078       m_l1GtMenuCacheID(0ULL),
0079       m_l1GtPfAlgoCacheID(0ULL),
0080       m_l1GtPfTechCacheID(0ULL),
0081       m_l1GtTmAlgoCacheID(0ULL),
0082       m_l1GtTmTechCacheID(0ULL),
0083       //
0084       m_agree(true),
0085       m_dataOnly(false),
0086       m_emulOnly(false),
0087       m_dataOnlyMask(false),
0088       m_emulOnlyMask(false),
0089       //
0090       m_nrEvJob(0),
0091       m_nrEvRun(0) {
0092   for (std::vector<edm::ParameterSet>::const_iterator itExclud = m_excludeCondCategTypeObject.begin();
0093        itExclud != m_excludeCondCategTypeObject.end();
0094        ++itExclud) {
0095     if (!(itExclud->getParameter<std::string>("ExcludedCondCategory")).empty()) {
0096       m_excludedCondCategory.push_back(
0097           l1GtConditionCategoryStringToEnum(itExclud->getParameter<std::string>("ExcludedCondCategory")));
0098 
0099     } else {
0100       m_excludedCondCategory.push_back(CondNull);
0101     }
0102 
0103     if (!(itExclud->getParameter<std::string>("ExcludedCondType")).empty()) {
0104       m_excludedCondType.push_back(
0105           l1GtConditionTypeStringToEnum(itExclud->getParameter<std::string>("ExcludedCondType")));
0106 
0107     } else {
0108       m_excludedCondType.push_back(TypeNull);
0109     }
0110 
0111     if (!(itExclud->getParameter<std::string>("ExcludedL1GtObject")).empty()) {
0112       m_excludedL1GtObject.push_back(l1GtObjectStringToEnum(itExclud->getParameter<std::string>("ExcludedL1GtObject")));
0113 
0114     } else {
0115       m_excludedL1GtObject.push_back(ObjNull);
0116     }
0117   }
0118 
0119   LogDebug("L1GtHwValidation") << "\nInput tag for the L1 GT DAQ hardware record:       " << m_l1GtDataDaqInputTag
0120                                << "\nInput tag for the L1 GT EVM hardware record:       " << m_l1GtDataEvmInputTag
0121                                << "\nInput tag for the L1 GT DAQ emulator records:          " << m_l1GtEmulDaqInputTag
0122                                << "\nInput tag for the L1 GT EVM emulator records:          " << m_l1GtEmulEvmInputTag
0123                                << "\nInput tag for the L1 GCT hardware record:          " << m_l1GctDataInputTag
0124                                << std::endl;
0125 
0126   // FIXME print in debug mode ExcludeCondCategTypeObject, ExcludeAlgoTrigByName, etc
0127 
0128   //set Token(-s)
0129   m_l1GtDataDaqInputToken_ =
0130       consumes<L1GlobalTriggerReadoutRecord>(paramSet.getParameter<edm::InputTag>("L1GtDataDaqInputTag"));
0131   m_l1GtEmulDaqInputToken_ =
0132       consumes<L1GlobalTriggerReadoutRecord>(paramSet.getParameter<edm::InputTag>("L1GtEmulDaqInputTag"));
0133   m_l1GtDataEvmInputToken_ =
0134       consumes<L1GlobalTriggerEvmReadoutRecord>(paramSet.getParameter<edm::InputTag>("L1GtDataEvmInputTag"));
0135   m_l1GtEmulEvmInputToken_ =
0136       consumes<L1GlobalTriggerEvmReadoutRecord>(paramSet.getParameter<edm::InputTag>("L1GtEmulEvmInputTag"));
0137   l1gtPrescaleTechToken_ = esConsumes<edm::Transition::BeginRun>();
0138   l1gtPrescaleAlgoToken_ = esConsumes<edm::Transition::BeginRun>();
0139   l1gtTrigmenuToken_ = esConsumes<edm::Transition::BeginRun>();
0140   l1gtTrigmaskTechToken_ = esConsumes<edm::Transition::BeginRun>();
0141   l1gtTrigmaskAlgoToken_ = esConsumes<edm::Transition::BeginRun>();
0142 }
0143 
0144 // destructor
0145 L1GtHwValidation::~L1GtHwValidation() {
0146   // empty
0147 }
0148 
0149 // member functions
0150 
0151 void L1GtHwValidation::bookHistograms(DQMStore::IBooker& ibooker,
0152                                       const edm::Run& iRun,
0153                                       const edm::EventSetup& evSetup) {
0154   ibooker.setCurrentFolder(m_dirName);
0155 
0156   // histograms
0157 
0158   const unsigned int numberTechTriggers = L1GlobalTriggerReadoutSetup::NumberTechnicalTriggers;
0159 
0160   const unsigned int numberAlgoTriggers = L1GlobalTriggerReadoutSetup::NumberPhysTriggers;
0161 
0162   for (int iRec = 0; iRec < NumberOfGtRecords; ++iRec) {
0163     std::string recString;
0164     if (iRec == 0) {
0165       recString = "Daq_";
0166       ibooker.setCurrentFolder(m_dirName + "/DAQ/");
0167 
0168     } else {
0169       recString = "Evm_";
0170       ibooker.setCurrentFolder(m_dirName + "/EVM/");
0171     }
0172 
0173     std::string hName;
0174     const char* histName;
0175 
0176     hName = recString + "gtfeDataEmul";
0177     histName = hName.c_str();
0178 
0179     // GTFE histograms
0180     m_gtfeDataEmul[iRec] = ibooker.book1D(histName, "GTFE data vs emul mismatch", 8, 0., 7.);
0181     m_gtfeDataEmul[iRec]->setBinLabel(1, "BoardId", 1);
0182     m_gtfeDataEmul[iRec]->setBinLabel(2, "RecordLength1", 1);
0183     m_gtfeDataEmul[iRec]->setBinLabel(3, "RecordLength0", 1);
0184     m_gtfeDataEmul[iRec]->setBinLabel(4, "BxNr", 1);
0185     m_gtfeDataEmul[iRec]->setBinLabel(5, "SetupVersion", 1);
0186     m_gtfeDataEmul[iRec]->setBinLabel(6, "DaqActiveBoards", 1);
0187     m_gtfeDataEmul[iRec]->setBinLabel(7, "AltNrBxBoard", 1);
0188     m_gtfeDataEmul[iRec]->setBinLabel(8, "TotalTriggerNr", 1);
0189 
0190     // FDL histograms
0191 
0192     for (int iHist = 0; iHist < TotalBxInEvent; ++iHist) {
0193       // convert [0, TotalBxInEvent] to [-X, +X] and add to histogram name
0194       int iIndex = iHist - ((TotalBxInEvent + 1) / 2 - 1);
0195       int hIndex = (iIndex + 16) % 16;
0196 
0197       std::stringstream ss;
0198       std::string str;
0199       ss << std::uppercase << std::hex << hIndex;
0200       ss >> str;
0201 
0202       if (iRec == 0) {
0203         ibooker.setCurrentFolder(m_dirName + "/DAQ/BxInEvent_" + str);
0204 
0205       } else {
0206         ibooker.setCurrentFolder(m_dirName + "/EVM/BxInEvent_" + str);
0207       }
0208 
0209       hName = recString + "FdlDataEmul_" + str;
0210       histName = hName.c_str();
0211 
0212       std::string hTitle = "FDL data vs emul mismatch for BxInEvent = " + str;
0213       const char* histTitle = hTitle.c_str();
0214 
0215       //
0216 
0217       m_fdlDataEmul[iHist][iRec] = ibooker.book1D(histName, histTitle, 13, 0., 13.);
0218       m_fdlDataEmul[iHist][iRec]->setBinLabel(1, "BoardId", 1);
0219       m_fdlDataEmul[iHist][iRec]->setBinLabel(2, "BxInEvent", 1);
0220       m_fdlDataEmul[iHist][iRec]->setBinLabel(3, "BxNr", 1);
0221       m_fdlDataEmul[iHist][iRec]->setBinLabel(4, "EventNr", 1);
0222       m_fdlDataEmul[iHist][iRec]->setBinLabel(5, "TechTrigger", 1);
0223       m_fdlDataEmul[iHist][iRec]->setBinLabel(6, "TechTriggerMask", 1);
0224       m_fdlDataEmul[iHist][iRec]->setBinLabel(7, "AlgoTrigger", 1);
0225       m_fdlDataEmul[iHist][iRec]->setBinLabel(8, "AlgoTriggerMask", 1);
0226       m_fdlDataEmul[iHist][iRec]->setBinLabel(9, "AlgoExtend", 1);
0227       m_fdlDataEmul[iHist][iRec]->setBinLabel(10, "NoAlgo", 1);
0228       m_fdlDataEmul[iHist][iRec]->setBinLabel(11, "FinalORAllParts", 1);
0229       m_fdlDataEmul[iHist][iRec]->setBinLabel(12, "FinalORPhysPart", 1);
0230       m_fdlDataEmul[iHist][iRec]->setBinLabel(13, "LocalBxNr", 1);
0231 
0232       // algorithm decision
0233       //   data
0234       hName = recString + "Data_AlgoDecision_" + str;
0235       histName = hName.c_str();
0236 
0237       hTitle = "Data: algorithm decision word for BxInEvent = " + str;
0238       histTitle = hTitle.c_str();
0239 
0240       m_fdlDataAlgoDecision[iHist][iRec] =
0241           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0242 
0243       //   emul
0244       hName = recString + "Emul_AlgoDecision_" + str;
0245       histName = hName.c_str();
0246 
0247       hTitle = "Emul: algorithm decision word for BxInEvent = " + str;
0248       histTitle = hTitle.c_str();
0249 
0250       m_fdlEmulAlgoDecision[iHist][iRec] =
0251           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0252 
0253       // algorithm decision for prescaled algorithms
0254       //   data
0255       hName = recString + "Data_AlgoDecision_Prescaled_" + str;
0256       histName = hName.c_str();
0257 
0258       hTitle = "Data: prescaled algorithms: algorithm decision for BxInEvent = " + str;
0259       histTitle = hTitle.c_str();
0260 
0261       m_fdlDataAlgoDecisionPrescaled[iHist][iRec] =
0262           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0263 
0264       //   emul
0265       hName = recString + "Emul_AlgoDecision_Prescaled_" + str;
0266       histName = hName.c_str();
0267 
0268       hTitle = "Emul: prescaled algorithms: algorithm decision for BxInEvent = " + str;
0269       histTitle = hTitle.c_str();
0270 
0271       m_fdlEmulAlgoDecisionPrescaled[iHist][iRec] =
0272           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0273 
0274       // algorithm decision for unprescaled algorithms
0275       //   data
0276       hName = recString + "Data_AlgoDecision_Unprescaled_" + str;
0277       histName = hName.c_str();
0278 
0279       hTitle = "Data: unprescaled algorithms: algorithm decision for BxInEvent = " + str;
0280       histTitle = hTitle.c_str();
0281 
0282       m_fdlDataAlgoDecisionUnprescaled[iHist][iRec] =
0283           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0284 
0285       //   emul
0286       hName = recString + "Emul_AlgoDecision_Unprescaled_" + str;
0287       histName = hName.c_str();
0288 
0289       hTitle = "Emul: unprescaled algorithms: algorithm decision for BxInEvent = " + str;
0290       histTitle = hTitle.c_str();
0291 
0292       m_fdlEmulAlgoDecisionUnprescaled[iHist][iRec] =
0293           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0294 
0295       // algorithm decision after masking (partition physics)
0296       //   data
0297       hName = recString + "Data_AlgoDecisionAfterMask_" + str;
0298       histName = hName.c_str();
0299 
0300       hTitle = "Data, physics partition: algorithm decision word after mask for BxInEvent = " + str;
0301       histTitle = hTitle.c_str();
0302 
0303       m_fdlDataAlgoDecisionMask[iHist][iRec] =
0304           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0305 
0306       //   emul
0307       hName = recString + "Emul_AlgoDecisionAfterMask_" + str;
0308       histName = hName.c_str();
0309 
0310       hTitle = "Emul, physics partition: algorithm decision word after mask for BxInEvent =  " + str;
0311       histTitle = hTitle.c_str();
0312 
0313       m_fdlEmulAlgoDecisionMask[iHist][iRec] =
0314           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0315 
0316       //
0317       hName = recString + "DataEmul_AlgoDecision_" + str;
0318       histName = hName.c_str();
0319 
0320       hTitle = "Data vs emul: non-matching algorithm decision word for BxInEvent = " + str;
0321       histTitle = hTitle.c_str();
0322 
0323       m_fdlDataEmulAlgoDecision[iHist][iRec] =
0324           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0325 
0326       //
0327       hName = recString + "DataEmul_AlgoDecision_Prescaled_" + str;
0328       histName = hName.c_str();
0329 
0330       hTitle = "Data vs emul: prescaled algorithms with non-matching decision for BxInEvent = " + str;
0331       histTitle = hTitle.c_str();
0332 
0333       m_fdlDataEmulAlgoDecisionPrescaled[iHist][iRec] =
0334           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0335 
0336       //
0337       hName = recString + "DataEmul_AlgoDecision_Unprescaled_" + str;
0338       histName = hName.c_str();
0339 
0340       hTitle = "Data vs emul: unprescaled algorithms with non-matching decision for BxInEvent = " + str;
0341       histTitle = hTitle.c_str();
0342 
0343       m_fdlDataEmulAlgoDecisionUnprescaled[iHist][iRec] =
0344           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0345 
0346       //
0347       hName = recString + "DataEmul_AlgoDecision_Unprescaled_Allowed_" + str;
0348       histName = hName.c_str();
0349 
0350       hTitle = "Data vs emul: unprescaled algorithms not excluded with non-matching decision for BxInEvent = " + str;
0351       histTitle = hTitle.c_str();
0352 
0353       m_fdlDataEmulAlgoDecisionUnprescaledAllowed[iHist][iRec] =
0354           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0355 
0356       //
0357       hName = recString + "Data_AlgoDecision_NoMatch_" + str;
0358       histName = hName.c_str();
0359 
0360       hTitle = "Data: algorithm decision for non-matching cases for BxInEvent = " + str;
0361       histTitle = hTitle.c_str();
0362 
0363       m_fdlDataAlgoDecision_NoMatch[iHist][iRec] =
0364           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0365 
0366       //
0367       hName = recString + "Emul_AlgoDecision_NoMatch_" + str;
0368       histName = hName.c_str();
0369 
0370       hTitle = "Emul: algorithm decision for non-matching cases for BxInEvent = " + str;
0371       histTitle = hTitle.c_str();
0372 
0373       m_fdlEmulAlgoDecision_NoMatch[iHist][iRec] =
0374           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0375 
0376       // prescaled algorithms
0377       hName = recString + "Data_AlgoDecision_Prescaled_NoMatch_" + str;
0378       histName = hName.c_str();
0379 
0380       hTitle = "Data: prescaled algorithms: non-matching algorithm decision for BxInEvent = " + str;
0381       histTitle = hTitle.c_str();
0382 
0383       m_fdlDataAlgoDecisionPrescaled_NoMatch[iHist][iRec] =
0384           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0385 
0386       //
0387       hName = recString + "Emul_AlgoDecision_Prescaled_NoMatch_" + str;
0388       histName = hName.c_str();
0389 
0390       hTitle = "Emul: prescaled algorithms: non-matching algorithm decision for BxInEvent = " + str;
0391       histTitle = hTitle.c_str();
0392 
0393       m_fdlEmulAlgoDecisionPrescaled_NoMatch[iHist][iRec] =
0394           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0395 
0396       // unprescaled algorithms - non-matching
0397       hName = recString + "Data_AlgoDecision_Unprescaled_NoMatch_" + str;
0398       histName = hName.c_str();
0399 
0400       hTitle = "Data: unprescaled algorithms: non-matching algorithm decision for BxInEvent = " + str;
0401       histTitle = hTitle.c_str();
0402 
0403       m_fdlDataAlgoDecisionUnprescaled_NoMatch[iHist][iRec] =
0404           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0405 
0406       //
0407       hName = recString + "Emul_AlgoDecision_Unprescaled_NoMatch_" + str;
0408       histName = hName.c_str();
0409 
0410       hTitle = "Emul: unprescaled algorithms: non-matching algorithm decision for BxInEvent = " + str;
0411       histTitle = hTitle.c_str();
0412 
0413       m_fdlEmulAlgoDecisionUnprescaled_NoMatch[iHist][iRec] =
0414           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0415 
0416       //
0417       hName = recString + "Data_AlgoDecisionMask_NoMatch_" + str;
0418       histName = hName.c_str();
0419 
0420       hTitle = "Data: algorithm decision for non-matching cases after mask for BxInEvent = " + str;
0421       histTitle = hTitle.c_str();
0422 
0423       m_fdlDataAlgoDecisionMask_NoMatch[iHist][iRec] =
0424           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0425 
0426       //
0427       hName = recString + "Emul_AlgoDecisionMask_NoMatch_" + str;
0428       histName = hName.c_str();
0429 
0430       hTitle = "Emul: algorithm decision for non-matching cases after mask for BxInEvent = " + str;
0431       histTitle = hTitle.c_str();
0432 
0433       m_fdlEmulAlgoDecisionMask_NoMatch[iHist][iRec] =
0434           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0435 
0436       // prescaled algorithms
0437       hName = recString + "Data_AlgoDecisionMask_Prescaled_NoMatch_" + str;
0438       histName = hName.c_str();
0439 
0440       hTitle = "Data: prescaled algorithms: non-matching algorithm decision after mask for BxInEvent = " + str;
0441       histTitle = hTitle.c_str();
0442 
0443       m_fdlDataAlgoDecisionPrescaledMask_NoMatch[iHist][iRec] =
0444           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0445 
0446       //
0447       hName = recString + "Emul_AlgoDecision_PrescaledMask_NoMatch_" + str;
0448       histName = hName.c_str();
0449 
0450       hTitle = "Emul: prescaled algorithms: non-matching algorithm decision after mask for BxInEvent = " + str;
0451       histTitle = hTitle.c_str();
0452 
0453       m_fdlEmulAlgoDecisionPrescaledMask_NoMatch[iHist][iRec] =
0454           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0455 
0456       // unprescaled algorithms - non-matching
0457       hName = recString + "Data_AlgoDecision_UnprescaledMask_NoMatch_" + str;
0458       histName = hName.c_str();
0459 
0460       hTitle = "Data: unprescaled algorithms: non-matching algorithm decision after mask for BxInEvent = " + str;
0461       histTitle = hTitle.c_str();
0462 
0463       m_fdlDataAlgoDecisionUnprescaledMask_NoMatch[iHist][iRec] =
0464           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0465 
0466       //
0467       hName = recString + "Emul_AlgoDecision_UnprescaledMask_NoMatch_" + str;
0468       histName = hName.c_str();
0469 
0470       hTitle = "Emul: unprescaled algorithms: non-matching algorithm decision after mask for BxInEvent = " + str;
0471       histTitle = hTitle.c_str();
0472 
0473       m_fdlEmulAlgoDecisionUnprescaledMask_NoMatch[iHist][iRec] =
0474           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0475 
0476       //
0477       hName = recString + "DataEmul_AlgoDecisionAfterMask_" + str;
0478       histName = hName.c_str();
0479 
0480       hTitle =
0481           "Data vs emul, physics partition: non-matching algorithm decision word after mask for BxInEvent = " + str;
0482       histTitle = hTitle.c_str();
0483 
0484       m_fdlDataEmulAlgoDecisionMask[iHist][iRec] =
0485           ibooker.book1D(histName, histTitle, numberAlgoTriggers, 0., numberAlgoTriggers);
0486 
0487       // technical trigger decision
0488       //   data
0489       hName = recString + "Data_TechDecision_" + str;
0490       histName = hName.c_str();
0491 
0492       hTitle = "Data technical trigger decision word for BxInEvent = " + str;
0493       histTitle = hTitle.c_str();
0494 
0495       m_fdlDataTechDecision[iHist][iRec] =
0496           ibooker.book1D(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
0497 
0498       //   emul
0499       hName = recString + "Emul_TechDecision_" + str;
0500       histName = hName.c_str();
0501 
0502       hTitle = "Emul: technical trigger decision word for BxInEvent = " + str;
0503       histTitle = hTitle.c_str();
0504 
0505       m_fdlEmulTechDecision[iHist][iRec] =
0506           ibooker.book1D(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
0507 
0508       // technical trigger decision after masking (partition physics)
0509       hName = recString + "Data_TechDecisionAfterMask_" + str;
0510       histName = hName.c_str();
0511 
0512       hTitle = "Data technical trigger decision word after mask for BxInEvent = " + str;
0513       histTitle = hTitle.c_str();
0514 
0515       m_fdlDataTechDecisionMask[iHist][iRec] =
0516           ibooker.book1D(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
0517 
0518       //
0519       hName = recString + "Emul_TechDecisionAfterMask_" + str;
0520       histName = hName.c_str();
0521 
0522       hTitle = "Emul: technical trigger decision word after mask for BxInEvent = " + str;
0523       histTitle = hTitle.c_str();
0524 
0525       m_fdlEmulTechDecisionMask[iHist][iRec] =
0526           ibooker.book1D(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
0527 
0528       //
0529       hName = recString + "DataEmul_TechDecision_" + str;
0530       histName = hName.c_str();
0531 
0532       hTitle = "Data vs emul: non-matching technical trigger decision word for BxInEvent = " + str;
0533       histTitle = hTitle.c_str();
0534 
0535       m_fdlDataEmulTechDecision[iHist][iRec] =
0536           ibooker.book1D(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
0537 
0538       hName = recString + "DataEmul_TechDecisionAfterMask_" + str;
0539       histName = hName.c_str();
0540 
0541       hTitle = "Data vs emul: non-matching technical trigger decision word after mask for BxInEvent = " + str;
0542       histTitle = hTitle.c_str();
0543 
0544       m_fdlDataEmulTechDecisionMask[iHist][iRec] =
0545           ibooker.book1D(histName, histTitle, numberTechTriggers, 0., numberTechTriggers);
0546     }
0547 
0548     if (iRec == 0) {
0549       ibooker.setCurrentFolder(m_dirName + "/DAQ/");
0550 
0551     } else {
0552       ibooker.setCurrentFolder(m_dirName + "/EVM/");
0553     }
0554 
0555     hName = recString + "FdlDataEmul_Err";
0556     histName = hName.c_str();
0557 
0558     m_fdlDataEmul_Err[iRec] =
0559         ibooker.book1D(histName, "FDL data vs emul mismatch for non-matching BxInEvent in FDL payload", 13, 0., 13.);
0560     m_fdlDataEmul_Err[iRec]->setBinLabel(1, "BoardId", 1);
0561     m_fdlDataEmul_Err[iRec]->setBinLabel(2, "BxInEvent", 1);
0562     m_fdlDataEmul_Err[iRec]->setBinLabel(3, "BxNr", 1);
0563     m_fdlDataEmul_Err[iRec]->setBinLabel(4, "EventNr", 1);
0564     m_fdlDataEmul_Err[iRec]->setBinLabel(5, "TechTrigger", 1);
0565     m_fdlDataEmul_Err[iRec]->setBinLabel(6, "TechTriggerMask", 1);
0566     m_fdlDataEmul_Err[iRec]->setBinLabel(7, "AlgoTrigger", 1);
0567     m_fdlDataEmul_Err[iRec]->setBinLabel(8, "AlgoTriggerMask", 1);
0568     m_fdlDataEmul_Err[iRec]->setBinLabel(9, "AlgoExtend", 1);
0569     m_fdlDataEmul_Err[iRec]->setBinLabel(10, "NoAlgo", 1);
0570     m_fdlDataEmul_Err[iRec]->setBinLabel(11, "FinalORAllParts", 1);
0571     m_fdlDataEmul_Err[iRec]->setBinLabel(12, "FinalORPhysPart", 1);
0572     m_fdlDataEmul_Err[iRec]->setBinLabel(13, "LocalBxNr", 1);
0573 
0574     hName = recString + "FdlDataAlgoDecision_Err";
0575     histName = hName.c_str();
0576 
0577     m_fdlDataAlgoDecision_Err[iRec] = ibooker.book1D(histName,
0578                                                      "Data: algorithm trigger decision word, non-matching BxInEvent",
0579                                                      numberAlgoTriggers,
0580                                                      0.,
0581                                                      numberAlgoTriggers);
0582 
0583     //
0584     hName = recString + "Emul_AlgoDecision_Err";
0585     histName = hName.c_str();
0586 
0587     m_fdlEmulAlgoDecision_Err[iRec] = ibooker.book1D(histName,
0588                                                      "Emul: algorithm trigger decision word, non-matching BxInEvent",
0589                                                      numberAlgoTriggers,
0590                                                      0.,
0591                                                      numberAlgoTriggers);
0592 
0593     hName = recString + "DataEmul_AlgoDecision_Err";
0594     histName = hName.c_str();
0595 
0596     m_fdlDataEmulAlgoDecision_Err[iRec] =
0597         ibooker.book1D(histName,
0598                        "Data vs emul: algorithm trigger decision word, non-matching BxInEvent",
0599                        numberAlgoTriggers,
0600                        0.,
0601                        numberAlgoTriggers);
0602 
0603     //
0604     hName = recString + "Data_TechDecision_Err";
0605     histName = hName.c_str();
0606 
0607     m_fdlDataTechDecision_Err[iRec] = ibooker.book1D(histName,
0608                                                      "Data: technical trigger decision word, non-matching BxInEvent",
0609                                                      numberTechTriggers,
0610                                                      0.,
0611                                                      numberTechTriggers);
0612 
0613     hName = recString + "Emul_TechDecision_Err";
0614     histName = hName.c_str();
0615 
0616     m_fdlEmulTechDecision_Err[iRec] = ibooker.book1D(histName,
0617                                                      "Emul: technical trigger decision word, non-matching BxInEvent",
0618                                                      numberTechTriggers,
0619                                                      0.,
0620                                                      numberTechTriggers);
0621 
0622     hName = recString + "DataEmul_TechDecision_Err";
0623     histName = hName.c_str();
0624 
0625     m_fdlDataEmulTechDecision_Err[iRec] =
0626         ibooker.book1D(histName,
0627                        "Data vs emul: technical trigger decision word, non-matching BxInEvent",
0628                        numberTechTriggers,
0629                        0.,
0630                        numberTechTriggers);
0631   }
0632 
0633   ibooker.setCurrentFolder(m_dirName);
0634 
0635   //
0636   m_excludedAlgorithmsAgreement = ibooker.book1D("ExcludedAlgorithmsFromAgreement",
0637                                                  "Algorithms excluded from data versus emulator agreement flag",
0638                                                  numberAlgoTriggers,
0639                                                  0.,
0640                                                  numberAlgoTriggers);
0641 
0642   //
0643 
0644   m_gtErrorFlag = ibooker.book1D("GTErrorFlag", "L1 GT error flag for data versus emulator comparison", 5, 0., 5);
0645 
0646   m_gtErrorFlag->setBinLabel(1, "Agree", 1);
0647   m_gtErrorFlag->setBinLabel(2, "", 1);
0648   m_gtErrorFlag->setBinLabel(3, "", 1);
0649   m_gtErrorFlag->setBinLabel(4, "Data only", 1);
0650   m_gtErrorFlag->setBinLabel(5, "Emul only", 1);
0651 
0652   m_nrEvRun = 0;
0653 
0654   // get / update the trigger menu from the EventSetup
0655   // local cache & check on cacheIdentifier
0656 
0657   unsigned long long l1GtMenuCacheID = evSetup.get<L1GtTriggerMenuRcd>().cacheIdentifier();
0658 
0659   if (m_l1GtMenuCacheID != l1GtMenuCacheID) {
0660     m_l1GtMenu = &evSetup.getData(l1gtTrigmenuToken_);
0661 
0662     // compute the list of algorithms excluded from the computing of the agreement flag
0663     m_excludedAlgoList.clear();
0664     excludedAlgoList();
0665 
0666     m_l1GtMenuCacheID = l1GtMenuCacheID;
0667   }
0668 
0669   // FIXME when the menu changes, make a copy of histograms, and clear the old one
0670   //       otherwise the labels are wrong
0671 
0672   LogDebug("L1GtHwValidation") << "\nUsing L1 menu: \n  " << m_l1GtMenu->gtTriggerMenuImplementation() << "\n"
0673                                << std::endl;
0674 
0675   const AlgorithmMap& algorithmMap = m_l1GtMenu->gtAlgorithmMap();
0676 
0677   for (CItAlgo itAlgo = algorithmMap.begin(); itAlgo != algorithmMap.end(); itAlgo++) {
0678     const int algBitNumber = (itAlgo->second).algoBitNumber();
0679 
0680     std::stringstream ss;
0681     std::string algBitString;
0682     ss << std::uppercase << algBitNumber;
0683     ss >> algBitString;
0684 
0685     const std::string& aName = algBitString + " " + itAlgo->first;
0686     const char* algName = aName.c_str();
0687 
0688     for (int iRec = 0; iRec < NumberOfGtRecords; ++iRec) {
0689       for (int iBxInEvent = 0; iBxInEvent < TotalBxInEvent; ++iBxInEvent) {
0690         // convert [0, TotalBxInEvent] to [-X, +X]
0691         int iIndex = iBxInEvent - ((TotalBxInEvent + 1) / 2 - 1);
0692         int hIndex = (iIndex + 16) % 16;
0693 
0694         std::stringstream ss;
0695         std::string str;
0696         ss << std::uppercase << std::hex << hIndex;
0697         ss >> str;
0698 
0699         if (iRec == 0) {
0700           //if (m_dbe) {
0701           ibooker.setCurrentFolder(m_dirName + "/DAQ/BxInEvent_" + str);
0702           //}
0703 
0704         } else {
0705           //if (m_dbe) {
0706           ibooker.setCurrentFolder(m_dirName + "/EVM/BxInEvent_" + str);
0707           //}
0708         }
0709 
0710         m_fdlDataAlgoDecision[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0711         m_fdlDataAlgoDecisionPrescaled[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0712         m_fdlDataAlgoDecisionUnprescaled[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0713         m_fdlDataAlgoDecisionMask[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0714         m_fdlDataAlgoDecision_NoMatch[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0715 
0716         m_fdlEmulAlgoDecision[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0717         m_fdlEmulAlgoDecisionPrescaled[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0718         m_fdlEmulAlgoDecisionUnprescaled[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0719         m_fdlEmulAlgoDecisionMask[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0720         m_fdlEmulAlgoDecision_NoMatch[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0721 
0722         m_fdlDataEmulAlgoDecision[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0723         m_fdlDataEmulAlgoDecisionPrescaled[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0724         m_fdlDataEmulAlgoDecisionUnprescaled[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0725         m_fdlDataEmulAlgoDecisionUnprescaledAllowed[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0726         m_fdlDataEmulAlgoDecisionMask[iBxInEvent][iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0727       }
0728 
0729       if (iRec == 0) {
0730         ibooker.setCurrentFolder(m_dirName + "/DAQ/");
0731 
0732       } else {
0733         ibooker.setCurrentFolder(m_dirName + "/EVM/");
0734       }
0735 
0736       m_fdlDataAlgoDecision_Err[iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0737 
0738       m_fdlEmulAlgoDecision_Err[iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0739 
0740       m_fdlDataEmulAlgoDecision_Err[iRec]->setBinLabel(algBitNumber + 1, algName, 1);
0741     }
0742 
0743     //
0744     for (std::vector<int>::const_iterator itAlgo = m_excludedAlgoList.begin(); itAlgo != m_excludedAlgoList.end();
0745          ++itAlgo) {
0746       if (algBitNumber == *itAlgo) {
0747         m_excludedAlgorithmsAgreement->setBinLabel(algBitNumber + 1, algName, 1);
0748       }
0749     }
0750   }
0751 
0752   // get / update the prescale factors from the EventSetup
0753   // local cache & check on cacheIdentifier
0754 
0755   unsigned long long l1GtPfAlgoCacheID = evSetup.get<L1GtPrescaleFactorsAlgoTrigRcd>().cacheIdentifier();
0756 
0757   if (m_l1GtPfAlgoCacheID != l1GtPfAlgoCacheID) {
0758     m_l1GtPfAlgo = &evSetup.getData(l1gtPrescaleAlgoToken_);
0759 
0760     m_prescaleFactorsAlgoTrig = &(m_l1GtPfAlgo->gtPrescaleFactors());
0761 
0762     m_l1GtPfAlgoCacheID = l1GtPfAlgoCacheID;
0763   }
0764 
0765   unsigned long long l1GtPfTechCacheID = evSetup.get<L1GtPrescaleFactorsTechTrigRcd>().cacheIdentifier();
0766 
0767   if (m_l1GtPfTechCacheID != l1GtPfTechCacheID) {
0768     m_l1GtPfTech = &evSetup.getData(l1gtPrescaleTechToken_);
0769 
0770     m_prescaleFactorsTechTrig = &(m_l1GtPfTech->gtPrescaleFactors());
0771 
0772     m_l1GtPfTechCacheID = l1GtPfTechCacheID;
0773   }
0774 
0775   // get / update the trigger mask from the EventSetup
0776   // local cache & check on cacheIdentifier
0777 
0778   unsigned long long l1GtTmAlgoCacheID = evSetup.get<L1GtTriggerMaskAlgoTrigRcd>().cacheIdentifier();
0779 
0780   if (m_l1GtTmAlgoCacheID != l1GtTmAlgoCacheID) {
0781     m_l1GtTmAlgo = &evSetup.getData(l1gtTrigmaskAlgoToken_);
0782 
0783     m_triggerMaskAlgoTrig = m_l1GtTmAlgo->gtTriggerMask();
0784 
0785     m_l1GtTmAlgoCacheID = l1GtTmAlgoCacheID;
0786   }
0787 
0788   unsigned long long l1GtTmTechCacheID = evSetup.get<L1GtTriggerMaskTechTrigRcd>().cacheIdentifier();
0789 
0790   if (m_l1GtTmTechCacheID != l1GtTmTechCacheID) {
0791     m_l1GtTmTech = &evSetup.getData(l1gtTrigmaskTechToken_);
0792 
0793     m_triggerMaskTechTrig = m_l1GtTmTech->gtTriggerMask();
0794 
0795     m_l1GtTmTechCacheID = l1GtTmTechCacheID;
0796   }
0797 }
0798 
0799 //compare the GTFE board
0800 void L1GtHwValidation::compareGTFE(const edm::Event& iEvent,
0801                                    const edm::EventSetup& evSetup,
0802                                    const L1GtfeWord& gtfeBlockData,
0803                                    const L1GtfeWord& gtfeBlockEmul,
0804                                    const int iRec) {
0805   std::string recString;
0806   if (gtfeBlockData == gtfeBlockEmul) {
0807     m_myCoutStream << "\n" << recString << " Data and emulated GTFE blocks: identical.\n";
0808     gtfeBlockData.print(m_myCoutStream);
0809   } else {
0810     m_myCoutStream << "\n" << recString << " Data and emulated GTFE blocks: different.\n";
0811 
0812     m_myCoutStream << "\nData: GTFE block\n";
0813     gtfeBlockData.print(m_myCoutStream);
0814 
0815     m_myCoutStream << "\nEmul: GTFE block\n";
0816     gtfeBlockEmul.print(m_myCoutStream);
0817   }
0818 
0819   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
0820 
0821   m_myCoutStream.str("");
0822   m_myCoutStream.clear();
0823 
0824   // get BoardId value
0825   const uint16_t boardIdData = gtfeBlockData.boardId();
0826   const uint16_t boardIdEmul = gtfeBlockEmul.boardId();
0827 
0828   if (boardIdData == boardIdEmul) {
0829     m_myCoutStream << "\n" << recString << " Data and emulated GTFE boardId identical.";
0830     m_myCoutStream << "\n boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0831                    << std::setfill(' ') << std::dec;
0832     m_myCoutStream << "\n";
0833 
0834   } else {
0835     m_myCoutStream << "\n" << recString << " Data and emulated GTFE boardId different.";
0836     m_myCoutStream << "\n Data: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
0837                    << std::setfill(' ') << std::dec;
0838     m_myCoutStream << "\n Emul: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdEmul
0839                    << std::setfill(' ') << std::dec;
0840     m_myCoutStream << "\n";
0841     m_gtfeDataEmul[iRec]->Fill(0);
0842   }
0843 
0844   /// get record length for alternative 1
0845   const uint16_t recordLength1Data = gtfeBlockData.recordLength1();
0846   const uint16_t recordLength1Emul = gtfeBlockEmul.recordLength1();
0847 
0848   if (recordLength1Data == recordLength1Emul) {
0849     m_myCoutStream << "\n" << recString << " Data and emulated GTFE recordLength for alternative 1 identical.";
0850     m_myCoutStream << "\n recordLength1() = " << recordLength1Data;
0851     m_myCoutStream << "\n";
0852 
0853   } else {
0854     m_myCoutStream << "\n" << recString << " Data and emulated GTFE recordLength for alternative 1 different.";
0855     m_myCoutStream << "\n Data: recordLength1() = " << recordLength1Data;
0856     m_myCoutStream << "\n Emul: recordLength1() = " << recordLength1Emul;
0857     m_myCoutStream << "\n";
0858     m_gtfeDataEmul[iRec]->Fill(1);
0859   }
0860 
0861   /// get record length for alternative 0
0862   const uint16_t recordLengthData = gtfeBlockData.recordLength();
0863   const uint16_t recordLengthEmul = gtfeBlockEmul.recordLength();
0864 
0865   if (recordLengthData == recordLengthEmul) {
0866     m_myCoutStream << "\n" << recString << " Data and emulated GTFE recordLength for alternative 0 identical.";
0867     m_myCoutStream << "\n recordLength() = " << recordLengthData;
0868     m_myCoutStream << "\n";
0869 
0870   } else {
0871     m_myCoutStream << "\n" << recString << " Data and emulated GTFE recordLength for alternative 1 different.";
0872     m_myCoutStream << "\n Data: recordLength() = " << recordLengthData;
0873     m_myCoutStream << "\n Emul: recordLength() = " << recordLengthEmul;
0874     m_myCoutStream << "\n";
0875     m_gtfeDataEmul[iRec]->Fill(2);
0876   }
0877 
0878   /// get bunch cross number as counted in the GTFE board
0879   const uint16_t bxNrData = gtfeBlockData.bxNr();
0880   const uint16_t bxNrEmul = gtfeBlockEmul.bxNr();
0881 
0882   if (bxNrData == bxNrEmul) {
0883     m_myCoutStream << "\n" << recString << " Data and emulated GTFE bxNr identical.";
0884     m_myCoutStream << "\n bxNr() = " << bxNrData;
0885     m_myCoutStream << "\n";
0886 
0887   } else {
0888     m_myCoutStream << "\n" << recString << " Data and emulated GTFE bxNr different.";
0889     m_myCoutStream << "\n Data: bxNr() = " << bxNrData;
0890     m_myCoutStream << "\n Emul: bxNr() = " << bxNrEmul;
0891     m_myCoutStream << "\n";
0892     m_gtfeDataEmul[iRec]->Fill(3);
0893   }
0894 
0895   /// get setup version
0896   const uint32_t setupVersionData = gtfeBlockData.setupVersion();
0897   const uint32_t setupVersionEmul = gtfeBlockEmul.setupVersion();
0898 
0899   if (setupVersionData == setupVersionEmul) {
0900     m_myCoutStream << "\n" << recString << " Data and emulated GTFE setupVersion identical.";
0901     m_myCoutStream << "\n setupVersion() = " << setupVersionData;
0902     m_myCoutStream << "\n";
0903 
0904   } else {
0905     m_myCoutStream << "\n" << recString << " Data and emulated GTFE setupVersion different.";
0906     m_myCoutStream << "\n Data: setupVersion() = " << setupVersionData;
0907     m_myCoutStream << "\n Emul: setupVersion() = " << setupVersionEmul;
0908     m_myCoutStream << "\n";
0909     m_gtfeDataEmul[iRec]->Fill(4);
0910   }
0911 
0912   /// get boards contributing to EVM respectively DAQ record
0913   const uint16_t activeBoardsData = gtfeBlockData.activeBoards();
0914   const uint16_t activeBoardsEmul = gtfeBlockEmul.activeBoards();
0915 
0916   if (activeBoardsData == activeBoardsEmul) {
0917     m_myCoutStream << "\n" << recString << " Data and emulated GTFE activeBoards identical.";
0918     m_myCoutStream << "\n activeBoards() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
0919                    << activeBoardsData << std::setfill(' ') << std::dec;
0920     m_myCoutStream << "\n";
0921 
0922   } else {
0923     m_myCoutStream << "\n" << recString << " Data and emulated GTFE activeBoards different.";
0924     m_myCoutStream << "\n Data: activeBoards() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
0925                    << activeBoardsData << std::setfill(' ') << std::dec;
0926     m_myCoutStream << "\n Emul: activeBoards() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
0927                    << activeBoardsEmul << std::setfill(' ') << std::dec;
0928     m_myCoutStream << "\n";
0929     m_gtfeDataEmul[iRec]->Fill(5);
0930   }
0931   /// alternative for number of BX per board
0932   ///     correlated with active boards
0933   ///     bit value is 0: take alternative 0
0934   ///     bit value is 1: take alternative 1
0935   const uint16_t altNrBxBoardData = gtfeBlockData.altNrBxBoard();
0936   const uint16_t altNrBxBoardEmul = gtfeBlockEmul.altNrBxBoard();
0937 
0938   if (altNrBxBoardData == altNrBxBoardEmul) {
0939     m_myCoutStream << "\n" << recString << " Data and emulated GTFE altNrBxBoard identical.";
0940     m_myCoutStream << "\n altNrBxBoard() = " << altNrBxBoardData;
0941     m_myCoutStream << "\n";
0942 
0943   } else {
0944     m_myCoutStream << "\n" << recString << " Data and emulated GTFE altNrBxBoard different.";
0945     m_myCoutStream << "\n Data: altNrBxBoard() = " << altNrBxBoardData;
0946     m_myCoutStream << "\n Emul: altNrBxBoard() = " << altNrBxBoardEmul;
0947     m_myCoutStream << "\n";
0948     m_gtfeDataEmul[iRec]->Fill(6);
0949   }
0950 
0951   /// get total number of L1A sent since start of run
0952   const uint32_t totalTriggerNrData = gtfeBlockData.totalTriggerNr();
0953   const uint32_t totalTriggerNrEmul = gtfeBlockEmul.totalTriggerNr();
0954 
0955   if (totalTriggerNrData == totalTriggerNrEmul) {
0956     m_myCoutStream << "\n" << recString << " Data and emulated GTFE totalTriggerNr identical.";
0957     m_myCoutStream << "\n totalTriggerNr() = " << totalTriggerNrData;
0958     m_myCoutStream << "\n";
0959 
0960   } else {
0961     m_myCoutStream << "\n" << recString << " Data and emulated GTFE totalTriggerNr different.";
0962     m_myCoutStream << "\n Data: totalTriggerNr() = " << totalTriggerNrData;
0963     m_myCoutStream << "\n Emul: totalTriggerNr() = " << totalTriggerNrEmul;
0964     m_myCoutStream << "\n";
0965     m_gtfeDataEmul[iRec]->Fill(7);
0966   }
0967 
0968   edm::LogInfo("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
0969   m_myCoutStream.str("");
0970   m_myCoutStream.clear();
0971 }
0972 
0973 //compare the FDL board
0974 void L1GtHwValidation::compareFDL(const edm::Event& iEvent,
0975                                   const edm::EventSetup& evSetup,
0976                                   const L1GtFdlWord& fdlBlockData,
0977                                   const L1GtFdlWord& fdlBlockEmul,
0978                                   const int iRec) {
0979   // index of physics partition
0980   int PhysicsPartition = 0;
0981 
0982   //
0983   std::string recString;
0984 
0985   if (fdlBlockData == fdlBlockEmul) {
0986     m_myCoutStream << "\n" << recString << " Data and emulated FDL blocks: identical.\n";
0987     fdlBlockData.print(m_myCoutStream);
0988 
0989   } else {
0990     m_myCoutStream << "\n" << recString << " Data and emulated FDL blocks: different.\n";
0991 
0992     m_myCoutStream << "\nData: FDL block\n";
0993     fdlBlockData.print(m_myCoutStream);
0994 
0995     m_myCoutStream << "\nEmul: FDL block\n";
0996     fdlBlockEmul.print(m_myCoutStream);
0997   }
0998 
0999   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1000 
1001   m_myCoutStream.str("");
1002   m_myCoutStream.clear();
1003 
1004   // get bunch cross in the GT event record -
1005   // move it first as histograms are BxInEvent dependent
1006   const int bxInEventData = fdlBlockData.bxInEvent();
1007   const int bxInEventEmul = fdlBlockEmul.bxInEvent();
1008 
1009   bool matchBxInEvent = false;
1010 
1011   if (bxInEventData == bxInEventEmul) {
1012     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxInEvent identical.";
1013     m_myCoutStream << "\n bxInEvent() = " << bxInEventData;
1014     m_myCoutStream << "\n";
1015     matchBxInEvent = true;
1016 
1017   } else {
1018     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxInEvent different.";
1019     m_myCoutStream << "\n Data: bxInEvent() = " << bxInEventData;
1020     m_myCoutStream << "\n Emul: bxInEvent() = " << bxInEventEmul;
1021     m_myCoutStream << "\n";
1022 
1023     m_fdlDataEmul_Err[iRec]->Fill(1);
1024 
1025     if (iRec == 0) {
1026       m_agree = false;
1027 
1028       m_myCoutStream << "\nDisagreement data versus emulator: "
1029                      << "\n  Data and emulated FDL bxInEvent different \n";
1030     }
1031   }
1032 
1033   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1034   m_myCoutStream.str("");
1035   m_myCoutStream.clear();
1036 
1037   // symmetrize
1038   bool validBxInEvent = false;
1039   int histIndex = bxInEventData + (TotalBxInEvent + 1) / 2 - 1;
1040   LogDebug("L1GtHwValidation") << "\n Convert bxInEvent = " << bxInEventData << " to histIndex = " << histIndex
1041                                << std::endl;
1042   if ((histIndex <= TotalBxInEvent) && (histIndex >= 0)) {
1043     validBxInEvent = true;
1044   }
1045 
1046   // loop over algorithms and increase the corresponding counters
1047 
1048   // get BoardId value
1049   const uint16_t boardIdData = fdlBlockData.boardId();
1050   const uint16_t boardIdEmul = fdlBlockEmul.boardId();
1051 
1052   if (boardIdData == boardIdEmul) {
1053     m_myCoutStream << "\n" << recString << " Data and emulated FDL boardId identical.";
1054     m_myCoutStream << "\n boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
1055                    << std::setfill(' ') << std::dec;
1056     m_myCoutStream << "\n";
1057 
1058   } else {
1059     m_myCoutStream << "\n" << recString << " Data and emulated FDL boardId different.";
1060     m_myCoutStream << "\n Data: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
1061                    << std::setfill(' ') << std::dec;
1062     m_myCoutStream << "\n Emul: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdEmul
1063                    << std::setfill(' ') << std::dec;
1064     m_myCoutStream << "\n";
1065 
1066     if (matchBxInEvent && validBxInEvent) {
1067       m_fdlDataEmul[histIndex][iRec]->Fill(0);
1068     } else {
1069       m_fdlDataEmul_Err[iRec]->Fill(0);
1070     }
1071   }
1072 
1073   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1074   m_myCoutStream.str("");
1075   m_myCoutStream.clear();
1076 
1077   // get BxNr - bunch cross number of the actual bx
1078   const uint16_t bxNrData = fdlBlockData.bxNr();
1079   const uint16_t bxNrEmul = fdlBlockEmul.bxNr();
1080 
1081   if (bxNrData == bxNrEmul) {
1082     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxNr identical.";
1083     m_myCoutStream << "\n bxNr() = " << bxNrData;
1084     m_myCoutStream << "\n";
1085 
1086   } else {
1087     m_myCoutStream << "\n" << recString << " Data and emulated FDL bxNr different.";
1088     m_myCoutStream << "\n Data: bxNr() = " << bxNrData;
1089     m_myCoutStream << "\n Emul: bxNr() = " << bxNrEmul;
1090     m_myCoutStream << "\n";
1091 
1092     if (matchBxInEvent && validBxInEvent) {
1093       m_fdlDataEmul[histIndex][iRec]->Fill(2);
1094     } else {
1095       m_fdlDataEmul_Err[iRec]->Fill(2);
1096     }
1097   }
1098 
1099   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1100   m_myCoutStream.str("");
1101   m_myCoutStream.clear();
1102 
1103   // get event number since last L1 reset generated in FDL
1104   const uint32_t eventNrData = fdlBlockData.eventNr();
1105   const uint32_t eventNrEmul = fdlBlockEmul.eventNr();
1106 
1107   if (eventNrData == eventNrEmul) {
1108     m_myCoutStream << "\n" << recString << " Data and emulated FDL eventNr identical.";
1109     m_myCoutStream << "\n eventNr() = " << eventNrData;
1110     m_myCoutStream << "\n";
1111 
1112   } else {
1113     m_myCoutStream << "\n" << recString << " Data and emulated FDL eventNr different.";
1114     m_myCoutStream << "\n Data: eventNr() = " << eventNrData;
1115     m_myCoutStream << "\n Emul: eventNr() = " << eventNrEmul;
1116     m_myCoutStream << "\n";
1117 
1118     if (matchBxInEvent && validBxInEvent) {
1119       m_fdlDataEmul[histIndex][iRec]->Fill(3);
1120     } else {
1121       m_fdlDataEmul_Err[iRec]->Fill(3);
1122     }
1123   }
1124 
1125   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1126   m_myCoutStream.str("");
1127   m_myCoutStream.clear();
1128 
1129   // get  technical trigger bits
1130   const TechnicalTriggerWord& gtTechnicalTriggerWordData = fdlBlockData.gtTechnicalTriggerWord();
1131   const TechnicalTriggerWord& gtTechnicalTriggerWordEmul = fdlBlockEmul.gtTechnicalTriggerWord();
1132 
1133   int nTechBits = gtTechnicalTriggerWordData.size();
1134 
1135   TechnicalTriggerWord gtTechnicalTriggerWordDataMask(nTechBits);
1136   TechnicalTriggerWord gtTechnicalTriggerWordEmulMask(nTechBits);
1137 
1138   unsigned int bitValue = 0;
1139 
1140   if (matchBxInEvent && validBxInEvent) {
1141     for (int iBit = 0; iBit < nTechBits; ++iBit) {
1142       unsigned int triggerMask = (m_triggerMaskTechTrig.at(iBit)) & (1 << PhysicsPartition);
1143 
1144       if (gtTechnicalTriggerWordData[iBit]) {
1145         m_fdlDataTechDecision[histIndex][iRec]->Fill(iBit);
1146 
1147         bitValue = (triggerMask) ? 0 : 1;
1148         gtTechnicalTriggerWordDataMask[iBit] = bitValue;
1149         if (bitValue) {
1150           m_fdlDataTechDecisionMask[histIndex][iRec]->Fill(iBit);
1151         }
1152       }
1153 
1154       if (gtTechnicalTriggerWordEmul.at(iBit)) {
1155         m_fdlEmulTechDecision[histIndex][iRec]->Fill(iBit);
1156 
1157         bitValue = (triggerMask) ? 0 : 1;
1158         gtTechnicalTriggerWordEmulMask[iBit] = bitValue;
1159         if (bitValue) {
1160           m_fdlEmulTechDecisionMask[histIndex][iRec]->Fill(iBit);
1161         }
1162       }
1163     }
1164   } else {
1165     for (int iBit = 0; iBit < nTechBits; ++iBit) {
1166       if (gtTechnicalTriggerWordData[iBit]) {
1167         m_fdlDataTechDecision_Err[iRec]->Fill(iBit);
1168       }
1169 
1170       if (gtTechnicalTriggerWordEmul.at(iBit)) {
1171         m_fdlEmulTechDecision_Err[iRec]->Fill(iBit);
1172       }
1173     }
1174   }
1175 
1176   if (gtTechnicalTriggerWordData == gtTechnicalTriggerWordEmul) {
1177     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord identical.\n";
1178     fdlBlockData.printGtTechnicalTriggerWord(m_myCoutStream);
1179     m_myCoutStream << "\n";
1180 
1181   } else {
1182     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord different.";
1183     m_myCoutStream << "\n Data: ";
1184     fdlBlockData.printGtTechnicalTriggerWord(m_myCoutStream);
1185     m_myCoutStream << "\n Emul: ";
1186     fdlBlockEmul.printGtTechnicalTriggerWord(m_myCoutStream);
1187     m_myCoutStream << "\n";
1188 
1189     if (matchBxInEvent && validBxInEvent) {
1190       m_fdlDataEmul[histIndex][iRec]->Fill(4);
1191     } else {
1192       m_fdlDataEmul_Err[iRec]->Fill(4);
1193     }
1194 
1195     if (matchBxInEvent && validBxInEvent) {
1196       for (int iBit = 0; iBit < nTechBits; ++iBit) {
1197         if (gtTechnicalTriggerWordData[iBit] != gtTechnicalTriggerWordEmul.at(iBit)) {
1198           m_fdlDataEmulTechDecision[histIndex][iRec]->Fill(iBit);
1199         }
1200       }
1201     } else {
1202       for (int iBit = 0; iBit < nTechBits; ++iBit) {
1203         if (gtTechnicalTriggerWordData[iBit] != gtTechnicalTriggerWordEmul.at(iBit)) {
1204           m_fdlDataEmulTechDecision_Err[iRec]->Fill(iBit);
1205         }
1206       }
1207     }
1208   }
1209 
1210   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1211   m_myCoutStream.str("");
1212   m_myCoutStream.clear();
1213 
1214   if (gtTechnicalTriggerWordDataMask == gtTechnicalTriggerWordEmulMask) {
1215     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord after mask identical.\n";
1216     m_myCoutStream << "\n";
1217 
1218   } else {
1219     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtTechnicalTriggerWord after mask different.";
1220     m_myCoutStream << "\n Data: ";
1221     m_myCoutStream << "\n Emul: ";
1222     m_myCoutStream << "\n";
1223 
1224     if (matchBxInEvent && validBxInEvent) {
1225       m_fdlDataEmul[histIndex][iRec]->Fill(5);
1226     } else {
1227       m_fdlDataEmul_Err[iRec]->Fill(5);
1228     }
1229 
1230     if (matchBxInEvent && validBxInEvent) {
1231       for (int iBit = 0; iBit < nTechBits; ++iBit) {
1232         if (gtTechnicalTriggerWordData[iBit] != gtTechnicalTriggerWordEmul.at(iBit)) {
1233           m_fdlDataEmulTechDecisionMask[histIndex][iRec]->Fill(iBit);
1234         }
1235       }
1236     }
1237   }
1238 
1239   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1240   m_myCoutStream.str("");
1241   m_myCoutStream.clear();
1242 
1243   // get algorithms bits (decision word)
1244   const DecisionWord& gtDecisionWordData = fdlBlockData.gtDecisionWord();
1245   const DecisionWord& gtDecisionWordEmul = fdlBlockEmul.gtDecisionWord();
1246 
1247   int nAlgoBits = gtDecisionWordData.size();
1248 
1249   DecisionWord gtDecisionWordDataMask(nAlgoBits);
1250   DecisionWord gtDecisionWordEmulMask(nAlgoBits);
1251 
1252   // get the index of the prescale factor set from data
1253   int iPfSet = fdlBlockData.gtPrescaleFactorIndexAlgo();
1254 
1255   // check that the prescale factor is not out of range for the prescale factor
1256   // record retrieved from event setup
1257   size_t pfSetsSize = (*m_prescaleFactorsAlgoTrig).size();
1258 
1259   if (iPfSet < 0) {
1260     LogDebug("L1GtHwValidation") << "\nError: index of prescale factor set retrieved from the data \n"
1261                                  << "less than zero."
1262                                  << "\n  Value of index retrieved from data = " << iPfSet << std::endl;
1263 
1264     // FIXME add a histogram to be used for a quality test
1265 
1266     return;
1267 
1268   } else if (iPfSet >= (static_cast<int>(pfSetsSize))) {
1269     LogDebug("L1GtHwValidation") << "\nError: index of prescale factor set retrieved from the data \n"
1270                                  << "greater than the size of the vector of prescale factor sets."
1271                                  << "\n  Value of index retrieved from data = " << iPfSet
1272                                  << "\n  Vector size = " << pfSetsSize << std::endl;
1273 
1274     // FIXME add a histogram to be used for a quality test
1275 
1276     return;
1277   }
1278 
1279   const std::vector<int>& prescaleFactorsAlgoTrig = (*m_prescaleFactorsAlgoTrig).at(iPfSet);
1280 
1281   if (matchBxInEvent && validBxInEvent) {
1282     for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
1283       unsigned int triggerMask = (m_triggerMaskAlgoTrig.at(iBit)) & (1 << PhysicsPartition);
1284 
1285       int prescaleFactor = prescaleFactorsAlgoTrig.at(iBit);
1286 
1287       LogTrace("L1GtHwValidation") << "Bit " << iBit << ": prescale factor = " << prescaleFactor
1288                                    << " trigger mask = " << triggerMask << std::endl;
1289 
1290       if (gtDecisionWordData[iBit]) {
1291         m_fdlDataAlgoDecision[histIndex][iRec]->Fill(iBit);
1292 
1293         if (prescaleFactor == 1) {
1294           m_fdlDataAlgoDecisionUnprescaled[histIndex][iRec]->Fill(iBit);
1295         } else {
1296           m_fdlDataAlgoDecisionPrescaled[histIndex][iRec]->Fill(iBit);
1297         }
1298 
1299         bitValue = (triggerMask) ? 0 : 1;
1300         gtDecisionWordDataMask[iBit] = bitValue;
1301         if (bitValue) {
1302           m_fdlDataAlgoDecisionMask[histIndex][iRec]->Fill(iBit);
1303         }
1304       }
1305 
1306       if (gtDecisionWordEmul.at(iBit)) {
1307         m_fdlEmulAlgoDecision[histIndex][iRec]->Fill(iBit);
1308 
1309         bitValue = (triggerMask) ? 0 : 1;
1310         gtDecisionWordEmulMask[iBit] = bitValue;
1311         if (bitValue) {
1312           m_fdlEmulAlgoDecisionMask[histIndex][iRec]->Fill(iBit);
1313         }
1314       }
1315     }
1316   } else {
1317     for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
1318       if (gtDecisionWordData[iBit]) {
1319         m_fdlDataAlgoDecision_Err[iRec]->Fill(iBit);
1320       }
1321     }
1322 
1323     for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
1324       if (gtDecisionWordEmul.at(iBit)) {
1325         m_fdlEmulAlgoDecision_Err[iRec]->Fill(iBit);
1326       }
1327     }
1328 
1329     if (iRec == 0) {
1330       m_agree = false;
1331 
1332       m_myCoutStream << "\nDisagreement data versus emulator: "
1333                      << "\n  matchBxInEvent && validBxInEvent false \n";
1334     }
1335   }
1336 
1337   if (gtDecisionWordData == gtDecisionWordEmul) {
1338     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord identical.";
1339     fdlBlockData.printGtDecisionWord(m_myCoutStream);
1340     m_myCoutStream << "\n";
1341 
1342   } else {
1343     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord different.";
1344     m_myCoutStream << "\n Data: ";
1345     fdlBlockData.printGtDecisionWord(m_myCoutStream);
1346     m_myCoutStream << "\n Emul: ";
1347     fdlBlockEmul.printGtDecisionWord(m_myCoutStream);
1348     m_myCoutStream << "\n";
1349 
1350     if (matchBxInEvent && validBxInEvent) {
1351       m_fdlDataEmul[histIndex][iRec]->Fill(6);
1352     } else {
1353       m_fdlDataEmul_Err[iRec]->Fill(6);
1354     }
1355 
1356     if (matchBxInEvent && validBxInEvent) {
1357       for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
1358         int prescaleFactor = prescaleFactorsAlgoTrig.at(iBit);
1359 
1360         if (gtDecisionWordData[iBit] != gtDecisionWordEmul.at(iBit)) {
1361           m_fdlDataEmulAlgoDecision[histIndex][iRec]->Fill(iBit);
1362 
1363           // for excluded algorithms, fill mismatch for BxInEvent = 0 and DAQ record only
1364           if (excludedAlgo(iBit) && (bxInEventData == 0) && (iRec == 0)) {
1365             m_excludedAlgorithmsAgreement->Fill(iBit);
1366           }
1367 
1368           if (prescaleFactor == 1) {
1369             m_fdlDataEmulAlgoDecisionUnprescaled[histIndex][iRec]->Fill(iBit);
1370 
1371             // fill a histogram for allowed algorithm triggers only
1372             if (!excludedAlgo(iBit)) {
1373               m_fdlDataEmulAlgoDecisionUnprescaledAllowed[histIndex][iRec]->Fill(iBit);
1374             }
1375 
1376           } else {
1377             m_fdlDataEmulAlgoDecisionPrescaled[histIndex][iRec]->Fill(iBit);
1378           }
1379 
1380           if (gtDecisionWordData[iBit]) {
1381             m_fdlDataAlgoDecision_NoMatch[histIndex][iRec]->Fill(iBit);
1382 
1383             if (prescaleFactor == 1) {
1384               m_fdlDataAlgoDecisionUnprescaled_NoMatch[histIndex][iRec]->Fill(iBit);
1385 
1386               // compare for agreement only unprescaled algorithms and algorithms which
1387               // are not excluded from comparison
1388               if ((!excludedAlgo(iBit)) && (bxInEventData == 0) && (iRec == 0)) {
1389                 m_agree = false;
1390                 m_dataOnly = true;
1391 
1392                 m_myCoutStream << "\nDisagreement data versus emulator: "
1393                                << "result before mask for algorithm with bit number " << iBit
1394                                << "\n  Data: true, emulator: false \n";
1395               }
1396 
1397             } else {
1398               m_fdlDataAlgoDecisionPrescaled_NoMatch[histIndex][iRec]->Fill(iBit);
1399             }
1400 
1401           } else {
1402             m_fdlEmulAlgoDecision_NoMatch[histIndex][iRec]->Fill(iBit);
1403 
1404             if (prescaleFactor == 1) {
1405               m_fdlEmulAlgoDecisionUnprescaled_NoMatch[histIndex][iRec]->Fill(iBit);
1406 
1407               // compare for agreement only unprescaled algorithms and algorithms which
1408               // are not excluded from comparison
1409               if ((!excludedAlgo(iBit)) && (bxInEventData == 0) && (iRec == 0)) {
1410                 m_agree = false;
1411                 m_emulOnly = true;
1412 
1413                 m_myCoutStream << "\nDisagreement data versus emulator: "
1414                                << "result before mask for algorithm with bit number " << iBit
1415                                << "\n  Data: false, emulator: true \n";
1416               }
1417 
1418             } else {
1419               m_fdlEmulAlgoDecisionPrescaled_NoMatch[histIndex][iRec]->Fill(iBit);
1420             }
1421           }
1422         }
1423       }
1424     } else {
1425       for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
1426         if (gtDecisionWordData[iBit] != gtDecisionWordEmul.at(iBit)) {
1427           m_fdlDataEmulAlgoDecision_Err[iRec]->Fill(iBit);
1428         }
1429       }
1430 
1431       if (iRec == 0) {
1432         m_agree = false;
1433 
1434         m_myCoutStream << "\nDisagreement data versus emulator: "
1435                        << "\n  matchBxInEvent && validBxInEvent false \n";
1436       }
1437     }
1438   }
1439 
1440   if (gtDecisionWordDataMask == gtDecisionWordEmulMask) {
1441     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord after mask identical.";
1442     m_myCoutStream << "\n";
1443 
1444   } else {
1445     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWord after mask different.";
1446     m_myCoutStream << "\n Data: ";
1447     m_myCoutStream << "\n Emul: ";
1448     m_myCoutStream << "\n";
1449 
1450     if (matchBxInEvent && validBxInEvent) {
1451       m_fdlDataEmul[histIndex][iRec]->Fill(7);
1452     } else {
1453       m_fdlDataEmul_Err[iRec]->Fill(7);
1454     }
1455 
1456     if (matchBxInEvent && validBxInEvent) {
1457       for (int iBit = 0; iBit < nAlgoBits; ++iBit) {
1458         if (gtDecisionWordDataMask[iBit] != gtDecisionWordEmulMask.at(iBit)) {
1459           m_fdlDataEmulAlgoDecisionMask[histIndex][iRec]->Fill(iBit);
1460 
1461           int prescaleFactor = prescaleFactorsAlgoTrig.at(iBit);
1462 
1463           if (gtDecisionWordDataMask[iBit]) {
1464             m_fdlDataAlgoDecisionMask_NoMatch[histIndex][iRec]->Fill(iBit);
1465 
1466             if (prescaleFactor == 1) {
1467               m_fdlDataAlgoDecisionUnprescaledMask_NoMatch[histIndex][iRec]->Fill(iBit);
1468 
1469               // compare for agreement only unprescaled algorithms and algorithms which
1470               // are not excluded from comparison
1471               if ((!excludedAlgo(iBit)) && (bxInEventData == 0) && (iRec == 0)) {
1472                 m_agree = false;
1473                 m_dataOnlyMask = true;
1474 
1475                 m_myCoutStream << "\nDisagreement data versus emulator: "
1476                                << "result after mask for algorithm with bit number " << iBit
1477                                << " different in data versus emulator "
1478                                << "\n  Data: true, emulator: false \n";
1479               }
1480 
1481             } else {
1482               m_fdlDataAlgoDecisionPrescaledMask_NoMatch[histIndex][iRec]->Fill(iBit);
1483             }
1484 
1485           } else {
1486             m_fdlEmulAlgoDecisionMask_NoMatch[histIndex][iRec]->Fill(iBit);
1487 
1488             if (prescaleFactor == 1) {
1489               m_fdlEmulAlgoDecisionUnprescaledMask_NoMatch[histIndex][iRec]->Fill(iBit);
1490 
1491               // compare for agreement only unprescaled algorithms and algorithms which
1492               // are not excluded from comparison
1493               if ((!excludedAlgo(iBit)) && (bxInEventData == 0) && (iRec == 0)) {
1494                 m_agree = false;
1495                 m_emulOnlyMask = true;
1496 
1497                 m_myCoutStream << "\nDisagreement data versus emulator: "
1498                                << "result after mask for algorithm with bit number " << iBit
1499                                << " different in data versus emulator "
1500                                << "\n  Data: false, emulator: true \n";
1501               }
1502 
1503             } else {
1504               m_fdlEmulAlgoDecisionPrescaledMask_NoMatch[histIndex][iRec]->Fill(iBit);
1505             }
1506           }
1507         }
1508       }
1509     }
1510   }
1511 
1512   // get  extended algorithms bits (extended decision word)
1513   const DecisionWordExtended& gtDecisionWordExtendedData = fdlBlockData.gtDecisionWordExtended();
1514   const DecisionWordExtended& gtDecisionWordExtendedEmul = fdlBlockEmul.gtDecisionWordExtended();
1515 
1516   if (gtDecisionWordExtendedData == gtDecisionWordExtendedEmul) {
1517     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWordExtended identical.\n";
1518     fdlBlockData.printGtDecisionWordExtended(m_myCoutStream);
1519     m_myCoutStream << "\n";
1520 
1521   } else {
1522     m_myCoutStream << "\n" << recString << " Data and emulated FDL gtDecisionWordExtended different.\n";
1523     m_myCoutStream << "\n Data: ";
1524     fdlBlockData.printGtDecisionWordExtended(m_myCoutStream);
1525     m_myCoutStream << "\n Emul: ";
1526     fdlBlockEmul.printGtDecisionWordExtended(m_myCoutStream);
1527     m_myCoutStream << "\n";
1528 
1529     if (matchBxInEvent && validBxInEvent) {
1530       m_fdlDataEmul[histIndex][iRec]->Fill(8);
1531     } else {
1532       m_fdlDataEmul_Err[iRec]->Fill(8);
1533     }
1534   }
1535 
1536   // get  NoAlgo
1537   const uint16_t noAlgoData = fdlBlockData.noAlgo();
1538   const uint16_t noAlgoEmul = fdlBlockEmul.noAlgo();
1539 
1540   if (noAlgoData == noAlgoEmul) {
1541     m_myCoutStream << "\n" << recString << " Data and emulated FDL noAlgo identical.";
1542     m_myCoutStream << "\n noAlgo() = " << noAlgoData;
1543     m_myCoutStream << "\n";
1544 
1545   } else {
1546     m_myCoutStream << "\n" << recString << " Data and emulated FDL noAlgo different.";
1547     m_myCoutStream << "\n Data: noAlgo() = " << noAlgoData;
1548     m_myCoutStream << "\n Emul: noAlgo() = " << noAlgoEmul;
1549     m_myCoutStream << "\n";
1550 
1551     if (matchBxInEvent && validBxInEvent) {
1552       m_fdlDataEmul[histIndex][iRec]->Fill(9);
1553     } else {
1554       m_fdlDataEmul_Err[iRec]->Fill(9);
1555     }
1556   }
1557 
1558   // get  "Final OR" bits
1559   const uint16_t finalORData = fdlBlockData.finalOR();
1560   const uint16_t finalOREmul = fdlBlockEmul.finalOR();
1561 
1562   if (finalORData == finalOREmul) {
1563     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR identical.";
1564     m_myCoutStream << "\n finalOR() = " << std::hex << "0x" << std::setw(2) << std::setfill('0') << finalORData
1565                    << std::setfill(' ') << std::dec;
1566     m_myCoutStream << "\n";
1567 
1568   } else {
1569     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR different.";
1570     m_myCoutStream << "\n Data: finalOR() = " << std::hex << "0x" << std::setw(2) << std::setfill('0') << finalORData
1571                    << std::setfill(' ') << std::dec;
1572     m_myCoutStream << "\n Emul: finalOR() = " << std::hex << "0x" << std::setw(2) << std::setfill('0') << finalOREmul
1573                    << std::setfill(' ') << std::dec;
1574     m_myCoutStream << "\n";
1575 
1576     if (matchBxInEvent && validBxInEvent) {
1577       m_fdlDataEmul[histIndex][iRec]->Fill(10);
1578     } else {
1579       m_fdlDataEmul_Err[iRec]->Fill(10);
1580     }
1581   }
1582 
1583   // get  "Final OR" for physics partition
1584   const int finalORPhysData = finalORData & (1 << PhysicsPartition);
1585   const int finalORPhysEmul = finalOREmul & (1 << PhysicsPartition);
1586 
1587   if (finalORPhysData == finalORPhysEmul) {
1588     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR for the physics partition identical.";
1589     m_myCoutStream << "\n finalOR() = " << finalORPhysData;
1590     m_myCoutStream << "\n";
1591 
1592   } else {
1593     m_myCoutStream << "\n" << recString << " Data and emulated FDL finalOR for the physics partition  different.";
1594     m_myCoutStream << "\n Data: finalOR() = " << finalORPhysData;
1595     m_myCoutStream << "\n Emul: finalOR() = " << finalORPhysEmul;
1596     m_myCoutStream << "\n";
1597 
1598     if (matchBxInEvent && validBxInEvent) {
1599       m_fdlDataEmul[histIndex][iRec]->Fill(11);
1600     } else {
1601       m_fdlDataEmul_Err[iRec]->Fill(11);
1602     }
1603   }
1604 
1605   // get  local bunch cross number of the actual bx
1606   const uint16_t localBxNrData = fdlBlockData.localBxNr();
1607   const uint16_t localBxNrEmul = fdlBlockEmul.localBxNr();
1608 
1609   if (localBxNrData == localBxNrEmul) {
1610     m_myCoutStream << "\n" << recString << " Data and emulated FDL localBxNr identical.";
1611     m_myCoutStream << "\n localBxNr() = " << localBxNrData;
1612     m_myCoutStream << "\n";
1613 
1614   } else {
1615     m_myCoutStream << "\n" << recString << " Data and emulated FDL localBxNr different.";
1616     m_myCoutStream << "\n Data: localBxNr() = " << localBxNrData;
1617     m_myCoutStream << "\n Emul: localBxNr() = " << localBxNrEmul;
1618     m_myCoutStream << "\n";
1619 
1620     if (matchBxInEvent && validBxInEvent) {
1621       m_fdlDataEmul[histIndex][iRec]->Fill(12);
1622     } else {
1623       m_fdlDataEmul_Err[iRec]->Fill(12);
1624     }
1625   }
1626 
1627   edm::LogInfo("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1628   m_myCoutStream.str("");
1629   m_myCoutStream.clear();
1630 }
1631 
1632 //compare the PSB board
1633 void L1GtHwValidation::comparePSB(const edm::Event& iEvent,
1634                                   const edm::EventSetup& evSetup,
1635                                   const L1GtPsbWord& psbBlockData,
1636                                   const L1GtPsbWord& psbBlockEmul) {
1637   if (psbBlockData == psbBlockEmul) {
1638     m_myCoutStream << "\nData and emulated PSB blocks: identical.\n";
1639     psbBlockData.print(m_myCoutStream);
1640 
1641   } else {
1642     m_myCoutStream << "\nData and emulated PSB blocks: different.\n";
1643 
1644     m_myCoutStream << "\nData: PSB block\n";
1645     psbBlockData.print(m_myCoutStream);
1646 
1647     m_myCoutStream << "\nEmul: PSB block\n";
1648     psbBlockEmul.print(m_myCoutStream);
1649   }
1650 
1651   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1652 
1653   m_myCoutStream.str("");
1654   m_myCoutStream.clear();
1655 
1656   // get BoardId value
1657   const uint16_t boardIdData = psbBlockData.boardId();
1658   const uint16_t boardIdEmul = psbBlockEmul.boardId();
1659 
1660   if (boardIdData == boardIdEmul) {
1661     m_myCoutStream << "\nData and emulated PSB boardId identical.";
1662     m_myCoutStream << "\n boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
1663                    << std::setfill(' ') << std::dec;
1664     m_myCoutStream << "\n";
1665 
1666   } else {
1667     m_myCoutStream << "\nData and emulated PSB boardId different.";
1668     m_myCoutStream << "\n Data: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdData
1669                    << std::setfill(' ') << std::dec;
1670     m_myCoutStream << "\n Emul: boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << boardIdEmul
1671                    << std::setfill(' ') << std::dec;
1672     m_myCoutStream << "\n";
1673   }
1674 
1675   // get bunch cross in the GT event record
1676   const int bxInEventData = psbBlockData.bxInEvent();
1677   const int bxInEventEmul = psbBlockEmul.bxInEvent();
1678 
1679   if (bxInEventData == bxInEventEmul) {
1680     m_myCoutStream << "\nData and emulated PSB bxInEvent identical.";
1681     m_myCoutStream << "\n bxInEvent() = " << bxInEventData;
1682     m_myCoutStream << "\n";
1683 
1684   } else {
1685     m_myCoutStream << "\nData and emulated PSB bxInEvent different.";
1686     m_myCoutStream << "\n Data: bxInEvent() = " << bxInEventData;
1687     m_myCoutStream << "\n Emul: bxInEvent() = " << bxInEventEmul;
1688     m_myCoutStream << "\n";
1689   }
1690 
1691   // get BxNr - bunch cross number of the actual bx
1692   const uint16_t bxNrData = psbBlockData.bxNr();
1693   const uint16_t bxNrEmul = psbBlockEmul.bxNr();
1694 
1695   if (bxNrData == bxNrEmul) {
1696     m_myCoutStream << "\nData and emulated PSB bxNr identical.";
1697     m_myCoutStream << "\n bxNr() = " << bxNrData;
1698     m_myCoutStream << "\n";
1699 
1700   } else {
1701     m_myCoutStream << "\nData and emulated PSB bxNr different.";
1702     m_myCoutStream << "\n Data: bxNr() = " << bxNrData;
1703     m_myCoutStream << "\n Emul: bxNr() = " << bxNrEmul;
1704     m_myCoutStream << "\n";
1705   }
1706 
1707   // get event number since last L1 reset generated in FDL
1708   const uint32_t eventNrData = psbBlockData.eventNr();
1709   const uint32_t eventNrEmul = psbBlockEmul.eventNr();
1710 
1711   if (eventNrData == eventNrEmul) {
1712     m_myCoutStream << "\nData and emulated PSB eventNr identical.";
1713     m_myCoutStream << "\n eventNr() = " << eventNrData;
1714     m_myCoutStream << "\n";
1715 
1716   } else {
1717     m_myCoutStream << "\nData and emulated PSB eventNr different.";
1718     m_myCoutStream << "\n Data: eventNr() = " << eventNrData;
1719     m_myCoutStream << "\n Emul: eventNr() = " << eventNrEmul;
1720     m_myCoutStream << "\n";
1721   }
1722 
1723   /// get/set A_DATA_CH_IA
1724   uint16_t valData;
1725   uint16_t valEmul;
1726 
1727   for (int iA = 0; iA < psbBlockData.NumberAData; ++iA) {
1728     valData = psbBlockData.aData(iA);
1729     valEmul = psbBlockEmul.aData(iA);
1730 
1731     if (valData == valEmul) {
1732       m_myCoutStream << "\nData and emulated PSB aData(" << iA << ") identical.";
1733       m_myCoutStream << "\n aData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
1734                      << std::setfill(' ') << std::dec;
1735       m_myCoutStream << "\n";
1736 
1737     } else {
1738       m_myCoutStream << "\nData and emulated PSB aData(" << iA << ") different.";
1739       m_myCoutStream << "\n Data: aData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
1740                      << std::setfill(' ') << std::dec;
1741       m_myCoutStream << "\n Emul: aData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valEmul
1742                      << std::setfill(' ') << std::dec;
1743       m_myCoutStream << "\n";
1744     }
1745   }
1746 
1747   /// get/set B_DATA_CH_IB
1748   for (int iB = 0; iB < psbBlockData.NumberBData; ++iB) {
1749     valData = psbBlockData.bData(iB);
1750     valEmul = psbBlockEmul.bData(iB);
1751 
1752     if (valData == valEmul) {
1753       m_myCoutStream << "\nData and emulated PSB bData(" << iB << ") identical.";
1754       m_myCoutStream << "\n bData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
1755                      << std::setfill(' ') << std::dec;
1756       m_myCoutStream << "\n";
1757 
1758     } else {
1759       m_myCoutStream << "\nData and emulated PSB bData(" << iB << ") different.";
1760       m_myCoutStream << "\n Data: bData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valData
1761                      << std::setfill(' ') << std::dec;
1762       m_myCoutStream << "\n Emul: bData(iA) = " << std::hex << "0x" << std::setw(4) << std::setfill('0') << valEmul
1763                      << std::setfill(' ') << std::dec;
1764       m_myCoutStream << "\n";
1765     }
1766   }
1767 
1768   // get  local bunch cross number of the actual bx
1769   const uint16_t localBxNrData = psbBlockData.localBxNr();
1770   const uint16_t localBxNrEmul = psbBlockEmul.localBxNr();
1771 
1772   if (localBxNrData == localBxNrEmul) {
1773     m_myCoutStream << "\nData and emulated PSB localBxNr identical.";
1774     m_myCoutStream << "\n localBxNr() = " << localBxNrData;
1775     m_myCoutStream << "\n";
1776 
1777   } else {
1778     m_myCoutStream << "\nData and emulated PSB localBxNr different.";
1779     m_myCoutStream << "\n Data: localBxNr() = " << localBxNrData;
1780     m_myCoutStream << "\n Emul: localBxNr() = " << localBxNrEmul;
1781     m_myCoutStream << "\n";
1782   }
1783 
1784   edm::LogInfo("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1785   m_myCoutStream.str("");
1786   m_myCoutStream.clear();
1787 }
1788 
1789 //compare the TCS board
1790 void L1GtHwValidation::compareTCS(const edm::Event& iEvent,
1791                                   const edm::EventSetup& evSetup,
1792                                   const L1TcsWord&,
1793                                   const L1TcsWord&) {
1794   // empty
1795 }
1796 
1797 //L1 GT DAQ record comparison
1798 void L1GtHwValidation::compareDaqRecord(const edm::Event& iEvent, const edm::EventSetup& evSetup) {
1799   // formal index for DAQ record
1800   int iRec = 0;
1801 
1802   // reset the flags - they are used for DAQ recor only
1803   m_agree = true;
1804   m_dataOnly = false;
1805   m_emulOnly = false;
1806   m_dataOnlyMask = false;
1807   m_emulOnlyMask = false;
1808 
1809   // get the L1 GT hardware DAQ record L1GlobalTriggerReadoutRecord
1810   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecordData;
1811   iEvent.getByToken(m_l1GtDataDaqInputToken_, gtReadoutRecordData);
1812 
1813   bool validData = false;
1814 
1815   if (!gtReadoutRecordData.isValid()) {
1816     m_nrDataEventError++;
1817   } else {
1818     validData = true;
1819   }
1820 
1821   // get the L1 GT emulator DAQ record L1GlobalTriggerReadoutRecord
1822   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecordEmul;
1823   iEvent.getByToken(m_l1GtEmulDaqInputToken_, gtReadoutRecordEmul);
1824 
1825   bool validEmul = false;
1826 
1827   if (!gtReadoutRecordEmul.isValid()) {
1828     m_nrEmulEventError++;
1829   } else {
1830     validEmul = true;
1831   }
1832 
1833   if ((!validData) || (!validEmul)) {
1834     edm::LogWarning("L1GtHwValidation") << "\n No valid product found: DAQ L1GlobalTriggerReadoutRecord"
1835                                         << "\n     Data validity [1 = true; 0 = false]: " << validData
1836                                         << "\n     Emulator validity: [1 = true; 0 = false]: " << validEmul
1837                                         << "\n DAQ histograms will not be filled.\n"
1838                                         << std::endl;
1839 
1840     return;
1841   }
1842 
1843   // compare GTFE
1844   const L1GtfeWord& gtfeBlockData = gtReadoutRecordData->gtfeWord();
1845   const L1GtfeWord& gtfeBlockEmul = gtReadoutRecordEmul->gtfeWord();
1846 
1847   compareGTFE(iEvent, evSetup, gtfeBlockData, gtfeBlockEmul, iRec);
1848 
1849   // FDL comparison
1850   const std::vector<L1GtFdlWord>& gtFdlVectorData = gtReadoutRecordData->gtFdlVector();
1851   const std::vector<L1GtFdlWord>& gtFdlVectorEmul = gtReadoutRecordEmul->gtFdlVector();
1852 
1853   int gtFdlVectorDataSize = gtFdlVectorData.size();
1854   int gtFdlVectorEmulSize = gtFdlVectorEmul.size();
1855 
1856   if (gtFdlVectorDataSize == gtFdlVectorEmulSize) {
1857     m_myCoutStream << "\nData and emulated FDL vector size: identical.\n";
1858     m_myCoutStream << "  Size: " << gtFdlVectorDataSize << std::endl;
1859 
1860     for (int iFdl = 0; iFdl < gtFdlVectorDataSize; ++iFdl) {
1861       const L1GtFdlWord& fdlBlockData = gtFdlVectorData[iFdl];
1862       const L1GtFdlWord& fdlBlockEmul = gtFdlVectorEmul[iFdl];
1863 
1864       compareFDL(iEvent, evSetup, fdlBlockData, fdlBlockEmul, iRec);
1865     }
1866   } else {
1867     m_myCoutStream << "\nData and emulated FDL vector size: different.\n";
1868     m_myCoutStream << "  Data: size = " << gtFdlVectorDataSize << std::endl;
1869     m_myCoutStream << "  Emul: size = " << gtFdlVectorEmulSize << std::endl;
1870   }
1871 
1872   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1873 
1874   m_myCoutStream.str("");
1875   m_myCoutStream.clear();
1876 
1877   // PSB comparison
1878   const std::vector<L1GtPsbWord>& gtPsbVectorData = gtReadoutRecordData->gtPsbVector();
1879   const std::vector<L1GtPsbWord>& gtPsbVectorEmul = gtReadoutRecordEmul->gtPsbVector();
1880 
1881   int gtPsbVectorDataSize = gtPsbVectorData.size();
1882   int gtPsbVectorEmulSize = gtPsbVectorEmul.size();
1883 
1884   if (gtPsbVectorDataSize == gtPsbVectorEmulSize) {
1885     m_myCoutStream << "\nData and emulated PSB vector size: identical.\n";
1886     m_myCoutStream << "  Size: " << gtPsbVectorDataSize << std::endl;
1887   } else {
1888     m_myCoutStream << "\nData and emulated PSB vector size: different.\n";
1889     m_myCoutStream << "  Data: size = " << gtPsbVectorDataSize << std::endl;
1890     m_myCoutStream << "  Emul: size = " << gtPsbVectorEmulSize << std::endl;
1891   }
1892 
1893   // the order of PSB block in the gtPsbVector is different in emulator and in data
1894   // in emulator: all active PSB in one BxInEvent, ordered L1A-1, L1A, L1A+1
1895   // in unpacker: every PSB in all BxInEvent
1896   for (int iPsb = 0; iPsb < gtPsbVectorDataSize; ++iPsb) {
1897     const L1GtPsbWord& psbBlockData = gtPsbVectorData[iPsb];
1898     const uint16_t boardIdData = psbBlockData.boardId();
1899     const int bxInEventData = psbBlockData.bxInEvent();
1900 
1901     // search the corresponding PSB in the emulated record using the
1902     // BoardId and the BxInEvent
1903 
1904     bool foundPSB = false;
1905 
1906     for (int iPsbF = 0; iPsbF < gtPsbVectorEmulSize; ++iPsbF) {
1907       const L1GtPsbWord& psbBlockEmul = gtPsbVectorEmul[iPsbF];
1908       const uint16_t boardIdEmul = psbBlockEmul.boardId();
1909       const int bxInEventEmul = psbBlockEmul.bxInEvent();
1910 
1911       if ((boardIdEmul == boardIdData) && (bxInEventData == bxInEventEmul)) {
1912         foundPSB = true;
1913 
1914         // compare the boards
1915         comparePSB(iEvent, evSetup, psbBlockData, psbBlockEmul);
1916       }
1917     }
1918 
1919     if (!foundPSB) {
1920       m_myCoutStream << "\nNo emulated PSB with boardId() = " << std::hex << "0x" << std::setw(4) << std::setfill('0')
1921                      << boardIdData << std::setfill(' ') << std::dec << " and BxInEvent = " << bxInEventData
1922                      << " was found";
1923     }
1924   }
1925 
1926   edm::LogInfo("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
1927 
1928   m_myCoutStream.str("");
1929   m_myCoutStream.clear();
1930 
1931   // fill the m_gtErrorFlag histogram (only for L1 GT DAQ record)
1932 
1933   if (m_agree) {
1934     m_gtErrorFlag->Fill(0.0001);
1935   }
1936 
1937   if (m_dataOnly || m_dataOnlyMask) {
1938     m_gtErrorFlag->Fill(3.0001);
1939   }
1940 
1941   if (m_emulOnly || m_emulOnlyMask) {
1942     m_gtErrorFlag->Fill(4.0001);
1943   }
1944 }
1945 
1946 // L1 GT EVM record comparison
1947 void L1GtHwValidation::compareEvmRecord(const edm::Event& iEvent, const edm::EventSetup& evSetup) {
1948   // formal index for EVM record
1949   int iRec = 1;
1950 
1951   // get the L1 GT hardware EVM record L1GlobalTriggerEvmReadoutRecord
1952   edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtReadoutRecordData;
1953   iEvent.getByToken(m_l1GtDataEvmInputToken_, gtReadoutRecordData);
1954 
1955   bool validData = false;
1956 
1957   if (!gtReadoutRecordData.isValid()) {
1958     m_nrDataEventError++;
1959   } else {
1960     validData = true;
1961   }
1962 
1963   // get the L1 GT emulator EVM record L1GlobalTriggerEvmReadoutRecord
1964   edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtReadoutRecordEmul;
1965   iEvent.getByToken(m_l1GtEmulEvmInputToken_, gtReadoutRecordEmul);
1966 
1967   bool validEmul = false;
1968 
1969   if (!gtReadoutRecordEmul.isValid()) {
1970     m_nrEmulEventError++;
1971   } else {
1972     validEmul = true;
1973   }
1974 
1975   if ((!validData) || (!validEmul)) {
1976     edm::LogWarning("L1GtHwValidation") << "\n No valid product found: EVM L1GlobalTriggerEvmReadoutRecord"
1977                                         << "\n     Data validity [1 = true; 0 = false]: " << validData
1978                                         << "\n     Emulator validity: [1 = true; 0 = false]: " << validEmul
1979                                         << "\n EVM histograms will not be filled.\n"
1980                                         << std::endl;
1981 
1982     return;
1983   }
1984 
1985   // compare GTFE
1986   const L1GtfeWord& gtfeBlockData = gtReadoutRecordData->gtfeWord();
1987   const L1GtfeWord& gtfeBlockEmul = gtReadoutRecordEmul->gtfeWord();
1988 
1989   compareGTFE(iEvent, evSetup, gtfeBlockData, gtfeBlockEmul, iRec);
1990 
1991   // FDL comparison
1992   const std::vector<L1GtFdlWord>& gtFdlVectorData = gtReadoutRecordData->gtFdlVector();
1993   const std::vector<L1GtFdlWord>& gtFdlVectorEmul = gtReadoutRecordEmul->gtFdlVector();
1994 
1995   int gtFdlVectorDataSize = gtFdlVectorData.size();
1996   int gtFdlVectorEmulSize = gtFdlVectorEmul.size();
1997 
1998   if (gtFdlVectorDataSize == gtFdlVectorEmulSize) {
1999     m_myCoutStream << "\nData and emulated FDL vector size: identical.\n";
2000     m_myCoutStream << "  Size: " << gtFdlVectorDataSize << std::endl;
2001 
2002     for (int iFdl = 0; iFdl < gtFdlVectorDataSize; ++iFdl) {
2003       const L1GtFdlWord& fdlBlockData = gtFdlVectorData[iFdl];
2004       const L1GtFdlWord& fdlBlockEmul = gtFdlVectorEmul[iFdl];
2005 
2006       compareFDL(iEvent, evSetup, fdlBlockData, fdlBlockEmul, iRec);
2007     }
2008   } else {
2009     m_myCoutStream << "\nData and emulated FDL vector size: different.\n";
2010     m_myCoutStream << "  Data: size = " << gtFdlVectorDataSize << std::endl;
2011     m_myCoutStream << "  Emul: size = " << gtFdlVectorEmulSize << std::endl;
2012   }
2013 
2014   // FIXME compare TCS
2015 
2016   LogDebug("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
2017 
2018   m_myCoutStream.str("");
2019   m_myCoutStream.clear();
2020 
2021   edm::LogInfo("L1GtHwValidation") << m_myCoutStream.str() << std::endl;
2022 
2023   m_myCoutStream.str("");
2024   m_myCoutStream.clear();
2025 }
2026 
2027 // compare the GCT collections obtained from L1 GT PSB with the input
2028 // GCT collections
2029 void L1GtHwValidation::compareGt_Gct(const edm::Event& iEvent, const edm::EventSetup&) {
2030   // FIXME
2031 }
2032 
2033 // analyze each event: event loop
2034 void L1GtHwValidation::analyze(const edm::Event& iEvent, const edm::EventSetup& evSetup) {
2035   ++m_nrEvJob;
2036   ++m_nrEvRun;
2037 
2038   // L1 GT DAQ record comparison
2039   compareDaqRecord(iEvent, evSetup);
2040 
2041   // L1 GT EVM record comparison
2042   compareEvmRecord(iEvent, evSetup);
2043 
2044   // GCT collections from L1 GT PSB versus unpacked GCT
2045   compareGt_Gct(iEvent, evSetup);
2046 }
2047 
2048 bool L1GtHwValidation::matchCondCategory(const L1GtConditionCategory& conditionCategory,
2049                                          const L1GtConditionCategory& excludedCategory) {
2050   bool matchValue = false;
2051 
2052   if (excludedCategory == CondNull) {
2053     matchValue = true;
2054   } else {
2055     if (conditionCategory == excludedCategory) {
2056       matchValue = true;
2057     }
2058   }
2059 
2060   return matchValue;
2061 }
2062 
2063 bool L1GtHwValidation::matchCondType(const L1GtConditionType& conditionType, const L1GtConditionType& excludedType) {
2064   bool matchValue = false;
2065 
2066   if (excludedType == TypeNull) {
2067     matchValue = true;
2068   } else {
2069     if (conditionType == excludedType) {
2070       matchValue = true;
2071     }
2072   }
2073 
2074   return matchValue;
2075 }
2076 
2077 bool L1GtHwValidation::matchCondL1GtObject(const std::vector<L1GtObject>& condObjects,
2078                                            const L1GtObject& excludedObject) {
2079   bool matchValue = false;
2080 
2081   if (excludedObject == ObjNull) {
2082     matchValue = true;
2083 
2084   } else {
2085     for (std::vector<L1GtObject>::const_iterator itCondObj = condObjects.begin(); itCondObj != condObjects.end();
2086          ++itCondObj) {
2087       if ((*itCondObj) == excludedObject) {
2088         matchValue = true;
2089       }
2090     }
2091   }
2092 
2093   return matchValue;
2094 }
2095 
2096 void L1GtHwValidation::excludedAlgoList() {
2097   const AlgorithmMap& algorithmMap = m_l1GtMenu->gtAlgorithmMap();
2098 
2099   for (CItAlgo itAlgo = algorithmMap.begin(); itAlgo != algorithmMap.end(); itAlgo++) {
2100     const std::string& algName = itAlgo->first;
2101     const int algBitNumber = (itAlgo->second).algoBitNumber();
2102     const int chipNr = (itAlgo->second).algoChipNumber();
2103 
2104     const ConditionMap& conditionMap = (m_l1GtMenu->gtConditionMap()).at(chipNr);
2105 
2106     const std::vector<L1GtLogicParser::TokenRPN>& aRpnVector = (itAlgo->second).algoRpnVector();
2107     size_t aRpnVectorSize = aRpnVector.size();
2108 
2109     bool algWithExcludedCondition = false;
2110     bool algWithConditionNotInMap = false;
2111 
2112     // loop over RpnVector and check each conditions against list of excluded conditions
2113     for (size_t opI = 0; opI < aRpnVectorSize; ++opI) {
2114       const std::string& cndName = (aRpnVector[opI]).operand;
2115 
2116       if (!cndName.empty()) {
2117         bool foundCond = false;
2118 
2119         CItCond itCond = conditionMap.find(cndName);
2120         if (itCond != conditionMap.end()) {
2121           const L1GtConditionCategory& cCateg = (itCond->second)->condCategory();
2122           const L1GtConditionType& cType = (itCond->second)->condType();
2123           const std::vector<L1GtObject>& objType = (itCond->second)->objectType();
2124 
2125           // condition index in the m_excludedCondCategory, m_excludedCondType, m_excludedL1GtObject vectors
2126           int iCond = -1;
2127 
2128           for (std::vector<L1GtConditionCategory>::const_iterator itCateg = m_excludedCondCategory.begin();
2129                itCateg != m_excludedCondCategory.end();
2130                ++itCateg) {
2131             iCond++;
2132 
2133             bool matchCondCategoryValue = matchCondCategory(cCateg, (*itCateg));
2134             bool matchCondTypeValue = matchCondType(cType, m_excludedCondType.at(iCond));
2135             bool matchCondL1GtObjectValue = matchCondL1GtObject(objType, m_excludedL1GtObject.at(iCond));
2136 
2137             LogTrace("L1GtHwValidation") << "\n  "
2138                                          << "Algorithm: " << algName << " Condition: " << cndName << "\n  "
2139                                          << "Category:  " << l1GtConditionCategoryEnumToString(cCateg)
2140                                          << "; excluded: " << l1GtConditionCategoryEnumToString((*itCateg)) << "\n  "
2141                                          << "Type:      " << l1GtConditionTypeEnumToString(cType) << "; excluded: "
2142                                          << l1GtConditionTypeEnumToString(m_excludedCondType.at(iCond)) << "\n  "
2143                                          << "Object excluded: "
2144                                          << l1GtObjectEnumToString(m_excludedL1GtObject.at(iCond)) << std::endl;
2145 
2146             if (matchCondCategoryValue && matchCondTypeValue && matchCondL1GtObjectValue) {
2147               algWithExcludedCondition = true;
2148             }
2149           }
2150 
2151           foundCond = true;
2152         }
2153 
2154         if (!foundCond) {
2155           // it should never be happen, all conditions are in the maps
2156 
2157           algWithConditionNotInMap = true;
2158 
2159           LogTrace("L1GtHwValidation") << "\n Error: condition " << cndName << " not found in condition map!"
2160                                        << "\n  Add algorithm " << algName << " (bit number " << algBitNumber << ") "
2161                                        << "\n  to list of algorithms excluded from comparison"
2162                                        << "\n  data versus emulator." << std::endl;
2163         }
2164       }
2165     }
2166 
2167     if (algWithConditionNotInMap) {
2168       // it should never be happen, all conditions are in the maps
2169 
2170       m_excludedAlgoList.push_back(algBitNumber);
2171 
2172       LogTrace("L1GtHwValidation") << "\n Error: one or more conditions from algorithm " << algName << " (bit number "
2173                                    << algBitNumber << ") "
2174                                    << " not found in condition map!"
2175                                    << "\n  Add it to list of algorithms excluded from comparison"
2176                                    << "\n  data versus emulator." << std::endl;
2177     }
2178 
2179     if (algWithExcludedCondition) {
2180       m_excludedAlgoList.push_back(algBitNumber);
2181 
2182       LogTrace("L1GtHwValidation") << "\n Algorithm " << algName << " (bit number " << algBitNumber
2183                                    << ") contains an excluded condition."
2184                                    << "\n  Add it to list of algorithms excluded from comparison"
2185                                    << "\n  data versus emulator." << std::endl;
2186     }
2187 
2188     // add algorithm triggers from ExcludeAlgoTrigByName
2189     for (std::vector<std::string>::const_iterator itExcl = m_excludeAlgoTrigByName.begin();
2190          itExcl != m_excludeAlgoTrigByName.end();
2191          ++itExcl) {
2192       if ((*itExcl) == algName) {
2193         m_excludedAlgoList.push_back(algBitNumber);
2194 
2195         LogTrace("L1GtHwValidation") << "\n Algorithm " << algName << " (bit number " << algBitNumber
2196                                      << ")\n  added to list of algorithms excluded from comparison"
2197                                      << " \n  data versus emulator by ExcludeAlgoTrigByName." << std::endl;
2198       }
2199     }
2200 
2201     // add algorithm triggers from ExcludeAlgoTrigByBit
2202     for (std::vector<int>::const_iterator itExcl = m_excludeAlgoTrigByBit.begin();
2203          itExcl != m_excludeAlgoTrigByBit.end();
2204          ++itExcl) {
2205       if ((*itExcl) == algBitNumber) {
2206         m_excludedAlgoList.push_back(algBitNumber);
2207 
2208         LogTrace("L1GtHwValidation") << "\n Algorithm " << algName << " (bit number " << algBitNumber
2209                                      << ")\n  added to list of algorithms excluded from comparison"
2210                                      << " \n  data versus emulator by ExcludeAlgoTrigByBit." << std::endl;
2211       }
2212     }
2213   }
2214 }
2215 
2216 bool L1GtHwValidation::excludedAlgo(const int& iBit) const {
2217   for (std::vector<int>::const_iterator itAlgo = m_excludedAlgoList.begin(); itAlgo != m_excludedAlgoList.end();
2218        ++itAlgo) {
2219     if (iBit == *itAlgo) {
2220       return true;
2221     }
2222   }
2223 
2224   return false;
2225 }