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