Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-06 07:38:28

0001 /** \class GEMDigiToRawModule
0002  *  \packer for gem
0003  *  \based on CSCDigiToRawModule
0004  *  \author J. Lee - UoS
0005  */
0006 
0007 #include "CondFormats/DataRecord/interface/GEMChMapRcd.h"
0008 #include "CondFormats/GEMObjects/interface/GEMChMap.h"
0009 #include "DataFormats/Common/interface/Handle.h"
0010 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0011 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0012 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0013 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0014 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0015 #include "DataFormats/GEMDigi/interface/GEMAMC13.h"
0016 #include "DataFormats/GEMDigi/interface/GEMDigiCollection.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/EventSetup.h"
0019 #include "FWCore/Framework/interface/Run.h"
0020 #include "FWCore/Framework/interface/global/EDProducer.h"
0021 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0024 #include "FWCore/Utilities/interface/ESGetToken.h"
0025 #include "FWCore/Utilities/interface/InputTag.h"
0026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0027 
0028 class GEMDigiToRawModule : public edm::global::EDProducer<edm::RunCache<GEMChMap>> {
0029 public:
0030   /// Constructor
0031   GEMDigiToRawModule(const edm::ParameterSet& pset);
0032 
0033   // global::EDProducer
0034   std::shared_ptr<GEMChMap> globalBeginRun(edm::Run const&, edm::EventSetup const&) const override;
0035   void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override;
0036   void globalEndRun(edm::Run const&, edm::EventSetup const&) const override{};
0037 
0038   // Fill parameters descriptions
0039   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0040 
0041 private:
0042   int event_type_;
0043   edm::EDGetTokenT<GEMDigiCollection> digi_token;
0044   edm::ESGetToken<GEMChMap, GEMChMapRcd> gemChMapToken_;
0045   bool useDBEMap_;
0046 };
0047 
0048 #include "FWCore/Framework/interface/MakerMacros.h"
0049 DEFINE_FWK_MODULE(GEMDigiToRawModule);
0050 
0051 GEMDigiToRawModule::GEMDigiToRawModule(const edm::ParameterSet& pset)
0052     : event_type_(pset.getParameter<int>("eventType")),
0053       digi_token(consumes<GEMDigiCollection>(pset.getParameter<edm::InputTag>("gemDigi"))),
0054       useDBEMap_(pset.getParameter<bool>("useDBEMap")) {
0055   produces<FEDRawDataCollection>();
0056   if (useDBEMap_) {
0057     gemChMapToken_ = esConsumes<GEMChMap, GEMChMapRcd, edm::Transition::BeginRun>();
0058   }
0059 }
0060 
0061 void GEMDigiToRawModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0062   edm::ParameterSetDescription desc;
0063   desc.add<edm::InputTag>("gemDigi", edm::InputTag("simMuonGEMDigis"));
0064   desc.add<int>("eventType", 0);
0065   desc.add<bool>("useDBEMap", false);
0066   descriptions.add("gemPackerDefault", desc);
0067 }
0068 
0069 std::shared_ptr<GEMChMap> GEMDigiToRawModule::globalBeginRun(edm::Run const&, edm::EventSetup const& iSetup) const {
0070   if (useDBEMap_) {
0071     const auto& eMap = iSetup.getData(gemChMapToken_);
0072     auto gemChMap = std::make_shared<GEMChMap>(eMap);
0073     return gemChMap;
0074   } else {
0075     // no EMap in DB, using dummy
0076     auto gemChMap = std::make_shared<GEMChMap>();
0077     gemChMap->setDummy();
0078     return gemChMap;
0079   }
0080 }
0081 
0082 void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::EventSetup const&) const {
0083   auto fedRawDataCol = std::make_unique<FEDRawDataCollection>();
0084 
0085   edm::Handle<GEMDigiCollection> gemDigis;
0086   iEvent.getByToken(digi_token, gemDigis);
0087   if (!gemDigis.isValid()) {
0088     iEvent.put(std::move(fedRawDataCol));
0089     return;
0090   }
0091 
0092   auto gemChMap = runCache(iEvent.getRun().index());
0093 
0094   std::vector<std::unique_ptr<GEMAMC13>> amc13s;
0095   amc13s.reserve(FEDNumbering::MAXGEMFEDID - FEDNumbering::MINGEMFEDID + 1);
0096 
0097   int LV1_id = iEvent.id().event();
0098   uint8_t BX_id(iEvent.bunchCrossing());
0099   int OrN = iEvent.orbitNumber();
0100 
0101   // making map of bx GEMDigiCollection
0102   // each bx will be saved as new GEMAMC13, so GEMDigiCollection needs to be split into bx
0103   std::map<int, GEMDigiCollection> gemBxMap;
0104   for (auto const& etaPart : *gemDigis) {
0105     GEMDetId gemId = etaPart.first;
0106     const GEMDigiCollection::Range& digis = etaPart.second;
0107     for (auto digi = digis.first; digi != digis.second; ++digi) {
0108       int bx = digi->bx();
0109       auto search = gemBxMap.find(bx);
0110       if (search != gemBxMap.end()) {
0111         search->second.insertDigi(gemId, *digi);
0112       } else {
0113         GEMDigiCollection newGDC;
0114         newGDC.insertDigi(gemId, *digi);
0115         gemBxMap.insert(std::pair<int, GEMDigiCollection>(bx, newGDC));
0116       }
0117     }
0118   }
0119 
0120   for (unsigned int fedId = FEDNumbering::MINGEMFEDID; fedId <= FEDNumbering::MAXGEMFEDID; ++fedId) {
0121     uint32_t amc13EvtLength = 0;
0122     std::unique_ptr<GEMAMC13> amc13 = std::make_unique<GEMAMC13>();
0123 
0124     for (uint8_t amcNum = 0; amcNum <= GEMChMap::maxAMCs_; ++amcNum) {
0125       uint32_t amcSize = 0;
0126       std::unique_ptr<GEMAMC> amc = std::make_unique<GEMAMC>();
0127 
0128       for (uint8_t gebId = 0; gebId <= GEMChMap::maxGEBs_; ++gebId) {
0129         std::unique_ptr<GEMOptoHybrid> optoH = std::make_unique<GEMOptoHybrid>();
0130 
0131         if (!gemChMap->isValidChamber(fedId, amcNum, gebId))
0132           continue;
0133 
0134         auto geb_dc = gemChMap->chamberPos(fedId, amcNum, gebId);
0135         GEMDetId cid = geb_dc.detId;
0136         int chamberType = geb_dc.chamberType;
0137 
0138         auto vfats = gemChMap->getVfats(chamberType);
0139 
0140         for (auto vfatId : vfats) {
0141           auto iEtas = gemChMap->getIEtas(chamberType, vfatId);
0142           for (auto iEta : iEtas) {
0143             GEMDetId gemId(cid.region(), cid.ring(), cid.station(), cid.layer(), cid.chamber(), iEta);
0144 
0145             for (auto const& gemBx : gemBxMap) {
0146               int bc = BX_id + gemBx.first;
0147 
0148               bool hasDigi = false;
0149               uint64_t lsData = 0;  ///<channels from 1to64
0150               uint64_t msData = 0;  ///<channels from 65to128
0151 
0152               GEMDigiCollection inBxGemDigis = gemBx.second;
0153               const GEMDigiCollection::Range& range = inBxGemDigis.get(gemId);
0154 
0155               for (GEMDigiCollection::const_iterator digiIt = range.first; digiIt != range.second; ++digiIt) {
0156                 const GEMDigi& digi = (*digiIt);
0157 
0158                 int strip = digi.strip();
0159 
0160                 hasDigi = true;
0161 
0162                 if (!gemChMap->isValidStrip(chamberType, iEta, strip))
0163                   continue;
0164                 auto chMap = gemChMap->getChannel(chamberType, iEta, strip);
0165 
0166                 if (chMap.vfatAdd != vfatId)
0167                   continue;
0168 
0169                 if (chMap.chNum < 64)
0170                   lsData |= 1UL << chMap.chNum;
0171                 else
0172                   msData |= 1UL << (chMap.chNum - 64);
0173 
0174                 LogDebug("GEMDigiToRawModule")
0175                     << "fed: " << fedId << " amc:" << int(amcNum) << " geb:" << int(gebId) << " vfat id:" << int(vfatId)
0176                     << ",type:" << chamberType << " id:" << gemId << " ch:" << chMap.chNum << " st:" << digi.strip()
0177                     << " bx:" << digi.bx();
0178               }
0179 
0180               if (!hasDigi)
0181                 continue;
0182               // only make vfat with hits
0183               amcSize += 3;
0184               int vfatVersion = (chamberType < 10) ? 2 : 3;
0185               auto vfat = std::make_unique<GEMVFAT>(vfatVersion, bc, LV1_id, vfatId, lsData, msData);
0186               optoH->addVFAT(*vfat);
0187             }
0188           }
0189         }  // end of vfats in GEB
0190 
0191         if (!optoH->vFATs()->empty()) {
0192           amcSize += 2;
0193           optoH->setChamberHeader(optoH->vFATs()->size() * 3, gebId);
0194           optoH->setChamberTrailer(LV1_id, BX_id, optoH->vFATs()->size() * 3);
0195           amc->addGEB(*optoH);
0196         }
0197       }  // end of GEB loop
0198 
0199       if (!amc->gebs()->empty()) {
0200         amcSize += 5;
0201         amc->setAMCheader1(amcSize, BX_id, LV1_id, amcNum);
0202         amc->setAMCheader2(amcNum, OrN, 1);
0203         amc->setGEMeventHeader(amc->gebs()->size(), 0);
0204         amc13->addAMCpayload(*amc);
0205         // AMC header in GEMAMC13
0206         amc13->addAMCheader(amcSize, 0, amcNum, 0);
0207         amc13EvtLength += amcSize + 1;  // AMC data size + AMC header size
0208       }
0209     }  // end of AMC loop
0210 
0211     if (!amc13->getAMCpayloads()->empty()) {
0212       // CDFHeader
0213       amc13->setCDFHeader(event_type_, LV1_id, BX_id, fedId);
0214       // AMC13header
0215       uint8_t nAMC = amc13->getAMCpayloads()->size();
0216       amc13->setAMC13Header(1, nAMC, OrN);
0217       amc13->setAMC13Trailer(BX_id, LV1_id, BX_id);
0218       //CDF trailer
0219       uint32_t EvtLength = amc13EvtLength + 4;  // 2 header and 2 trailer
0220       amc13->setCDFTrailer(EvtLength);
0221       amc13s.emplace_back(std::move(amc13));
0222     }  // finished making amc13 data
0223   }    // end of FED loop
0224 
0225   // read out amc13s into fedRawData
0226   for (const auto& amc13e : amc13s) {
0227     std::vector<uint64_t> words;
0228     words.emplace_back(amc13e->getCDFHeader());
0229     words.emplace_back(amc13e->getAMC13Header());
0230 
0231     for (const auto& w : *amc13e->getAMCheaders())
0232       words.emplace_back(w);
0233 
0234     for (const auto& amc : *amc13e->getAMCpayloads()) {
0235       words.emplace_back(amc.getAMCheader1());
0236       words.emplace_back(amc.getAMCheader2());
0237       words.emplace_back(amc.getGEMeventHeader());
0238 
0239       for (const auto& geb : *amc.gebs()) {
0240         words.emplace_back(geb.getChamberHeader());
0241 
0242         for (const auto& vfat : *geb.vFATs()) {
0243           words.emplace_back(vfat.get_fw());
0244           words.emplace_back(vfat.get_sw());
0245           words.emplace_back(vfat.get_tw());
0246         }
0247 
0248         words.emplace_back(geb.getChamberTrailer());
0249       }
0250 
0251       words.emplace_back(amc.getGEMeventTrailer());
0252       words.emplace_back(amc.getAMCTrailer());
0253     }
0254 
0255     words.emplace_back(amc13e->getAMC13Trailer());
0256     words.emplace_back(amc13e->getCDFTrailer());
0257 
0258     FEDRawData& fedRawData = fedRawDataCol->FEDData(amc13e->sourceId());
0259 
0260     int dataSize = (words.size()) * sizeof(uint64_t);
0261     fedRawData.resize(dataSize);
0262 
0263     uint64_t* w = reinterpret_cast<uint64_t*>(fedRawData.data());
0264     for (const auto& word : words) {
0265       *(w++) = word;
0266     }
0267     LogDebug("GEMDigiToRawModule") << "fedId:" << amc13e->sourceId() << " words:" << words.size();
0268   }
0269 
0270   iEvent.put(std::move(fedRawDataCol));
0271 }