CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/DTRawToDigi/plugins/DTROS25Unpacker.cc

Go to the documentation of this file.
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 // Mapping
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   // enable DQM if Service is available
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   / The the loop is performed with "do-while" statements
00090   / because the ORDER of the words in the event data
00091   / is assumed to be fixed. Eventual changes into the
00092   / structure should be considered as data corruption
00093   *******************************************************/
00094   
00095   // Loop on ROSs
00096   while (wordCounter < numberOfWords) {
00097 
00098     controlData.clean();
00099     
00100     rosID++; // to be mapped;
00101 
00102     if ( readingDDU ) {
00103       // matching the ROS number with the enabled DDU channel
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     // FRC prepare info for DTLocalTrigger: wheel and sector corresponding to this ROS
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     // ROS Header;
00124     if (DTROSWordType(word).type() == DTROSWordType::ROSHeader) {
00125       DTROSHeaderWord rosHeaderWord(word);
00126 
00127       if (debug) cout<<"[DTROS25Unpacker]: ROSHeader "<<rosHeaderWord.TTCEventCounter()<<endl;
00128 
00129       // container for words to be sent to DQM
00130       controlData.setROSId(rosID);
00131       controlData.addROSHeader(rosHeaderWord);
00132       
00133 
00134       // Loop on ROBs
00135       do {
00136         wordCounter++; word = index[swap(wordCounter)];
00137 
00138         // Eventual ROS Error: occurs when some errors are found in a ROB
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         // Eventual ROS Debugging;
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         // Check ROB header
00155         else if (DTROSWordType(word).type() == DTROSWordType::GroupHeader) {
00156 
00157           DTROBHeaderWord robHeaderWord(word);
00158           int eventID = robHeaderWord.eventID(); // from the TDCs
00159           int bunchID = robHeaderWord.bunchID(); // from the TDCs
00160           int robID = robHeaderWord.robID(); // to be mapped
00161 
00162           DTROBHeader robHeader(robID,robHeaderWord);  // IJ
00163           controlData.addROBHeader(robHeader);    // IJ
00164 
00165           if (debug) cout<<"[DTROS25Unpacker] ROB: ID "<<robID
00166                          <<" Event ID "<<eventID
00167                          <<" BXID "<<bunchID<<endl;
00168 
00169           // Loop on TDCs data (headers and trailers are not there)
00170           do {
00171             wordCounter++; word = index[swap(wordCounter)];
00172 
00173             // Eventual TDC Error
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             // Eventual TDC Debug
00184             else if ( DTROSWordType(word).type() == DTROSWordType::TDCDebug) {
00185               if (debug) cout<<"TDC Debugging"<<endl;
00186             }
00187             
00188             // The TDC information
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               // FRC if not already done for this ROS, find wheel and sector for SC data
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               // Map the RO channel to the DetId and wire
00229               DTWireId detId;
00230               // if ( ! mapping->readOutToGeometry(dduID, rosID, robID, tdcID, tdcChannel, detId)) {
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                 // skip the digi if the detId is invalid 
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                 // Produce the digi
00243                 DTDigi digi( wire, tdcMeasurementWord.tdcTime(), hitOrder[channelIndex.getCode()]-1);
00244 
00245                 // Commit to the event
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             } // TDC information
00256 
00257           } while ( DTROSWordType(word).type() != DTROSWordType::GroupTrailer &&
00258                     DTROSWordType(word).type() != DTROSWordType::ROSError); // loop on TDC's?
00259 
00260           // Check ROB Trailer (condition already verified)
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         } // ROB header
00269 
00270         // Check the eventual Sector Collector Header
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           // RT added : first word following SCHeader is a SC private header
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             // if no SC data -> no loop ;
00292             // otherwise subtract 1 word (subheader) and countdown for bx assignment
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                 //second word following SCHeader is a SC private SUB-header
00301                 leftword--;
00302 
00303                 DTLocalTriggerSectorCollectorSubHeaderWord scPrivateSubHeaderWord(word);
00304                 // read the event BX in the SC header (will be stored in SC digis)
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                 // actual loop on SC time slots
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                     //RT: bx are sent from SC in reverse order starting from the one
00322                     //which stopped the spy buffer
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                     // DTSectorCollectorData scData(scDataWord, int(round(bx_counter/2.))); M.Z.
00333                     DTSectorCollectorData scData(scDataWord,bx_counter);
00334                     controlData.addSCData(scData);
00335 
00336                     if (debug) {
00337                       //cout<<"[DTROS25Unpacker]: SCData bits "<<scDataWord.SCData()<<endl;
00338                       //cout << " word in esadecimale: " << hex << word << dec << endl;
00339                       if (scDataWord.hasTrigger(0))
00340                         cout<<" at BX "<< bx_counter //round(bx_counter/2.)
00341                             <<" lower part has trigger! with track quality "
00342                             << scDataWord.trackQuality(0)<<endl;
00343                       if (scDataWord.hasTrigger(1))
00344                         cout<<" at BX "<< bx_counter //round(bx_counter/2.)
00345                             <<" upper part has trigger! with track quality "
00346                             << scDataWord.trackQuality(1)<<endl;
00347                     }
00348 
00349                     if (writeSC && SCwheel >= -2  && SCsector >=1 ) {
00350 
00351                       // FRC: start constructing persistent SC objects:
00352                       // first identify the station (data come in 2 triggers per word: MB1+MB2, MB3+MB4)
00353                       if ( scDataWord.hasTrigger(0) || (scDataWord.getBits(0) & 0x30) ) {
00354                         if ( stationGroup%2 == 0) SCstation = 1;
00355                         else                      SCstation = 3;
00356 
00357                         // construct localtrigger for first station of this "group" ...
00358                         DTLocalTrigger localtrigger(scEventBX, bx_counter,(scDataWord.SCData()) & 0xFF);
00359                         // ... and commit it to the event
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                         // construct localtrigger for second station of this "group" ...
00372                         DTLocalTrigger localtrigger(scEventBX, bx_counter,(scDataWord.SCData()) >> 8);
00373                         // ... and commit it to the event
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                     } // if writeSC
00385                   } // if SC data
00386                 } while ( DTROSWordType(word).type() != DTROSWordType::SCTrailer );
00387 
00388               } // end SC subheader
00389             } // end if SC send more than only its own header!
00390           } //  end if first data following SCheader is not SCData
00391 
00392           if (DTROSWordType(word).type() == DTROSWordType::SCTrailer) {
00393             DTLocalTriggerTrailerWord scTrailerWord(word);
00394             // add infos for data integrity monitoring
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 ); // loop on ROBS
00404 
00405       // check ROS Trailer (condition already verified)
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       // Perform dqm if requested:
00413       // DQM IS PERFORMED FOR EACH ROS SEPARATELY
00414       if (performDataIntegrityMonitor) {
00415         dataMonitor->processROS25(controlData, dduID, rosID);
00416         // fill the vector with ROS's control data
00417         controlDataFromAllROS.push_back(controlData);
00418       }
00419 
00420     }
00421 
00422     else if (index[swap(wordCounter)] == 0) {
00423       // in the case of odd number of words of a given ROS the header of
00424       // the next one is postponed by 4 bytes word set to 0.
00425       // rosID needs to be step back by 1 unit
00426       if (debug) cout<<"[DTROS25Unpacker]: odd number of ROS words"<<endl;
00427       rosID--;
00428     } // if ROS header
00429     
00430     else {
00431       cout<<"[DTROS25Unpacker]: ERROR! First word is not a ROS Header"<<endl;
00432     }
00433     
00434     // (needed if there are more than 1 ROS)
00435     wordCounter++; word = index[swap(wordCounter)];
00436 
00437   } // loop on ROS!
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