Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:00:31

0001 #include "EventFilter/Utilities/interface/DAQSource.h"
0002 #include "EventFilter/Utilities/interface/DAQSourceModelsFRD.h"
0003 
0004 #include <iostream>
0005 #include <sstream>
0006 #include <sys/types.h>
0007 #include <sys/file.h>
0008 #include <sys/time.h>
0009 #include <unistd.h>
0010 #include <vector>
0011 
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 
0014 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0015 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0016 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0017 
0018 #include "DataFormats/TCDS/interface/TCDSRaw.h"
0019 
0020 #include "FWCore/Framework/interface/Event.h"
0021 #include "EventFilter/Utilities/interface/GlobalEventNumber.h"
0022 #include "EventFilter/Utilities/interface/DAQSourceModels.h"
0023 #include "EventFilter/Utilities/interface/DAQSource.h"
0024 
0025 #include "EventFilter/Utilities/interface/AuxiliaryMakers.h"
0026 
0027 #include "DataFormats/Provenance/interface/EventAuxiliary.h"
0028 #include "DataFormats/Provenance/interface/EventID.h"
0029 #include "DataFormats/Provenance/interface/Timestamp.h"
0030 #include "EventFilter/Utilities/interface/crc32c.h"
0031 
0032 void DataModeFRD::readEvent(edm::EventPrincipal& eventPrincipal) {
0033   std::unique_ptr<FEDRawDataCollection> rawData(new FEDRawDataCollection);
0034   bool tcdsInRange;
0035   unsigned char* tcds_pointer = nullptr;
0036   edm::Timestamp tstamp = fillFEDRawDataCollection(*rawData, tcdsInRange, tcds_pointer);
0037 
0038   if (daqSource_->useL1EventID()) {
0039     uint32_t L1EventID = event_->event();
0040     edm::EventID eventID = edm::EventID(daqSource_->eventRunNumber(), daqSource_->currentLumiSection(), L1EventID);
0041     edm::EventAuxiliary aux(
0042         eventID, daqSource_->processGUID(), tstamp, event_->isRealData(), edm::EventAuxiliary::PhysicsTrigger);
0043     aux.setProcessHistoryID(daqSource_->processHistoryID());
0044     daqSource_->makeEventWrapper(eventPrincipal, aux);
0045   } else if (tcds_pointer == nullptr) {
0046     uint32_t L1EventID = event_->event();
0047     throw cms::Exception("DAQSource::read") << "No TCDS FED in event with FEDHeader EID -: " << L1EventID;
0048   } else {
0049     const FEDHeader fedHeader(tcds_pointer);
0050     tcds::Raw_v1 const* tcds = reinterpret_cast<tcds::Raw_v1 const*>(tcds_pointer + FEDHeader::length);
0051     edm::EventAuxiliary aux =
0052         evf::evtn::makeEventAuxiliary(tcds,
0053                                       daqSource_->eventRunNumber(),      //TODO_ eventRunNumber_
0054                                       daqSource_->currentLumiSection(),  //currentLumiSection_
0055                                       event_->isRealData(),
0056                                       static_cast<edm::EventAuxiliary::ExperimentType>(fedHeader.triggerType()),
0057                                       daqSource_->processGUID(),
0058                                       !daqSource_->fileListLoopMode(),
0059                                       !tcdsInRange);
0060     aux.setProcessHistoryID(daqSource_->processHistoryID());
0061     daqSource_->makeEventWrapper(eventPrincipal, aux);
0062   }
0063 
0064   std::unique_ptr<edm::WrapperBase> edp(new edm::Wrapper<FEDRawDataCollection>(std::move(rawData)));
0065   eventPrincipal.put(
0066       daqProvenanceHelpers_[0]->branchDescription(), std::move(edp), daqProvenanceHelpers_[0]->dummyProvenance());
0067 }
0068 
0069 edm::Timestamp DataModeFRD::fillFEDRawDataCollection(FEDRawDataCollection& rawData,
0070                                                      bool& tcdsInRange,
0071                                                      unsigned char*& tcds_pointer) {
0072   edm::TimeValue_t time;
0073   timeval stv;
0074   gettimeofday(&stv, nullptr);
0075   time = stv.tv_sec;
0076   time = (time << 32) + stv.tv_usec;
0077   edm::Timestamp tstamp(time);
0078 
0079   uint32_t eventSize = event_->eventSize();
0080   unsigned char* event = (unsigned char*)event_->payload();
0081   tcds_pointer = nullptr;
0082   tcdsInRange = false;
0083   uint16_t selectedTCDSFed = 0;
0084   while (eventSize > 0) {
0085     assert(eventSize >= FEDTrailer::length);
0086     eventSize -= FEDTrailer::length;
0087     const FEDTrailer fedTrailer(event + eventSize);
0088     const uint32_t fedSize = fedTrailer.fragmentLength() << 3;  //trailer length counts in 8 bytes
0089     assert(eventSize >= fedSize - FEDHeader::length);
0090     eventSize -= (fedSize - FEDHeader::length);
0091     const FEDHeader fedHeader(event + eventSize);
0092     const uint16_t fedId = fedHeader.sourceID();
0093     if (fedId > FEDNumbering::MAXFEDID) {
0094       throw cms::Exception("DAQSource::fillFEDRawDataCollection") << "Out of range FED ID : " << fedId;
0095     } else if (fedId >= MINTCDSuTCAFEDID_ && fedId <= MAXTCDSuTCAFEDID_) {
0096       if (!selectedTCDSFed) {
0097         selectedTCDSFed = fedId;
0098         tcds_pointer = event + eventSize;
0099         if (fedId >= FEDNumbering::MINTCDSuTCAFEDID && fedId <= FEDNumbering::MAXTCDSuTCAFEDID) {
0100           tcdsInRange = true;
0101         }
0102       } else
0103         throw cms::Exception("DAQSource::fillFEDRawDataCollection")
0104             << "Second TCDS FED ID " << fedId << " found. First ID: " << selectedTCDSFed;
0105     }
0106     //take event ID from GTPE FED
0107     FEDRawData& fedData = rawData.FEDData(fedId);
0108     fedData.resize(fedSize);
0109     memcpy(fedData.data(), event + eventSize, fedSize);
0110   }
0111   assert(eventSize == 0);
0112 
0113   return tstamp;
0114 }
0115 
0116 std::vector<std::shared_ptr<const edm::DaqProvenanceHelper>>& DataModeFRD::makeDaqProvenanceHelpers() {
0117   //set FRD data collection
0118   daqProvenanceHelpers_.clear();
0119   daqProvenanceHelpers_.emplace_back(std::make_shared<const edm::DaqProvenanceHelper>(
0120       edm::TypeID(typeid(FEDRawDataCollection)), "FEDRawDataCollection", "FEDRawDataCollection", "DAQSource"));
0121   return daqProvenanceHelpers_;
0122 }
0123 
0124 bool DataModeFRD::nextEventView() {
0125   if (eventCached_)
0126     return true;
0127   event_ = std::make_unique<FRDEventMsgView>(dataBlockAddr_);
0128   if (event_->size() > dataBlockMax_) {
0129     throw cms::Exception("DAQSource::getNextEvent")
0130         << " event id:" << event_->event() << " lumi:" << event_->lumi() << " run:" << event_->run()
0131         << " of size:" << event_->size() << " bytes does not fit into a chunk of size:" << dataBlockMax_ << " bytes";
0132   }
0133   return true;
0134 }
0135 
0136 bool DataModeFRD::checksumValid() {
0137   crc_ = 0;
0138   if (event_->version() >= 5) {
0139     crc_ = crc32c(crc_, (const unsigned char*)event_->payload(), event_->eventSize());
0140     if (crc_ != event_->crc32c())
0141       return false;
0142   }
0143   return true;
0144 }
0145 
0146 std::string DataModeFRD::getChecksumError() const {
0147   std::stringstream ss;
0148   ss << "Found a wrong crc32c checksum: expected 0x" << std::hex << event_->crc32c() << " but calculated 0x" << crc_;
0149   return ss.str();
0150 }
0151 
0152 /*
0153  * FRD Multi Test
0154  */
0155 
0156 void DataModeFRDStriped::makeDirectoryEntries(std::vector<std::string> const& baseDirs, std::string const& runDir) {
0157   std::filesystem::path runDirP(runDir);
0158   for (auto& baseDir : baseDirs) {
0159     std::filesystem::path baseDirP(baseDir);
0160     buPaths_.emplace_back(baseDirP / runDirP);
0161   }
0162 }
0163 
0164 void DataModeFRDStriped::readEvent(edm::EventPrincipal& eventPrincipal) {
0165   assert(!events_.empty());
0166   std::unique_ptr<FEDRawDataCollection> rawData(new FEDRawDataCollection);
0167   bool tcdsInRange;
0168   unsigned char* tcds_pointer = nullptr;
0169   edm::Timestamp tstamp = fillFRDCollection(*rawData, tcdsInRange, tcds_pointer);
0170 
0171   auto const& event = events_[0];
0172   if (daqSource_->useL1EventID()) {
0173     uint32_t L1EventID = event->event();
0174     edm::EventID eventID = edm::EventID(daqSource_->eventRunNumber(), daqSource_->currentLumiSection(), L1EventID);
0175     edm::EventAuxiliary aux(
0176         eventID, daqSource_->processGUID(), tstamp, event->isRealData(), edm::EventAuxiliary::PhysicsTrigger);
0177     aux.setProcessHistoryID(daqSource_->processHistoryID());
0178     daqSource_->makeEventWrapper(eventPrincipal, aux);
0179   } else if (tcds_pointer == nullptr) {
0180     uint32_t L1EventID = event->event();
0181     throw cms::Exception("DAQSource::read") << "No TCDS FED in event with FEDHeader EID -: " << L1EventID;
0182   } else {
0183     const FEDHeader fedHeader(tcds_pointer);
0184     tcds::Raw_v1 const* tcds = reinterpret_cast<tcds::Raw_v1 const*>(tcds_pointer + FEDHeader::length);
0185     edm::EventAuxiliary aux =
0186         evf::evtn::makeEventAuxiliary(tcds,
0187                                       daqSource_->eventRunNumber(),
0188                                       daqSource_->currentLumiSection(),
0189                                       event->isRealData(),
0190                                       static_cast<edm::EventAuxiliary::ExperimentType>(fedHeader.triggerType()),
0191                                       daqSource_->processGUID(),
0192                                       !daqSource_->fileListLoopMode(),
0193                                       !tcdsInRange);
0194     aux.setProcessHistoryID(daqSource_->processHistoryID());
0195     daqSource_->makeEventWrapper(eventPrincipal, aux);
0196   }
0197   std::unique_ptr<edm::WrapperBase> edp(new edm::Wrapper<FEDRawDataCollection>(std::move(rawData)));
0198   eventPrincipal.put(
0199       daqProvenanceHelpers_[0]->branchDescription(), std::move(edp), daqProvenanceHelpers_[0]->dummyProvenance());
0200   eventCached_ = false;
0201 }
0202 
0203 edm::Timestamp DataModeFRDStriped::fillFRDCollection(FEDRawDataCollection& rawData,
0204                                                      bool& tcdsInRange,
0205                                                      unsigned char*& tcds_pointer) {
0206   edm::TimeValue_t time;
0207   timeval stv;
0208   gettimeofday(&stv, nullptr);
0209   time = stv.tv_sec;
0210   time = (time << 32) + stv.tv_usec;
0211   edm::Timestamp tstamp(time);
0212 
0213   tcds_pointer = nullptr;
0214   tcdsInRange = false;
0215   uint16_t selectedTCDSFed = 0;
0216   int selectedTCDSFileIndex = -1;
0217   for (size_t index = 0; index < events_.size(); index++) {
0218     uint32_t eventSize = events_[index]->eventSize();
0219     unsigned char* event = (unsigned char*)events_[index]->payload();
0220     while (eventSize > 0) {
0221       assert(eventSize >= FEDTrailer::length);
0222       eventSize -= FEDTrailer::length;
0223       const FEDTrailer fedTrailer(event + eventSize);
0224       const uint32_t fedSize = fedTrailer.fragmentLength() << 3;  //trailer length counts in 8 bytes
0225       assert(eventSize >= fedSize - FEDHeader::length);
0226       eventSize -= (fedSize - FEDHeader::length);
0227       const FEDHeader fedHeader(event + eventSize);
0228       const uint16_t fedId = fedHeader.sourceID();
0229       if (fedId > FEDNumbering::MAXFEDID) {
0230         throw cms::Exception("DataModeFRDStriped:::fillFRDCollection") << "Out of range FED ID : " << fedId;
0231       } else if (fedId >= MINTCDSuTCAFEDID_ && fedId <= MAXTCDSuTCAFEDID_) {
0232         if (!selectedTCDSFed) {
0233           selectedTCDSFed = fedId;
0234           selectedTCDSFileIndex = index;
0235           tcds_pointer = event + eventSize;
0236           if (fedId >= FEDNumbering::MINTCDSuTCAFEDID && fedId <= FEDNumbering::MAXTCDSuTCAFEDID) {
0237             tcdsInRange = true;
0238           }
0239         } else if (!testing_)
0240           throw cms::Exception("DataModeFRDStriped:::fillFRDCollection")
0241               << "Second TCDS FED ID " << fedId << " found in file " << selectedTCDSFileIndex
0242               << ". First ID: " << selectedTCDSFed << " in file " << index;
0243       }
0244       FEDRawData& fedData = rawData.FEDData(fedId);
0245       fedData.resize(fedSize);
0246       memcpy(fedData.data(), event + eventSize, fedSize);
0247     }
0248     assert(eventSize == 0);
0249   }
0250 
0251   return tstamp;
0252 }
0253 
0254 std::vector<std::shared_ptr<const edm::DaqProvenanceHelper>>& DataModeFRDStriped::makeDaqProvenanceHelpers() {
0255   //set FRD data collection
0256   daqProvenanceHelpers_.clear();
0257   daqProvenanceHelpers_.emplace_back(std::make_shared<const edm::DaqProvenanceHelper>(
0258       edm::TypeID(typeid(FEDRawDataCollection)), "FEDRawDataCollection", "FEDRawDataCollection", "DAQSource"));
0259   return daqProvenanceHelpers_;
0260 }
0261 
0262 /* TODO: adapt to multi-fils
0263 bool DataModeFRD::nextEventView() {
0264   if (eventCached_) return true;
0265   event_ = std::make_unique<FRDEventMsgView>(dataBlockAddr_);
0266   if (event_->size() > dataBlockMax_) {
0267     throw cms::Exception("DAQSource::getNextEvent")
0268       << " event id:" << event_->event() << " lumi:" << event_->lumi() << " run:" << event_->run()
0269       << " of size:" << event_->size() << " bytes does not fit into a chunk of size:" << dataBlockMax_
0270       << " bytes";
0271   }
0272   return true;
0273 }
0274 */
0275 
0276 bool DataModeFRDStriped::checksumValid() {
0277   bool status = true;
0278   for (size_t i = 0; i < events_.size(); i++) {
0279     uint32_t crc = 0;
0280     auto const& event = events_[i];
0281     if (event->version() >= 5) {
0282       crc = crc32c(crc, (const unsigned char*)event->payload(), event->eventSize());
0283       if (crc != event->crc32c()) {
0284         std::ostringstream ss;
0285         ss << "Found a wrong crc32c checksum at readout index " << i << ": expected 0x" << std::hex << event->crc32c()
0286            << " but calculated 0x" << crc << ". ";
0287         crcMsg_ += ss.str();
0288         status = false;
0289       }
0290     }
0291   }
0292   return status;
0293 }
0294 
0295 std::string DataModeFRDStriped::getChecksumError() const { return crcMsg_; }
0296 
0297 /*
0298   read multiple input files for this model
0299 */
0300 
0301 std::pair<bool, std::vector<std::string>> DataModeFRDStriped::defineAdditionalFiles(std::string const& primaryName,
0302                                                                                     bool fileListMode) const {
0303   std::vector<std::string> additionalFiles;
0304 
0305   if (fileListMode) {
0306     //for the unit test
0307     additionalFiles.push_back(primaryName + "_1");
0308     return std::make_pair(true, additionalFiles);
0309   }
0310 
0311   auto fullpath = std::filesystem::path(primaryName);
0312   auto fullname = fullpath.filename();
0313 
0314   for (size_t i = 1; i < buPaths_.size(); i++) {
0315     std::filesystem::path newPath = buPaths_[i] / fullname;
0316     additionalFiles.push_back(newPath.generic_string());
0317   }
0318   return std::make_pair(true, additionalFiles);
0319 }
0320 
0321 bool DataModeFRDStriped::nextEventView() {
0322   blockCompleted_ = false;
0323   if (eventCached_)
0324     return true;
0325   for (unsigned int i = 0; i < events_.size(); i++) {
0326     //add last event length to each stripe
0327     dataBlockAddrs_[i] += events_[i]->size();
0328   }
0329   return makeEvents();
0330 }
0331 
0332 bool DataModeFRDStriped::makeEvents() {
0333   events_.clear();
0334   assert(!blockCompleted_);
0335   for (int i = 0; i < numFiles_; i++) {
0336     if (dataBlockAddrs_[i] >= dataBlockMaxAddrs_[i]) {
0337       //must be exact
0338       assert(dataBlockAddrs_[i] == dataBlockMaxAddrs_[i]);
0339       blockCompleted_ = true;
0340       return false;
0341     } else {
0342       if (blockCompleted_)
0343         throw cms::Exception("DataModeFRDStriped::makeEvents")
0344             << "not all striped blocks were completed at the same time";
0345     }
0346     if (blockCompleted_)
0347       continue;
0348     events_.emplace_back(std::make_unique<FRDEventMsgView>(dataBlockAddrs_[i]));
0349     if (dataBlockAddrs_[i] + events_[i]->size() > dataBlockMaxAddrs_[i])
0350       throw cms::Exception("DAQSource::getNextEvent")
0351           << " event id:" << events_[i]->event() << " lumi:" << events_[i]->lumi() << " run:" << events_[i]->run()
0352           << " of size:" << events_[i]->size() << " bytes does not fit into the buffer or has corrupted header";
0353   }
0354   return !blockCompleted_;
0355 }