00001
00002
00003
00004
00005
00006
00007 #include <iostream>
00008 #include <iomanip>
00009 #include "CalibCalorimetry/EcalLaserSorting/interface/LmfSource.h"
00010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00011 #include "FWCore/Framework/interface/Event.h"
00012 #include "FWCore/Framework/interface/EventSetup.h"
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00015 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00016 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00017
00018 using namespace edm;
00019 using namespace std;
00020
00021 unsigned char LmfSource::minDataFormatVersion_ = 4;
00022 unsigned char LmfSource::maxDataFormatVersion_ = 5;
00023 unsigned LmfSource::fileHeaderSize = 2;
00024
00025
00026 LmfSource::LmfSource(const ParameterSet& pset,
00027 const InputSourceDescription& desc) :
00028 ProducerSourceBase(pset, desc, true),
00029 fileNames_(pset.getParameter<vector<string> >("fileNames")),
00030 iFile_ (-1),
00031 fedId_(-1),
00032 fileHeader_(fileHeaderSize),
00033 dataFormatVers_(5),
00034 rcRead_(false),
00035 preScale_(pset.getParameter<unsigned>("preScale")),
00036 iEvent_(0),
00037 iEventInFile_(0),
00038 indexTablePos_(0),
00039 orderedRead_(pset.getParameter<bool>("orderedRead")),
00040 watchFileList_(pset.getParameter<bool>("watchFileList")),
00041 fileListName_(pset.getParameter<std::string>("fileListName")),
00042 inputDir_(pset.getParameter<std::string>("inputDir")),
00043 nSecondsToSleep_(pset.getParameter<int>("nSecondsToSleep")),
00044 verbosity_(pset.getUntrackedParameter<int>("verbosity"))
00045 {
00046 if(preScale_==0) preScale_ = 1;
00047 produces<FEDRawDataCollection>();
00048
00049 if (watchFileList_) {
00050 fileList_.open( fileListName_.c_str() );
00051 if (fileList_.fail()) {
00052 throw cms::Exception("FileListOpenError")
00053 << "Failed to open input file " << fileListName_ << "\n";
00054 }
00055 } else {
00056
00057 checkFileNames();
00058 }
00059 }
00060
00061 bool LmfSource::readFileHeader(){
00062 if(iFile_==-1) return false;
00063
00064 if(verbosity_) cout << "[LmfSource]"
00065 << "Opening file #" << (iFile_+1) << " '"
00066 << currentFileName_ << "'\n";
00067
00068 in_.read((char*)&fileHeader_[0], fileHeaderSize*sizeof(uint32_t));
00069
00070 if(in_.eof()) return false;
00071
00072 if(verbosity_){
00073 cout << "[LmfSource]"
00074 << "File header (in hex):" << hex;
00075 for(unsigned i=0; i < fileHeaderSize; ++i){
00076 if(i%8==0) cout << "\n";
00077 cout << setw(8) << fileHeader_[i] << " ";
00078 }
00079 cout << dec << "\n";
00080 }
00081
00082
00083 char id[4];
00084
00085 id[0] = fileHeader_[0] & 0xFF;
00086 id[1] = (fileHeader_[0] >>8) & 0xFF;
00087 id[2] = (fileHeader_[0] >>16) & 0xFF;
00088 id[3] = (fileHeader_[0] >>24) & 0xFF;
00089
00090 if(!(id[0]=='L' && id[1] == 'M'
00091 && id[2] == 'F')){
00092 throw cms::Exception("FileReadError")
00093 << currentFileName_ << " is not a file in LMF format!";
00094 }
00095 dataFormatVers_ = id[3];
00096 if(verbosity_) cout << "[LmfSource]"
00097 << "LMF format: " << (int)dataFormatVers_ << "\n";
00098
00099 if(dataFormatVers_ > maxDataFormatVersion_
00100 || dataFormatVers_ < minDataFormatVersion_){
00101 throw cms::Exception("FileReadError")
00102 << currentFileName_ << ": LMF format version " << (int) dataFormatVers_
00103 << " is not supported by this release of LmfSource module";
00104 }
00105
00106 indexTablePos_ = fileHeader_[1];
00107
00108 if(verbosity_) cout << "[LmfSource] File position of index table: 0x"
00109 << setfill('0') << hex << setw(8) << indexTablePos_
00110 << setfill(' ') << dec << "\n";
00111
00112 if(dataFormatVers_ < 5){
00113 in_.ignore(4);
00114 }
00115
00116 return true;
00117 }
00118
00119 void LmfSource::produce(edm::Event& evt){
00120
00121
00122
00123
00124
00125
00126
00127
00128 auto_ptr<FEDRawDataCollection> coll(new FEDRawDataCollection);
00129 coll->swap(fedColl_);
00130 if(verbosity_) cout << "[LmfSource] Putting FEDRawDataCollection in event\n";
00131 evt.put(coll);
00132 }
00133
00134 bool LmfSource::openFile(int iFile){
00135 iEventInFile_ = 0;
00136 if(watchFileList_) {
00137 for ( ;; ) {
00138
00139 fileList_ >> currentFileName_;
00140 currentFileName_ = inputDir_ + "/" + currentFileName_;
00141 if (!fileList_.fail()) {
00142
00143 std::string tmp_buffer;
00144 std::getline(fileList_, tmp_buffer);
00145 if(verbosity_) cout << "[LmfSource]"
00146 << "Opening file " << currentFileName_ << "\n";
00147 in_.open(currentFileName_.c_str());
00148 if (!in_.fail()) {
00149
00150 return true;
00151 } else {
00152
00153 edm::LogError("FileOpenError")
00154 << "Failed to open input file " << currentFileName_ << ". Skipping file\n";
00155 in_.close();
00156 in_.clear();
00157 }
00158 }
00159
00160 if (verbosity_) std::cout << "[LmfSource]"
00161 << " going to sleep 5 seconds\n";
00162 sleep(nSecondsToSleep_);
00163 fileList_.clear();
00164 }
00165 } else {
00166 if(iFile > (int)fileNames_.size()-1) return false;
00167 currentFileName_ = fileNames_[iFile];
00168 if(verbosity_) cout << "[LmfSource]"
00169 << "Opening file " << currentFileName_ << "\n";
00170 in_.open(currentFileName_.c_str());
00171 if(in_.fail()){
00172 throw cms::Exception("FileOpenError")
00173 << "Failed to open input file " << currentFileName_ << "\n";
00174 }
00175 }
00176 return true;
00177 }
00178
00179 bool LmfSource::nextEventWithinFile(){
00180 if(iFile_<0) return false;
00181 if(orderedRead_){
00182 if(iEventInFile_>=indexTable_.size()) return false;
00183 if(verbosity_){
00184 cout << "[LmfSource] move to event with orbit Id "
00185 << indexTable_[iEventInFile_].orbit
00186 << " at file position 0x"
00187 << hex << setfill('0')
00188 << setw(8) << indexTable_[iEventInFile_].filePos
00189 << setfill(' ') << dec << "\n";
00190 }
00191 const streampos pos = indexTable_[iEventInFile_].filePos;
00192 in_.clear();
00193 in_.seekg(pos);
00194 if(in_.bad()){
00195 cout << "[LmfSource] Problem while reading file "
00196 << currentFileName_ << ". Problem with event index table?\n";
00197 return false;
00198 }
00199 ++iEventInFile_;
00200 return true;
00201 } else{
00202 return true;
00203 }
00204 }
00205
00206 bool LmfSource::readEvent(bool doSkip){
00207 while(!(nextEventWithinFile() && readEventWithinFile(doSkip))){
00208
00209 in_.close();
00210 in_.clear();
00211 bool rcOpen = openFile(++iFile_);
00212 if(rcOpen==false){
00213 if(verbosity_) cout << "[LmfSource]"
00214 << "No more input file";
00215 rcRead_ = false;
00216 return rcRead_;
00217 }
00218 rcRead_ = readFileHeader();
00219 if(verbosity_) cout << "File header readout "
00220 << (rcRead_?"succeeded":"failed") << "\n";
00221 if(rcRead_ && orderedRead_) readIndexTable();
00222 }
00223 return rcRead_;
00224 }
00225
00226 bool LmfSource::setRunAndEventInfo(EventID& id, TimeValue_t& time){
00227
00228 if(fedId_>0){
00229 fedColl_.FEDData(fedId_).resize(0);
00230 }
00231 if(verbosity_) cout << "[LmfSource]"
00232 << "About to read event...\n";
00233
00234 bool rc;
00235 for(;;){
00236 if(filter()){
00237 rc = readEvent();
00238 break;
00239 } else {
00240 rc = readEvent(true);
00241 if(rc==false){
00242 break;
00243 }
00244 }
00245 }
00246
00247 if(!rc) return false;
00248
00249 if(verbosity_) cout << "[LmfSource]"
00250 << "Setting event time to "
00251 << timeStamp_ << ", "
00252 << "Run number to " << runNum_ << ","
00253 << "Event number to " << eventNum_ << "\n";
00254
00255 time = timeStamp_;
00256 id = EventID(runNum_, lumiBlock_, eventNum_);
00257 return true;
00258 }
00259
00260 bool LmfSource::readEventWithinFile(bool doSkip){
00261 if(iFile_==-1 || !rcRead_) return false;
00262
00263
00264
00265 const int timeStamp32[] = {0, 0};
00266 const int lumiBlock32[] = {2, 2};
00267 const int runNum32[] = {3, 3};
00268 const int orbitNum32[] = {4, 4};
00269 const int bx32[] = {5, 5};
00270 const int eventNum32[] = {6, 6};
00271 const int activeFedId32[] = {7,-1};
00272 const int calibTrig32[] = {-1,7};
00273 const int nFeds32[] = {-1,8};
00274
00275 const int evtHeadSize32[] = {8,10};
00276
00277 const unsigned char iv = dataFormatVers_-minDataFormatVersion_;
00278 assert(iv<=sizeof(timeStamp32)/sizeof(timeStamp32[0]));
00279
00280 if((int)header_.size() < evtHeadSize32[iv]) header_.resize(evtHeadSize32[iv]);
00281
00282
00283 if(verbosity_) cout << "[LmfSource]"
00284 << "Reading event header\n";
00285
00286 in_.read((char*)&header_[0], evtHeadSize32[iv]*4);
00287 if(in_.bad()){
00288 throw cms::Exception("FileReadError")
00289 << "Error while reading from file " << currentFileName_;
00290 }
00291 if(in_.eof()) return false;
00292
00293 if(verbosity_){
00294 cout << "[LmfSource]"
00295 << "Event header (in hex):" << hex << setfill('0');
00296 for(int i=0; i < evtHeadSize32[iv]; ++i){
00297 if(i%8==0) cout << "\n";
00298 cout << setw(8) << header_[i] << " ";
00299 }
00300 cout << dec << setfill(' ') << "\n";
00301 }
00302
00303 timeStamp_ = *(uint64_t*)&header_[timeStamp32[iv]];
00304 lumiBlock_ = header_[lumiBlock32[iv]];
00305 runNum_ = header_[runNum32[iv]];
00306 orbitNum_ = header_[orbitNum32[iv]];
00307 eventNum_ = header_[eventNum32[iv]];
00308 bx_ = header_[bx32[iv]];
00309 calibTrig_ = calibTrig32[iv]>=0?header_[calibTrig32[iv]]:0;
00310 int activeFedId = activeFedId32[iv]>=0?
00311 header_[activeFedId32[iv]]:
00312 ((calibTrig_ & 0x3F) + 600);
00313 nFeds_ = nFeds32<0?1:header_[nFeds32[iv]];
00314
00315 if(verbosity_){
00316 cout << "[LmfSource] "
00317 << "timeStamp: " << timeStamp_ << "\n"
00318 << "lumiBlock: " << lumiBlock_ << "\n"
00319 << "runNum: " << runNum_ << "\n"
00320 << "orbitNum: " << orbitNum_ << "\n"
00321 << "eventNum: " << eventNum_ << "\n"
00322 << "bx: " << bx_ << "\n"
00323 << "activeFedId: " << activeFedId << "\n"
00324 << "Calib trigger type: " << ((calibTrig_ >>8) & 0x3) << "\n"
00325 << "Color: " << ((calibTrig_ >>6) & 0x3) << "\n"
00326 << "nFeds: " << nFeds_ << "\n";
00327 }
00328
00329 const int dccLenOffset32 = 2;
00330 const int fedIdOffset32 = 0;
00331 const int nPreRead32 = 3;
00332 vector<int32_t> buf(nPreRead32);
00333 for(int iFed = 0; iFed < nFeds_; ++iFed){
00334 in_.read((char*) &buf[0], nPreRead32*sizeof(uint32_t));
00335
00336 if(verbosity_){
00337 cout << "[LmfSource] " << nPreRead32 << " first 32-bit words of "
00338 << "FED block: " << hex << setfill('0');
00339 for(unsigned i = 0; i< buf.size(); ++i){
00340 cout << "0x" << setw(8) << buf[i] << " ";
00341 }
00342 cout << dec << setfill(' ');
00343 }
00344
00345
00346 if(in_.bad()) return false;
00347
00348 const unsigned eventSize64 = buf[dccLenOffset32] & 0x00FFFFFF;
00349 const unsigned eventSize32 = eventSize64*2;
00350 const unsigned eventSize8 = eventSize64*8;
00351 const unsigned fedId_ = (buf[fedIdOffset32] >>8) & 0xFFF;
00352
00353 if(eventSize8 > maxEventSize_){
00354 throw cms::Exception("FileReadError")
00355 << "Size of event fragment (FED block) read from "
00356 << " data of file " << currentFileName_
00357 << "is unexpctively large (" << (eventSize8 >>10)
00358 << " kByte). "
00359 << "This must be an error (corrupted file?)\n";
00360 }
00361
00362 if(!FEDNumbering::inRange(fedId_)){
00363 throw cms::Exception("FileReadError")
00364 << "Invalid FED number read from data file.";
00365 }
00366
00367 int32_t toRead8 = (eventSize32-nPreRead32)*sizeof(int32_t);
00368
00369 if(toRead8<0){
00370 throw cms::Exception("FileReadError")
00371 << "Event size error while reading an event from file "
00372 << currentFileName_ << "\n";
00373 }
00374
00375 if(doSkip){
00376 if(verbosity_) cout << "[LmfSource] "
00377 << "Skipping on event. Move file pointer "
00378 << toRead8 << " ahead.\n";
00379 in_.seekg(toRead8, ios::cur);
00380 if(in_.bad()){
00381 throw cms::Exception("FileReadError")
00382 << "Error while reading from file " << currentFileName_;
00383 }
00384 } else{
00385
00386 FEDRawData& data_ = fedColl_.FEDData(fedId_);
00387 data_.resize(eventSize8);
00388
00389
00390 copy(buf.begin(), buf.end(), (int32_t*)data_.data());
00391
00392 in_.read((char*)(data_.data()) + nPreRead32*4,
00393 toRead8);
00394
00395 if(in_.bad()){
00396 throw cms::Exception("FileReadError")
00397 << "Error while reading from file " << currentFileName_;
00398 }
00399
00400 if(verbosity_ && data_.size()>16){
00401 cout << "[LmfSource]"
00402 << "Head of DCC data (in hex):" << hex;
00403 for(int i=0; i < 16; ++i){
00404 if(i%8==0) cout << "\n";
00405 cout << setw(8) << ((uint32_t*)data_.data())[i] << " ";
00406 }
00407 cout << dec << "\n";
00408 }
00409
00410 if(dataFormatVers_<=4){
00411
00412 calibTrig_ = (((uint32_t*)data_.data())[5] & 0xFC0)
00413 | ((activeFedId-600) & 0x3F);
00414 if(verbosity_){
00415 cout << "[LmfSource] Old data format. "
00416 "Uses information read from FED block to retrieve calibration "
00417 "trigger type. Value is: 0x"
00418 << hex << setfill('0') << setw(3) << calibTrig_
00419 << setfill(' ') << dec << "\n";
00420 }
00421 }
00422 }
00423 if(in_.eof()) return false;
00424 }
00425 ++iEvent_;
00426 return true;
00427 }
00428
00429 bool LmfSource::filter() const{
00430 return (iEvent_%preScale_==0);
00431 }
00432
00433 std::string LmfSource::toString(TimeValue_t& t) const{
00434 char buf[256];
00435 const int secTousec = 1000*1000;
00436 time_t tsec = t/secTousec;
00437 uint32_t tusec = (uint32_t)(t-tsec);
00438 strftime(buf, sizeof(buf), "%F %R %S s", localtime(&tsec));
00439 buf[sizeof(buf)-1] = 0;
00440 stringstream buf2;
00441 buf2 << (tusec+500)/1000;
00442 return string(buf) + " " + buf2.str() + " ms";
00443 }
00444
00445 void LmfSource::checkFileNames(){
00446 for(unsigned i = 0; i < fileNames_.size(); ++i){
00447 std::string& fileName = fileNames_[i];
00448 const char s[] = "file:";
00449 if(fileName.compare(0, sizeof(s)-1, s)==0){
00450 fileName.erase(fileName.begin(),
00451 fileName.begin() + sizeof(s)-1);
00452 }
00453 if(fileName.find_first_of(":")!=string::npos){
00454 throw cms::Exception("LmfSource")
00455 << "Character ':' is not allowed in paths specified fileNames "
00456 << "parameter. Please note only local file (or NFS, AFS)"
00457 << " is supported (no rfio, no /store)";
00458 }
00459 const char s1[] = "/store";
00460 if(fileName.compare(0, sizeof(s1)-1, s1)==0){
00461 throw cms::Exception("LmfSource")
00462 << "CMSSW /store not supported by LmfSource. Only local file "
00463 << "(or NFS/AFS) allowed. Path starting with /store not permitted";
00464 }
00465 }
00466 }
00467
00468 void LmfSource::readIndexTable(){
00469
00470 stringstream errMsg;
00471 errMsg << "Error while reading event index table of file "
00472 << currentFileName_ << ". Try to read it with "
00473 << "option orderedRead disabled.\n";
00474
00475 if(indexTablePos_==0) throw cms::Exception("LmfSource") << errMsg.str();
00476
00477 in_.clear();
00478 in_.seekg(indexTablePos_);
00479
00480 uint32_t nevts = 0;
00481 in_.read((char*)&nevts, sizeof(nevts));
00482 in_.ignore(4);
00483 if(nevts>maxEvents_){
00484 throw cms::Exception("LmfSource")
00485 << "Number of events indicated in event index of file "
00486 << currentFileName_ << " is unexpectively large. File cannot be "
00487 << "read in time-ordered event mode. See orderedRead parmater of "
00488 << "LmfSource module.\n";
00489 }
00490
00491 if(in_.bad()) throw cms::Exception("LmfSource") << errMsg.str();
00492 indexTable_.resize(nevts);
00493 in_.read((char*)&indexTable_[0], nevts*sizeof(IndexRecord));
00494 }