File indexing completed on 2024-04-06 11:57:58
0001
0002
0003
0004
0005 #include <iostream>
0006 #include <iomanip>
0007 #include "CalibCalorimetry/EcalLaserSorting/interface/LmfSource.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0009 #include "FWCore/Framework/interface/Event.h"
0010 #include "FWCore/Framework/interface/EventSetup.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0013 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0014 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0015
0016 using namespace edm;
0017 using namespace std;
0018
0019 const unsigned char LmfSource::minDataFormatVersion_ = 4;
0020 const unsigned char LmfSource::maxDataFormatVersion_ = 5;
0021 const unsigned LmfSource::fileHeaderSize = 2;
0022
0023 LmfSource::LmfSource(const ParameterSet& pset, const InputSourceDescription& desc)
0024 : ProducerSourceBase(pset, desc, true),
0025 fileNames_(pset.getParameter<vector<string> >("fileNames")),
0026 iFile_(-1),
0027 fedId_(-1),
0028 fileHeader_(fileHeaderSize),
0029 dataFormatVers_(5),
0030 rcRead_(false),
0031 preScale_(pset.getParameter<unsigned>("preScale")),
0032 iEvent_(0),
0033 iEventInFile_(0),
0034 indexTablePos_(0),
0035 orderedRead_(pset.getParameter<bool>("orderedRead")),
0036 watchFileList_(pset.getParameter<bool>("watchFileList")),
0037 fileListName_(pset.getParameter<std::string>("fileListName")),
0038 inputDir_(pset.getParameter<std::string>("inputDir")),
0039 nSecondsToSleep_(pset.getParameter<int>("nSecondsToSleep")),
0040 verbosity_(pset.getUntrackedParameter<int>("verbosity")) {
0041 if (preScale_ == 0)
0042 preScale_ = 1;
0043 produces<FEDRawDataCollection>();
0044
0045 if (watchFileList_) {
0046 fileList_.open(fileListName_.c_str());
0047 if (fileList_.fail()) {
0048 throw cms::Exception("FileListOpenError") << "Failed to open input file " << fileListName_ << "\n";
0049 }
0050 } else {
0051
0052 checkFileNames();
0053 }
0054 }
0055
0056 bool LmfSource::readFileHeader() {
0057 if (iFile_ == -1)
0058 return false;
0059
0060 if (verbosity_)
0061 cout << "[LmfSource]"
0062 << "Opening file #" << (iFile_ + 1) << " '" << currentFileName_ << "'\n";
0063
0064 in_.read((char*)&fileHeader_[0], fileHeaderSize * sizeof(uint32_t));
0065
0066 if (in_.eof())
0067 return false;
0068
0069 if (verbosity_) {
0070 cout << "[LmfSource]"
0071 << "File header (in hex):" << hex;
0072 for (unsigned i = 0; i < fileHeaderSize; ++i) {
0073 if (i % 8 == 0)
0074 cout << "\n";
0075 cout << setw(8) << fileHeader_[i] << " ";
0076 }
0077 cout << dec << "\n";
0078 }
0079
0080 char id[4];
0081
0082 id[0] = fileHeader_[0] & 0xFF;
0083 id[1] = (fileHeader_[0] >> 8) & 0xFF;
0084 id[2] = (fileHeader_[0] >> 16) & 0xFF;
0085 id[3] = (fileHeader_[0] >> 24) & 0xFF;
0086
0087 if (!(id[0] == 'L' && id[1] == 'M' && id[2] == 'F')) {
0088 throw cms::Exception("FileReadError") << currentFileName_ << " is not a file in LMF format!";
0089 }
0090 dataFormatVers_ = id[3];
0091 if (verbosity_)
0092 cout << "[LmfSource]"
0093 << "LMF format: " << (int)dataFormatVers_ << "\n";
0094
0095 if (dataFormatVers_ > maxDataFormatVersion_ || dataFormatVers_ < minDataFormatVersion_) {
0096 throw cms::Exception("FileReadError") << currentFileName_ << ": LMF format version " << (int)dataFormatVers_
0097 << " is not supported by this release of LmfSource module";
0098 }
0099
0100 indexTablePos_ = fileHeader_[1];
0101
0102 if (verbosity_)
0103 cout << "[LmfSource] File position of index table: 0x" << setfill('0') << hex << setw(8) << indexTablePos_
0104 << setfill(' ') << dec << "\n";
0105
0106 if (dataFormatVers_ < 5) {
0107 in_.ignore(4);
0108 }
0109
0110 return true;
0111 }
0112
0113 void LmfSource::produce(edm::Event& evt) {
0114
0115
0116
0117
0118
0119
0120
0121
0122 auto coll = std::make_unique<FEDRawDataCollection>();
0123 coll->swap(fedColl_);
0124 if (verbosity_)
0125 cout << "[LmfSource] Putting FEDRawDataCollection in event\n";
0126 evt.put(std::move(coll));
0127 }
0128
0129 bool LmfSource::openFile(int iFile) {
0130 iEventInFile_ = 0;
0131 if (watchFileList_) {
0132 for (;;) {
0133
0134 fileList_ >> currentFileName_;
0135 currentFileName_ = inputDir_ + "/" + currentFileName_;
0136 if (!fileList_.fail()) {
0137
0138 std::string tmp_buffer;
0139 std::getline(fileList_, tmp_buffer);
0140 if (verbosity_)
0141 cout << "[LmfSource]"
0142 << "Opening file " << currentFileName_ << "\n";
0143 in_.open(currentFileName_.c_str());
0144 if (!in_.fail()) {
0145
0146 return true;
0147 } else {
0148
0149 edm::LogError("FileOpenError") << "Failed to open input file " << currentFileName_ << ". Skipping file\n";
0150 in_.close();
0151 in_.clear();
0152 }
0153 }
0154
0155 if (verbosity_)
0156 std::cout << "[LmfSource]"
0157 << " going to sleep 5 seconds\n";
0158 sleep(nSecondsToSleep_);
0159 fileList_.clear();
0160 }
0161 } else {
0162 if (iFile > (int)fileNames_.size() - 1)
0163 return false;
0164 currentFileName_ = fileNames_[iFile];
0165 if (verbosity_)
0166 cout << "[LmfSource]"
0167 << "Opening file " << currentFileName_ << "\n";
0168 in_.open(currentFileName_.c_str());
0169 if (in_.fail()) {
0170 throw cms::Exception("FileOpenError") << "Failed to open input file " << currentFileName_ << "\n";
0171 }
0172 }
0173 return true;
0174 }
0175
0176 bool LmfSource::nextEventWithinFile() {
0177 if (iFile_ < 0)
0178 return false;
0179 if (orderedRead_) {
0180 if (iEventInFile_ >= indexTable_.size())
0181 return false;
0182 if (verbosity_) {
0183 cout << "[LmfSource] move to event with orbit Id " << indexTable_[iEventInFile_].orbit << " at file position 0x"
0184 << hex << setfill('0') << setw(8) << indexTable_[iEventInFile_].filePos << setfill(' ') << dec << "\n";
0185 }
0186 const streampos pos = indexTable_[iEventInFile_].filePos;
0187 in_.clear();
0188 in_.seekg(pos);
0189 if (in_.bad()) {
0190 cout << "[LmfSource] Problem while reading file " << currentFileName_ << ". Problem with event index table?\n";
0191 return false;
0192 }
0193 ++iEventInFile_;
0194 return true;
0195 } else {
0196 return true;
0197 }
0198 }
0199
0200 bool LmfSource::readEvent(bool doSkip) {
0201 while (!(nextEventWithinFile() && readEventWithinFile(doSkip))) {
0202
0203 in_.close();
0204 in_.clear();
0205 bool rcOpen = openFile(++iFile_);
0206 if (rcOpen == false) {
0207 if (verbosity_)
0208 cout << "[LmfSource]"
0209 << "No more input file";
0210 rcRead_ = false;
0211 return rcRead_;
0212 }
0213 rcRead_ = readFileHeader();
0214 if (verbosity_)
0215 cout << "File header readout " << (rcRead_ ? "succeeded" : "failed") << "\n";
0216 if (rcRead_ && orderedRead_)
0217 readIndexTable();
0218 }
0219 return rcRead_;
0220 }
0221
0222 bool LmfSource::setRunAndEventInfo(EventID& id, TimeValue_t& time, edm::EventAuxiliary::ExperimentType& eType) {
0223
0224 if (fedId_ > 0) {
0225 fedColl_.FEDData(fedId_).resize(0);
0226 }
0227 if (verbosity_)
0228 cout << "[LmfSource]"
0229 << "About to read event...\n";
0230
0231 bool rc;
0232 for (;;) {
0233 if (filter()) {
0234 rc = readEvent();
0235 break;
0236 } else {
0237 rc = readEvent(true);
0238 if (rc == false) {
0239 break;
0240 }
0241 }
0242 }
0243
0244 if (!rc)
0245 return false;
0246
0247 if (verbosity_)
0248 cout << "[LmfSource]"
0249 << "Setting event time to " << timeStamp_ << ", "
0250 << "Run number to " << runNum_ << ","
0251 << "Event number to " << eventNum_ << "\n";
0252
0253 time = timeStamp_;
0254 id = EventID(runNum_, lumiBlock_, eventNum_);
0255 return true;
0256 }
0257
0258 bool LmfSource::readEventWithinFile(bool doSkip) {
0259 if (iFile_ == -1 || !rcRead_)
0260 return false;
0261
0262
0263
0264 const int timeStamp32[] = {0, 0};
0265 const int lumiBlock32[] = {2, 2};
0266 const int runNum32[] = {3, 3};
0267 const int orbitNum32[] = {4, 4};
0268 const int bx32[] = {5, 5};
0269 const int eventNum32[] = {6, 6};
0270 const int activeFedId32[] = {7, -1};
0271 const int calibTrig32[] = {-1, 7};
0272 const int nFeds32[] = {-1, 8};
0273
0274 const int evtHeadSize32[] = {8, 10};
0275
0276 const unsigned char iv = dataFormatVers_ - minDataFormatVersion_;
0277 assert(iv <= sizeof(timeStamp32) / sizeof(timeStamp32[0]));
0278
0279 if ((int)header_.size() < evtHeadSize32[iv])
0280 header_.resize(evtHeadSize32[iv]);
0281
0282 if (verbosity_)
0283 cout << "[LmfSource]"
0284 << "Reading event header\n";
0285
0286 in_.read((char*)&header_[0], evtHeadSize32[iv] * 4);
0287 if (in_.bad()) {
0288 throw cms::Exception("FileReadError") << "Error while reading from file " << currentFileName_;
0289 }
0290 if (in_.eof())
0291 return false;
0292
0293 if (verbosity_) {
0294 cout << "[LmfSource]"
0295 << "Event header (in hex):" << hex << setfill('0');
0296 for (int i = 0; i < evtHeadSize32[iv]; ++i) {
0297 if (i % 8 == 0)
0298 cout << "\n";
0299 cout << setw(8) << header_[i] << " ";
0300 }
0301 cout << dec << setfill(' ') << "\n";
0302 }
0303
0304 timeStamp_ = *(uint64_t*)&header_[timeStamp32[iv]];
0305 lumiBlock_ = header_[lumiBlock32[iv]];
0306 runNum_ = header_[runNum32[iv]];
0307 orbitNum_ = header_[orbitNum32[iv]];
0308 eventNum_ = header_[eventNum32[iv]];
0309 bx_ = header_[bx32[iv]];
0310 calibTrig_ = calibTrig32[iv] >= 0 ? header_[calibTrig32[iv]] : 0;
0311 int activeFedId = activeFedId32[iv] >= 0 ? header_[activeFedId32[iv]] : ((calibTrig_ & 0x3F) + 600);
0312 nFeds_ = nFeds32[iv] < 0 ? 1 : header_[nFeds32[iv]];
0313
0314 if (verbosity_) {
0315 time_t t = time_t(timeStamp_ >> 32);
0316 div_t t_ms_us = div(timeStamp_ & 0xFFFFFFFF, 1000);
0317 char tbuf[256];
0318 strftime(tbuf, sizeof(tbuf), "%F %T", localtime(&t));
0319 tbuf[sizeof(tbuf) - 1] = 0;
0320 cout << "[LmfSource] "
0321 << "timeStamp: " << timeStamp_ << " (" << tbuf << " " << t_ms_us.quot
0322 << " ms " << t_ms_us.rem << " us)\n"
0323 << "lumiBlock: " << lumiBlock_ << "\n"
0324 << "runNum: " << runNum_ << "\n"
0325 << "orbitNum: " << orbitNum_ << "\n"
0326 << "eventNum: " << eventNum_ << "\n"
0327 << "bx: " << bx_ << "\n"
0328 << "activeFedId: " << activeFedId << "\n"
0329 << "Calib trigger type: " << ((calibTrig_ >> 8) & 0x3) << "\n"
0330 << "Color: " << ((calibTrig_ >> 6) & 0x3) << "\n"
0331 << "Side: " << ((calibTrig_ >> 11) & 0x1) << "\n"
0332 << "nFeds: " << nFeds_ << "\n";
0333 }
0334
0335 const int dccLenOffset32 = 2;
0336 const int fedIdOffset32 = 0;
0337 const int nPreRead32 = 3;
0338 vector<int32_t> buf(nPreRead32);
0339 for (int iFed = 0; iFed < nFeds_; ++iFed) {
0340 in_.read((char*)&buf[0], nPreRead32 * sizeof(uint32_t));
0341
0342 if (verbosity_) {
0343 cout << "[LmfSource] " << nPreRead32 << " first 32-bit words of "
0344 << "FED block: " << hex << setfill('0');
0345 for (unsigned i = 0; i < buf.size(); ++i) {
0346 cout << "0x" << setw(8) << buf[i] << " ";
0347 }
0348 cout << dec << setfill(' ');
0349 }
0350
0351 if (in_.bad())
0352 return false;
0353
0354 const unsigned eventSize64 = buf[dccLenOffset32] & 0x00FFFFFF;
0355 const unsigned eventSize32 = eventSize64 * 2;
0356 const unsigned eventSize8 = eventSize64 * 8;
0357 const unsigned fedId_ = (buf[fedIdOffset32] >> 8) & 0xFFF;
0358
0359 if (eventSize8 > maxEventSize_) {
0360 throw cms::Exception("FileReadError")
0361 << "Size of event fragment (FED block) read from "
0362 << " data of file " << currentFileName_ << "is unexpctively large (" << (eventSize8 >> 10) << " kByte). "
0363 << "This must be an error (corrupted file?)\n";
0364 }
0365
0366 if (!FEDNumbering::inRange(fedId_)) {
0367 throw cms::Exception("FileReadError") << "Invalid FED number read from data file.";
0368 }
0369
0370 int32_t toRead8 = (eventSize32 - nPreRead32) * sizeof(int32_t);
0371
0372 if (toRead8 < 0) {
0373 throw cms::Exception("FileReadError")
0374 << "Event size error while reading an event from file " << currentFileName_ << "\n";
0375 }
0376
0377 if (doSkip) {
0378 if (verbosity_)
0379 cout << "[LmfSource] "
0380 << "Skipping on event. Move file pointer " << toRead8 << " ahead.\n";
0381 in_.seekg(toRead8, ios::cur);
0382 if (in_.bad()) {
0383 throw cms::Exception("FileReadError") << "Error while reading from file " << currentFileName_;
0384 }
0385 } else {
0386
0387 FEDRawData& data_ = fedColl_.FEDData(fedId_);
0388 data_.resize(eventSize8);
0389
0390
0391 copy(buf.begin(), buf.end(), (int32_t*)data_.data());
0392
0393 in_.read((char*)(data_.data()) + nPreRead32 * 4, toRead8);
0394
0395 if (in_.bad()) {
0396 throw cms::Exception("FileReadError") << "Error while reading from file " << currentFileName_;
0397 }
0398
0399 if (verbosity_ && data_.size() > 16) {
0400 cout << "[LmfSource]"
0401 << "Head of DCC data (in hex):" << hex;
0402 for (int i = 0; i < 16; ++i) {
0403 if (i % 8 == 0)
0404 cout << "\n";
0405 cout << setw(8) << ((uint32_t*)data_.data())[i] << " ";
0406 }
0407 cout << dec << "\n";
0408 }
0409
0410 if (dataFormatVers_ <= 4) {
0411
0412 calibTrig_ = (((uint32_t*)data_.data())[5] & 0xFC0) | ((activeFedId - 600) & 0x3F);
0413 if (verbosity_) {
0414 cout << "[LmfSource] Old data format. "
0415 "Uses information read from FED block to retrieve calibration "
0416 "trigger type. Value is: 0x"
0417 << hex << setfill('0') << setw(3) << calibTrig_ << setfill(' ') << dec << "\n";
0418 }
0419 }
0420 }
0421 if (in_.eof())
0422 return false;
0423 }
0424 ++iEvent_;
0425 return true;
0426 }
0427
0428 bool LmfSource::filter() const { return (iEvent_ % preScale_ == 0); }
0429
0430 std::string LmfSource::toString(TimeValue_t& t) const {
0431 char buf[256];
0432 const int secTousec = 1000 * 1000;
0433 time_t tsec = t / secTousec;
0434 uint32_t tusec = (uint32_t)(t - tsec);
0435 strftime(buf, sizeof(buf), "%F %R %S s", localtime(&tsec));
0436 buf[sizeof(buf) - 1] = 0;
0437 stringstream buf2;
0438 buf2 << (tusec + 500) / 1000;
0439 return string(buf) + " " + buf2.str() + " ms";
0440 }
0441
0442 void LmfSource::checkFileNames() {
0443 for (unsigned i = 0; i < fileNames_.size(); ++i) {
0444 std::string& fileName = fileNames_[i];
0445 const char s[] = "file:";
0446 if (fileName.compare(0, sizeof(s) - 1, s) == 0) {
0447 fileName.erase(fileName.begin(), fileName.begin() + sizeof(s) - 1);
0448 }
0449 if (fileName.find_first_of(':') != string::npos) {
0450 throw cms::Exception("LmfSource") << "Character ':' is not allowed in paths specified fileNames "
0451 << "parameter. Please note only local file (or NFS, AFS)"
0452 << " is supported (no rfio, no /store)";
0453 }
0454 const char s1[] = "/store";
0455 if (fileName.compare(0, sizeof(s1) - 1, s1) == 0) {
0456 throw cms::Exception("LmfSource") << "CMSSW /store not supported by LmfSource. Only local file "
0457 << "(or NFS/AFS) allowed. Path starting with /store not permitted";
0458 }
0459 }
0460 }
0461
0462 void LmfSource::readIndexTable() {
0463 stringstream errMsg;
0464 errMsg << "Error while reading event index table of file " << currentFileName_ << ". Try to read it with "
0465 << "option orderedRead disabled.\n";
0466
0467 if (indexTablePos_ == 0)
0468 throw cms::Exception("LmfSource") << errMsg.str();
0469
0470 in_.clear();
0471 in_.seekg(indexTablePos_);
0472
0473 uint32_t nevts = 0;
0474 in_.read((char*)&nevts, sizeof(nevts));
0475 in_.ignore(4);
0476 if (nevts > maxEvents_) {
0477 throw cms::Exception("LmfSource") << "Number of events indicated in event index of file " << currentFileName_
0478 << " is unexpectively large. File cannot be "
0479 << "read in time-ordered event mode. See orderedRead parmater of "
0480 << "LmfSource module.\n";
0481 }
0482
0483 if (in_.bad())
0484 throw cms::Exception("LmfSource") << errMsg.str();
0485 indexTable_.resize(nevts);
0486 in_.read((char*)&indexTable_[0], nevts * sizeof(IndexRecord));
0487 }