00001
00009 #include <EventFilter/DTRawToDigi/plugins/DTROS25Unpacker.h>
00010
00011 #include <EventFilter/DTRawToDigi/interface/DTDDUWords.h>
00012 #include <EventFilter/DTRawToDigi/interface/DTControlData.h>
00013 #include <EventFilter/DTRawToDigi/interface/DTROChainCoding.h>
00014
00015 #include <EventFilter/DTRawToDigi/interface/DTDataMonitorInterface.h>
00016 #include "FWCore/ServiceRegistry/interface/Service.h"
00017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00018
00019 #include <EventFilter/DTRawToDigi/plugins/DTTDCErrorNotifier.h>
00020
00021
00022 #include <CondFormats/DTObjects/interface/DTReadOutMapping.h>
00023
00024 #include <iostream>
00025 #include <math.h>
00026
00027 using namespace std;
00028 using namespace edm;
00029
00030
00031
00032
00033 DTROS25Unpacker::DTROS25Unpacker(const edm::ParameterSet& ps) {
00034
00035
00036 localDAQ = ps.getUntrackedParameter<bool>("localDAQ",false);
00037 readingDDU = ps.getUntrackedParameter<bool>("readingDDU",true);
00038
00039 readDDUIDfromDDU = ps.getUntrackedParameter<bool>("readDDUIDfromDDU",true);
00040 hardcodedDDUID = ps.getUntrackedParameter<int>("dduID",770);
00041
00042 writeSC = ps.getUntrackedParameter<bool>("writeSC",false);
00043 performDataIntegrityMonitor = ps.getUntrackedParameter<bool>("performDataIntegrityMonitor",false);
00044 debug = ps.getUntrackedParameter<bool>("debug",false);
00045
00046
00047 if(performDataIntegrityMonitor) {
00048 if (edm::Service<DTDataMonitorInterface>().isAvailable()) {
00049 dataMonitor = edm::Service<DTDataMonitorInterface>().operator->();
00050 } else {
00051 LogWarning("DTRawToDigi|DTROS25Unpacker") <<
00052 "[DTROS25Unpacker] WARNING! Data Integrity Monitoring requested but no DTDataMonitorInterface Service available" << endl;
00053 performDataIntegrityMonitor = false;
00054 }
00055 }
00056
00057 }
00058
00059
00060 DTROS25Unpacker::~DTROS25Unpacker() {}
00061
00062
00063 void DTROS25Unpacker::interpretRawData(const unsigned int* index, int datasize,
00064 int dduIDfromDDU,
00065 edm::ESHandle<DTReadOutMapping>& mapping,
00066 std::auto_ptr<DTDigiCollection>& detectorProduct,
00067 std::auto_ptr<DTLocalTriggerCollection>& triggerProduct,
00068 uint16_t rosList) {
00069
00070
00071 int dduID;
00072 if (readDDUIDfromDDU) dduID = dduIDfromDDU;
00073 else dduID = hardcodedDDUID;
00074
00075 const int wordLength = 4;
00076 int numberOfWords = datasize / wordLength;
00077
00078 int rosID = 0;
00079 DTROS25Data controlData(rosID);
00080 controlDataFromAllROS.clear();
00081
00082 int wordCounter = 0;
00083 uint32_t word = index[swap(wordCounter)];
00084
00085 map<uint32_t,int> hitOrder;
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 while (wordCounter < numberOfWords) {
00097
00098 controlData.clean();
00099
00100 rosID++;
00101
00102 if ( readingDDU ) {
00103
00104 if ( rosID <= 12 && !((rosList & int(pow(2., (rosID-1) )) ) >> (rosID-1) ) ) continue;
00105 if (debug) cout<<"[DTROS25Unpacker]: ros list: "<<rosList <<" ROS ID "<<rosID<<endl;
00106 }
00107
00108
00109
00110 int SCwheel=-3;
00111 int SCsector=0;
00112 int dum1, dum2, dum3, dum4;
00113
00114 if (writeSC && ! mapping->readOutToGeometry(dduID, rosID, 1, 1, 1,
00115 SCwheel, dum1, SCsector, dum2, dum3, dum4) ) {
00116 if (debug) cout <<" found SCwheel: "<<SCwheel<<" and SCsector: "<<SCsector<<endl;
00117 }
00118 else {
00119 if (writeSC && debug) cout <<" WARNING failed to find WHEEL and SECTOR for ROS "<<rosID<<" !"<<endl;
00120 }
00121
00122
00123
00124 if (DTROSWordType(word).type() == DTROSWordType::ROSHeader) {
00125 DTROSHeaderWord rosHeaderWord(word);
00126
00127 if (debug) cout<<"[DTROS25Unpacker]: ROSHeader "<<rosHeaderWord.TTCEventCounter()<<endl;
00128
00129
00130 controlData.setROSId(rosID);
00131 controlData.addROSHeader(rosHeaderWord);
00132
00133
00134
00135 do {
00136 wordCounter++; word = index[swap(wordCounter)];
00137
00138
00139 if (DTROSWordType(word).type() == DTROSWordType::ROSError) {
00140 DTROSErrorWord dtROSErrorWord(word);
00141 controlData.addROSError(dtROSErrorWord);
00142 if (debug) cout<<"[DTROS25Unpacker]: ROSError, Error type "<<dtROSErrorWord.errorType()
00143 <<" robID "<<dtROSErrorWord.robID()<<endl;
00144 }
00145
00146
00147 else if (DTROSWordType(word).type() == DTROSWordType::ROSDebug) {
00148 DTROSDebugWord rosDebugWord(word);
00149 controlData.addROSDebug(rosDebugWord);
00150 if (debug) cout<<"[DTROS25Unpacker]: ROSDebug, type "<<rosDebugWord.debugType()
00151 <<" message "<<rosDebugWord.debugMessage()<<endl;
00152 }
00153
00154
00155 else if (DTROSWordType(word).type() == DTROSWordType::GroupHeader) {
00156
00157 DTROBHeaderWord robHeaderWord(word);
00158 int eventID = robHeaderWord.eventID();
00159 int bunchID = robHeaderWord.bunchID();
00160 int robID = robHeaderWord.robID();
00161
00162 DTROBHeader robHeader(robID,robHeaderWord);
00163 controlData.addROBHeader(robHeader);
00164
00165 if (debug) cout<<"[DTROS25Unpacker] ROB: ID "<<robID
00166 <<" Event ID "<<eventID
00167 <<" BXID "<<bunchID<<endl;
00168
00169
00170 do {
00171 wordCounter++; word = index[swap(wordCounter)];
00172
00173
00174 if ( DTROSWordType(word).type() == DTROSWordType::TDCError) {
00175 DTTDCErrorWord dtTDCErrorWord(word);
00176 DTTDCError tdcError(robID,dtTDCErrorWord);
00177 controlData.addTDCError(tdcError);
00178
00179 DTTDCErrorNotifier dtTDCError(dtTDCErrorWord);
00180 if (debug) dtTDCError.print();
00181 }
00182
00183
00184 else if ( DTROSWordType(word).type() == DTROSWordType::TDCDebug) {
00185 if (debug) cout<<"TDC Debugging"<<endl;
00186 }
00187
00188
00189 else if (DTROSWordType(word).type() == DTROSWordType::TDCMeasurement) {
00190
00191 DTTDCMeasurementWord tdcMeasurementWord(word);
00192 DTTDCData tdcData(robID,tdcMeasurementWord);
00193 controlData.addTDCData(tdcData);
00194
00195 int tdcID = tdcMeasurementWord.tdcID();
00196 int tdcChannel = tdcMeasurementWord.tdcChannel();
00197
00198 if (debug) cout<<"[DTROS25Unpacker] TDC: ID "<<tdcID
00199 <<" Channel "<< tdcChannel
00200 <<" Time "<<tdcMeasurementWord.tdcTime()<<endl;
00201
00202 DTROChainCoding channelIndex(dduID, rosID, robID, tdcID, tdcChannel);
00203
00204 hitOrder[channelIndex.getCode()]++;
00205
00206 if (debug) {
00207 cout<<"[DTROS25Unpacker] ROAddress: DDU "<< dduID
00208 <<", ROS "<< rosID
00209 <<", ROB "<< robID
00210 <<", TDC "<< tdcID
00211 <<", Channel "<< tdcChannel<<endl;
00212 }
00213
00214
00215 if (writeSC && (SCsector < 1 || SCwheel < -2) ) {
00216
00217 if (debug) cout <<" second try to find SCwheel and SCsector "<<endl;
00218 if ( ! mapping->readOutToGeometry(dduID, rosID, robID, tdcID, tdcChannel,
00219 SCwheel, dum1, SCsector, dum2, dum3, dum4) ) {
00220 if (debug) cout<<" ROS "<<rosID<<" SC wheel "<<SCwheel<<" SC sector "<<SCsector<<endl;
00221 }
00222 else {
00223 if (debug) cout<<" WARNING !! ROS "<<rosID<<" failed again to map for SC!! "<<endl;
00224 }
00225 }
00226
00227
00228
00229 DTWireId detId;
00230
00231 int wheelId, stationId, sectorId, slId,layerId, cellId;
00232 if ( ! mapping->readOutToGeometry(dduID, rosID, robID, tdcID, tdcChannel,
00233 wheelId, stationId, sectorId, slId, layerId, cellId)) {
00234
00235
00236 if (sectorId==0 || stationId == 0) continue;
00237 else detId = DTWireId(wheelId, stationId, sectorId, slId, layerId, cellId);
00238
00239 if (debug) cout<<"[DTROS25Unpacker] "<<detId<<endl;
00240 int wire = detId.wire();
00241
00242
00243 DTDigi digi( wire, tdcMeasurementWord.tdcTime(), hitOrder[channelIndex.getCode()]-1);
00244
00245
00246 detectorProduct->insertDigi(detId.layerId(),digi);
00247 }
00248 else {
00249 LogWarning ("DTRawToDigi|DTROS25Unpacker") <<"Unable to map the RO channel: DDU "<<dduID
00250 <<" ROS "<<rosID<<" ROB "<<robID<<" TDC "<<tdcID<<" TDC ch. "<<tdcChannel;
00251 if (debug) cout<<"[DTROS25Unpacker] ***ERROR*** Missing wire: DDU "<<dduID
00252 <<" ROS "<<rosID<<" ROB "<<robID<<" TDC "<<tdcID<<" TDC ch. "<<tdcChannel<<endl;
00253 }
00254
00255 }
00256
00257 } while ( DTROSWordType(word).type() != DTROSWordType::GroupTrailer &&
00258 DTROSWordType(word).type() != DTROSWordType::ROSError);
00259
00260
00261 if (DTROSWordType(word).type() == DTROSWordType::GroupTrailer) {
00262 DTROBTrailerWord robTrailerWord(word);
00263 controlData.addROBTrailer(robTrailerWord);
00264 if (debug) cout<<"[DTROS25Unpacker]: ROBTrailer, robID "<<robTrailerWord.robID()
00265 <<" eventID "<<robTrailerWord.eventID()
00266 <<" wordCount "<<robTrailerWord.wordCount()<<endl;
00267 }
00268 }
00269
00270
00271 else if (DTROSWordType(word).type() == DTROSWordType::SCHeader) {
00272 DTLocalTriggerHeaderWord scHeaderWord(word);
00273 if (debug) cout<<"[DTROS25Unpacker]: SC header eventID " << scHeaderWord.eventID()<<endl;
00274
00275
00276 wordCounter++; word = index[swap(wordCounter)];
00277
00278 if(DTROSWordType(word).type() == DTROSWordType::SCData) {
00279 DTLocalTriggerSectorCollectorHeaderWord scPrivateHeaderWord(word);
00280
00281 if(performDataIntegrityMonitor) {
00282 controlData.addSCPrivHeader(scPrivateHeaderWord);
00283 }
00284
00285 int numofscword = scPrivateHeaderWord.NumberOf16bitWords();
00286 int leftword = numofscword;
00287
00288 if(debug) cout<<" SC PrivateHeader (number of words + subheader = "
00289 << scPrivateHeaderWord.NumberOf16bitWords() << ")" <<endl;
00290
00291
00292
00293 if(numofscword > 0){
00294
00295 int bx_received = (numofscword - 1) / 2;
00296 if(debug) cout<<" SC number of bx read-out: " << bx_received << endl;
00297
00298 wordCounter++; word = index[swap(wordCounter)];
00299 if (DTROSWordType(word).type() == DTROSWordType::SCData) {
00300
00301 leftword--;
00302
00303 DTLocalTriggerSectorCollectorSubHeaderWord scPrivateSubHeaderWord(word);
00304
00305 int scEventBX = scPrivateSubHeaderWord.LocalBunchCounter();
00306 if(debug) cout <<" SC trigger delay = "
00307 << scPrivateSubHeaderWord.TriggerDelay() << endl
00308 <<" SC bunch counter = "
00309 << scEventBX << endl;
00310
00311 controlData.addSCPrivSubHeader(scPrivateSubHeaderWord);
00312
00313
00314 int stationGroup=0;
00315 do {
00316 wordCounter++; word = index[swap(wordCounter)];
00317 int SCstation=0;
00318
00319 if (DTROSWordType(word).type() == DTROSWordType::SCData) {
00320 leftword--;
00321
00322
00323 int bx_counter = int(round( (leftword + 1)/ 2.));
00324
00325 if(debug){
00326 if(bx_counter < 0 || leftword < 0)
00327 cout<<"[DTROS25Unpacker]: SC data more than expected; negative bx counter reached! "<<endl;
00328 }
00329
00330 DTLocalTriggerDataWord scDataWord(word);
00331
00332
00333 DTSectorCollectorData scData(scDataWord,bx_counter);
00334 controlData.addSCData(scData);
00335
00336 if (debug) {
00337
00338
00339 if (scDataWord.hasTrigger(0))
00340 cout<<" at BX "<< bx_counter
00341 <<" lower part has trigger! with track quality "
00342 << scDataWord.trackQuality(0)<<endl;
00343 if (scDataWord.hasTrigger(1))
00344 cout<<" at BX "<< bx_counter
00345 <<" upper part has trigger! with track quality "
00346 << scDataWord.trackQuality(1)<<endl;
00347 }
00348
00349 if (writeSC && SCwheel >= -2 && SCsector >=1 ) {
00350
00351
00352
00353 if ( scDataWord.hasTrigger(0) || (scDataWord.getBits(0) & 0x30) ) {
00354 if ( stationGroup%2 == 0) SCstation = 1;
00355 else SCstation = 3;
00356
00357
00358 DTLocalTrigger localtrigger(scEventBX, bx_counter,(scDataWord.SCData()) & 0xFF);
00359
00360 DTChamberId chamberId (SCwheel,SCstation,SCsector);
00361 triggerProduct->insertDigi(chamberId,localtrigger);
00362 if (debug) {
00363 cout<<"Add SC digi to the collection, for chamber: " << chamberId
00364 <<endl;
00365 localtrigger.print(); }
00366 }
00367 if ( scDataWord.hasTrigger(1) || (scDataWord.getBits(1) & 0x30) ) {
00368 if ( stationGroup%2 == 0) SCstation = 2;
00369 else SCstation = 4;
00370
00371
00372 DTLocalTrigger localtrigger(scEventBX, bx_counter,(scDataWord.SCData()) >> 8);
00373
00374 DTChamberId chamberId (SCwheel,SCstation,SCsector);
00375 triggerProduct->insertDigi(chamberId,localtrigger);
00376 if(debug) {
00377 cout<<"Add SC digi to the collection, for chamber: " << chamberId
00378 <<endl;
00379 localtrigger.print();
00380 }
00381 }
00382
00383 stationGroup++;
00384 }
00385 }
00386 } while ( DTROSWordType(word).type() != DTROSWordType::SCTrailer );
00387
00388 }
00389 }
00390 }
00391
00392 if (DTROSWordType(word).type() == DTROSWordType::SCTrailer) {
00393 DTLocalTriggerTrailerWord scTrailerWord(word);
00394
00395 controlData.addSCHeader(scHeaderWord);
00396 controlData.addSCTrailer(scTrailerWord);
00397
00398 if (debug) cout<<" SC Trailer, # of words: "
00399 << scTrailerWord.wordCount() <<endl;
00400 }
00401 }
00402
00403 } while ( DTROSWordType(word).type() != DTROSWordType::ROSTrailer );
00404
00405
00406 if (DTROSWordType(word).type() == DTROSWordType::ROSTrailer){
00407 DTROSTrailerWord rosTrailerWord(word);
00408 controlData.addROSTrailer(rosTrailerWord);
00409 if (debug) cout<<"[DTROS25Unpacker]: ROSTrailer "<<rosTrailerWord.EventWordCount()<<endl;
00410 }
00411
00412
00413
00414 if (performDataIntegrityMonitor) {
00415 dataMonitor->processROS25(controlData, dduID, rosID);
00416
00417 controlDataFromAllROS.push_back(controlData);
00418 }
00419
00420 }
00421
00422 else if (index[swap(wordCounter)] == 0) {
00423
00424
00425
00426 if (debug) cout<<"[DTROS25Unpacker]: odd number of ROS words"<<endl;
00427 rosID--;
00428 }
00429
00430 else {
00431 cout<<"[DTROS25Unpacker]: ERROR! First word is not a ROS Header"<<endl;
00432 }
00433
00434
00435 wordCounter++; word = index[swap(wordCounter)];
00436
00437 }
00438
00439 }
00440
00441
00442 int DTROS25Unpacker::swap(int n) {
00443
00444 int result=n;
00445
00446 if ( !localDAQ ) {
00447 if (n%2==0) result = (n+1);
00448 if (n%2==1) result = (n-1);
00449 }
00450
00451 return result;
00452 }
00453