00001 #include "FWCore/Framework/interface/Frameworkfwd.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "DataFormats/Common/interface/Handle.h"
00004 #include "FWCore/Framework/interface/ESHandle.h"
00005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00006 #include "FWCore/Framework/interface/Event.h"
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008
00009 #include "IORawData/RPCFileReader/interface/LinkDataXMLReader.h"
00010 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00011 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00012 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00013 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00014
00015 #include <xercesc/sax2/SAX2XMLReader.hpp>
00016 #include <xercesc/sax2/XMLReaderFactory.hpp>
00017 #include <xercesc/util/PlatformUtils.hpp>
00018 #include <xercesc/util/XMLString.hpp>
00019 #include <xercesc/dom/DOM.hpp>
00020 #include <xercesc/framework/LocalFileFormatTarget.hpp>
00021 #include "boost/bind.hpp"
00022 #include <boost/cstdint.hpp>
00023
00024 #include <algorithm>
00025 #include <iomanip>
00026 #include <sstream>
00027 #include <iostream>
00028 #include <fstream>
00029
00030 XERCES_CPP_NAMESPACE_USE
00031
00032 using namespace std;
00033 using namespace edm;
00034 using namespace rpcrawtodigi;
00035
00036
00037 int local_bx;
00038 typedef uint64_t Word64;
00039
00040
00041
00042
00043
00044 string xMLCh2String(const XMLCh* ch) {
00045 #ifdef __BORLANDC__
00046 if(ch == 0) return "";
00047 WideString wstr(ch);
00048 AnsiString astr(wstr);
00049 return astr.c_str();
00050 #else
00051 if(ch == 0) return "";
00052
00053
00054
00055 char* buf = XMLString::transcode(ch);
00056 string str(buf);
00057 XMLString::release(&buf);
00058 return str;
00059 #endif
00060 }
00062 class XStr
00063 {
00064 public :
00065 XStr(const char* const toTranscode)
00066 {
00067 fUnicodeForm = XMLString::transcode(toTranscode);
00068 }
00069
00070 ~XStr()
00071 {
00072 XMLString::release(&fUnicodeForm);
00073 }
00074
00075 const XMLCh* unicodeForm() const
00076 {
00077 return fUnicodeForm;
00078 }
00079
00080 private :
00081 XMLCh* fUnicodeForm;
00082 };
00083
00084 #define X(str) XStr(str).unicodeForm()
00085 #define Char2XMLCh(str) XStr(str).unicodeForm()
00086
00087 int LinkDataXMLReader::m_instanceCount = 0;
00088
00089
00090
00091
00092
00093 LinkDataXMLReader::LinkDataXMLReader(const edm::ParameterSet& iConfig,
00094 InputSourceDescription const& desc):
00095 ExternalInputSource(iConfig, desc)
00096 {
00097
00098
00099
00100 produces<FEDRawDataCollection>();
00101
00102
00103
00104 eventCounter_=0; fileCounter_ = 0;
00105 run_ = 0;
00106 event_ = 0;
00107 isOpen_ = false; noMoreData_ = false;
00108 endOfFile_ = false;
00109
00110 pair<int,int> rpcFEDS=FEDNumbering::getRPCFEDIds();
00111 for (int id= rpcFEDS.first; id<=rpcFEDS.second; ++id){
00112 results[id] = std::vector<rpcrawtodigi::EventRecords>();
00113 }
00114
00115 clear();
00116
00117 if(m_instanceCount == 0) {
00118 try {
00119 XMLPlatformUtils::Initialize();
00120 m_instanceCount++;
00121 }
00122 catch(const XMLException &toCatch) {
00123 edm::LogError("LinkDataXMLReader")<< "Error during Xerces-c Initialization: "
00124 + xMLCh2String(toCatch.getMessage());
00125 }
00126 }
00127 }
00128
00129
00130
00131
00132 LinkDataXMLReader::~LinkDataXMLReader(){}
00133
00134
00135
00136
00137
00138
00139 void LinkDataXMLReader::setRunAndEventInfo(){
00140
00141 bool triggeredOrEmpty = false;
00142 clear();
00143
00144 if(endOfFile_){
00145 isOpen_ = false;
00146 if(parser) {
00147 delete parser;
00148 parser = 0;
00149 }
00150 }
00151
00152 if(!isOpen_){
00153 if(fileCounter_<(int)fileNames().size()){
00154 eventPos_[0]=0; eventPos_[1]=0;
00155 isOpen_=true;
00156 endOfFile_ = false;
00157 fileCounter_++;
00158 ++run_;
00159 event_ = 0;
00160 edm::LogInfo("LinkDataXMLReader")<< "[LinkDataXMLReader::setRunAndEventInfo] "
00161 << "Open for reading file no. " << fileCounter_
00162 << " " << fileNames()[fileCounter_-1].substr(5);
00163 parser = XMLReaderFactory::createXMLReader();
00164 parser->setContentHandler(this);
00165 parser->parseFirst(fileNames()[fileCounter_-1].substr(5).c_str(),aToken);
00166 }
00167 else{
00168 edm::LogInfo("LinkDataXMLReader")<< "[LinkDataXMLReader::setRunAndEventInfo] "
00169 << "No more events to read. Finishing after "
00170 << eventCounter_ << " events.";
00171 noMoreData_=true;
00172 return;
00173 }
00174 }
00175
00176 endOfEvent_ = false;
00177 while(parser->parseNext(aToken) && !endOfEvent_){}
00178
00179 ++event_;
00180 ++eventCounter_;
00181
00182 setRunNumber(run_);
00183 setEventNumber(event_);
00184
00185 return;
00186 }
00188 bool LinkDataXMLReader::produce(edm::Event& ev){
00189
00190 if(noMoreData_) return false;
00191
00192 auto_ptr<FEDRawDataCollection> buffers( new FEDRawDataCollection );
00193
00194 pair<int,int> rpcFEDS=FEDNumbering::getRPCFEDIds();
00195
00196 for (int id= rpcFEDS.first; id<=rpcFEDS.second; ++id){
00197
00198 FEDRawData * rawData1 = rawData(id, results[id]);
00199 FEDRawData& fedRawData = buffers->FEDData(id);
00200
00201 fedRawData = *rawData1;
00202 }
00203 ev.put( buffers );
00204
00205
00206 return true;
00207 }
00208
00209
00210
00211
00212 void LinkDataXMLReader::startElement(const XMLCh* const uri,
00213 const XMLCh* const localname,
00214 const XMLCh* const qname,
00215 const Attributes& attrs) {
00216 m_CurrElement = xMLCh2String(localname);
00217
00218
00219 int lbNum, partitionNum, endOfData, halfPartition, partitionData;
00220 uint16_t rawData;
00221
00222 if(m_CurrElement=="bxData") {
00223 local_bx = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("num"))),1);
00224
00225 }
00226 if(m_CurrElement=="tc") triggerCrateNum = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("num"))),1);
00227 if(m_CurrElement=="tb") triggerBoardNum = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("num"))),1);
00228 if(m_CurrElement=="ol") opticalLinkNum = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("num"))),1);
00229 if(m_CurrElement=="lmd"){
00230 if(triggerCrateNum==-1 || triggerBoardNum==-1 || opticalLinkNum==-1){
00231
00232 return;
00233 }
00234
00235 lbNum = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("lb"))),1);
00236 partitionNum = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("par"))),1);
00237 endOfData = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("eod"))),1);
00238 halfPartition = 0;
00239 partitionData = stringToInt(xMLCh2String(attrs.getValue(Char2XMLCh("dat"))),0);
00240
00241
00242 int trigger_BX = 200;
00243
00244 int current_BX = trigger_BX + local_bx;
00245
00246
00247 RecordBX bxr(current_BX);
00248
00249
00250 int tbLinkInputNumber = opticalLinkNum;
00251 int rmb = getDCCInputChannelNum(triggerCrateNum, triggerBoardNum).second;
00252 edm::LogInfo(" ")
00253 <<"tc: "<<triggerCrateNum
00254 <<" tb: "<<triggerBoardNum
00255 <<" rmb: "<<rmb
00256 <<" fedID: "<<getDCCInputChannelNum(triggerCrateNum, triggerBoardNum).first
00257 <<" ol: "<< opticalLinkNum
00258 <<" partNum: "<<partitionNum
00259 <<" eod: "<<endOfData
00260 <<" hp: "<<halfPartition
00261 <<" raw data: "<<hex<<partitionData<<dec;
00262
00263 RecordSLD tbr( tbLinkInputNumber, rmb);
00264
00265
00266 uint16_t theData = 0;
00267 static const int PARTITION_DATA_MASK = 0XFF;
00268 static const int PARTITION_DATA_SHIFT =0;
00269
00270 static const int PARTITION_NUMBER_MASK = 0XF;
00271 static const int PARTITION_NUMBER_SHIFT =10;
00272
00273 static const int HALFP_MASK = 0X1;
00274 static const int HALFP_SHIFT =8;
00275
00276 static const int EOD_MASK = 0X1;
00277 static const int EOD_SHIFT =9;
00278
00279 static const int LB_MASK = 0X3;
00280 static const int LB_SHIFT =14;
00281
00282 static const int BITS_PER_PARTITION=8;
00283
00284 theData |= (endOfData<<EOD_SHIFT );
00285 theData |= (halfPartition<<HALFP_SHIFT);
00286 theData |= (partitionNum<<PARTITION_NUMBER_SHIFT);
00287 theData |= (lbNum<<LB_SHIFT);
00288 theData |= (partitionData<<PARTITION_DATA_SHIFT);
00289
00290 RecordCD lbr(theData);
00291
00292
00293
00294
00295
00296 int fedId = getDCCInputChannelNum(triggerCrateNum, triggerBoardNum).first;
00297
00298 results[fedId].push_back( EventRecords(trigger_BX, bxr, tbr, lbr) );
00299 }
00300
00301 }
00302
00303
00304
00305
00306 void LinkDataXMLReader::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) {
00307
00308 string m_CurrElement = xMLCh2String(localname);
00309
00310
00311
00312 if(m_CurrElement=="event") endOfEvent_ = true;
00313 if(m_CurrElement=="rpctDataStream") endOfFile_ = true;
00314 }
00315
00316
00317
00318 FEDRawData * LinkDataXMLReader::rawData(int fedId, const vector<EventRecords> & result){
00319
00320
00321
00322
00323
00324 int trigger_BX = 200;
00325
00326
00327
00328
00329 vector<Word64> dataWords;
00330 DataRecord empty;
00331 typedef vector<EventRecords>::const_iterator IR;
00332 for (IR ir = result.begin(), irEnd = result.end() ; ir != irEnd; ++ir) {
00333 Word64 w = ( ( (Word64(ir->recordBX().data()) << 16) | ir->recordSLD().data() ) << 16
00334 | ir->recordCD().data() ) << 16 | empty.data();
00335 dataWords.push_back(w);
00336 }
00337
00338
00339
00340
00341 int nHeaders = 1;
00342 int nTrailers = 1;
00343 int dataSize = (nHeaders+nTrailers+dataWords.size()) * sizeof(Word64);
00344 FEDRawData * raw = new FEDRawData(dataSize);
00345
00346
00347
00348
00349 unsigned char *pHeader = raw->data();
00350 int evt_ty = 3;
00351 int lvl1_ID = 100;
00352 int source_ID = fedId;
00353 FEDHeader::set(pHeader, evt_ty, lvl1_ID, trigger_BX, source_ID);
00354
00355
00356
00357
00358 for (unsigned int idata = 0; idata < dataWords.size(); idata ++) {
00359 Word64 * word = reinterpret_cast<Word64* >(pHeader+(idata+1)*sizeof(Word64));
00360 *word = dataWords[idata];
00361 }
00362
00363
00364
00365
00366 unsigned char *pTrailer = pHeader + raw->size()-sizeof(Word64);
00367 int crc = 0;
00368 int evt_stat = 15;
00369 int tts = 0;
00370 int datasize = raw->size()/sizeof(Word64);
00371 FEDTrailer::set(pTrailer, datasize, crc, evt_stat, tts);
00372
00373 return raw;
00374 }
00375
00376
00377
00378
00379
00380
00381 std::string LinkDataXMLReader::IntToString(int i, int opt){
00382
00383 std::stringstream ss;
00384 if(opt==1) ss << std::hex << i << std::dec;
00385 else ss << i ;
00386
00387 return ss.str();
00388
00389 }
00390
00391 int LinkDataXMLReader::stringToInt(std::string str, int opt) {
00392
00393 int number;
00394 std::stringstream lineStream(str);
00395 if(opt==0) lineStream>>hex>>number;
00396 if(opt==1) lineStream>>dec>>number;
00397 return number;
00398
00399 for(unsigned int i = 0; i < str.size(); i++)
00400 if(str[i] < '0' || str[i] > '9')
00401 edm::LogError("LinkDataXMLReader")<< "Error in stringToInt(): the string: "
00402 <<str<<" cannot be converted to a number";
00403 return atoi(str.c_str());
00404 }
00405
00406
00407 void LinkDataXMLReader::clear(){
00408
00409 triggerCrateNum = -1;
00410 triggerBoardNum = -1;
00411 opticalLinkNum = -1;
00412
00413 pair<int,int> rpcFEDS=FEDNumbering::getRPCFEDIds();
00414 for (int id= rpcFEDS.first; id<=rpcFEDS.second; ++id){
00415 results[id].clear();
00416 }
00417 }
00418
00419
00420 std::pair<int,int> LinkDataXMLReader::getDCCInputChannelNum(int tcNumber, int tbNumber){
00421
00422
00423
00424 int fedNumber = 792 - tcNumber/4;
00425 int dccInputChannelNum = tbNumber + 9*(tcNumber%4);
00426
00427 return std::pair<int,int>(fedNumber,dccInputChannelNum);
00428 }