File indexing completed on 2024-09-07 04:36:12
0001
0002
0003
0004
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
0031 GEMDigiToRawModule(const edm::ParameterSet& pset);
0032
0033
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
0039 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0040
0041 private:
0042 const int event_type_;
0043 const int minBunch_;
0044 const int maxBunch_;
0045 const edm::EDGetTokenT<GEMDigiCollection> digiToken_;
0046 edm::ESGetToken<GEMChMap, GEMChMapRcd> gemChMapToken_;
0047 const bool useDBEMap_;
0048 const bool simulatePulseStretching_;
0049 };
0050
0051 #include "FWCore/Framework/interface/MakerMacros.h"
0052 DEFINE_FWK_MODULE(GEMDigiToRawModule);
0053
0054 GEMDigiToRawModule::GEMDigiToRawModule(const edm::ParameterSet& pset)
0055 : event_type_(pset.getParameter<int>("eventType")),
0056 minBunch_(pset.getParameter<int>("minBunch")),
0057 maxBunch_(pset.getParameter<int>("maxBunch")),
0058 digiToken_(consumes<GEMDigiCollection>(pset.getParameter<edm::InputTag>("gemDigi"))),
0059 useDBEMap_(pset.getParameter<bool>("useDBEMap")),
0060 simulatePulseStretching_(pset.getParameter<bool>("simulatePulseStretching")) {
0061 produces<FEDRawDataCollection>();
0062 if (useDBEMap_) {
0063 gemChMapToken_ = esConsumes<GEMChMap, GEMChMapRcd, edm::Transition::BeginRun>();
0064 }
0065 }
0066
0067 void GEMDigiToRawModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0068 edm::ParameterSetDescription desc;
0069 desc.add<edm::InputTag>("gemDigi", edm::InputTag("simMuonGEMDigis"));
0070 desc.add<int>("eventType", 0);
0071
0072
0073 desc.add<int>("minBunch", -3);
0074 desc.add<int>("maxBunch", 4);
0075
0076 desc.add<bool>("useDBEMap", false);
0077 desc.add<bool>("simulatePulseStretching", false);
0078 descriptions.add("gemPackerDefault", desc);
0079 }
0080
0081 std::shared_ptr<GEMChMap> GEMDigiToRawModule::globalBeginRun(edm::Run const&, edm::EventSetup const& iSetup) const {
0082 if (useDBEMap_) {
0083 const auto& eMap = iSetup.getData(gemChMapToken_);
0084 auto gemChMap = std::make_shared<GEMChMap>(eMap);
0085 return gemChMap;
0086 } else {
0087
0088 auto gemChMap = std::make_shared<GEMChMap>();
0089 gemChMap->setDummy();
0090 return gemChMap;
0091 }
0092 }
0093
0094 void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::EventSetup const&) const {
0095 auto fedRawDataCol = std::make_unique<FEDRawDataCollection>();
0096
0097 edm::Handle<GEMDigiCollection> gemDigis;
0098 iEvent.getByToken(digiToken_, gemDigis);
0099 if (!gemDigis.isValid()) {
0100 iEvent.put(std::move(fedRawDataCol));
0101 return;
0102 }
0103
0104 auto gemChMap = runCache(iEvent.getRun().index());
0105
0106 std::vector<std::unique_ptr<GEMAMC13>> amc13s;
0107 amc13s.reserve(FEDNumbering::MAXGEMFEDID - FEDNumbering::MINGEMFEDID + 1);
0108
0109 int LV1_id = iEvent.id().event();
0110 uint8_t BX_id(iEvent.bunchCrossing());
0111 int OrN = iEvent.orbitNumber();
0112
0113
0114
0115 std::map<int, GEMDigiCollection> gemBxMap;
0116 for (auto const& etaPart : *gemDigis) {
0117 GEMDetId gemId = etaPart.first;
0118 const GEMDigiCollection::Range& digis = etaPart.second;
0119 for (auto digi = digis.first; digi != digis.second; ++digi) {
0120 int bx = digi->bx();
0121 if (simulatePulseStretching_) {
0122 if (bx < minBunch_ or bx > maxBunch_)
0123 continue;
0124 else
0125 bx = 0;
0126 }
0127 auto search = gemBxMap.find(bx);
0128 if (search != gemBxMap.end()) {
0129 search->second.insertDigi(gemId, *digi);
0130 } else {
0131 GEMDigiCollection newGDC;
0132 newGDC.insertDigi(gemId, *digi);
0133 gemBxMap.insert(std::pair<int, GEMDigiCollection>(bx, newGDC));
0134 }
0135 }
0136 }
0137
0138 for (unsigned int fedId = FEDNumbering::MINGEMFEDID; fedId <= FEDNumbering::MAXGEMFEDID; ++fedId) {
0139 uint32_t amc13EvtLength = 0;
0140 std::unique_ptr<GEMAMC13> amc13 = std::make_unique<GEMAMC13>();
0141
0142 for (uint8_t amcNum = 0; amcNum <= GEMChMap::maxAMCs_; ++amcNum) {
0143 uint32_t amcSize = 0;
0144 std::unique_ptr<GEMAMC> amc = std::make_unique<GEMAMC>();
0145
0146 for (uint8_t gebId = 0; gebId <= GEMChMap::maxGEBs_; ++gebId) {
0147 std::unique_ptr<GEMOptoHybrid> optoH = std::make_unique<GEMOptoHybrid>();
0148
0149 if (!gemChMap->isValidChamber(fedId, amcNum, gebId))
0150 continue;
0151
0152 auto geb_dc = gemChMap->chamberPos(fedId, amcNum, gebId);
0153 GEMDetId cid = geb_dc.detId;
0154 int chamberType = geb_dc.chamberType;
0155
0156 auto vfats = gemChMap->getVfats(chamberType);
0157
0158 for (auto vfatId : vfats) {
0159 auto iEtas = gemChMap->getIEtas(chamberType, vfatId);
0160 for (auto iEta : iEtas) {
0161 GEMDetId gemId(cid.region(), cid.ring(), cid.station(), cid.layer(), cid.chamber(), iEta);
0162
0163 for (auto const& gemBx : gemBxMap) {
0164 int bc = BX_id + gemBx.first;
0165
0166 bool hasDigi = false;
0167 uint64_t lsData = 0;
0168 uint64_t msData = 0;
0169
0170 GEMDigiCollection inBxGemDigis = gemBx.second;
0171 const GEMDigiCollection::Range& range = inBxGemDigis.get(gemId);
0172
0173 for (GEMDigiCollection::const_iterator digiIt = range.first; digiIt != range.second; ++digiIt) {
0174 const GEMDigi& digi = (*digiIt);
0175
0176 int strip = digi.strip();
0177
0178 hasDigi = true;
0179
0180 if (!gemChMap->isValidStrip(chamberType, iEta, strip))
0181 continue;
0182 auto chMap = gemChMap->getChannel(chamberType, iEta, strip);
0183
0184 if (chMap.vfatAdd != vfatId)
0185 continue;
0186
0187 if (chMap.chNum < 64)
0188 lsData |= 1UL << chMap.chNum;
0189 else
0190 msData |= 1UL << (chMap.chNum - 64);
0191
0192 LogDebug("GEMDigiToRawModule")
0193 << "fed: " << fedId << " amc:" << int(amcNum) << " geb:" << int(gebId) << " vfat id:" << int(vfatId)
0194 << ",type:" << chamberType << " id:" << gemId << " ch:" << chMap.chNum << " st:" << digi.strip()
0195 << " bx:" << digi.bx();
0196 }
0197
0198 if (!hasDigi)
0199 continue;
0200
0201 amcSize += 3;
0202 int vfatVersion = (chamberType < 10) ? 2 : 3;
0203 auto vfat = std::make_unique<GEMVFAT>(vfatVersion, bc, LV1_id, vfatId, lsData, msData);
0204 optoH->addVFAT(*vfat);
0205 }
0206 }
0207 }
0208
0209 if (!optoH->vFATs()->empty()) {
0210 amcSize += 2;
0211 optoH->setChamberHeader(optoH->vFATs()->size() * 3, gebId);
0212 optoH->setChamberTrailer(LV1_id, BX_id, optoH->vFATs()->size() * 3);
0213 amc->addGEB(*optoH);
0214 }
0215 }
0216
0217 if (!amc->gebs()->empty()) {
0218 amcSize += 5;
0219 amc->setAMCheader1(amcSize, BX_id, LV1_id, amcNum);
0220 amc->setAMCheader2(amcNum, OrN, 1);
0221 amc->setGEMeventHeader(amc->gebs()->size(), 0);
0222 amc13->addAMCpayload(*amc);
0223
0224 amc13->addAMCheader(amcSize, 0, amcNum, 0);
0225 amc13EvtLength += amcSize + 1;
0226 }
0227 }
0228
0229 if (!amc13->getAMCpayloads()->empty()) {
0230
0231 amc13->setCDFHeader(event_type_, LV1_id, BX_id, fedId);
0232
0233 uint8_t nAMC = amc13->getAMCpayloads()->size();
0234 amc13->setAMC13Header(1, nAMC, OrN);
0235 amc13->setAMC13Trailer(BX_id, LV1_id, BX_id);
0236
0237 uint32_t EvtLength = amc13EvtLength + 4;
0238 amc13->setCDFTrailer(EvtLength);
0239 amc13s.emplace_back(std::move(amc13));
0240 }
0241 }
0242
0243
0244 for (const auto& amc13e : amc13s) {
0245 std::vector<uint64_t> words;
0246 words.emplace_back(amc13e->getCDFHeader());
0247 words.emplace_back(amc13e->getAMC13Header());
0248
0249 for (const auto& w : *amc13e->getAMCheaders())
0250 words.emplace_back(w);
0251
0252 for (const auto& amc : *amc13e->getAMCpayloads()) {
0253 words.emplace_back(amc.getAMCheader1());
0254 words.emplace_back(amc.getAMCheader2());
0255 words.emplace_back(amc.getGEMeventHeader());
0256
0257 for (const auto& geb : *amc.gebs()) {
0258 words.emplace_back(geb.getChamberHeader());
0259
0260 for (const auto& vfat : *geb.vFATs()) {
0261 words.emplace_back(vfat.get_fw());
0262 words.emplace_back(vfat.get_sw());
0263 words.emplace_back(vfat.get_tw());
0264 }
0265
0266 words.emplace_back(geb.getChamberTrailer());
0267 }
0268
0269 words.emplace_back(amc.getGEMeventTrailer());
0270 words.emplace_back(amc.getAMCTrailer());
0271 }
0272
0273 words.emplace_back(amc13e->getAMC13Trailer());
0274 words.emplace_back(amc13e->getCDFTrailer());
0275
0276 FEDRawData& fedRawData = fedRawDataCol->FEDData(amc13e->sourceId());
0277
0278 int dataSize = (words.size()) * sizeof(uint64_t);
0279 fedRawData.resize(dataSize);
0280
0281 uint64_t* w = reinterpret_cast<uint64_t*>(fedRawData.data());
0282 for (const auto& word : words) {
0283 *(w++) = word;
0284 }
0285 LogDebug("GEMDigiToRawModule") << "fedId:" << amc13e->sourceId() << " words:" << words.size();
0286 }
0287
0288 iEvent.put(std::move(fedRawDataCol));
0289 }