Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-11 22:51:05

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     // ----------member data ---------------------------
0056     edm::EDGetTokenT<FEDRawDataCollection> fedData_;
0057     std::vector<int> fedIds_;
0058     unsigned int minFeds_;
0059     unsigned int fwId_;
0060     unsigned int dmxFwId_;
0061     bool fwOverride_;
0062 
0063     std::unique_ptr<PackingSetup> prov_;
0064 
0065     // header and trailer sizes in chars
0066     int slinkHeaderSize_;
0067     int slinkTrailerSize_;
0068     int amcHeaderSize_;
0069     int amcTrailerSize_;
0070     int amc13HeaderSize_;
0071     int amc13TrailerSize_;
0072 
0073     bool tmtCheck_;
0074 
0075     bool ctp7_mode_;
0076     bool mtf7_mode_;
0077     bool debug_;
0078     int warnsa_;
0079     int warnsb_;
0080   };
0081 }  // namespace l1t
0082 
0083 std::ostream& operator<<(std::ostream& o, const l1t::BlockHeader& h) {
0084   o << "L1T Block Header " << h.getID() << " with size " << h.getSize();
0085   return o;
0086 };
0087 
0088 namespace l1t {
0089   L1TRawToDigi::L1TRawToDigi(const edm::ParameterSet& config)
0090       : fedIds_(config.getParameter<std::vector<int>>("FedIds")),
0091         minFeds_(config.getParameter<unsigned int>("MinFeds")),
0092         fwId_(config.getParameter<unsigned int>("FWId")),
0093         dmxFwId_(config.getParameter<unsigned int>("DmxFWId")),
0094         fwOverride_(config.getParameter<bool>("FWOverride")),
0095         tmtCheck_(config.getParameter<bool>("TMTCheck")),
0096         ctp7_mode_(config.getUntrackedParameter<bool>("CTP7")),
0097         mtf7_mode_(config.getUntrackedParameter<bool>("MTF7")) {
0098     fedData_ = consumes<FEDRawDataCollection>(config.getParameter<edm::InputTag>("InputLabel"));
0099 
0100     if (ctp7_mode_ and mtf7_mode_) {
0101       throw cms::Exception("L1TRawToDigi") << "Can only use one unpacking mode concurrently!";
0102     }
0103 
0104     prov_ = PackingSetupFactory::get()->make(config.getParameter<std::string>("Setup"));
0105     prov_->registerProducts(producesCollector());
0106 
0107     slinkHeaderSize_ = config.getUntrackedParameter<int>("lenSlinkHeader");
0108     slinkTrailerSize_ = config.getUntrackedParameter<int>("lenSlinkTrailer");
0109     amcHeaderSize_ = config.getUntrackedParameter<int>("lenAMCHeader");
0110     amcTrailerSize_ = config.getUntrackedParameter<int>("lenAMCTrailer");
0111     amc13HeaderSize_ = config.getUntrackedParameter<int>("lenAMC13Header");
0112     amc13TrailerSize_ = config.getUntrackedParameter<int>("lenAMC13Trailer");
0113 
0114     debug_ = config.getUntrackedParameter<bool>("debug");
0115     warnsa_ = 0;
0116     warnsb_ = 0;
0117   }
0118 
0119   L1TRawToDigi::~L1TRawToDigi() {}
0120 
0121   //
0122   // member functions
0123   //
0124 
0125   // ------------ method called to produce the data  ------------
0126   void L1TRawToDigi::produce(edm::Event& event, const edm::EventSetup& setup) {
0127     using namespace edm;
0128 
0129     std::unique_ptr<UnpackerCollections> coll = prov_->getCollections(event);
0130 
0131     edm::Handle<FEDRawDataCollection> feds;
0132     event.getByToken(fedData_, feds);
0133 
0134     if (!feds.isValid()) {
0135       LogError("L1T") << "Cannot unpack: no FEDRawDataCollection found";
0136       return;
0137     }
0138 
0139     unsigned valid_count = 0;
0140     for (const auto& fedId : fedIds_) {
0141       const FEDRawData& l1tRcd = feds->FEDData(fedId);
0142 
0143       LogDebug("L1T") << "Found FEDRawDataCollection with ID " << fedId << " and size " << l1tRcd.size();
0144 
0145       if ((int)l1tRcd.size() < slinkHeaderSize_ + slinkTrailerSize_ + amc13HeaderSize_ + amc13TrailerSize_ +
0146                                    amcHeaderSize_ + amcTrailerSize_) {
0147         if (l1tRcd.size() > 0) {
0148           LogError("L1T") << "Cannot unpack: invalid L1T raw data (size = " << l1tRcd.size() << ") for ID " << fedId
0149                           << ". Returning empty collections!";
0150         } else if (warnsa_ < 5) {
0151           warnsa_++;
0152           LogInfo("L1T") << "During unpacking, encountered empty L1T raw data (size = " << l1tRcd.size()
0153                          << ") for FED ID " << fedId << ".";
0154         }
0155         continue;
0156       } else {
0157         valid_count++;
0158       }
0159 
0160       const unsigned char* data = l1tRcd.data();
0161       FEDHeader header(data);
0162 
0163       if (header.check()) {
0164         LogDebug("L1T") << "Found SLink header:"
0165                         << " Trigger type " << header.triggerType() << " L1 event ID " << header.lvl1ID()
0166                         << " BX Number " << header.bxID() << " FED source " << header.sourceID() << " FED version "
0167                         << header.version();
0168       } else {
0169         LogWarning("L1T") << "Did not find a SLink header!";
0170       }
0171 
0172       FEDTrailer trailer(data + (l1tRcd.size() - slinkTrailerSize_));
0173 
0174       if (trailer.check()) {
0175         LogDebug("L1T") << "Found SLink trailer:"
0176                         << " Length " << trailer.fragmentLength() << " CRC " << trailer.crc() << " Status "
0177                         << trailer.evtStatus() << " Throttling bits " << trailer.ttsBits();
0178       } else {
0179         LogWarning("L1T") << "Did not find a SLink trailer!";
0180       }
0181 
0182       // FIXME Hard-coded firmware version for first 74x MC campaigns.
0183       // Will account for differences in the AMC payload, MP7 payload,
0184       // and unpacker setup.
0185       bool legacy_mc = fwOverride_ && ((fwId_ >> 24) == 0xff);
0186 
0187       amc13::Packet packet;
0188       if (!packet.parse((const uint64_t*)data,
0189                         (const uint64_t*)(data + slinkHeaderSize_),
0190                         (l1tRcd.size() - slinkHeaderSize_ - slinkTrailerSize_) / 8,
0191                         header.lvl1ID(),
0192                         header.bxID(),
0193                         legacy_mc,
0194                         mtf7_mode_)) {
0195         LogError("L1T") << "Could not extract AMC13 Packet.";
0196         return;
0197       }
0198 
0199       for (auto& amc : packet.payload()) {
0200         if (amc.size() == 0)
0201           continue;
0202 
0203         auto payload64 = amc.data();
0204         const uint32_t* start = (const uint32_t*)payload64.get();
0205         // Want to have payload size in 32 bit words, but AMC measures
0206         // it in 64 bit words → factor 2.
0207         const uint32_t* end = start + (amc.size() * 2);
0208 
0209         std::unique_ptr<Payload> payload;
0210         if (ctp7_mode_) {
0211           LogDebug("L1T") << "Using CTP7 mode";
0212           // CTP7 uses userData in AMC header
0213           payload = std::make_unique<CTP7Payload>(start, end, amc.header());
0214         } else if (mtf7_mode_) {
0215           LogDebug("L1T") << "Using MTF7 mode";
0216           payload = std::make_unique<MTF7Payload>(start, end);
0217         } else {
0218           LogDebug("L1T") << "Using MP7 mode";
0219           payload = std::make_unique<MP7Payload>(start, end, legacy_mc);
0220         }
0221         unsigned fw = payload->getAlgorithmFWVersion();
0222         unsigned board = amc.blockHeader().getBoardID();
0223         unsigned amc_no = amc.blockHeader().getAMCNumber();
0224 
0225         // Let parameterset value override FW version
0226         if (fwOverride_) {
0227           if (fedId == 1360)
0228             fw = fwId_;
0229           else if (fedId == 1366)
0230             fw = dmxFwId_;
0231         }
0232 
0233         auto unpackers = prov_->getUnpackers(fedId, board, amc_no, fw);
0234 
0235         // getBlock() returns a non-null unique_ptr on success
0236         std::unique_ptr<Block> block;
0237         while ((block = payload->getBlock()).get()) {
0238           // only unpack the Calo Layer 2 MP TMT node if it has processed this BX
0239           unsigned tmtId = board - l1t::stage2::layer2::mp::offsetBoardId + 1;
0240           unsigned bxId = header.bxID();
0241           unsigned unpackTMT = (!tmtCheck_ || ((tmtId - 1) == ((bxId - 1 + 3) % 9)));
0242           unsigned isCaloL2TMT =
0243               (fedId == l1t::stage2::layer2::fedId && (amc_no != l1t::stage2::layer2::demux::amcSlotNum));
0244 
0245           if (!isCaloL2TMT || unpackTMT) {
0246             if (debug_) {
0247               std::cout << ">>> block to unpack <<<" << std::endl
0248                         << "hdr:  " << std::hex << std::setw(8) << std::setfill('0') << block->header().raw()
0249                         << std::dec << " (ID " << block->header().getID() << ", size " << block->header().getSize()
0250                         << ", CapID 0x" << std::hex << std::setw(2) << std::setfill('0') << block->header().getCapID()
0251                         << ")" << std::dec << std::endl;
0252               for (const auto& word : block->payload()) {
0253                 if (debug_)
0254                   std::cout << "data: " << std::hex << std::setw(8) << std::setfill('0') << word << std::dec
0255                             << std::endl;
0256               }
0257             }
0258 
0259             auto unpacker = unpackers.find(block->header().getID());
0260 
0261             block->amc(amc.header());
0262 
0263             if (unpacker == unpackers.end()) {
0264               LogDebug("L1T") << "Cannot find an unpacker for"
0265                               << "\n\tblock: ID " << block->header().getID() << ", size " << block->header().getSize()
0266                               << "\n\tAMC: # " << amc_no << ", board ID 0x" << std::hex << board << std::dec
0267                               << "\n\tFED ID " << fedId << ", and FW ID " << fw;
0268               // TODO Handle error
0269             } else if (!unpacker->second->unpack(*block, coll.get())) {
0270               LogDebug("L1T") << "Error unpacking data for block ID " << block->header().getID() << ", AMC # " << amc_no
0271                               << ", board ID " << board << ", FED ID " << fedId << ", and FW ID " << fw << "!";
0272               // TODO Handle error
0273             }
0274           }
0275         }
0276       }
0277     }
0278     if (valid_count < minFeds_) {
0279       if (warnsb_ < 5) {
0280         warnsb_++;
0281         LogWarning("L1T") << "Unpacked " << valid_count << " non-empty FED IDs but minimum is set to " << minFeds_
0282                           << "\n";
0283       }
0284     }
0285   }
0286 
0287   namespace {
0288     edm::ParameterSetDescription makeDesc(std::vector<int> const& fedIDs,
0289                                           unsigned int fwid,
0290                                           std::string const& setup,
0291                                           edm::InputTag const& label) {
0292       edm::ParameterSetDescription desc;
0293       // These parameters are part of the L1T/HLT interface, avoid changing if possible:
0294       desc.add<std::vector<int>>("FedIds", fedIDs)->setComment("required parameter:  default value is invalid");
0295       desc.add<std::string>("Setup", setup)->setComment("required parameter:  default value is invalid");
0296       // These parameters have well defined  default values and are not currently
0297       // part of the L1T/HLT interface.  They can be cleaned up or updated at will:
0298       desc.add<unsigned int>("FWId", fwid)
0299           ->setComment(
0300               "Ignored unless FWOverride is true.  Calo Stage1:  32 bits: if the first eight bits are 0xff, will read "
0301               "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", label);
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       return desc;
0322     }
0323   }  // namespace
0324 
0325   // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0326   void L1TRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0327     descriptions.addDefault(makeDesc({}, 0, "", edm::InputTag("rawDataCollector")));
0328     descriptions.add("l1tRawToDigi", makeDesc({1352}, 1, "stage2::CaloSetup", edm::InputTag("l1tDigiToRaw")));
0329   }
0330 }  // namespace l1t
0331 
0332 using namespace l1t;
0333 //define this as a plug-in
0334 DEFINE_FWK_MODULE(L1TRawToDigi);