Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:45:52

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