Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-26 22:29:26

0001 #include <iostream>
0002 #include <memory>
0003 #include <zlib.h>
0004 
0005 #include "IOPool/Streamer/interface/FRDEventMessage.h"
0006 #include "IOPool/Streamer/interface/FRDFileHeader.h"
0007 
0008 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0009 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0010 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0011 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0012 
0013 #include "DataFormats/TCDS/interface/TCDSRaw.h"
0014 
0015 #include "EventFilter/Utilities/interface/GlobalEventNumber.h"
0016 
0017 #include "EventFilter/Utilities/plugins/FRDStreamSource.h"
0018 #include "EventFilter/Utilities/interface/crc32c.h"
0019 
0020 FRDStreamSource::FRDStreamSource(edm::ParameterSet const& pset, edm::InputSourceDescription const& desc)
0021     : ProducerSourceFromFiles(pset, desc, true),
0022       verifyAdler32_(pset.getUntrackedParameter<bool>("verifyAdler32", true)),
0023       verifyChecksum_(pset.getUntrackedParameter<bool>("verifyChecksum", true)),
0024       useL1EventID_(pset.getUntrackedParameter<bool>("useL1EventID", false)) {
0025   fileNames_ = fileNames(0), itFileName_ = fileNames_.begin();
0026   endFileName_ = fileNames_.end();
0027   openFile(*itFileName_);
0028   produces<FEDRawDataCollection>();
0029 }
0030 
0031 bool FRDStreamSource::setRunAndEventInfo(edm::EventID& id,
0032                                          edm::TimeValue_t& theTime,
0033                                          edm::EventAuxiliary::ExperimentType& eType) {
0034   if (fin_.peek() == EOF) {
0035     if (++itFileName_ == endFileName_) {
0036       fin_.close();
0037       return false;
0038     }
0039     if (!openFile(*itFileName_)) {
0040       throw cms::Exception("FRDStreamSource::setRunAndEventInfo") << "could not open file " << *itFileName_;
0041     }
0042   }
0043   //look for FRD header at beginning of the file and skip it
0044   if (fin_.tellg() == 0) {
0045     constexpr size_t buf_sz = sizeof(FRDFileHeader_v1);  //try to read v1 FRD header size
0046     FRDFileHeader_v1 fileHead;
0047     fin_.read((char*)&fileHead, buf_sz);
0048 
0049     if (fin_.gcount() == 0)
0050       throw cms::Exception("FRDStreamSource::setRunAndEventInfo")
0051           << "Unable to read file or empty file" << *itFileName_;
0052     else if (fin_.gcount() < (ssize_t)buf_sz)
0053       fin_.seekg(0);
0054     else {
0055       uint16_t frd_version = getFRDFileHeaderVersion(fileHead.id_, fileHead.version_);
0056       if (frd_version >= 1) {
0057         if (fileHead.headerSize_ < buf_sz)
0058           throw cms::Exception("FRDStreamSource::setRunAndEventInfo")
0059               << "Invalid FRD file header (size mismatch) in file " << *itFileName_;
0060         else if (fileHead.headerSize_ > buf_sz)
0061           fin_.seekg(fileHead.headerSize_, fin_.beg);
0062       } else
0063         fin_.seekg(0, fin_.beg);
0064     }
0065   }
0066 
0067   if (detectedFRDversion_ == 0) {
0068     fin_.read((char*)&detectedFRDversion_, sizeof(uint16_t));
0069     fin_.read((char*)&flags_, sizeof(uint16_t));
0070     assert(detectedFRDversion_ > 0 && detectedFRDversion_ <= FRDHeaderMaxVersion);
0071     if (buffer_.size() < FRDHeaderVersionSize[detectedFRDversion_])
0072       buffer_.resize(FRDHeaderVersionSize[detectedFRDversion_]);
0073     *((uint32_t*)(&buffer_[0])) = detectedFRDversion_;
0074     fin_.read(&buffer_[0] + sizeof(uint32_t), FRDHeaderVersionSize[detectedFRDversion_] - sizeof(uint32_t));
0075     assert(fin_.gcount() == FRDHeaderVersionSize[detectedFRDversion_] - (unsigned int)(sizeof(uint32_t)));
0076   } else {
0077     if (buffer_.size() < FRDHeaderVersionSize[detectedFRDversion_])
0078       buffer_.resize(FRDHeaderVersionSize[detectedFRDversion_]);
0079     fin_.read(&buffer_[0], FRDHeaderVersionSize[detectedFRDversion_]);
0080     assert(fin_.gcount() == FRDHeaderVersionSize[detectedFRDversion_]);
0081   }
0082 
0083   std::unique_ptr<FRDEventMsgView> frdEventMsg(new FRDEventMsgView(&buffer_[0]));
0084   if (useL1EventID_)
0085     id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), frdEventMsg->event());
0086 
0087   const uint32_t totalSize = frdEventMsg->size();
0088   if (totalSize > buffer_.size()) {
0089     buffer_.resize(totalSize);
0090   }
0091   if (totalSize > FRDHeaderVersionSize[detectedFRDversion_]) {
0092     fin_.read(&buffer_[0] + FRDHeaderVersionSize[detectedFRDversion_],
0093               totalSize - FRDHeaderVersionSize[detectedFRDversion_]);
0094     if (fin_.gcount() != totalSize - FRDHeaderVersionSize[detectedFRDversion_]) {
0095       throw cms::Exception("FRDStreamSource::setRunAndEventInfo") << "premature end of file " << *itFileName_;
0096     }
0097     frdEventMsg = std::make_unique<FRDEventMsgView>(&buffer_[0]);
0098   }
0099 
0100   if (verifyChecksum_ && frdEventMsg->version() >= 5) {
0101     uint32_t crc = 0;
0102     crc = crc32c(crc, (const unsigned char*)frdEventMsg->payload(), frdEventMsg->eventSize());
0103     if (crc != frdEventMsg->crc32c()) {
0104       throw cms::Exception("FRDStreamSource::getNextEvent") << "Found a wrong crc32c checksum: expected 0x" << std::hex
0105                                                             << frdEventMsg->crc32c() << " but calculated 0x" << crc;
0106     }
0107   } else if (verifyAdler32_ && frdEventMsg->version() >= 3) {
0108     uint32_t adler = adler32(0L, Z_NULL, 0);
0109     adler = adler32(adler, (Bytef*)frdEventMsg->payload(), frdEventMsg->eventSize());
0110 
0111     if (adler != frdEventMsg->adler32()) {
0112       throw cms::Exception("FRDStreamSource::setRunAndEventInfo")
0113           << "Found a wrong Adler32 checksum: expected 0x" << std::hex << frdEventMsg->adler32() << " but calculated 0x"
0114           << adler;
0115     }
0116   }
0117 
0118   rawData_ = std::make_unique<FEDRawDataCollection>();
0119 
0120   uint32_t eventSize = frdEventMsg->eventSize();
0121   unsigned char* event = (unsigned char*)frdEventMsg->payload();
0122   bool foundTCDSFED = false;
0123   bool foundGTPFED = false;
0124 
0125   while (eventSize > 0) {
0126     assert(eventSize >= FEDTrailer::length);
0127     eventSize -= FEDTrailer::length;
0128     const FEDTrailer fedTrailer(event + eventSize);
0129     const uint32_t fedSize = fedTrailer.fragmentLength() << 3;  //trailer length counts in 8 bytes
0130     assert(eventSize >= fedSize - FEDHeader::length);
0131     eventSize -= (fedSize - FEDHeader::length);
0132     const FEDHeader fedHeader(event + eventSize);
0133     const uint16_t fedId = fedHeader.sourceID();
0134     if (fedId > FEDNumbering::MAXFEDID) {
0135       throw cms::Exception("FedRawDataInputSource::fillFEDRawDataCollection") << "Out of range FED ID : " << fedId;
0136     }
0137     if (fedId == FEDNumbering::MINTCDSuTCAFEDID) {
0138       foundTCDSFED = true;
0139       tcds::Raw_v1 const* tcds = reinterpret_cast<tcds::Raw_v1 const*>(event + eventSize + FEDHeader::length);
0140       id = edm::EventID(frdEventMsg->run(), tcds->header.lumiSection, tcds->header.eventNumber);
0141       eType = static_cast<edm::EventAuxiliary::ExperimentType>(fedHeader.triggerType());
0142       theTime = static_cast<edm::TimeValue_t>(((uint64_t)tcds->bst.gpstimehigh << 32) | tcds->bst.gpstimelow);
0143     }
0144 
0145     if (fedId == FEDNumbering::MINTriggerGTPFEDID && !foundTCDSFED) {
0146       foundGTPFED = true;
0147       const bool GTPEvmBoardSense = evf::evtn::evm_board_sense(event + eventSize, fedSize);
0148       if (!useL1EventID_) {
0149         if (GTPEvmBoardSense)
0150           id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), evf::evtn::get(event + eventSize, true));
0151         else
0152           id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), evf::evtn::get(event + eventSize, false));
0153       }
0154       //evf::evtn::evm_board_setformat(fedSize);
0155       const uint64_t gpsl = evf::evtn::getgpslow(event + eventSize);
0156       const uint64_t gpsh = evf::evtn::getgpshigh(event + eventSize);
0157       theTime = static_cast<edm::TimeValue_t>((gpsh << 32) + gpsl);
0158     }
0159 
0160     //take event ID from GTPE FED
0161     if (fedId == FEDNumbering::MINTriggerEGTPFEDID && !foundGTPFED && !foundTCDSFED && !useL1EventID_) {
0162       if (evf::evtn::gtpe_board_sense(event + eventSize)) {
0163         id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), evf::evtn::gtpe_get(event + eventSize));
0164       }
0165     }
0166     FEDRawData& fedData = rawData_->FEDData(fedId);
0167     fedData.resize(fedSize);
0168     memcpy(fedData.data(), event + eventSize, fedSize);
0169   }
0170   assert(eventSize == 0);
0171 
0172   return true;
0173 }
0174 
0175 void FRDStreamSource::produce(edm::Event& e) { e.put(std::move(rawData_)); }
0176 
0177 bool FRDStreamSource::openFile(const std::string& fileName) {
0178   std::cout << " open file.. " << fileName << std::endl;
0179   fin_.close();
0180   fin_.clear();
0181   size_t pos = fileName.find(':');
0182   if (pos != std::string::npos) {
0183     std::string prefix = fileName.substr(0, pos);
0184     if (prefix != "file")
0185       return false;
0186     pos++;
0187   } else
0188     pos = 0;
0189 
0190   fin_.open(fileName.substr(pos).c_str(), std::ios::in | std::ios::binary);
0191   return fin_.is_open();
0192 }
0193 
0194 //////////////////////////////////////////
0195 // define this class as an input source //
0196 //////////////////////////////////////////
0197 DEFINE_FWK_INPUT_SOURCE(FRDStreamSource);
0198 
0199 // Keep old naming from DAQ1
0200 using ErrorStreamSource = FRDStreamSource;
0201 DEFINE_FWK_INPUT_SOURCE(ErrorStreamSource);