Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include <memory>
0002 
0003 #include "FWCore/Framework/interface/Frameworkfwd.h"
0004 #include "FWCore/Framework/interface/stream/EDProducer.h"
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/MakerMacros.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/Utilities/interface/StreamID.h"
0009 
0010 #include "EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h"
0011 
0012 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0013 #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
0014 #include "DataFormats/HGCalDigi/interface/HGCalDigiCollections.h"
0015 
0016 class HGCalRawToDigi : public edm::stream::EDProducer<> {
0017 public:
0018   explicit HGCalRawToDigi(const edm::ParameterSet&);
0019 
0020   static void fillDescriptions(edm::ConfigurationDescriptions&);
0021 
0022 private:
0023   void produce(edm::Event&, const edm::EventSetup&) override;
0024 
0025   const edm::EDGetTokenT<FEDRawDataCollection> fedRawToken_;
0026   const edm::EDPutTokenT<HGCalDigiCollection> digisToken_;
0027   const edm::EDPutTokenT<HGCalElecDigiCollection> elecDigisToken_;
0028 
0029   const std::vector<unsigned int> fedIds_;
0030   const unsigned int badECONDMax_;
0031   const unsigned int numERxsInECOND_;
0032   const std::unique_ptr<HGCalUnpacker<HGCalElectronicsId> > unpacker_;
0033 };
0034 
0035 HGCalRawToDigi::HGCalRawToDigi(const edm::ParameterSet& iConfig)
0036     : fedRawToken_(consumes<FEDRawDataCollection>(iConfig.getParameter<edm::InputTag>("src"))),
0037       digisToken_(produces<HGCalDigiCollection>()),
0038       elecDigisToken_(produces<HGCalElecDigiCollection>()),
0039       fedIds_(iConfig.getParameter<std::vector<unsigned int> >("fedIds")),
0040       badECONDMax_(iConfig.getParameter<unsigned int>("badECONDMax")),
0041       numERxsInECOND_(iConfig.getParameter<unsigned int>("numERxsInECOND")),
0042       unpacker_(new HGCalUnpacker<HGCalElectronicsId>(
0043           HGCalUnpackerConfig{.sLinkBOE = iConfig.getParameter<unsigned int>("slinkBOE"),
0044                               .captureBlockReserved = iConfig.getParameter<unsigned int>("captureBlockReserved"),
0045                               .econdHeaderMarker = iConfig.getParameter<unsigned int>("econdHeaderMarker"),
0046                               .sLinkCaptureBlockMax = iConfig.getParameter<unsigned int>("maxCaptureBlock"),
0047                               .captureBlockECONDMax = iConfig.getParameter<unsigned int>("captureBlockECONDMax"),
0048                               .econdERXMax = iConfig.getParameter<unsigned int>("econdERXMax"),
0049                               .erxChannelMax = iConfig.getParameter<unsigned int>("erxChannelMax"),
0050                               .payloadLengthMax = iConfig.getParameter<unsigned int>("payloadLengthMax"),
0051                               .channelMax = iConfig.getParameter<unsigned int>("channelMax"),
0052                               .commonModeMax = iConfig.getParameter<unsigned int>("commonModeMax")})) {}
0053 
0054 void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0055   // retrieve the FED raw data
0056   const auto& raw_data = iEvent.get(fedRawToken_);
0057   // prepare the output
0058   HGCalDigiCollection digis;
0059   HGCalElecDigiCollection elec_digis;
0060   for (const auto& fed_id : fedIds_) {
0061     const auto& fed_data = raw_data.FEDData(fed_id);
0062     if (fed_data.size() == 0)
0063       continue;
0064 
0065     std::vector<uint32_t> data_32bit;
0066     auto* ptr = fed_data.data();
0067     size_t fed_size = fed_data.size();
0068     for (size_t i = 0; i < fed_size; i += 4)
0069       data_32bit.emplace_back(((*(ptr + i) & 0xff) << 0) + (((i + 1) < fed_size) ? ((*(ptr + i + 1) & 0xff) << 8) : 0) +
0070                               (((i + 2) < fed_size) ? ((*(ptr + i + 2) & 0xff) << 16) : 0) +
0071                               (((i + 3) < fed_size) ? ((*(ptr + i + 3) & 0xff) << 24) : 0));
0072 
0073     unpacker_->parseSLink(
0074         data_32bit,
0075         [this](uint16_t /*sLink*/, uint8_t /*captureBlock*/, uint8_t /*econd*/) { return (1 << numERxsInECOND_) - 1; },
0076         [](HGCalElectronicsId elecID) -> HGCalElectronicsId { return elecID; });
0077     const auto elecid_to_detid = [](const HGCalElectronicsId& id) -> HGCalDetId {
0078       return HGCalDetId(id.raw());
0079     };  //TODO: implement something more relevant
0080 
0081     auto channeldata = unpacker_->channelData();
0082     auto cms = unpacker_->commonModeIndex();
0083     for (unsigned int i = 0; i < channeldata.size(); i++) {
0084       auto data = channeldata.at(i);
0085       auto cm = cms.at(i);
0086       const auto& id = data.id();
0087       auto idraw = id.raw();
0088       auto raw = data.raw();
0089       LogDebug("HGCalRawToDigi:produce") << "id=" << idraw << ", raw=" << raw << ", common mode index=" << cm << ".";
0090       digis.push_back(HGCROCChannelDataFrameSpec(elecid_to_detid(id), data.raw()));
0091       elec_digis.push_back(data);
0092     }
0093     if (const auto& bad_econds = unpacker_->badECOND(); !bad_econds.empty()) {
0094       if (bad_econds.size() > badECONDMax_)
0095         throw cms::Exception("HGCalRawToDigi:produce")
0096             << "Too many bad ECON-Ds: " << bad_econds.size() << " > " << badECONDMax_ << ".";
0097       edm::LogWarning("HGCalRawToDigi:produce").log([&bad_econds](auto& log) {
0098         log << "Bad ECON-D: " << std::dec;
0099         std::string prefix;
0100         for (const auto& badECOND : bad_econds)
0101           log << prefix << badECOND, prefix = ", ";
0102         log << ".";
0103       });
0104     }
0105   }
0106   iEvent.emplace(digisToken_, std::move(digis));
0107   iEvent.emplace(elecDigisToken_, std::move(elec_digis));
0108 }
0109 
0110 void HGCalRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0111   edm::ParameterSetDescription desc;
0112   desc.add<edm::InputTag>("src", edm::InputTag("rawDataCollector"));
0113   desc.add<unsigned int>("maxCaptureBlock", 1)->setComment("maximum number of capture blocks in one S-Link");
0114   desc.add<unsigned int>("captureBlockReserved", 0)->setComment("capture block reserved pattern");
0115   desc.add<unsigned int>("econdHeaderMarker", 0x154)->setComment("ECON-D header Marker pattern");
0116   desc.add<unsigned int>("slinkBOE", 0x2a)->setComment("SLink BOE pattern");
0117   desc.add<unsigned int>("captureBlockECONDMax", 12)->setComment("maximum number of ECON-D's in one capture block");
0118   desc.add<unsigned int>("econdERXMax", 12)->setComment("maximum number of eRx's in one ECON-D");
0119   desc.add<unsigned int>("erxChannelMax", 37)->setComment("maximum number of channels in one eRx");
0120   desc.add<unsigned int>("payloadLengthMax", 469)->setComment("maximum length of payload length");
0121   desc.add<unsigned int>("channelMax", 7000000)->setComment("maximum number of channels unpacked");
0122   desc.add<unsigned int>("commonModeMax", 4000000)->setComment("maximum number of common modes unpacked");
0123   desc.add<unsigned int>("badECONDMax", 200)->setComment("maximum number of bad ECON-D's");
0124   desc.add<std::vector<unsigned int> >("fedIds", {});
0125   desc.add<unsigned int>("numERxsInECOND", 12)->setComment("number of eRxs in each ECON-D payload");
0126   descriptions.add("hgcalDigis", desc);
0127 }
0128 
0129 // define this as a plug-in
0130 DEFINE_FWK_MODULE(HGCalRawToDigi);