Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-31 04:19:30

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