00001 #include "IORawData/SiStripInputSources/interface/TBRUInputSource.h"
00002 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00003 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include "IORawData/SiStripInputSources/src/TBRU.h"
00006 #include "interface/evb/i2oEVBMsgs.h"
00007 #include "interface/shared/i2oXFunctionCodes.h"
00008 #include "interface/shared/frl_header.h"
00009 #include "interface/shared/fed_header.h"
00010 #include "interface/shared/fed_trailer.h"
00011 #include "Fed9UUtils.hh"
00012 #include "ICExDecl.hh"
00013 #include "TFile.h"
00014 #include "TTree.h"
00015 #include <iostream>
00016 #include <sstream>
00017
00018 using namespace Fed9U;
00019 using namespace ICUtils;
00020 using namespace edm;
00021 using namespace std;
00022 using namespace sistrip;
00023
00024 ClassImp(TBRU)
00025
00026 TBRUInputSource::TBRUInputSource(const edm::ParameterSet & pset, edm::InputSourceDescription const& desc) :
00027 edm::ExternalInputSource(pset,desc),
00028 m_quiet( pset.getUntrackedParameter<bool>("quiet",true)),
00029 m_branches(-1),
00030 nfeds(-1)
00031 {
00032 m_tree=0;
00033 m_fileCounter=-1;
00034 m_file=0;
00035 m_i=0;
00036 n_fed9ubufs=0;
00037 for (int i=0;i<MAX_FED9U_BUFFER;i++)
00038 m_fed9ubufs[i]=0;
00039 nfeds = pset.getUntrackedParameter<int>("nFeds",-1);
00040 triggerFedId = pset.getUntrackedParameter<int>("TriggerFedId",1023);
00041 produces<FEDRawDataCollection>();
00042 }
00043
00044
00045
00046 void TBRUInputSource::openFile(const std::string& filename) {
00047 if (m_file!=0) {
00048 m_file->Close();
00049 m_file=0;
00050 m_tree=0;
00051 }
00052
00053
00054 m_file=TFile::Open(filename.c_str());
00055 if (m_file==0) {
00056 edm::LogWarning(mlInputSource_)
00057 << "[TBRUInputSource::" << __func__ << "]"
00058 << "Unable to open " << filename;
00059 m_tree=0;
00060 return;
00061 }
00062
00063
00064 if ( filename.find("RU") == string::npos ||
00065 filename.find("_") == string::npos ) {
00066 n_run = 1;
00067 edm::LogWarning(mlInputSource_)
00068 << "[TBRUInputSource::" << __func__ << "]"
00069 << " No run number found in 'fileNames' configurable!"
00070 << " Expected format is 'RU00xxxxx_yyy.root'"
00071 << " Setting run number to '1'";
00072 } else {
00073 unsigned short ipass = filename.find("RU");
00074 unsigned short ipath = filename.find("_");
00075 string run;
00076 run.clear();
00077 run = filename.substr( ipass+2, ipath-ipass-2 );
00078 sscanf( run.c_str(), "%d", &n_run );
00079 LogTrace(mlInputSource_)
00080 << "[TBRUInputSource::" << __func__ << "]"
00081 << " Run number: " << run
00082 << ", " << run.c_str()
00083 << ", " << n_run;
00084
00085 }
00086
00087 m_tree=(TTree*)m_file->Get("TRU");
00088
00089 if (m_tree==0) {
00090 m_file->Close();
00091 m_file=0;
00092 edm::LogWarning(mlInputSource_)
00093 << "[TBRUInputSource::" << __func__ << "]"
00094 << " Unable to find TBRU tree";
00095 return;
00096 }
00097
00098 if (!m_quiet) {
00099 LogTrace(mlInputSource_)
00100 << "[TBRUInputSource::" << __func__ << "]"
00101 << " Opening '" << filename << "' with "
00102 << m_tree->GetEntries() << " events.";
00103 }
00104
00105 TObjArray* lb=m_tree->GetListOfBranches();
00106 n_fed9ubufs=0;
00107 m_branches = (nfeds<0) ? lb->GetSize() : (nfeds+1)*2;
00108 for (int i=0; i<lb->GetSize(); i++) {
00109 TBranch* b=(TBranch*)lb->At(i);
00110 if (b==0) continue;
00111
00112 char sizename[256];
00113 char arrayname[256];
00114 sprintf(sizename,"size_RU_%x",i/2);
00115
00116
00117 sprintf(arrayname,"RU_%x",i/2);
00118
00119 LogTrace(mlInputSource_)
00120 << "[TBRUInputSource::" << __func__ << "]"
00121 <<" Branch "<< b->GetName()<<" is found ";
00122
00123 if (!strcmp(b->GetName(),sizename)) {
00124 if (m_fed9ubufs[n_fed9ubufs] == 0)
00125 {
00126 m_fed9ubufs[n_fed9ubufs]= new TBRU(i/2);
00127 LogTrace(mlInputSource_)
00128 << "[TBRUInputSource::" << __func__ << "]"
00129 << " Creating TBRU " << n_fed9ubufs
00130 << " for Instance " << i/2;
00131 }
00132 b->SetAddress(&(m_fed9ubufs[n_fed9ubufs]->fSize));
00133
00134 } else {
00135 if (strcmp(b->GetName(),arrayname)) continue;
00136 b->SetAddress(&(m_fed9ubufs[n_fed9ubufs]->fBuffer));
00137 n_fed9ubufs++;
00138 }
00139 }
00140 m_i=0;
00141 LogTrace(mlInputSource_)
00142 << "[TBRUInputSource::" << __func__ << "]"
00143 << " File " << filename << " is opened";
00144
00145 if (nfeds>0) n_fed9ubufs = m_branches/2;
00146 }
00147
00148 void TBRUInputSource::setRunAndEventInfo() {
00149 bool is_new=false;
00150
00151 while (m_tree==0 || m_i==m_tree->GetEntries()) {
00152 m_fileCounter++;
00153 if (m_file!=0) {
00154 m_file->Close();
00155 m_file=0;
00156 m_tree=0;
00157 }
00158 if (m_fileCounter>=int(fileNames().size())) return;
00159 openFile(fileNames()[m_fileCounter]);
00160 is_new=true;
00161 }
00162
00163 if (m_tree==0 || m_i==m_tree->GetEntries()) return;
00164
00165 m_tree->GetEntry(m_i);
00166 m_i++;
00167 TBRU* r= m_fed9ubufs[0];
00168 int* rud =r->fBuffer;
00169
00170 I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME *block = ( I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME*) rud;
00171 if ( (!m_quiet) || block->eventNumber%100 == 0)
00172 LogTrace(mlInputSource_)
00173 << "[TBRUInputSource::" << __func__ << "]"
00174 << " Event number " << n_run << ":"
00175 << block->eventNumber <<" is read ";
00176
00177 setRunNumber(n_run);
00178 setEventNumber( block->eventNumber);
00179
00180
00181 edm::TimeValue_t present_time = presentTime();
00182 unsigned long time_between_events = timeBetweenEvents();
00183
00184 setTime(present_time + time_between_events);
00185 if (!m_quiet)
00186 LogTrace(mlInputSource_)
00187 << "[TBRUInputSource::" << __func__ << "]"
00188 <<" Event & run end";
00189 }
00190 #define FEDID_MASK 0x0003FF00
00191 int TBRUInputSource::getFedId(bool swap, unsigned int* dest)
00192 {
00193 if (swap)
00194 {
00195 fedh_t* fedHeader= (fedh_t*) dest;
00196 return ((fedHeader->sourceid & FEDID_MASK) >>8);
00197 }
00198 else
00199 {
00200 unsigned int order[1024];
00201 for (unsigned int i=0;i <sizeof(fedh_t)/sizeof(int);)
00202 {
00203 order[i]=dest[i+1];
00204 order[i+1] = dest[i];
00205 i+=2;
00206 }
00207 fedh_t* fedHeader= (fedh_t*) order;
00208 return ((fedHeader->sourceid & FEDID_MASK)>>8);
00209 }
00210 }
00211
00212 bool TBRUInputSource::checkFedStructure(int i, unsigned int* dest,unsigned int &length)
00213 {
00214 size_t msgHeaderSize = sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00215 I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME *block = ( I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME*) m_fed9ubufs[i]->fBuffer;
00216 unsigned char* cbuf = (unsigned char*) block + msgHeaderSize;
00217 int* ibuf = (int*) cbuf;
00218
00219 bool old = ( (unsigned int) ibuf[0] == (m_fed9ubufs[i]->fSize*sizeof(int) - msgHeaderSize));
00220
00221 bool slinkswap = false;
00222 if (old)
00223 {
00224
00225 if (i == 0)
00226 {
00227
00228 fedh_t* fedHeader= (fedh_t*) dest;
00229 fedHeader->sourceid = triggerFedId<<8;
00230 fedHeader->eventid = 0x50000000 | block->eventNumber;
00231
00232 memcpy(&dest[sizeof(fedh_t)/sizeof(int)],ibuf,ibuf[0]);
00233
00234 int tlen = (sizeof(fedh_t) + sizeof(fedt_t)+ibuf[0]);
00235 int offset = (tlen%8 ==0)?0:1;
00236
00237 fedt_t* fedTrailer= (fedt_t*) &dest[(sizeof(fedh_t)+ibuf[0])/sizeof(int)+offset];
00238 fedTrailer->conscheck = 0xDEADFACE;
00239 fedTrailer->eventsize = 0xA0000000 |
00240 ((sizeof(fedh_t) + sizeof(fedt_t)+ibuf[0]+offset*sizeof(int) )>> 3);
00241 slinkswap = true;
00242 length=(sizeof(fedh_t) + sizeof(fedt_t)+ibuf[0])/sizeof(int)+offset;
00243 }
00244 else
00245 {
00246
00247
00248 memcpy(&dest[0],&ibuf[1],ibuf[0]-2*sizeof(int));
00249 int fed_len = (ibuf[0]-2*sizeof(int))/sizeof(int);
00250
00251
00252 int blen=fed_len*sizeof(int);
00253 if ( dest[fed_len-1] == (0xa0000000 | (blen>>3)) )
00254 slinkswap = true;
00255 else
00256 if ( dest[fed_len-2] == (0xa0000000 | (blen>>3) ))
00257 slinkswap = false;
00258 else
00259 cout << " Not a FED structure " << i << endl;
00260 length =fed_len;
00261 }
00262 }
00263 else
00264 {
00265
00266 if (i == 0)
00267 {
00268
00269 unsigned char* fbuf = cbuf + sizeof(frlh_t);
00270 memcpy(&dest[0],fbuf,(m_fed9ubufs[i]->fSize*sizeof(int) - msgHeaderSize- sizeof(frlh_t)));
00271 slinkswap = true;
00272 length = (m_fed9ubufs[i]->fSize*sizeof(int) - msgHeaderSize- sizeof(frlh_t))/sizeof(int);
00273 }
00274 else
00275 {
00276
00277 unsigned char* fbuf = cbuf + sizeof(frlh_t);
00278 memcpy(&dest[0],fbuf,(m_fed9ubufs[i]->fSize*sizeof(int) - msgHeaderSize)-sizeof(frlh_t));
00279
00280
00281 unsigned int* fedb = &dest[0];
00282 int fed_len = m_fed9ubufs[i]->fSize - msgHeaderSize/sizeof(int)- sizeof(frlh_t)/sizeof(int);
00283
00284 int fedlen = (fed_len*sizeof(int))>>3;
00285 if ( fedb[fed_len-1] == (0xa0000000 | (fedlen) ))
00286 slinkswap = true;
00287 else
00288 if ( fedb[fed_len-2] == (0xa0000000 | (fedlen) ))
00289 slinkswap = false;
00290 else
00291 cout << " Not a FED structure " << i << endl;
00292
00293 length =fed_len;
00294 }
00295
00296 }
00297
00298 return slinkswap;
00299 }
00300 bool TBRUInputSource::produce(edm::Event& e) {
00301
00302
00303 static unsigned int output[96*1024];
00304 if (m_tree==0) return false;
00305 Fed9U::Fed9UEvent fedEvent;
00306 std::auto_ptr<FEDRawDataCollection> bare_product(new FEDRawDataCollection());
00307 for (int i=0; i<n_fed9ubufs; i++)
00308 {
00309 unsigned int fed_len;
00310 bool slinkswap = checkFedStructure(i,output,fed_len);
00311 int fed_id = getFedId(slinkswap,output);
00312
00313 if (!m_quiet) {
00314 stringstream ss;
00315 ss << "[TBRUInputSource::" << __func__ << "]"
00316 << " Reading bytes for FED " << i
00317 << " At address " <<hex<< m_fed9ubufs[i] << dec;
00318 LogTrace(mlInputSource_) << ss.str();
00319 }
00320 #ifdef OLDSTYLE
00321 I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME *block = ( I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME*) m_fed9ubufs[i]->fBuffer;
00322 size_t msgHeaderSize = sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00323
00324
00325 unsigned char* cbuf = (unsigned char*) block + msgHeaderSize;
00326
00327 int* ibuf = (int*) cbuf;
00328 int len = (ibuf[0]-8);
00329 int id=0;
00330 if (i == 0)
00331 id =1023;
00332 else
00333 {
00334
00335
00336
00337 int* rudat = &ibuf[1];
00338 int buf_len= ibuf[0]/sizeof(int)-2;
00339 try
00340 {
00341 fedEvent.Init((u32*) rudat,0,(u32)buf_len);
00342 fedEvent.checkEvent();
00343 id = fedEvent.getSourceId();
00344 if (!m_quiet)
00345 LogTrace(mlInputSource_)
00346 << "[TBRUInputSource::" << __func__ << "]"
00347 <<" Fed ID is "<<fedEvent.getSourceId();
00348
00349 } catch (ICUtils::ICException &ex)
00350 {
00351 stringstream ss;
00352 ss << "[TBRUInputSource::" << __func__ << "]" << endl
00353 << "======================================================> ERROR in " << "\n"
00354 << e.id().run() <<"::"<<e.id().event()<<"- Super fragment -" << i<< "\n"
00355 << ex.what() << "\n"
00356 << "Cannot construct FED Event: Fed ID Might be "<<fedEvent.getSourceId() << "\n"
00357 << "======================================================>" << "\n";
00358 edm::LogWarning(mlInputSource_) << ss.str();
00359 continue;
00360 }
00361
00362 }
00363
00364
00365 if (id!=1023)
00366 {
00367 const unsigned char* data=(const unsigned char*) &ibuf[1];
00368 FEDRawData& fed=bare_product->FEDData(id);
00369 int fulllen =(len%8)?len+8-len%8:len;
00370 fed.resize(fulllen);
00371 memcpy(fed.data(),data,len);
00372 }
00373 else
00374 {
00375 }
00376
00377 if (!m_quiet)
00378 LogTrace(mlInputSource_)
00379 << "[TBRUInputSource::" << __func__ << "]"
00380 << " Reading " << len << " bytes for FED " << id;
00381 }
00382 #else
00383 FEDRawData& fed=bare_product->FEDData(fed_id);
00384 fed.resize(fed_len*sizeof(int));
00385 memcpy(fed.data(),output,fed_len*sizeof(int));
00386
00387 if (!m_quiet)
00388 LogTrace(mlInputSource_)
00389 << "[TBRUInputSource::" << __func__ << "]"
00390 << " Reading " << fed_len << " bytes for FED " << fed_id;
00391 }
00392 #endif
00393
00394 e.put(bare_product);
00395
00396 return true;
00397 }
00398
00399