Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-12-02 10:36:17

0001 // L1TGlobalProducer.cc
0002 //author:   Brian Winer - Ohio State
0003 //          Vladimir Rekovic - extend for overlap removal
0004 //          Elisa Fontanesi - extended for three-body correlation conditions
0005 
0006 #include "L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h"
0007 
0008 // system include files
0009 #include <memory>
0010 #include <iostream>
0011 #include <iomanip>
0012 #include <algorithm>
0013 
0014 #include "FWCore/Utilities/interface/typedefs.h"
0015 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/EventSetup.h"
0019 #include "FWCore/Framework/interface/ESHandle.h"
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0022 #include "FWCore/Utilities/interface/InputTag.h"
0023 #include "DataFormats/Common/interface/RefProd.h"
0024 
0025 #include "L1Trigger/L1TGlobal/interface/GlobalParamsHelper.h"
0026 
0027 #include "DataFormats/L1TGlobal/interface/GlobalAlgBlk.h"
0028 #include "DataFormats/L1TGlobal/interface/GlobalExtBlk.h"
0029 #include "DataFormats/L1TGlobal/interface/GlobalObjectMapRecord.h"
0030 
0031 #include "L1Trigger/L1TGlobal/interface/TriggerMenu.h"
0032 
0033 #include "TriggerMenuParser.h"
0034 
0035 using namespace l1t;
0036 
0037 void L1TGlobalProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0038   edm::ParameterSetDescription desc;
0039   // These parameters are part of the L1T/HLT interface, avoid changing if possible::
0040   desc.add<edm::InputTag>("MuonInputTag", edm::InputTag(""))
0041       ->setComment("InputTag for Global Muon Trigger (required parameter:  default value is invalid)");
0042   desc.add<edm::InputTag>("MuonShowerInputTag", edm::InputTag(""))
0043       ->setComment("InputTag for Global Muon Shower Trigger (required parameter:  default value is invalid)");
0044   desc.add<edm::InputTag>("EGammaInputTag", edm::InputTag(""))
0045       ->setComment("InputTag for Calo Trigger EGamma (required parameter:  default value is invalid)");
0046   desc.add<edm::InputTag>("TauInputTag", edm::InputTag(""))
0047       ->setComment("InputTag for Calo Trigger Tau (required parameter:  default value is invalid)");
0048   desc.add<edm::InputTag>("JetInputTag", edm::InputTag(""))
0049       ->setComment("InputTag for Calo Trigger Jet (required parameter:  default value is invalid)");
0050   desc.add<edm::InputTag>("EtSumInputTag", edm::InputTag(""))
0051       ->setComment("InputTag for Calo Trigger EtSum (required parameter:  default value is invalid)");
0052   desc.add<edm::InputTag>("ExtInputTag", edm::InputTag(""))
0053       ->setComment("InputTag for external conditions (not required, but recommend to specify explicitly in config)");
0054   desc.add<edm::InputTag>("AlgoBlkInputTag", edm::InputTag("hltGtStage2Digis"))
0055       ->setComment(
0056           "InputTag for unpacked Algblk (required only if GetPrescaleColumnFromData orRequireMenuToMatchAlgoBlkInput "
0057           "set to true)");
0058   desc.add<bool>("GetPrescaleColumnFromData", false)
0059       ->setComment("Get prescale column from unpacked GlobalAlgBck. Otherwise use value specified in PrescaleSet");
0060   desc.add<bool>("AlgorithmTriggersUnprescaled", false)
0061       ->setComment("not required, but recommend to specify explicitly in config");
0062   desc.add<bool>("RequireMenuToMatchAlgoBlkInput", true)
0063       ->setComment(
0064           "This requires that the L1 menu record to match the menu used to produce the inputed L1 results, should be "
0065           "true when used by the HLT to produce the object map");
0066   desc.add<bool>("AlgorithmTriggersUnmasked", false)
0067       ->setComment("not required, but recommend to specify explicitly in config");
0068 
0069   // switch for muon showers in Run-3
0070   desc.add<bool>("useMuonShowers", false);
0071 
0072   // disables resetting the prescale counters each lumisection (needed for offline)
0073   //  originally, the L1T firmware applied the reset of prescale counters at the end of every LS;
0074   //  this reset was disabled in the L1T firmware starting from run-362658 (November 25th, 2022), see
0075   //  https://github.com/cms-sw/cmssw/pull/37395#issuecomment-1323437044
0076   desc.add<bool>("resetPSCountersEachLumiSec", false);
0077 
0078   // initialise prescale counters with a semi-random value in the range [0, prescale*10^precision - 1];
0079   // if false, the prescale counters are initialised to zero
0080   desc.add<bool>("semiRandomInitialPSCounters", false);
0081 
0082   // These parameters have well defined  default values and are not currently
0083   // part of the L1T/HLT interface.  They can be cleaned up or updated at will:
0084   desc.add<bool>("ProduceL1GtDaqRecord", true);
0085   desc.add<bool>("ProduceL1GtObjectMapRecord", true);
0086   desc.add<int>("EmulateBxInEvent", 1);
0087   desc.add<int>("L1DataBxInEvent", 5);
0088   desc.add<unsigned int>("AlternativeNrBxBoardDaq", 0);
0089   desc.add<int>("BstLengthBytes", -1);
0090   desc.add<unsigned int>("PrescaleSet", 1);
0091   desc.addUntracked<int>("Verbosity", 0);
0092   desc.addUntracked<bool>("PrintL1Menu", false);
0093   desc.add<std::string>("TriggerMenuLuminosity", "startup");
0094   descriptions.add("L1TGlobalProducer", desc);
0095 }
0096 
0097 // constructors
0098 
0099 L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet)
0100     : m_muInputTag(parSet.getParameter<edm::InputTag>("MuonInputTag")),
0101       m_muShowerInputTag(parSet.getParameter<edm::InputTag>("MuonShowerInputTag")),
0102       m_egInputTag(parSet.getParameter<edm::InputTag>("EGammaInputTag")),
0103       m_tauInputTag(parSet.getParameter<edm::InputTag>("TauInputTag")),
0104       m_jetInputTag(parSet.getParameter<edm::InputTag>("JetInputTag")),
0105       m_sumInputTag(parSet.getParameter<edm::InputTag>("EtSumInputTag")),
0106       m_extInputTag(parSet.getParameter<edm::InputTag>("ExtInputTag")),
0107 
0108       m_produceL1GtDaqRecord(parSet.getParameter<bool>("ProduceL1GtDaqRecord")),
0109       m_produceL1GtObjectMapRecord(parSet.getParameter<bool>("ProduceL1GtObjectMapRecord")),
0110 
0111       m_emulateBxInEvent(parSet.getParameter<int>("EmulateBxInEvent")),
0112       m_L1DataBxInEvent(parSet.getParameter<int>("L1DataBxInEvent")),
0113 
0114       m_alternativeNrBxBoardDaq(parSet.getParameter<unsigned int>("AlternativeNrBxBoardDaq")),
0115       m_psBstLengthBytes(parSet.getParameter<int>("BstLengthBytes")),
0116 
0117       m_prescaleSet(parSet.getParameter<unsigned int>("PrescaleSet")),
0118 
0119       m_algorithmTriggersUnprescaled(parSet.getParameter<bool>("AlgorithmTriggersUnprescaled")),
0120       m_algorithmTriggersUnmasked(parSet.getParameter<bool>("AlgorithmTriggersUnmasked")),
0121 
0122       m_verbosity(parSet.getUntrackedParameter<int>("Verbosity")),
0123       m_printL1Menu(parSet.getUntrackedParameter<bool>("PrintL1Menu")),
0124       m_isDebugEnabled(edm::isDebugEnabled()),
0125       m_getPrescaleColumnFromData(parSet.getParameter<bool>("GetPrescaleColumnFromData")),
0126       m_requireMenuToMatchAlgoBlkInput(parSet.getParameter<bool>("RequireMenuToMatchAlgoBlkInput")),
0127       m_algoblkInputTag(parSet.getParameter<edm::InputTag>("AlgoBlkInputTag")),
0128       m_resetPSCountersEachLumiSec(parSet.getParameter<bool>("resetPSCountersEachLumiSec")),
0129       m_semiRandomInitialPSCounters(parSet.getParameter<bool>("semiRandomInitialPSCounters")),
0130       m_useMuonShowers(parSet.getParameter<bool>("useMuonShowers")) {
0131   m_egInputToken = consumes<BXVector<EGamma>>(m_egInputTag);
0132   m_tauInputToken = consumes<BXVector<Tau>>(m_tauInputTag);
0133   m_jetInputToken = consumes<BXVector<Jet>>(m_jetInputTag);
0134   m_sumInputToken = consumes<BXVector<EtSum>>(m_sumInputTag);
0135   m_muInputToken = consumes<BXVector<Muon>>(m_muInputTag);
0136   if (m_useMuonShowers)
0137     m_muShowerInputToken = consumes<BXVector<MuonShower>>(m_muShowerInputTag);
0138   m_extInputToken = consumes<BXVector<GlobalExtBlk>>(m_extInputTag);
0139   m_l1GtStableParToken = esConsumes<L1TGlobalParameters, L1TGlobalParametersRcd>();
0140   m_l1GtMenuToken = esConsumes<L1TUtmTriggerMenu, L1TUtmTriggerMenuRcd>();
0141   if (!(m_algorithmTriggersUnprescaled && m_algorithmTriggersUnmasked)) {
0142     m_l1GtPrescaleVetosToken = esConsumes<L1TGlobalPrescalesVetosFract, L1TGlobalPrescalesVetosFractRcd>();
0143   }
0144   if (m_getPrescaleColumnFromData || m_requireMenuToMatchAlgoBlkInput) {
0145     m_algoblkInputToken = consumes<BXVector<GlobalAlgBlk>>(m_algoblkInputTag);
0146   }
0147 
0148   if (m_verbosity) {
0149     LogTrace("L1TGlobalProducer") << "\nInput tag for muon collection from uGMT:         " << m_muInputTag
0150                                   << "\nInput tag for calorimeter jet collections from Cal: " << m_jetInputTag
0151                                   << "\nInput tag for external conditions     :         " << m_extInputTag << std::endl;
0152 
0153     LogTrace("L1TGlobalProducer") << "\nProduce the L1 uGT DAQ readout record:          " << m_produceL1GtDaqRecord
0154                                   << "\nProduce the L1 uGT Object Map record:           "
0155                                   << m_produceL1GtObjectMapRecord << " \n"
0156                                   << "\nNumber of BxInEvent to be emulated:             " << m_emulateBxInEvent << " \n"
0157                                   << "\nAlternative for number of BX in GT DAQ record:   0x" << std::hex
0158                                   << m_alternativeNrBxBoardDaq << " \n"
0159                                   << "\nRun algorithm triggers unprescaled:             "
0160                                   << m_algorithmTriggersUnprescaled
0161                                   << "\nRun algorithm triggers unmasked (all enabled):  " << m_algorithmTriggersUnmasked
0162                                   << "\n"
0163                                   << std::endl;
0164   }
0165 
0166   if ((m_emulateBxInEvent > 0) && ((m_emulateBxInEvent % 2) == 0)) {
0167     m_emulateBxInEvent = m_emulateBxInEvent - 1;
0168 
0169     if (m_verbosity) {
0170       edm::LogWarning("L1TGlobalProducer")
0171           << "\nWARNING: Number of bunch crossing to be emulated rounded to: " << m_emulateBxInEvent
0172           << "\n         The number must be an odd number!\n"
0173           << std::endl;
0174     }
0175   }
0176 
0177   if ((m_L1DataBxInEvent > 0) && ((m_L1DataBxInEvent % 2) == 0)) {
0178     m_L1DataBxInEvent = m_L1DataBxInEvent - 1;
0179 
0180     if (m_verbosity) {
0181       edm::LogWarning("L1TGlobalProducer")
0182           << "\nWARNING: Number of bunch crossing for incoming L1 Data rounded to: " << m_L1DataBxInEvent
0183           << "\n         The number must be an odd number!\n"
0184           << std::endl;
0185     }
0186   } else if (m_L1DataBxInEvent < 0) {
0187     m_L1DataBxInEvent = 1;
0188 
0189     if (m_verbosity) {
0190       edm::LogWarning("L1TGlobalProducer")
0191           << "\nWARNING: Number of bunch crossing for incoming L1 Data was changed to: " << m_L1DataBxInEvent
0192           << "\n         The number must be an odd positive number!\n"
0193           << std::endl;
0194     }
0195   }
0196 
0197   // register products
0198   if (m_produceL1GtDaqRecord) {
0199     produces<GlobalAlgBlkBxCollection>();
0200     //blwEXT produces<GlobalExtBlkBxCollection>();
0201   }
0202 
0203   if (m_produceL1GtObjectMapRecord) {
0204     produces<GlobalObjectMapRecord>();
0205   }
0206 
0207   // create new uGt Board
0208   m_uGtBrd = std::make_unique<GlobalBoard>();
0209   m_uGtBrd->setVerbosity(m_verbosity);
0210   m_uGtBrd->setResetPSCountersEachLumiSec(m_resetPSCountersEachLumiSec);
0211   m_uGtBrd->setSemiRandomInitialPSCounters(m_semiRandomInitialPSCounters);
0212 
0213   // initialize cached IDs
0214 
0215   //
0216   m_l1GtParCacheID = 0ULL;
0217   m_l1GtMenuCacheID = 0ULL;
0218 
0219   m_numberPhysTriggers = 0;
0220   m_numberDaqPartitions = 0;
0221 
0222   m_nrL1Mu = 0;
0223   m_nrL1MuShower = 0;
0224   m_nrL1EG = 0;
0225   m_nrL1Tau = 0;
0226 
0227   m_nrL1Jet = 0;
0228 
0229   m_ifMuEtaNumberBits = 0;
0230   m_ifCaloEtaNumberBits = 0;
0231 
0232   //
0233   m_l1GtParCacheID = 0ULL;
0234 
0235   m_totalBxInEvent = 0;
0236 
0237   m_activeBoardsGtDaq = 0;
0238   m_bstLengthBytes = 0;
0239 
0240   //
0241   m_l1GtBMCacheID = 0ULL;
0242 
0243   //
0244   m_l1GtPfAlgoCacheID = 0ULL;
0245 
0246   m_l1GtTmAlgoCacheID = 0ULL;
0247 
0248   m_l1GtTmVetoAlgoCacheID = 0ULL;
0249 
0250   m_currentLumi = 0;
0251 
0252   // Set default, initial, dummy prescale factor table
0253   std::vector<std::vector<double>> temp_prescaleTable;
0254 
0255   temp_prescaleTable.push_back(std::vector<double>());
0256   m_initialPrescaleFactorsAlgoTrig = temp_prescaleTable;
0257 }
0258 
0259 // destructor
0260 L1TGlobalProducer::~L1TGlobalProducer() {}
0261 
0262 // member functions
0263 
0264 // method called to produce the data
0265 void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSetup) {
0266   // process event iEvent
0267   // get / update the stable parameters from the EventSetup
0268   // local cache & check on cacheIdentifier
0269 
0270   unsigned long long l1GtParCacheID = evSetup.get<L1TGlobalParametersRcd>().cacheIdentifier();
0271 
0272   if (m_l1GtParCacheID != l1GtParCacheID) {
0273     edm::ESHandle<L1TGlobalParameters> l1GtStablePar = evSetup.getHandle(m_l1GtStableParToken);
0274     m_l1GtStablePar = l1GtStablePar.product();
0275     const GlobalParamsHelper* data = GlobalParamsHelper::readFromEventSetup(m_l1GtStablePar);
0276 
0277     // number of bx
0278     m_totalBxInEvent = data->totalBxInEvent();
0279 
0280     // number of physics triggers
0281     m_numberPhysTriggers = data->numberPhysTriggers();
0282 
0283     // number of objects of each type
0284     m_nrL1Mu = data->numberL1Mu();
0285 
0286     // There should be at most 1 muon shower object per BX
0287     // This object contains information for the in-time
0288     // showers and out-of-time showers
0289     if (m_useMuonShowers)
0290       m_nrL1MuShower = 1;
0291 
0292     // EG
0293     m_nrL1EG = data->numberL1EG();
0294 
0295     // jets
0296     m_nrL1Jet = data->numberL1Jet();
0297 
0298     // taus
0299     m_nrL1Tau = data->numberL1Tau();
0300 
0301     if (m_L1DataBxInEvent < 1)
0302       m_L1DataBxInEvent = 1;
0303     int minL1DataBxInEvent = (m_L1DataBxInEvent + 1) / 2 - m_L1DataBxInEvent;
0304     int maxL1DataBxInEvent = (m_L1DataBxInEvent + 1) / 2 - 1;
0305 
0306     // Initialize Board
0307     m_uGtBrd->init(m_numberPhysTriggers,
0308                    m_nrL1Mu,
0309                    m_nrL1MuShower,
0310                    m_nrL1EG,
0311                    m_nrL1Tau,
0312                    m_nrL1Jet,
0313                    minL1DataBxInEvent,
0314                    maxL1DataBxInEvent);
0315 
0316     //
0317     m_l1GtParCacheID = l1GtParCacheID;
0318   }
0319 
0320   if (m_emulateBxInEvent < 0) {
0321     m_emulateBxInEvent = m_totalBxInEvent;
0322   }
0323 
0324   if (m_emulateBxInEvent < 1)
0325     m_emulateBxInEvent = 1;
0326   int minEmulBxInEvent = (m_emulateBxInEvent + 1) / 2 - m_emulateBxInEvent;
0327   int maxEmulBxInEvent = (m_emulateBxInEvent + 1) / 2 - 1;
0328 
0329   // get / update the trigger menu from the EventSetup
0330   // local cache & check on cacheIdentifier
0331   unsigned long long l1GtMenuCacheID = evSetup.get<L1TUtmTriggerMenuRcd>().cacheIdentifier();
0332 
0333   if (m_l1GtMenuCacheID != l1GtMenuCacheID) {
0334     const GlobalParamsHelper* data = GlobalParamsHelper::readFromEventSetup(m_l1GtStablePar);
0335 
0336     edm::ESHandle<L1TUtmTriggerMenu> l1GtMenu = evSetup.getHandle(m_l1GtMenuToken);
0337     const L1TUtmTriggerMenu* utml1GtMenu = l1GtMenu.product();
0338 
0339     if (m_requireMenuToMatchAlgoBlkInput) {
0340       edm::Handle<BXVector<GlobalAlgBlk>> m_uGtAlgBlk;
0341       iEvent.getByToken(m_algoblkInputToken, m_uGtAlgBlk);
0342       if (m_uGtAlgBlk->size() >= 1) {
0343         if ((*m_uGtAlgBlk)[0].getL1FirmwareUUID() != static_cast<int>(utml1GtMenu->getFirmwareUuidHashed())) {
0344           throw cms::Exception("ConditionsError")
0345               << " Error L1 menu loaded in via conditions does not match the L1 actually run "
0346               << (*m_uGtAlgBlk)[0].getL1FirmwareUUID() << " vs " << utml1GtMenu->getFirmwareUuidHashed()
0347               << ". This means that the mapping of the names to the bits may be incorrect. Please check the "
0348                  "L1TUtmTriggerMenuRcd record supplied. Unless you know what you are doing, do not simply disable this "
0349                  "check via the config as this a major error and the indication of something very wrong";
0350         }
0351       }
0352     }
0353 
0354     // Instantiate Parser
0355     TriggerMenuParser gtParser = TriggerMenuParser();
0356 
0357     gtParser.setGtNumberConditionChips(data->numberChips());
0358     gtParser.setGtPinsOnConditionChip(data->pinsOnChip());
0359     gtParser.setGtOrderConditionChip(data->orderOfChip());
0360     gtParser.setGtNumberPhysTriggers(data->numberPhysTriggers());
0361 
0362     //Parse menu into emulator classes
0363     gtParser.parseCondFormats(utml1GtMenu);
0364 
0365     // transfer the condition map and algorithm map from parser to L1uGtTriggerMenu
0366     m_l1GtMenu = std::make_unique<TriggerMenu>(gtParser.gtTriggerMenuName(),
0367                                                data->numberChips(),
0368                                                gtParser.vecMuonTemplate(),
0369                                                gtParser.vecMuonShowerTemplate(),
0370                                                gtParser.vecCaloTemplate(),
0371                                                gtParser.vecEnergySumTemplate(),
0372                                                gtParser.vecExternalTemplate(),
0373                                                gtParser.vecCorrelationTemplate(),
0374                                                gtParser.vecCorrelationThreeBodyTemplate(),
0375                                                gtParser.vecCorrelationWithOverlapRemovalTemplate(),
0376                                                gtParser.corMuonTemplate(),
0377                                                gtParser.corCaloTemplate(),
0378                                                gtParser.corEnergySumTemplate());
0379 
0380     m_l1GtMenu->setGtTriggerMenuInterface(gtParser.gtTriggerMenuInterface());
0381     m_l1GtMenu->setGtTriggerMenuImplementation(gtParser.gtTriggerMenuImplementation());
0382     m_l1GtMenu->setGtScaleDbKey(gtParser.gtScaleDbKey());
0383     m_l1GtMenu->setGtScales(gtParser.gtScales());
0384     m_l1GtMenu->setGtTriggerMenuUUID(gtParser.gtTriggerMenuUUID());
0385 
0386     m_l1GtMenu->setGtAlgorithmMap(gtParser.gtAlgorithmMap());
0387     m_l1GtMenu->setGtAlgorithmAliasMap(gtParser.gtAlgorithmAliasMap());
0388 
0389     m_l1GtMenu->buildGtConditionMap();
0390 
0391     int printV = 2;
0392     if (m_printL1Menu)
0393       m_l1GtMenu->print(std::cout, printV);
0394 
0395     m_l1GtMenuCacheID = l1GtMenuCacheID;
0396   }
0397 
0398   // get / update the board maps from the EventSetup
0399   // local cache & check on cacheIdentifier
0400 
0401   /*   *** Drop L1GtBoard Maps for now
0402     typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
0403 
0404     unsigned long long l1GtBMCacheID = evSetup.get<L1GtBoardMapsRcd>().cacheIdentifier();
0405 */
0406 
0407   /*  ** Drop board mapping for now
0408     if (m_l1GtBMCacheID != l1GtBMCacheID) {
0409 
0410         edm::ESHandle< L1GtBoardMaps > l1GtBM;
0411         evSetup.get< L1GtBoardMapsRcd >().get( l1GtBM );
0412         m_l1GtBM = l1GtBM.product();
0413 
0414         m_l1GtBMCacheID = l1GtBMCacheID;
0415 
0416     }
0417    
0418 
0419     // TODO need changes in CondFormats to cache the maps
0420     const std::vector<L1GtBoard>& boardMaps = m_l1GtBM->gtBoardMaps();
0421 */
0422   // get / update the prescale factors from the EventSetup
0423   // local cache & check on cacheIdentifier
0424 
0425   // Only get event record if not unprescaled and not unmasked
0426   if (!(m_algorithmTriggersUnprescaled && m_algorithmTriggersUnmasked)) {
0427     unsigned long long l1GtPfAlgoCacheID = evSetup.get<L1TGlobalPrescalesVetosFractRcd>().cacheIdentifier();
0428 
0429     if (m_l1GtPfAlgoCacheID != l1GtPfAlgoCacheID) {
0430       edm::ESHandle<L1TGlobalPrescalesVetosFract> l1GtPrescalesFractVetoes =
0431           evSetup.getHandle(m_l1GtPrescaleVetosToken);
0432       const L1TGlobalPrescalesVetosFract* es = l1GtPrescalesFractVetoes.product();
0433       m_l1GtPrescalesVetosFract = PrescalesVetosFractHelper::readFromEventSetup(es);
0434 
0435       m_prescaleFactorsAlgoTrig = &(m_l1GtPrescalesVetosFract->prescaleTable());
0436       m_triggerMaskVetoAlgoTrig = &(m_l1GtPrescalesVetosFract->triggerMaskVeto());
0437 
0438       m_l1GtPfAlgoCacheID = l1GtPfAlgoCacheID;
0439     }
0440     if (m_getPrescaleColumnFromData &&
0441         (m_currentLumi != iEvent.luminosityBlock())) {  // get prescale column from unpacked data
0442 
0443       m_currentLumi = iEvent.luminosityBlock();
0444 
0445       edm::Handle<BXVector<GlobalAlgBlk>> m_uGtAlgBlk;
0446       iEvent.getByToken(m_algoblkInputToken, m_uGtAlgBlk);
0447 
0448       if (m_uGtAlgBlk.isValid() && !m_uGtAlgBlk->isEmpty(0)) {
0449         std::vector<GlobalAlgBlk>::const_iterator algBlk = m_uGtAlgBlk->begin(0);
0450         m_prescaleSet = static_cast<unsigned int>(algBlk->getPreScColumn());
0451       } else {
0452         m_prescaleSet = 1;
0453         edm::LogError("L1TGlobalProduce")
0454             << "Could not find valid algo block. Setting prescale column to 1" << std::endl;
0455       }
0456     }
0457   } else {
0458     // Set Prescale factors to initial dummy values
0459     m_prescaleSet = 0;
0460     m_prescaleFactorsAlgoTrig = &m_initialPrescaleFactorsAlgoTrig;
0461     m_triggerMaskAlgoTrig = &m_initialTriggerMaskAlgoTrig;
0462     m_triggerMaskVetoAlgoTrig = &m_initialTriggerMaskVetoAlgoTrig;
0463   }
0464 
0465   // get / update the trigger mask from the EventSetup
0466   // local cache & check on cacheIdentifier
0467 
0468   /*  **** For now Leave out Masks  *****
0469     unsigned long long l1GtTmAlgoCacheID =
0470         evSetup.get<L1GtTriggerMaskAlgoTrigRcd>().cacheIdentifier();
0471 
0472     if (m_l1GtTmAlgoCacheID != l1GtTmAlgoCacheID) {
0473 
0474         edm::ESHandle< L1GtTriggerMask > l1GtTmAlgo;
0475         evSetup.get< L1GtTriggerMaskAlgoTrigRcd >().get( l1GtTmAlgo );
0476         m_l1GtTmAlgo = l1GtTmAlgo.product();
0477 
0478         m_triggerMaskAlgoTrig = m_l1GtTmAlgo->gtTriggerMask();
0479 
0480         m_l1GtTmAlgoCacheID = l1GtTmAlgoCacheID;
0481 
0482     }
0483 */
0484 
0485   /*  **** For now Leave out Veto Masks  *****
0486     unsigned long long l1GtTmVetoAlgoCacheID =
0487         evSetup.get<L1GtTriggerMaskVetoAlgoTrigRcd>().cacheIdentifier();
0488 
0489     if (m_l1GtTmVetoAlgoCacheID != l1GtTmVetoAlgoCacheID) {
0490 
0491         edm::ESHandle< L1GtTriggerMask > l1GtTmVetoAlgo;
0492         evSetup.get< L1GtTriggerMaskVetoAlgoTrigRcd >().get( l1GtTmVetoAlgo );
0493         m_l1GtTmVetoAlgo = l1GtTmVetoAlgo.product();
0494 
0495         m_triggerMaskVetoAlgoTrig = m_l1GtTmVetoAlgo->gtTriggerMask();
0496 
0497         m_l1GtTmVetoAlgoCacheID = l1GtTmVetoAlgoCacheID;
0498 
0499     }
0500 */
0501 
0502   // ******  Board Maps Need to be redone....hard code for now ******
0503   // loop over blocks in the GT DAQ record receiving data, count them if they are active
0504   // all board type are defined in CondFormats/L1TObjects/L1GtFwd
0505   // &
0506   // set the active flag for each object type received from GMT and GCT
0507   // all objects in the GT system
0508 
0509   //
0510   bool receiveMu = true;
0511   bool receiveMuShower = true;
0512   bool receiveEG = true;
0513   bool receiveTau = true;
0514   bool receiveJet = true;
0515   bool receiveEtSums = true;
0516   bool receiveExt = true;
0517 
0518   /*  *** Boards need redefining *****
0519     for (CItBoardMaps
0520             itBoard = boardMaps.begin();
0521             itBoard != boardMaps.end(); ++itBoard) {
0522 
0523         int iPosition = itBoard->gtPositionDaqRecord();
0524         if (iPosition > 0) {
0525 
0526             int iActiveBit = itBoard->gtBitDaqActiveBoards();
0527             bool activeBoard = false;
0528 
0529             if (iActiveBit >= 0) {
0530                 activeBoard = m_activeBoardsGtDaq & (1 << iActiveBit);
0531             }
0532 
0533             // use board if: in the record, but not in ActiveBoardsMap (iActiveBit < 0)
0534             //               in the record and ActiveBoardsMap, and active
0535             if ((iActiveBit < 0) || activeBoard) {
0536 
0537 // ******  Decide what board manipulation (if any we want here)
0538 
0539             }
0540         }
0541 
0542     }
0543 */
0544 
0545   // Produce the Output Records for the GT
0546   std::unique_ptr<GlobalAlgBlkBxCollection> uGtAlgRecord(
0547       new GlobalAlgBlkBxCollection(0, minEmulBxInEvent, maxEmulBxInEvent));
0548 
0549   // * produce the GlobalObjectMapRecord
0550   std::unique_ptr<GlobalObjectMapRecord> gtObjectMapRecord(new GlobalObjectMapRecord());
0551 
0552   // fill the boards not depending on the BxInEvent in the L1 GT DAQ record
0553   // GMT, PSB and FDL depend on BxInEvent
0554 
0555   // fill in emulator the same bunch crossing (12 bits - hardwired number of bits...)
0556   // and the same local bunch crossing for all boards
0557   int bxCross = iEvent.bunchCrossing();
0558   uint16_t bxCrossHw = 0;
0559   if ((bxCross & 0xFFF) == bxCross) {
0560     bxCrossHw = static_cast<uint16_t>(bxCross);
0561   } else {
0562     bxCrossHw = 0;  // Bx number too large, set to 0!
0563     if (m_verbosity) {
0564       LogDebug("L1TGlobalProducer") << "\nBunch cross number [hex] = " << std::hex << bxCross
0565                                     << "\n  larger than 12 bits. Set to 0! \n"
0566                                     << std::dec << std::endl;
0567     }
0568   }
0569   LogDebug("L1TGlobalProducer") << "HW BxCross " << bxCrossHw << std::endl;
0570 
0571   // get the prescale factor from the configuration for now
0572   // prescale set index counts from zero
0573   unsigned int pfAlgoSetIndex = m_prescaleSet;
0574 
0575   auto max = (*m_prescaleFactorsAlgoTrig).size() - 1;
0576   if (pfAlgoSetIndex > max) {
0577     edm::LogWarning("L1TGlobalProducer") << "\nAttempting to access prescale algo set: " << m_prescaleSet
0578                                          << "\nNumber of prescale algo sets available: 0.." << max
0579                                          << "Setting former to latter." << std::endl;
0580     pfAlgoSetIndex = max;
0581   }
0582 
0583   const std::vector<double>& prescaleFactorsAlgoTrig = (*m_prescaleFactorsAlgoTrig).at(pfAlgoSetIndex);
0584 
0585   // For now, set masks according to prescale value of 0
0586   m_initialTriggerMaskAlgoTrig.clear();
0587   for (unsigned int iAlgo = 0; iAlgo < prescaleFactorsAlgoTrig.size(); iAlgo++) {
0588     unsigned int value = prescaleFactorsAlgoTrig[iAlgo];
0589     value = (value == 0) ? 0 : 1;
0590     m_initialTriggerMaskAlgoTrig.push_back(value);
0591   }
0592   m_triggerMaskAlgoTrig = &m_initialTriggerMaskAlgoTrig;
0593 
0594   const std::vector<unsigned int>& triggerMaskAlgoTrig = *m_triggerMaskAlgoTrig;
0595   const std::vector<int>& triggerMaskVetoAlgoTrig = *m_triggerMaskVetoAlgoTrig;
0596 
0597   LogDebug("L1TGlobalProducer") << "Size of prescale vector" << prescaleFactorsAlgoTrig.size() << std::endl;
0598 
0599   // Load the calorimeter input onto the uGt Board
0600   m_uGtBrd->receiveCaloObjectData(iEvent,
0601                                   m_egInputToken,
0602                                   m_tauInputToken,
0603                                   m_jetInputToken,
0604                                   m_sumInputToken,
0605                                   receiveEG,
0606                                   m_nrL1EG,
0607                                   receiveTau,
0608                                   m_nrL1Tau,
0609                                   receiveJet,
0610                                   m_nrL1Jet,
0611                                   receiveEtSums);
0612 
0613   m_uGtBrd->receiveMuonObjectData(iEvent, m_muInputToken, receiveMu, m_nrL1Mu);
0614 
0615   if (m_useMuonShowers)
0616     m_uGtBrd->receiveMuonShowerObjectData(iEvent, m_muShowerInputToken, receiveMuShower, m_nrL1MuShower);
0617 
0618   m_uGtBrd->receiveExternalData(iEvent, m_extInputToken, receiveExt);
0619 
0620   // loop over BxInEvent
0621   for (int iBxInEvent = minEmulBxInEvent; iBxInEvent <= maxEmulBxInEvent; ++iBxInEvent) {
0622     //  run GTL
0623     LogDebug("L1TGlobalProducer") << "\nL1TGlobalProducer : running GTL  for bx = " << iBxInEvent << "\n" << std::endl;
0624 
0625     //  Run the GTL for this BX
0626     m_uGtBrd->runGTL(iEvent,
0627                      evSetup,
0628                      m_l1GtMenu.get(),
0629                      m_produceL1GtObjectMapRecord,
0630                      iBxInEvent,
0631                      gtObjectMapRecord,
0632                      m_numberPhysTriggers,
0633                      m_nrL1Mu,
0634                      m_nrL1MuShower,
0635                      m_nrL1EG,
0636                      m_nrL1Tau,
0637                      m_nrL1Jet);
0638 
0639     //  run FDL
0640     LogDebug("L1TGlobalProducer") << "\nL1TGlobalProducer : running FDL for bx = " << iBxInEvent << "\n" << std::endl;
0641 
0642     //  Run the Final Decision Logic for this BX
0643     m_uGtBrd->runFDL(iEvent,
0644                      iBxInEvent,
0645                      m_totalBxInEvent,
0646                      m_numberPhysTriggers,
0647                      prescaleFactorsAlgoTrig,
0648                      triggerMaskAlgoTrig,
0649                      triggerMaskVetoAlgoTrig,
0650                      m_algorithmTriggersUnprescaled,
0651                      m_algorithmTriggersUnmasked);
0652 
0653     // Fill in the DAQ Records
0654     if (m_produceL1GtDaqRecord) {
0655       m_uGtBrd->fillAlgRecord(iBxInEvent,
0656                               uGtAlgRecord,
0657                               m_prescaleSet,
0658                               m_l1GtMenu->gtTriggerMenuUUID(),
0659                               m_l1GtMenu->gtTriggerMenuImplementation());
0660     }
0661 
0662   }  //End Loop over Bx
0663 
0664   // Add explicit reset of Board
0665   m_uGtBrd->reset();
0666 
0667   if (m_verbosity && m_isDebugEnabled) {
0668     std::ostringstream myCoutStream;
0669 
0670     for (int bx = minEmulBxInEvent; bx < maxEmulBxInEvent; bx++) {
0671       /// Needs error checking that something exists at this bx.
0672       (uGtAlgRecord->at(bx, 0)).print(myCoutStream);
0673     }
0674 
0675     LogTrace("L1TGlobalProducer") << "\n The following L1 GT DAQ readout record was produced:\n"
0676                                   << myCoutStream.str() << "\n"
0677                                   << std::endl;
0678 
0679     myCoutStream.str("");
0680     myCoutStream.clear();
0681 
0682     const std::vector<GlobalObjectMap> objMapVec = gtObjectMapRecord->gtObjectMap();
0683 
0684     for (std::vector<GlobalObjectMap>::const_iterator it = objMapVec.begin(); it != objMapVec.end(); ++it) {
0685       (*it).print(myCoutStream);
0686     }
0687 
0688     LogDebug("L1TGlobalProducer") << "Test gtObjectMapRecord in L1TGlobalProducer \n\n"
0689                                   << myCoutStream.str() << "\n\n"
0690                                   << std::endl;
0691 
0692     myCoutStream.str("");
0693     myCoutStream.clear();
0694   }
0695 
0696   // register products
0697   if (m_produceL1GtDaqRecord) {
0698     iEvent.put(std::move(uGtAlgRecord));
0699   }
0700 
0701   if (m_produceL1GtObjectMapRecord) {
0702     iEvent.put(std::move(gtObjectMapRecord));
0703   }
0704 }
0705 
0706 //define this as a plug-in
0707 #include "FWCore/PluginManager/interface/ModuleDef.h"
0708 #include "FWCore/Framework/interface/MakerMacros.h"
0709 #include <cstdint>
0710 DEFINE_FWK_MODULE(L1TGlobalProducer);