Back to home page

Project CMSSW displayed by LXR

 
 

    


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