Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:00:07

0001 // -*- C++ -*-
0002 //
0003 // Package:    EventFilter/L1TRawToDigi
0004 // Class:      L1TRawToDigi
0005 //
0006 /**\class L1TRawToDigi L1TRawToDigi.cc EventFilter/L1TRawToDigi/plugins/L1TRawToDigi.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Matthias Wolf
0015 //         Created:  Mon, 10 Feb 2014 14:29:40 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <iostream>
0021 #include <iomanip>
0022 #include <memory>
0023 
0024 // user include files
0025 #include "FWCore/Framework/interface/Frameworkfwd.h"
0026 #include "FWCore/Framework/interface/stream/EDProducer.h"
0027 #include "FWCore/Framework/interface/Event.h"
0028 #include "FWCore/Framework/interface/MakerMacros.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030 #include "FWCore/Utilities/interface/InputTag.h"
0031 
0032 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0033 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0034 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0035 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0036 
0037 #include "EventFilter/L1TRawToDigi/interface/AMC13Spec.h"
0038 #include "EventFilter/L1TRawToDigi/interface/Block.h"
0039 
0040 #include "PackingSetupFactory.h"
0041 
0042 #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TStage2Layer2Constants.h"
0043 
0044 namespace l1t {
0045   class L1TRawToDigi : public edm::stream::EDProducer<> {
0046   public:
0047     explicit L1TRawToDigi(const edm::ParameterSet&);
0048     ~L1TRawToDigi() override;
0049 
0050     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0051 
0052   private:
0053     void produce(edm::Event&, const edm::EventSetup&) override;
0054 
0055     void beginRun(edm::Run const&, edm::EventSetup const&) override{};
0056     void endRun(edm::Run const&, edm::EventSetup const&) override{};
0057     void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override{};
0058     void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override{};
0059 
0060     // ----------member data ---------------------------
0061     edm::EDGetTokenT<FEDRawDataCollection> fedData_;
0062     std::vector<int> fedIds_;
0063     unsigned int minFeds_;
0064     unsigned int fwId_;
0065     unsigned int dmxFwId_;
0066     bool fwOverride_;
0067 
0068     std::unique_ptr<PackingSetup> prov_;
0069 
0070     // header and trailer sizes in chars
0071     int slinkHeaderSize_;
0072     int slinkTrailerSize_;
0073     int amcHeaderSize_;
0074     int amcTrailerSize_;
0075     int amc13HeaderSize_;
0076     int amc13TrailerSize_;
0077 
0078     bool tmtCheck_;
0079 
0080     bool ctp7_mode_;
0081     bool mtf7_mode_;
0082     bool debug_;
0083     int warnsa_;
0084     int warnsb_;
0085   };
0086 }  // namespace l1t
0087 
0088 std::ostream& operator<<(std::ostream& o, const l1t::BlockHeader& h) {
0089   o << "L1T Block Header " << h.getID() << " with size " << h.getSize();
0090   return o;
0091 };
0092 
0093 namespace l1t {
0094   L1TRawToDigi::L1TRawToDigi(const edm::ParameterSet& config)
0095       : fedIds_(config.getParameter<std::vector<int>>("FedIds")),
0096         minFeds_(config.getParameter<unsigned int>("MinFeds")),
0097         fwId_(config.getParameter<unsigned int>("FWId")),
0098         dmxFwId_(config.getParameter<unsigned int>("DmxFWId")),
0099         fwOverride_(config.getParameter<bool>("FWOverride")),
0100         tmtCheck_(config.getParameter<bool>("TMTCheck")),
0101         ctp7_mode_(config.getUntrackedParameter<bool>("CTP7")),
0102         mtf7_mode_(config.getUntrackedParameter<bool>("MTF7")) {
0103     fedData_ = consumes<FEDRawDataCollection>(config.getParameter<edm::InputTag>("InputLabel"));
0104 
0105     if (ctp7_mode_ and mtf7_mode_) {
0106       throw cms::Exception("L1TRawToDigi") << "Can only use one unpacking mode concurrently!";
0107     }
0108 
0109     prov_ = PackingSetupFactory::get()->make(config.getParameter<std::string>("Setup"));
0110     prov_->registerProducts(producesCollector());
0111 
0112     slinkHeaderSize_ = config.getUntrackedParameter<int>("lenSlinkHeader");
0113     slinkTrailerSize_ = config.getUntrackedParameter<int>("lenSlinkTrailer");
0114     amcHeaderSize_ = config.getUntrackedParameter<int>("lenAMCHeader");
0115     amcTrailerSize_ = config.getUntrackedParameter<int>("lenAMCTrailer");
0116     amc13HeaderSize_ = config.getUntrackedParameter<int>("lenAMC13Header");
0117     amc13TrailerSize_ = config.getUntrackedParameter<int>("lenAMC13Trailer");
0118 
0119     debug_ = config.getUntrackedParameter<bool>("debug");
0120     warnsa_ = 0;
0121     warnsb_ = 0;
0122   }
0123 
0124   L1TRawToDigi::~L1TRawToDigi() {}
0125 
0126   //
0127   // member functions
0128   //
0129 
0130   // ------------ method called to produce the data  ------------
0131   void L1TRawToDigi::produce(edm::Event& event, const edm::EventSetup& setup) {
0132     using namespace edm;
0133 
0134     std::unique_ptr<UnpackerCollections> coll = prov_->getCollections(event);
0135 
0136     edm::Handle<FEDRawDataCollection> feds;
0137     event.getByToken(fedData_, feds);
0138 
0139     if (!feds.isValid()) {
0140       LogError("L1T") << "Cannot unpack: no FEDRawDataCollection found";
0141       return;
0142     }
0143 
0144     unsigned valid_count = 0;
0145     for (const auto& fedId : fedIds_) {
0146       const FEDRawData& l1tRcd = feds->FEDData(fedId);
0147 
0148       LogDebug("L1T") << "Found FEDRawDataCollection with ID " << fedId << " and size " << l1tRcd.size();
0149 
0150       if ((int)l1tRcd.size() < slinkHeaderSize_ + slinkTrailerSize_ + amc13HeaderSize_ + amc13TrailerSize_ +
0151                                    amcHeaderSize_ + amcTrailerSize_) {
0152         if (l1tRcd.size() > 0) {
0153           LogError("L1T") << "Cannot unpack: invalid L1T raw data (size = " << l1tRcd.size() << ") for ID " << fedId
0154                           << ". Returning empty collections!";
0155         } else if (warnsa_ < 5) {
0156           warnsa_++;
0157           LogInfo("L1T") << "During unpacking, encountered empty L1T raw data (size = " << l1tRcd.size()
0158                          << ") for FED ID " << fedId << ".";
0159         }
0160         continue;
0161       } else {
0162         valid_count++;
0163       }
0164 
0165       const unsigned char* data = l1tRcd.data();
0166       FEDHeader header(data);
0167 
0168       if (header.check()) {
0169         LogDebug("L1T") << "Found SLink header:"
0170                         << " Trigger type " << header.triggerType() << " L1 event ID " << header.lvl1ID()
0171                         << " BX Number " << header.bxID() << " FED source " << header.sourceID() << " FED version "
0172                         << header.version();
0173       } else {
0174         LogWarning("L1T") << "Did not find a SLink header!";
0175       }
0176 
0177       FEDTrailer trailer(data + (l1tRcd.size() - slinkTrailerSize_));
0178 
0179       if (trailer.check()) {
0180         LogDebug("L1T") << "Found SLink trailer:"
0181                         << " Length " << trailer.fragmentLength() << " CRC " << trailer.crc() << " Status "
0182                         << trailer.evtStatus() << " Throttling bits " << trailer.ttsBits();
0183       } else {
0184         LogWarning("L1T") << "Did not find a SLink trailer!";
0185       }
0186 
0187       // FIXME Hard-coded firmware version for first 74x MC campaigns.
0188       // Will account for differences in the AMC payload, MP7 payload,
0189       // and unpacker setup.
0190       bool legacy_mc = fwOverride_ && ((fwId_ >> 24) == 0xff);
0191 
0192       amc13::Packet packet;
0193       if (!packet.parse((const uint64_t*)data,
0194                         (const uint64_t*)(data + slinkHeaderSize_),
0195                         (l1tRcd.size() - slinkHeaderSize_ - slinkTrailerSize_) / 8,
0196                         header.lvl1ID(),
0197                         header.bxID(),
0198                         legacy_mc,
0199                         mtf7_mode_)) {
0200         LogError("L1T") << "Could not extract AMC13 Packet.";
0201         return;
0202       }
0203 
0204       for (auto& amc : packet.payload()) {
0205         if (amc.size() == 0)
0206           continue;
0207 
0208         auto payload64 = amc.data();
0209         const uint32_t* start = (const uint32_t*)payload64.get();
0210         // Want to have payload size in 32 bit words, but AMC measures
0211         // it in 64 bit words → factor 2.
0212         const uint32_t* end = start + (amc.size() * 2);
0213 
0214         std::unique_ptr<Payload> payload;
0215         if (ctp7_mode_) {
0216           LogDebug("L1T") << "Using CTP7 mode";
0217           // CTP7 uses userData in AMC header
0218           payload = std::make_unique<CTP7Payload>(start, end, amc.header());
0219         } else if (mtf7_mode_) {
0220           LogDebug("L1T") << "Using MTF7 mode";
0221           payload = std::make_unique<MTF7Payload>(start, end);
0222         } else {
0223           LogDebug("L1T") << "Using MP7 mode";
0224           payload = std::make_unique<MP7Payload>(start, end, legacy_mc);
0225         }
0226         unsigned fw = payload->getAlgorithmFWVersion();
0227         unsigned board = amc.blockHeader().getBoardID();
0228         unsigned amc_no = amc.blockHeader().getAMCNumber();
0229 
0230         // Let parameterset value override FW version
0231         if (fwOverride_) {
0232           if (fedId == 1360)
0233             fw = fwId_;
0234           else if (fedId == 1366)
0235             fw = dmxFwId_;
0236         }
0237 
0238         auto unpackers = prov_->getUnpackers(fedId, board, amc_no, fw);
0239 
0240         // getBlock() returns a non-null unique_ptr on success
0241         std::unique_ptr<Block> block;
0242         while ((block = payload->getBlock()).get()) {
0243           // only unpack the Calo Layer 2 MP TMT node if it has processed this BX
0244           unsigned tmtId = board - l1t::stage2::layer2::mp::offsetBoardId + 1;
0245           unsigned bxId = header.bxID();
0246           unsigned unpackTMT = (!tmtCheck_ || ((tmtId - 1) == ((bxId - 1 + 3) % 9)));
0247           unsigned isCaloL2TMT =
0248               (fedId == l1t::stage2::layer2::fedId && (amc_no != l1t::stage2::layer2::demux::amcSlotNum));
0249 
0250           if (!isCaloL2TMT || unpackTMT) {
0251             if (debug_) {
0252               std::cout << ">>> block to unpack <<<" << std::endl
0253                         << "hdr:  " << std::hex << std::setw(8) << std::setfill('0') << block->header().raw()
0254                         << std::dec << " (ID " << block->header().getID() << ", size " << block->header().getSize()
0255                         << ", CapID 0x" << std::hex << std::setw(2) << std::setfill('0') << block->header().getCapID()
0256                         << ")" << std::dec << std::endl;
0257               for (const auto& word : block->payload()) {
0258                 if (debug_)
0259                   std::cout << "data: " << std::hex << std::setw(8) << std::setfill('0') << word << std::dec
0260                             << std::endl;
0261               }
0262             }
0263 
0264             auto unpacker = unpackers.find(block->header().getID());
0265 
0266             block->amc(amc.header());
0267 
0268             if (unpacker == unpackers.end()) {
0269               LogDebug("L1T") << "Cannot find an unpacker for"
0270                               << "\n\tblock: ID " << block->header().getID() << ", size " << block->header().getSize()
0271                               << "\n\tAMC: # " << amc_no << ", board ID 0x" << std::hex << board << std::dec
0272                               << "\n\tFED ID " << fedId << ", and FW ID " << fw;
0273               // TODO Handle error
0274             } else if (!unpacker->second->unpack(*block, coll.get())) {
0275               LogDebug("L1T") << "Error unpacking data for block ID " << block->header().getID() << ", AMC # " << amc_no
0276                               << ", board ID " << board << ", FED ID " << fedId << ", and FW ID " << fw << "!";
0277               // TODO Handle error
0278             }
0279           }
0280         }
0281       }
0282     }
0283     if (valid_count < minFeds_) {
0284       if (warnsb_ < 5) {
0285         warnsb_++;
0286         LogWarning("L1T") << "Unpacked " << valid_count << " non-empty FED IDs but minimum is set to " << minFeds_
0287                           << "\n";
0288       }
0289     }
0290   }
0291 
0292   // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0293   void L1TRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0294     edm::ParameterSetDescription desc;
0295     // These parameters are part of the L1T/HLT interface, avoid changing if possible:
0296     desc.add<std::vector<int>>("FedIds", {})->setComment("required parameter:  default value is invalid");
0297     desc.add<std::string>("Setup", "")->setComment("required parameter:  default value is invalid");
0298     // These parameters have well defined  default values and are not currently
0299     // part of the L1T/HLT interface.  They can be cleaned up or updated at will:
0300     desc.add<unsigned int>("FWId", 0)->setComment(
0301         "Ignored unless FWOverride is true.  Calo Stage1:  32 bits: if the first eight bits are 0xff, will read the "
0302         "74x MC format.\n");
0303     desc.add<unsigned int>("DmxFWId", 0)
0304         ->setComment(
0305             "Ignored unless FWOverride is true.  Calo Stage1:  32 bits: if the first eight bits are 0xff, will read "
0306             "the 74x MC format.\n");
0307     desc.add<bool>("FWOverride", false)->setComment("Firmware version should be taken as FWId parameters");
0308     desc.add<bool>("TMTCheck", true)->setComment("Flag for turning on/off Calo Layer 2 TMT node check");
0309     desc.addUntracked<bool>("CTP7", false);
0310     desc.addUntracked<bool>("MTF7", false);
0311     desc.add<edm::InputTag>("InputLabel", edm::InputTag("rawDataCollector"));
0312     desc.addUntracked<int>("lenSlinkHeader", 8);
0313     desc.addUntracked<int>("lenSlinkTrailer", 8);
0314     desc.addUntracked<int>("lenAMCHeader", 8);
0315     desc.addUntracked<int>("lenAMCTrailer", 0);
0316     desc.addUntracked<int>("lenAMC13Header", 8);
0317     desc.addUntracked<int>("lenAMC13Trailer", 8);
0318     desc.addUntracked<bool>("debug", false)->setComment("turn on verbose output");
0319     desc.add<unsigned int>("MinFeds", 0)
0320         ->setComment("optional parameter:  warn if less than MinFeds non-empty FED ids unpacked.");
0321     descriptions.add("l1tRawToDigi", desc);
0322   }
0323 }  // namespace l1t
0324 
0325 using namespace l1t;
0326 //define this as a plug-in
0327 DEFINE_FWK_MODULE(L1TRawToDigi);