Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:39

0001 #include "EventFilter/GctRawToDigi/plugins/GctDigiToRaw.h"
0002 
0003 // system
0004 #include <vector>
0005 #include <sstream>
0006 #include <iostream>
0007 #include <iomanip>
0008 
0009 // framework
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 #include "FWCore/PluginManager/interface/ModuleDef.h"
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 
0014 // Raw data collection
0015 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0016 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0017 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0018 #include "DataFormats/Provenance/interface/EventID.h"
0019 
0020 // Header needed to computer CRCs
0021 #include "FWCore/Utilities/interface/CRC16.h"
0022 
0023 // GCT input data formats
0024 #include "DataFormats/L1CaloTrigger/interface/L1CaloEmCand.h"
0025 #include "DataFormats/L1CaloTrigger/interface/L1CaloRegion.h"
0026 #include "DataFormats/L1CaloTrigger/interface/L1CaloRegionDetId.h"
0027 #include "DataFormats/L1CaloTrigger/interface/L1CaloCollections.h"
0028 
0029 // GCT output data formats
0030 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctCollections.h"
0031 
0032 // Raw data collection
0033 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0034 
0035 using std::cout;
0036 using std::endl;
0037 using std::vector;
0038 
0039 GctDigiToRaw::GctDigiToRaw(const edm::ParameterSet& iConfig)
0040     : packRctEm_(iConfig.getUntrackedParameter<bool>("packRctEm", true)),
0041       packRctCalo_(iConfig.getUntrackedParameter<bool>("packRctCalo", true)),
0042       fedId_(iConfig.getParameter<int>("gctFedId")),
0043       verbose_(iConfig.getUntrackedParameter<bool>("verbose", false)),
0044       counter_(0) {
0045   LogDebug("GCT") << "GctDigiToRaw will pack FED Id " << fedId_;
0046 
0047   //register the products
0048   tokenPut_ = produces<FEDRawDataCollection>();
0049   const edm::InputTag rctInputTag = iConfig.getParameter<edm::InputTag>("rctInputLabel");
0050   const edm::InputTag gctInputTag = iConfig.getParameter<edm::InputTag>("gctInputLabel");
0051   const std::string& gctInputLabelStr = gctInputTag.label();
0052   tokenL1GctEmCand_isoEm_ = consumes<L1GctEmCandCollection>(edm::InputTag(gctInputLabelStr, "isoEm"));
0053   tokenL1GctEmCand_nonIsoEm_ = consumes<L1GctEmCandCollection>(edm::InputTag(gctInputLabelStr, "nonIsoEm"));
0054   tokenGctJetCand_cenJets_ = consumes<L1GctJetCandCollection>(edm::InputTag(gctInputLabelStr, "cenJets"));
0055   tokenGctJetCand_forJets_ = consumes<L1GctJetCandCollection>(edm::InputTag(gctInputLabelStr, "forJets"));
0056   tokenGctJetCand_tauJets_ = consumes<L1GctJetCandCollection>(edm::InputTag(gctInputLabelStr, "tauJets"));
0057   tokenGctEtTotal_ = consumes<L1GctEtTotalCollection>(gctInputTag);
0058   tokenGctEtHad_ = consumes<L1GctEtHadCollection>(gctInputTag);
0059   tokenGctEtMiss_ = consumes<L1GctEtMissCollection>(gctInputTag);
0060   tokenGctHFRingEtSums_ = consumes<L1GctHFRingEtSumsCollection>(gctInputTag);
0061   tokenGctHFBitCounts_ = consumes<L1GctHFBitCountsCollection>(gctInputTag);
0062   tokenGctHtMiss_ = consumes<L1GctHtMissCollection>(gctInputTag);
0063   tokenGctJetCounts_ = consumes<L1GctJetCountsCollection>(gctInputTag);
0064   if (packRctEm_) {
0065     tokenCaloEm_ = consumes<L1CaloEmCollection>(rctInputTag);
0066   }
0067   if (packRctCalo_) {
0068     tokenCaloRegion_ = consumes<L1CaloRegionCollection>(rctInputTag);
0069   }
0070 }
0071 
0072 //
0073 // member functions
0074 //
0075 
0076 // ------------ method called to produce the data  ------------
0077 void GctDigiToRaw::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0078   using namespace edm;
0079 
0080   auto counter = counter_++;         // To "simulate" bunch crossings for now...
0081   unsigned int bx = counter % 3564;  // What's the proper way of doing this?
0082   EventNumber_t eventNumber = iEvent.id().event();
0083 
0084   // digi to block converter
0085   // Supply bx and EvID to the packer so it can make internal capture block headers.
0086   GctFormatTranslateMCLegacy formatTranslator;
0087   formatTranslator.setPackingBxId(bx);
0088   formatTranslator.setPackingEventId(eventNumber);
0089 
0090   // get GCT digis
0091   edm::Handle<L1GctEmCandCollection> isoEm;
0092   iEvent.getByToken(tokenL1GctEmCand_isoEm_, isoEm);
0093   edm::Handle<L1GctEmCandCollection> nonIsoEm;
0094   iEvent.getByToken(tokenL1GctEmCand_nonIsoEm_, nonIsoEm);
0095   edm::Handle<L1GctJetCandCollection> cenJets;
0096   iEvent.getByToken(tokenGctJetCand_cenJets_, cenJets);
0097   edm::Handle<L1GctJetCandCollection> forJets;
0098   iEvent.getByToken(tokenGctJetCand_forJets_, forJets);
0099   edm::Handle<L1GctJetCandCollection> tauJets;
0100   iEvent.getByToken(tokenGctJetCand_tauJets_, tauJets);
0101   edm::Handle<L1GctEtTotalCollection> etTotal;
0102   iEvent.getByToken(tokenGctEtTotal_, etTotal);
0103   edm::Handle<L1GctEtHadCollection> etHad;
0104   iEvent.getByToken(tokenGctEtHad_, etHad);
0105   edm::Handle<L1GctEtMissCollection> etMiss;
0106   iEvent.getByToken(tokenGctEtMiss_, etMiss);
0107   edm::Handle<L1GctHFRingEtSumsCollection> hfRingSums;
0108   iEvent.getByToken(tokenGctHFRingEtSums_, hfRingSums);
0109   edm::Handle<L1GctHFBitCountsCollection> hfBitCounts;
0110   iEvent.getByToken(tokenGctHFBitCounts_, hfBitCounts);
0111   edm::Handle<L1GctHtMissCollection> htMiss;
0112   iEvent.getByToken(tokenGctHtMiss_, htMiss);
0113   edm::Handle<L1GctJetCountsCollection> jetCounts;
0114   iEvent.getByToken(tokenGctJetCounts_, jetCounts);
0115 
0116   // get RCT EM Cand digi
0117   bool packRctEmThisEvent = packRctEm_;
0118   edm::Handle<L1CaloEmCollection> rctEm;
0119   if (packRctEmThisEvent) {
0120     iEvent.getByToken(tokenCaloEm_, rctEm);
0121     if (rctEm.failedToGet()) {
0122       packRctEmThisEvent = false;
0123       LogDebug("GCT") << "RCT EM Candidate packing requested, but failed to get them from event!";
0124     }
0125   }
0126 
0127   // get RCT Calo region digi
0128   bool packRctCaloThisEvent = packRctCalo_;
0129   edm::Handle<L1CaloRegionCollection> rctCalo;
0130   if (packRctCaloThisEvent) {
0131     iEvent.getByToken(tokenCaloRegion_, rctCalo);
0132     if (rctCalo.failedToGet()) {
0133       packRctCaloThisEvent = false;
0134       LogDebug("GCT") << "RCT Calo Region packing requested, but failed to get them from event!";
0135     }
0136   }
0137 
0138   // create the raw data collection
0139   FEDRawDataCollection rawColl;
0140 
0141   // get the GCT buffer
0142   FEDRawData& fedRawData = rawColl.FEDData(fedId_);
0143 
0144   // set the size & make pointers to the header, beginning of payload, and footer.
0145   unsigned int rawSize = 88;  // MUST BE MULTIPLE OF 8! (slink packets are 64 bit, but using 8-bit data struct).
0146   if (packRctEmThisEvent) {
0147     rawSize += 232;
0148   }  // Space for RCT EM Cands.
0149   if (packRctCaloThisEvent) {
0150     rawSize += 800;
0151   }  // Space for RCT Calo Regions (plus a 32-bit word of padding to make divisible by 8)
0152   fedRawData.resize(rawSize);
0153   unsigned char* pHeader = fedRawData.data();
0154   unsigned char* pPayload = pHeader + 16;  //  16 = 8 for slink header + 8 for Greg's versioning header.
0155   unsigned char* pFooter = pHeader + rawSize - 8;
0156 
0157   // Write CDF header (exactly as told by Marco Zanetti)
0158   FEDHeader fedHeader(pHeader);
0159   fedHeader.set(pHeader, 1, eventNumber, bx, fedId_);  // what should the bx_ID be?
0160 
0161   // Pack GCT jet output digis
0162   formatTranslator.writeGctOutJetBlock(pPayload,
0163                                        cenJets.product(),
0164                                        forJets.product(),
0165                                        tauJets.product(),
0166                                        hfRingSums.product(),
0167                                        hfBitCounts.product(),
0168                                        htMiss.product());
0169 
0170   pPayload += 36;  //advance payload pointer
0171 
0172   // Pack GCT EM and energy sums digis.
0173   formatTranslator.writeGctOutEmAndEnergyBlock(
0174       pPayload, isoEm.product(), nonIsoEm.product(), etTotal.product(), etHad.product(), etMiss.product());
0175 
0176   pPayload += 28;  //advance payload pointer
0177 
0178   // Pack RCT EM Cands
0179   if (packRctEmThisEvent) {
0180     formatTranslator.writeRctEmCandBlocks(pPayload, rctEm.product());
0181     pPayload += 232;  //advance payload pointer
0182   }
0183 
0184   // Pack RCT Calo Regions
0185   if (packRctCaloThisEvent) {
0186     formatTranslator.writeAllRctCaloRegionBlock(pPayload, rctCalo.product());
0187   }
0188 
0189   // Write CDF footer (exactly as told by Marco Zanetti)
0190   FEDTrailer fedTrailer(pFooter);
0191   fedTrailer.set(pFooter, rawSize / 8, evf::compute_crc(pHeader, rawSize), 0, 0);
0192 
0193   // Debug output.
0194   if (verbose_) {
0195     print(fedRawData);
0196   }
0197 
0198   // Put the collection in the event.
0199   iEvent.emplace(tokenPut_, std::move(rawColl));
0200 }
0201 
0202 void GctDigiToRaw::print(FEDRawData& data) const {
0203   const unsigned char* d = data.data();
0204 
0205   for (unsigned int i = 0; i < data.size(); i = i + 4) {
0206     uint32_t w = (uint32_t)d[i] + (uint32_t)(d[i + 1] << 8) + (uint32_t)(d[i + 2] << 16) + (uint32_t)(d[i + 3] << 24);
0207     cout << std::hex << std::setw(4) << i / 4 << " " << std::setw(8) << w << endl;
0208   }
0209 }
0210 
0211 /// make this a plugin
0212 DEFINE_FWK_MODULE(GctDigiToRaw);