00001 #include "CSCFileReader.h"
00002
00003
00004
00005 #include <errno.h>
00006 #include <stdlib.h>
00007 #include <cstring>
00008
00009 #include <DataFormats/FEDRawData/interface/FEDHeader.h>
00010 #include <DataFormats/FEDRawData/interface/FEDTrailer.h>
00011 #include <DataFormats/FEDRawData/interface/FEDNumbering.h>
00012 #include <DataFormats/Provenance/interface/EventID.h>
00013 #include <DataFormats/Provenance/interface/Timestamp.h>
00014 #include <DataFormats/FEDRawData/interface/FEDRawData.h>
00015 #include <DataFormats/FEDRawData/interface/FEDRawDataCollection.h>
00016
00017 #include <FWCore/ParameterSet/interface/ParameterSet.h>
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019
00020 #include <vector>
00021 #include <string>
00022 #include <iosfwd>
00023 #include <sstream>
00024 #include <iostream>
00025 #include <algorithm>
00026
00027 #define nRUIs 40
00028 #define nFUs 4
00029
00030 CSCFileReader::CSCFileReader(const edm::ParameterSet& pset):DaqBaseReader(){
00031 LogDebug("CSCFileReader|ctor")<<"Started ...";
00032
00033
00034 nActiveRUIs = 0;
00035 nActiveFUs = 0;
00036 for(int unit=0; unit<nRUIs; unit++){
00037 std::ostringstream ruiName, fuName;
00038 ruiName<<"RUI"<<(unit<10?"0":"")<<unit<<std::ends;
00039 fuName <<"FU" <<unit<<std::ends;
00040 std::vector<std::string> ruiFiles = pset.getUntrackedParameter< std::vector<std::string> >(ruiName.str().c_str(),std::vector<std::string>(0));
00041 std::vector<std::string> fuFiles = pset.getUntrackedParameter< std::vector<std::string> >(fuName.str().c_str(),std::vector<std::string>(0));
00042 if( ruiFiles.begin() != ruiFiles.end() ) nActiveRUIs++;
00043 if( fuFiles.begin() != fuFiles.end() ) nActiveFUs++;
00044 }
00045 if( nActiveFUs && nActiveRUIs )
00046 throw cms::Exception("CSCFileReader|configuration")<<"RUIs and FUs in conflict: either RUI or FU may be defined at a time, not both";
00047 if( !nActiveFUs && !nActiveRUIs )
00048 throw cms::Exception("CSCFileReader|configuration")<<"Module lacks configuration";
00049
00050
00051
00052 for(int rui=0; rui<nRUIs && !nActiveFUs; rui++){
00053 std::ostringstream name;
00054 name<<"RUI"<<(rui<10?"0":"")<<rui<<std::ends;
00055
00056
00057 fileNames[rui] = pset.getUntrackedParameter< std::vector<std::string> >(name.str().c_str(),std::vector<std::string>(0));
00058 currentFile[rui] = fileNames[rui].begin();
00059
00060
00061 if( currentFile[rui] != fileNames[rui].end() ){
00062 try {
00063 RUI[rui].open(currentFile[rui]->c_str());
00064 } catch ( std::runtime_error err ){
00065 throw cms::Exception("CSCFileReader")<<"InputFileMissing: "<<err.what()<<" (errno="<<errno<<")";
00066 }
00067 nActiveRUIs++;
00068 }
00069
00070
00071 RUI[rui].reject(FileReaderDDU::DDUoversize|FileReaderDDU::FFFF|FileReaderDDU::Unknown);
00072
00073 RUI[rui].select(0);
00074
00075 currentL1A[rui] = -1;
00076 }
00077
00078
00079 for(int fu=0; fu<nFUs && !nActiveRUIs; fu++){
00080 std::ostringstream name;
00081 name<<"FU"<<fu<<std::ends;
00082
00083
00084 fileNames[fu] = pset.getUntrackedParameter< std::vector<std::string> >(name.str().c_str(),std::vector<std::string>(0));
00085 currentFile[fu] = fileNames[fu].begin();
00086
00087
00088 if( currentFile[fu] != fileNames[fu].end() ){
00089 try {
00090 FU[fu].open(currentFile[fu]->c_str());
00091 } catch ( std::runtime_error err ){
00092 throw cms::Exception("CSCFileReader")<<"InputFileMissing: "<<err.what()<<" (errno="<<errno<<")";
00093 }
00094 nActiveFUs++;
00095 }
00096
00097
00098 FU[fu].reject(FileReaderDCC::DCCoversize|FileReaderDCC::FFFF|FileReaderDCC::Unknown);
00099
00100 FU[fu].select(0);
00101
00102 currentL1A[fu] = -1;
00103 }
00104
00105 if( nActiveRUIs && !nActiveFUs ){
00106
00107 for(int fed=FEDNumbering::MINCSCFEDID; fed<=FEDNumbering::MAXCSCFEDID; fed++){
00108 std::ostringstream name;
00109 name<<"FED"<<fed<<std::ends;
00110 std::vector<std::string> rui_list = pset.getUntrackedParameter< std::vector<std::string> >(name.str().c_str(),std::vector<std::string>(0));
00111 for(std::vector<std::string>::const_iterator rui=rui_list.begin(); rui!=rui_list.end(); rui++)
00112 FED[fed].push_back((unsigned int)atoi(rui->c_str()+rui->length()-2));
00113 }
00114
00115 for(int fed=FEDNumbering::MINCSCTFFEDID; fed<=FEDNumbering::MAXCSCTFFEDID; fed++){
00116 std::ostringstream name;
00117 name<<"FED"<<fed<<std::ends;
00118 std::vector<std::string> rui_list = pset.getUntrackedParameter< std::vector<std::string> >(name.str().c_str(),std::vector<std::string>(0));
00119 for(std::vector<std::string>::const_iterator rui=rui_list.begin(); rui!=rui_list.end(); rui++)
00120 FED[fed].push_back((unsigned int)atoi(rui->c_str()+rui->length()-2));
00121 }
00122 }
00123
00124 firstEvent = pset.getUntrackedParameter<int>("firstEvent",0);
00125 nEvents = 0;
00126 expectedNextL1A = -1;
00127
00128
00129
00130 tfDDUnumber = pset.getUntrackedParameter<int>("tfDDUnumber",-1);
00131
00132
00133 tmpBuf = new unsigned short[200000*nRUIs+4*4];
00134
00135 fuEvent[0]=0; fuEventSize[0]=0;
00136 fuEvent[1]=0; fuEventSize[1]=0;
00137 fuEvent[2]=0; fuEventSize[2]=0;
00138 fuEvent[3]=0; fuEventSize[3]=0;
00139
00140 for(int rui=0; rui<nRUIs; rui++){
00141 ruBuf[rui] = 0;
00142 ruBufSize[rui] = 0;
00143 }
00144 LogDebug("CSCFileReader|ctor")<<"... and finished";
00145 }
00146
00147 CSCFileReader::~CSCFileReader(void){ if(tmpBuf) delete [] tmpBuf; }
00148
00149 int CSCFileReader::readRUI(int rui, const unsigned short* &buf, size_t &length){
00150 if( currentFile[rui] == fileNames[rui].end() ) return -1;
00151 do {
00152 try {
00153 length = RUI[rui].next(buf);
00154 } catch ( std::runtime_error err ){
00155 throw cms::Exception("CSCFileReader|reading")<<"EndOfStream: "<<err.what()<<" (errno="<<errno<<")";
00156 }
00157 if( length==0 ){
00158 if( ++currentFile[rui] != fileNames[rui].end() ){
00159 try {
00160 RUI[rui].open(currentFile[rui]->c_str());
00161 } catch ( std::runtime_error err ){
00162 throw cms::Exception("CSCFileReader|reading")<<"InputFileMissing: "<<err.what()<<" (errno="<<errno<<")";
00163 }
00164 } else return -1;
00165 }
00166 } while( length==0 );
00167 return buf[2]|((buf[3]&0xFF)<<16);
00168 }
00169
00170 int CSCFileReader::readFU(int fu, const unsigned short* &buf, size_t &length){
00171 if( currentFile[fu] == fileNames[fu].end() ) return -1;
00172 do {
00173 try {
00174 length = FU[fu].next(buf);
00175 } catch ( std::runtime_error err ){
00176 throw cms::Exception("CSCFileReader|reading")<<"EndOfStream: "<<err.what()<<" (errno="<<errno<<")";
00177 }
00178 if( length==0 ){
00179 if( ++currentFile[fu] != fileNames[fu].end() ){
00180 try {
00181 FU[fu].open(currentFile[fu]->c_str());
00182 } catch ( std::runtime_error err ){
00183 throw cms::Exception("CSCFileReader|reading")<<"InputFileMissing: "<<err.what()<<" (errno="<<errno<<")";
00184 }
00185 } else return -1;
00186 }
00187 } while( length==0 );
00188
00189 return buf[2+8]|((buf[3+8]&0xFF)<<16);
00190 }
00191
00192 int CSCFileReader::buildEventFromRUIs(FEDRawDataCollection *data){
00193 int eventNumber =-1;
00194
00195 do {
00196
00197 for(int rui=0; rui<nRUIs; rui++){
00198
00199
00200
00201 if((currentL1A[rui]>0 && currentL1A[rui]<expectedNextL1A) || expectedNextL1A<0 )
00202 currentL1A[rui] = readRUI(rui,ruBuf[rui],ruBufSize[rui]);
00203 }
00204 eventNumber =-1;
00205
00206
00207 for(int rui=0; rui<nRUIs; rui++)
00208 if( currentL1A[rui]>=0 && (eventNumber>currentL1A[rui] || eventNumber==-1) ) eventNumber=currentL1A[rui];
00209
00210 if( eventNumber<0 ) return -1;
00211
00212 expectedNextL1A = eventNumber+1;
00213
00214 } while(nEvents++<firstEvent);
00215
00216 for(std::map<unsigned int,std::list<unsigned int> >::const_iterator fed=FED.begin(); fed!=FED.end(); fed++)
00217 if( fed->first<(unsigned int)FEDNumbering::MINCSCTFFEDID ){
00218
00219 unsigned short *dccBuf=tmpBuf, *dccCur=dccBuf;
00220 dccCur[3] = 0x5000; dccCur[2] = 0x0000; dccCur[1] = 0x0000; dccCur[0] = 0x005F;
00221 dccCur[7] = 0xD900; dccCur[6] = 0x0000; dccCur[5] = 0x0000; dccCur[4] = 0x0017;
00222 dccCur += 8;
00223
00224 for(std::list<unsigned int>::const_iterator rui=fed->second.begin(); rui!=fed->second.end(); rui++){
00225
00226 if( currentL1A[*rui]==eventNumber ){
00227 if(dccCur-dccBuf+ruBufSize[*rui]>=200000*nRUIs+8) throw cms::Exception("CSCFileReader|eventBuffer")<<"OutOfBuffer: Event size exceeds maximal size allowed!";
00228 memcpy(dccCur,ruBuf[*rui],ruBufSize[*rui]*sizeof(unsigned short));
00229 dccCur += ruBufSize[*rui];
00230 }
00231 }
00232 dccCur[3] = 0xEF00; dccCur[2] = 0x0000; dccCur[1] = 0x0000; dccCur[0] = 0x0000;
00233 dccCur[7] = 0xAF00; dccCur[6] = 0x0000; dccCur[5] = 0x0000; dccCur[4] = 0x0007;
00234 dccCur += 8;
00235
00236 FEDRawData& fedRawData = data->FEDData(fed->first);
00237 fedRawData.resize((dccCur-dccBuf)*sizeof(unsigned short));
00238 std::copy((unsigned char*)dccBuf,(unsigned char*)dccCur,fedRawData.data());
00239 } else {
00240 for(std::list<unsigned int>::const_iterator rui=fed->second.begin(); rui!=fed->second.end(); rui++){
00241 FEDRawData& fedRawData = data->FEDData(fed->first);
00242 fedRawData.resize(ruBufSize[*rui]*sizeof(unsigned short));
00243 std::copy((unsigned char*)ruBuf[*rui],(unsigned char*)(ruBuf[*rui]+ruBufSize[*rui]),fedRawData.data());
00244 }
00245 }
00246
00247 return eventNumber;
00248 }
00249
00250 int CSCFileReader::nextEventFromFUs(FEDRawDataCollection *data){
00251 int eventNumber =-1;
00252
00253
00254 if( expectedNextL1A<0 )
00255 for(int fu=0; fu<nFUs; fu++)
00256 currentL1A[fu] = readFU(fu,fuEvent[fu],fuEventSize[fu]);
00257
00258
00259
00260
00261 int readyToGo = -1;
00262 for(int fu=0; fu<nFUs; fu++){
00263
00264 if(currentL1A[fu]>=0 && (eventNumber<0 || currentL1A[fu]<eventNumber)){
00265 readyToGo = fu;
00266 eventNumber = currentL1A[fu];
00267 }
00268 }
00269
00270 if( readyToGo<0 ) return -1;
00271
00272 expectedNextL1A = eventNumber + 1;
00273
00274
00275 unsigned long long *start = (unsigned long long *)fuEvent[readyToGo];
00276 unsigned long long *end = 0;
00277 enum {Header=1,Trailer=2};
00278 unsigned int eventStatus = 0;
00279 for(int dduRecord=0; dduRecord<=tfDDUnumber; dduRecord++){
00280 unsigned long long word_0=0, word_1=0, word_2=0;
00281 size_t dduWordCount = 0;
00282 while( !end && dduWordCount<fuEventSize[readyToGo] ){
00283 unsigned long long *dduWord = start;
00284
00285 while( dduWordCount<fuEventSize[readyToGo] ){
00286 word_0 = word_1;
00287 word_1 = word_2;
00288 word_2 = *dduWord;
00289 if( (word_2&0xFFFFFFFFFFFF0000LL)==0x8000000180000000LL ){
00290 if( eventStatus&Header ){
00291 word_2 = word_1;
00292 end = dduWord;
00293 break;
00294 }
00295 start = dduWord;
00296 }
00297 if( (word_0&0xFFFFFFFFFFFF0000LL)==0x8000FFFF80000000LL ){
00298 eventStatus |= Trailer;
00299 end = ++dduWord;
00300 break;
00301 }
00302
00303 dduWord++;
00304 dduWordCount++;
00305 }
00306 }
00307
00308 if( dduWordCount==fuEventSize[readyToGo] ){
00309 end = (unsigned long long *)(fuEvent[readyToGo]+fuEventSize[readyToGo]);
00310 break;
00311 }
00312 }
00313
00314 if( start>(unsigned long long *)fuEvent[readyToGo] && (*(start-1)&0xF000000000000000LL)==0x5000000000000000LL ) start--;
00315
00316
00317 if( tfDDUnumber>=0 ){
00318
00319 if( !end ) throw cms::Exception("CSCFileReader|lookingForTF")<<" Sanity check failed (end==0)! Should never happen";
00320
00321 FEDRawData& tfRawData = data->FEDData(FEDNumbering::MINCSCTFFEDID);
00322 tfRawData.resize((end-start)*sizeof(unsigned long long));
00323 std::copy((unsigned char*)start,(unsigned char*)end,tfRawData.data());
00324
00325
00326 unsigned short *event = tmpBuf;
00327 memcpy(event,fuEvent[readyToGo],((unsigned short*)start-fuEvent[readyToGo])*sizeof(unsigned short));
00328 event += ((unsigned short*)start-fuEvent[readyToGo]);
00329 memcpy(event,end,(fuEvent[readyToGo]+fuEventSize[readyToGo]-(unsigned short*)end)*sizeof(unsigned short));
00330 event += fuEvent[readyToGo]+fuEventSize[readyToGo]-(unsigned short*)end;
00331 FEDRawData& fedRawData = data->FEDData(FEDNumbering::MINCSCFEDID);
00332 fedRawData.resize((fuEventSize[readyToGo]-((unsigned short*)end-(unsigned short*)start))*sizeof(unsigned short));
00333 std::copy((unsigned char*)tmpBuf,(unsigned char*)event,fedRawData.data());
00334 } else {
00335 FEDRawData& fedRawData = data->FEDData(FEDNumbering::MINCSCFEDID);
00336 fedRawData.resize((fuEventSize[readyToGo])*sizeof(unsigned short));
00337 std::copy((unsigned char*)fuEvent[readyToGo],(unsigned char*)(fuEvent[readyToGo]+fuEventSize[readyToGo]),fedRawData.data());
00338 }
00339
00340 currentL1A[readyToGo] = readFU(readyToGo,fuEvent[readyToGo],fuEventSize[readyToGo]);
00341
00342 return eventNumber;
00343 }
00344
00345 int CSCFileReader::fillRawData(edm::EventID& eID, edm::Timestamp& tstamp, FEDRawDataCollection *& data){
00346 data = new FEDRawDataCollection();
00347
00348 int runNumber = 0;
00349 int eventNumber =-1;
00350
00351 if( !nActiveFUs && nActiveRUIs ){
00352 eventNumber = buildEventFromRUIs(data);
00353 } else {
00354 eventNumber = nextEventFromFUs(data);
00355 }
00356
00357 if( eventNumber<0 ) return false;
00358
00359 eID = edm::EventID(runNumber,1U,eventNumber);
00360
00361 return true;
00362 }
00363
00364 #undef nRUIs
00365 #undef nFUs