Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:07

0001 // -*- C++ -*-
0002 //
0003 // Package:    EventFilter/L1TRawToDigi
0004 // Class:      MP7BufferDumpToRaw
0005 //
0006 /**\class Stage2InputPatternWriter Stage2InputPatternWriter.cc L1Trigger/L1TCalorimeter/plugins/Stage2InputPatternWriter.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  James Brooke
0015 //         Created:  Tue, 11 Mar 2014 14:55:45 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 
0022 // user include files
0023 #include "FWCore/Utilities/interface/Exception.h"
0024 #include "FWCore/Framework/interface/Frameworkfwd.h"
0025 #include "FWCore/Framework/interface/EDProducer.h"
0026 #include "FWCore/Framework/interface/Event.h"
0027 #include "FWCore/Framework/interface/MakerMacros.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0029 #include "FWCore/ServiceRegistry/interface/Service.h"
0030 
0031 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0032 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0033 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0034 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0035 
0036 #include "FWCore/Utilities/interface/CRC16.h"
0037 
0038 #include <fstream>
0039 #include <iostream>
0040 #include <sstream>
0041 #include <string>
0042 #include <iomanip>
0043 #include <boost/algorithm/string.hpp>
0044 
0045 #include "EventFilter/L1TRawToDigi/interface/MP7FileReader.h"
0046 #include "EventFilter/L1TRawToDigi/interface/MP7PacketReader.h"
0047 #include "EventFilter/L1TRawToDigi/interface/Block.h"
0048 #include "EventFilter/L1TRawToDigi/interface/AMC13Spec.h"
0049 //#include "EventFilter/L1TRawToDigi/interface/PackingSetup.h"
0050 //
0051 // class declaration
0052 //
0053 
0054 namespace l1t {
0055 
0056   class MP7BufferDumpToRaw : public edm::EDProducer {
0057   public:
0058     explicit MP7BufferDumpToRaw(const edm::ParameterSet&);
0059     ~MP7BufferDumpToRaw() override;
0060 
0061     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0062 
0063   private:
0064     void beginJob() override;
0065     void produce(edm::Event&, const edm::EventSetup&) override;
0066     void endJob() override;
0067 
0068     std::vector<Block> getBlocks(int iAmc);
0069 
0070     void formatAMC(amc13::Packet& amc13, const std::vector<Block>& blocks, int iAmc);
0071 
0072     void formatRaw(edm::Event& iEvent, amc13::Packet& amc13, FEDRawData& fed_data);
0073 
0074     //virtual void beginRun(edm::Run const&, edm::EventSetup const&) override;
0075     //virtual void endRun(edm::Run const&, edm::EventSetup const&) override;
0076     //virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0077     //virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0078 
0079     // ----------member data ---------------------------
0080 
0081     // file readers
0082     MP7FileReader rxFileReader_;
0083     MP7FileReader txFileReader_;
0084     std::vector<unsigned> rxIndex_;
0085     std::vector<unsigned> txIndex_;
0086 
0087     // packet readers
0088     MP7PacketReader rxPacketReader_;
0089     MP7PacketReader txPacketReader_;
0090     //  MP7PacketReader::PacketData::const_iter rxItr_;
0091     //  MP7PacketReader::PacketData txItr_;
0092 
0093     // formatting parameters
0094     bool packetisedData_;
0095 
0096     // non packetised data parameters
0097     unsigned nFramesPerEvent_;
0098 
0099     // packetised data parameters
0100 
0101     // hardware params
0102     unsigned nBoard_;
0103     unsigned iBoard_;
0104     std::vector<int> boardId_;
0105 
0106     // board readout params
0107     std::vector<std::vector<int> > rxBlockLength_;
0108     std::vector<std::vector<int> > txBlockLength_;
0109     bool mux_;
0110     int muxOffset_;
0111 
0112     // DAQ params
0113     int fedId_;
0114     int evType_;
0115     int fwVer_;
0116     int slinkHeaderSize_;  // in 8-bit words
0117     int slinkTrailerSize_;
0118   };
0119 
0120   //
0121   // constants, enums and typedefs
0122   //
0123 
0124   //
0125   // static data member definitions
0126   //
0127 
0128   //
0129   // constructors and destructor
0130   //
0131   MP7BufferDumpToRaw::MP7BufferDumpToRaw(const edm::ParameterSet& iConfig)
0132       : rxFileReader_(iConfig.getUntrackedParameter<std::string>("rxFile", "rx_summary.txt")),
0133         txFileReader_(iConfig.getUntrackedParameter<std::string>("txFile", "tx_summary.txt")),
0134         rxPacketReader_(iConfig.getUntrackedParameter<std::string>("rxFile", "rx_summary.txt"),
0135                         iConfig.getUntrackedParameter<int>("rxHeaderFrames", 1),
0136                         0,
0137                         iConfig.getUntrackedParameter<int>("rxKeyLink", 0)),
0138         txPacketReader_(iConfig.getUntrackedParameter<std::string>("txFile", "tx_summary.txt"),
0139                         iConfig.getUntrackedParameter<int>("txHeaderFrames", 1),
0140                         0,
0141                         iConfig.getUntrackedParameter<int>("txKeyLink", 0)),
0142         packetisedData_(iConfig.getUntrackedParameter<bool>("packetisedData", true)),
0143         nFramesPerEvent_(iConfig.getUntrackedParameter<int>("nFramesPerEvent", 6)),
0144         iBoard_(iConfig.getUntrackedParameter<int>("boardOffset", 0)),
0145         boardId_(iConfig.getUntrackedParameter<std::vector<int> >("boardId")),
0146         mux_(iConfig.getUntrackedParameter<bool>("mux", false)),
0147         fedId_(iConfig.getUntrackedParameter<int>("fedId", 1)),
0148         evType_(iConfig.getUntrackedParameter<int>("eventType", 1)),
0149         fwVer_(iConfig.getUntrackedParameter<int>("fwVersion", 1)),
0150         slinkHeaderSize_(iConfig.getUntrackedParameter<int>("lenSlinkHeader", 8)),
0151         slinkTrailerSize_(iConfig.getUntrackedParameter<int>("lenSlinkTrailer", 8)) {
0152     produces<FEDRawDataCollection>();
0153 
0154     // check tx/rx file size consistency and number of boards
0155     if (rxFileReader_.size() != txFileReader_.size()) {
0156       edm::LogError("L1T") << "Different number of boards in Rx and Tx files";
0157     }
0158     nBoard_ = std::max(rxFileReader_.size(), txFileReader_.size());
0159     LogDebug("L1T") << "# boards : " << nBoard_;
0160 
0161     // advance pointers for non packetised data
0162     rxIndex_ = iConfig.getUntrackedParameter<std::vector<unsigned> >("nFramesOffset");
0163     if (rxIndex_.size() != nBoard_) {
0164       edm::LogError("L1T") << "Wrong number of boards in nFramesOffset " << rxIndex_.size();
0165     }
0166 
0167     txIndex_ = iConfig.getUntrackedParameter<std::vector<unsigned> >("nFramesLatency");
0168     if (txIndex_.size() != nBoard_) {
0169       edm::LogError("L1T") << "Wrong number of boards in nFramesLatency " << txIndex_.size();
0170     }
0171 
0172     // add latency to offset for Tx
0173     for (unsigned i = 0; i < rxIndex_.size(); ++i)
0174       txIndex_.at(i) += rxIndex_.at(i);
0175 
0176     // check board IDs
0177     if (nBoard_ != boardId_.size()) {
0178       edm::LogError("L1T") << "Found " << nBoard_ << " boards, but given " << boardId_.size() << " IDs";
0179     }
0180 
0181     // block length PSet
0182     std::vector<edm::ParameterSet> vpset = iConfig.getUntrackedParameter<std::vector<edm::ParameterSet> >("blocks");
0183 
0184     if (vpset.size() != nBoard_) {
0185       edm::LogError("L1T") << "Wrong number of block specs " << vpset.size();
0186     }
0187 
0188     rxBlockLength_.resize(nBoard_);
0189     txBlockLength_.resize(nBoard_);
0190 
0191     for (unsigned i = 0; i < nBoard_; ++i) {
0192       std::vector<int> rx = vpset.at(i).getUntrackedParameter<std::vector<int> >("rxBlockLength");
0193 
0194       rxBlockLength_.at(i).resize(rx.size());
0195 
0196       for (unsigned j = 0; j < rx.size(); ++j) {
0197         rxBlockLength_.at(i).at(j) = rx.at(j);
0198 
0199         if (rx.at(j) != 0) {
0200           //    LogDebug("L1T") << "Block readout : board " << i << " Rx link " << j << " size " << rx.at(j);
0201         }
0202       }
0203 
0204       std::vector<int> tx = vpset.at(i).getUntrackedParameter<std::vector<int> >("txBlockLength");
0205       txBlockLength_.at(i).resize(tx.size());
0206 
0207       for (unsigned j = 0; j < tx.size(); ++j) {
0208         txBlockLength_.at(i).at(j) = tx.at(j);
0209 
0210         if (tx.at(j) != 0) {
0211           //    LogDebug("L1T") << "Block readout : board " << i << " Tx link " << j << " size " << tx.at(j);
0212         }
0213       }
0214     }
0215 
0216     LogDebug("L1T") << "Board ID size " << boardId_.size();
0217 
0218     LogDebug("L1T") << "Frames per event " << nFramesPerEvent_;
0219   }
0220 
0221   MP7BufferDumpToRaw::~MP7BufferDumpToRaw() {
0222     // do anything here that needs to be done at desctruction time
0223     // (e.g. close files, deallocate resources etc.)
0224   }
0225 
0226   //
0227   // member functions
0228   //
0229 
0230   // ------------ method called for each event  ------------
0231   void MP7BufferDumpToRaw::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0232     using namespace edm;
0233 
0234     // AMC 13 packet
0235     amc13::Packet amc13;
0236 
0237     // create AMC formatted data
0238     if (mux_) {
0239       std::vector<Block> blocks = getBlocks(iBoard_);
0240       formatAMC(amc13, blocks, iBoard_);
0241     } else {
0242       for (unsigned iBoard = 0; iBoard < nBoard_; ++iBoard) {
0243         std::vector<Block> blocks = getBlocks(iBoard);
0244         formatAMC(amc13, blocks, iBoard);
0245       }
0246     }
0247 
0248     LogDebug("L1T") << "AMC13 size " << amc13.size();
0249 
0250     // prepare the raw data collection
0251     std::unique_ptr<FEDRawDataCollection> raw_coll(new FEDRawDataCollection());
0252     FEDRawData& fed_data = raw_coll->FEDData(fedId_);
0253 
0254     formatRaw(iEvent, amc13, fed_data);
0255 
0256     LogDebug("L1T") << "Packing FED ID " << fedId_ << " size " << fed_data.size();
0257 
0258     // put the collection in the event
0259     iEvent.put(std::move(raw_coll));
0260 
0261     //advance to next AMC for next event, if required...
0262     if (mux_) {
0263       iBoard_++;
0264       iBoard_ = iBoard_ % nBoard_;
0265     }
0266   }
0267 
0268   std::vector<Block> MP7BufferDumpToRaw::getBlocks(int iBoard) {
0269     LogDebug("L1T") << "Getting blocks from board " << iBoard << ", " << rxBlockLength_.at(iBoard).size()
0270                     << " Rx links, " << txBlockLength_.at(iBoard).size() << " Tx links";
0271 
0272     std::vector<Block> blocks;
0273 
0274     // Rx blocks first
0275     for (unsigned link = 0; link < rxBlockLength_.at(iBoard).size(); ++link) {
0276       unsigned id = link * 2;
0277       unsigned size = rxBlockLength_.at(iBoard).at(link);
0278 
0279       if (size == 0)
0280         continue;
0281 
0282       std::vector<uint32_t> data;
0283       if (packetisedData_) {
0284         const PacketData& p = rxPacketReader_.get(iBoard);
0285         PacketData::const_iterator itr = p.begin();
0286         for (unsigned i = 0; i < rxIndex_.at(iBoard); i++)
0287           itr++;
0288 
0289         LogDebug("L1T") << "Found packet [" << itr->first_ << ", " << itr->last_ << "]";
0290         LogDebug("L1T") << "Link " << link << " has " << itr->links_.find(link)->second.size() << " frames";
0291 
0292         for (unsigned iFrame = 0; iFrame < itr->links_.find(link)->second.size(); ++iFrame) {
0293           uint64_t d = itr->links_.find(link)->second.at(iFrame);
0294           data.push_back(d);
0295         }
0296       } else {
0297         for (unsigned iFrame = rxIndex_.at(iBoard); iFrame < rxIndex_.at(iBoard) + size; ++iFrame) {
0298           uint64_t d = rxFileReader_.get(iBoard).link(link).at(iFrame);
0299           LogDebug("L1T") << "Frame " << iFrame << " : " << std::hex << d;
0300           if ((d & 0x100000000) > 0)
0301             data.push_back(d & 0xffffffff);
0302         }
0303       }
0304 
0305       LogDebug("L1T") << "Board " << iBoard << " block " << id << ", size " << data.size();
0306 
0307       Block block(id, data);
0308       blocks.push_back(block);
0309     }
0310 
0311     // then Tx blocks
0312     for (unsigned link = 0; link < txBlockLength_.at(iBoard).size(); ++link) {
0313       unsigned id = (link * 2) + 1;
0314       unsigned size = txBlockLength_.at(iBoard).at(link);
0315 
0316       if (size == 0)
0317         continue;
0318 
0319       LogDebug("L1T") << "Block " << id << " expecting size " << size;
0320 
0321       std::vector<uint32_t> data;
0322       if (packetisedData_) {
0323         const PacketData& p = txPacketReader_.get(iBoard);
0324         PacketData::const_iterator itr = p.begin();
0325         for (unsigned i = 0; i < txIndex_.at(iBoard); i++)
0326           itr++;
0327 
0328         LogDebug("L1T") << "Found packet [" << itr->first_ << ", " << itr->last_ << "]";
0329         LogDebug("L1T") << "Link " << link << " has " << itr->links_.find(link)->second.size() << " frames";
0330 
0331         for (unsigned iFrame = 0; iFrame < itr->links_.find(link)->second.size(); ++iFrame) {
0332           uint64_t d = itr->links_.find(link)->second.at(iFrame);
0333           data.push_back(d);
0334         }
0335 
0336       } else {
0337         for (unsigned iFrame = txIndex_.at(iBoard); iFrame < txIndex_.at(iBoard) + size; ++iFrame) {
0338           uint64_t d = txFileReader_.get(iBoard).link(link).at(iFrame);
0339           LogDebug("L1T") << "Frame " << iFrame << " : " << std::hex << d;
0340           if ((d & 0x100000000) > 0)
0341             data.push_back(d & 0xffffffff);
0342         }
0343       }
0344 
0345       LogDebug("L1T") << "Board " << iBoard << " block " << id << ", size " << data.size();
0346 
0347       Block block(id, data);
0348 
0349       blocks.push_back(block);
0350     }
0351 
0352     if (packetisedData_) {
0353       rxIndex_.at(iBoard)++;
0354       txIndex_.at(iBoard)++;
0355     } else {
0356       rxIndex_.at(iBoard) += nFramesPerEvent_;
0357       txIndex_.at(iBoard) += nFramesPerEvent_;
0358     }
0359 
0360     LogDebug("L1T") << "Board " << iBoard << ", read " << blocks.size() << " blocks";
0361 
0362     return blocks;
0363   }
0364 
0365   void MP7BufferDumpToRaw::formatAMC(amc13::Packet& amc13, const std::vector<Block>& blocks, int iBoard) {
0366     LogDebug("L1T") << "Formatting Board " << iBoard;
0367 
0368     std::vector<uint32_t> load32;
0369     // TODO this is an empty word to be replaced with a proper MP7
0370     // header containing at least the firmware version
0371     load32.push_back(0);
0372     load32.push_back(fwVer_);
0373 
0374     for (const auto& block : blocks) {
0375       LogDebug("L1T") << "Adding block " << block.header().getID() << " with size " << block.payload().size();
0376       auto load = block.payload();
0377 
0378 #ifdef EDM_ML_DEBUG
0379       std::stringstream s("");
0380       s << "Block content:" << std::endl << std::hex << std::setfill('0');
0381       for (const auto& word : load)
0382         s << std::setw(8) << word << std::endl;
0383       LogDebug("L1T") << s.str();
0384 #endif
0385 
0386       load32.push_back(block.header().raw());
0387       load32.insert(load32.end(), load.begin(), load.end());
0388     }
0389 
0390     LogDebug("L1T") << "Converting payload " << iBoard;
0391 
0392     std::vector<uint64_t> load64;
0393     for (unsigned int i = 0; i < load32.size(); i += 2) {
0394       uint64_t word = load32[i];
0395       if (i + 1 < load32.size())
0396         word |= static_cast<uint64_t>(load32[i + 1]) << 32;
0397       load64.push_back(word);
0398     }
0399 
0400     LogDebug("L1T") << "Creating AMC packet " << iBoard;
0401     //  LogDebug("L1T") << iBoard << ", " << boardId_.at(iBoard) << ", " << load64.size();
0402 
0403     amc13.add(iBoard, boardId_.at(iBoard), 0, 0, 0, load64);
0404   }
0405 
0406   void MP7BufferDumpToRaw::formatRaw(edm::Event& iEvent, amc13::Packet& amc13, FEDRawData& fed_data) {
0407     unsigned int size = slinkHeaderSize_ + slinkTrailerSize_ + amc13.size() * 8;
0408     fed_data.resize(size);
0409     unsigned char* payload = fed_data.data();
0410     unsigned char* payload_start = payload;
0411 
0412     auto bxId = iEvent.bunchCrossing();
0413     auto evtId = iEvent.id().event();
0414 
0415     LogDebug("L1T") << "Creating FEDRawData ID " << fedId_ << ", size " << size;
0416 
0417     FEDHeader header(payload);
0418     header.set(payload, evType_, evtId, bxId, fedId_);
0419 
0420     amc13.write(iEvent, payload, slinkHeaderSize_, size - slinkHeaderSize_ - slinkTrailerSize_);
0421 
0422     payload += slinkHeaderSize_;
0423     payload += amc13.size() * 8;
0424 
0425     FEDTrailer trailer(payload);
0426     trailer.set(payload, size / 8, evf::compute_crc(payload_start, size), 0, 0);
0427   }
0428 
0429   // ------------ method called once each job just before starting event loop  ------------
0430   void MP7BufferDumpToRaw::beginJob() {}
0431 
0432   // ------------ method called once each job just after ending the event loop  ------------
0433   void MP7BufferDumpToRaw::endJob() {}
0434 
0435   // ------------ method called when starting to processes a run  ------------
0436   /*
0437 void 
0438 MP7BufferDumpToRaw::beginRun(edm::Run const&, edm::EventSetup const&)
0439 {
0440 }
0441 */
0442 
0443   // ------------ method called when ending the processing of a run  ------------
0444   /*
0445 void 
0446 MP7BufferDumpToRaw::endRun(edm::Run const&, edm::EventSetup const&)
0447 {
0448 }
0449 */
0450 
0451   // ------------ method called when starting to processes a luminosity block  ------------
0452   /*
0453 vvoid 
0454 MP7BufferDumpToRaw::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0455 {
0456 }
0457 */
0458 
0459   // ------------ method called when ending the processing of a luminosity block  ------------
0460   /*
0461 void 
0462 MP7BufferDumpToRaw::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0463 {
0464 }
0465 */
0466 
0467   // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0468   void MP7BufferDumpToRaw::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0469     //The following says we do not know what parameters are allowed so do no validation
0470     // Please change this to state exactly what you do use, even if it is no parameters
0471     edm::ParameterSetDescription desc;
0472     desc.setUnknown();
0473     descriptions.addDefault(desc);
0474   }
0475 
0476 }  // namespace l1t
0477 
0478 using namespace l1t;
0479 //define this as a plug-in
0480 DEFINE_FWK_MODULE(MP7BufferDumpToRaw);