CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/EventFilter/EcalRawToDigi/plugins/EcalDumpRaw.cc

Go to the documentation of this file.
00001 //emacs settings:-*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
00002 /*
00003  * $Id: EcalDumpRaw.cc,v 1.11 2012/09/11 20:47:03 wdd Exp $
00004  *
00005  * Author: Ph Gras. CEA/IRFU - Saclay
00006  *
00007  */
00008 
00009 #include "EventFilter/EcalRawToDigi/interface/EcalDumpRaw.h"
00010 
00011 #include <iostream>
00012 #include <fstream>
00013 #include <iomanip>
00014 #include <limits>
00015 #include <algorithm>
00016 #include <sys/time.h>
00017 
00018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00019 #include "FWCore/Framework/interface/Event.h"
00020 #include "FWCore/Framework/interface/EventSetup.h"
00021 
00022 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00023 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00024 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00025 #include "DataFormats/Scalers/interface/L1AcceptBunchCrossing.h"
00026 
00027 // FE BX counter starts at 0, while OD BX starts at 1.
00028 // For some reason, I do not understand myself,
00029 // Bx offset is often set such that:
00030 //     BX_FE = BX_OD for BX_OD < 3564
00031 // and BX_FE = BX_OD - 3564 for BX_OD = 3564
00032 // set feBxOffset to 1 if this FE BX shift is operated, 0 otherwise
00033 //Ph. Gras.
00034 const int feBxOffset = 1;
00035 
00036 const int EcalDumpRaw::ttId_[nTccTypes_][maxTpgsPerTcc_] = {
00037   //EB-
00038   { 1,   2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
00039     17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
00040     33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
00041     49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
00042     65, 66, 67, 68
00043   },
00044 
00045   //EB+
00046   { 4,   3,  2,  1,  8,  7,  6,  5, 12, 11, 10,  9, 16, 15, 14, 13,
00047     20, 19, 18, 17, 24, 23, 22, 21, 28, 27, 26, 25, 32, 31, 30, 29,
00048     36, 35, 34, 33, 40, 39, 38, 37, 44, 43, 42, 41, 48, 47, 46, 45,
00049     52, 51, 50, 49, 56, 55, 54, 53, 60, 59, 58, 57, 64, 63, 62, 61,
00050     68, 67, 66, 65
00051   },
00052 
00053   //inner EE
00054   { 1,   2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
00055     17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,  0,  0,  0,  0,
00056     0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00057     0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00058     0,   0,  0,  0
00059   },
00060   
00061   //outer EE
00062   { 1,   2,  3,  4,  5,  6,  7,  8,  9,
00063     0,   0,  0,  0,  0,  0,  0,  0,  0,
00064     10, 11, 12, 13, 14, 15, 16,  0,  0,
00065     0,   0,  0,  0,  0,  0,  0,  0,  0,
00066     0,   0,  0,  0,  0,  0,  0,  0,  0,
00067     0,   0,  0,  0,  0,  0,  0,  0,  0,
00068     0,   0,  0,  0,  0,  0,  0,  0,  0,
00069     0,   0,  0,  0,  0
00070   }
00071 };
00072 
00073 using namespace std;
00074 
00075 static const char* const trigNames[] = {
00076   "Unknown",
00077   "Phys",
00078   "Calib",
00079   "Test",
00080   "Ext",
00081   "Simu",
00082   "Trace",
00083   "Err"
00084 };
00085 
00086 static const char* const detailedTrigNames[] = {
00087   "?",   //000
00088   "?",   //001
00089   "?",   //010
00090   "?",   //011
00091   "Las", //100
00092   "Led", //101
00093   "TP",  //110
00094   "Ped"  //111
00095 };
00096 
00097 static const char* const colorNames[] = {
00098   "Blue",
00099   "Green",
00100   "Red",
00101   "IR"
00102 };
00103 
00104 static const char* const ttsNames[] = {
00105   "Discon'd", //0000
00106   "OvFWarn",  //0001
00107   "OoS",      //0010
00108   "Forb",     //0011
00109   "Busy",     //0100
00110   "Forb",     //0101
00111   "Forb",     //0110
00112   "Forb",     //0111
00113   "Ready",    //1000
00114   "Forb",     //1001
00115   "Idle",     //1010
00116   "Forb",     //1011
00117   "Err",      //1100
00118   "Forb",     //1101
00119   "Forb",     //1110
00120   "Discon'd"  //1111
00121 };
00122 
00123 //double mgpaGainFactors[] = {12., 1., 12./6., 12.}; //index 0->saturation
00124 //          gain setting:     sat  12       6    1  //index 0->saturation
00125 //          gain setting:  1(sat)     12      6        1
00126 //index 0->saturation
00127 double mgpaGainFactors[] = {10.63, 1., 10.63/5.43, 10.63};
00128 double fppaGainFactors[] = {0, 1., 16./1.,  0.};
00129 
00130 EcalDumpRaw::EcalDumpRaw(const edm::ParameterSet& ps):
00131   iEvent_(0),
00132   adc_(nSamples, 0.),
00133   amplCut_(ps.getUntrackedParameter<double>("amplCut", 5.)),
00134   dump_(ps.getUntrackedParameter<bool>("dump", true)),
00135   dumpAdc_(ps.getUntrackedParameter<bool>("dumpAdc", true)),
00136   l1aHistory_(ps.getUntrackedParameter<bool>("l1aHistory", true)),
00137   //  doHisto_(ps.getUntrackedParameter<bool>("doHisto", true)),
00138   maxEvt_(ps.getUntrackedParameter<int>("maxEvt", 10000)),
00139   profileFedId_(ps.getUntrackedParameter<int>("profileFedId", 0)),
00140   profileRuId_(ps.getUntrackedParameter<int>("profileRuId", 1)),
00141   l1aMinX_(ps.getUntrackedParameter<int>("l1aMinX", 1)),
00142   l1aMaxX_(ps.getUntrackedParameter<int>("l1aMaxX", 601)),
00143   lastOrbit_(nDccs_, numeric_limits<uint32_t>::max()),
00144   eventId_(numeric_limits<unsigned>::max()),
00145   eventList_(ps.getUntrackedParameter<vector<unsigned> >("eventList", vector<unsigned>())),
00146   minEventId_(999999),
00147   maxEventId_(0),
00148   orbit0_(0),
00149   orbit0Set_(false),
00150   bx_(-1),
00151   l1a_(-1),
00152   l1amin_(numeric_limits<int>::max()),
00153   l1amax_(-numeric_limits<int>::min()),
00154   simpleTrigType_(-1),
00155   detailedTrigType_(-1),
00156   //  histo_("hist.root", "RECREATE"),
00157   l1as_(36+2),
00158   orbits_(36+2),
00159   tpg_(maxTccsPerDcc_, std::vector<int>(maxTpgsPerTcc_)),
00160   nTpgs_(maxTccsPerDcc_, 0),
00161   dccChStatus_(70, 0),
00162   srpL1a_(-1),
00163   tccL1a_(-1),
00164   nTts_(-1),
00165   tccBlockLen64_(19),
00166   feL1a_(nRu_,-1),
00167   srpBx_(-1),
00168   tccBx_(-1),
00169   tccType_(0),
00170   feBx_(nRu_,-1),
00171   feRuId_(nRu_,-1),
00172   iTow_(0),
00173   pulsePerRu_(ps.getUntrackedParameter<bool>("pulsePerRu", true)),
00174   pulsePerLmod_(ps.getUntrackedParameter<bool>("pulsePerLmod", true)),
00175   pulsePerLme_(ps.getUntrackedParameter<bool>("pulsePerLme", true)),
00176   tccId_(0),
00177   fedRawDataCollectionTag_(ps.getParameter<edm::InputTag>("fedRawDataCollectionTag")),
00178   l1AcceptBunchCrossingCollectionTag_(ps.getParameter<edm::InputTag>("l1AcceptBunchCrossingCollectionTag"))
00179 {
00180   verbosity_= ps.getUntrackedParameter<int>("verbosity",1);
00181 
00182   beg_fed_id_= ps.getUntrackedParameter<int>("beg_fed_id",601);
00183   end_fed_id_= ps.getUntrackedParameter<int>("end_fed_id",654);
00184 
00185 
00186   first_event_ = ps.getUntrackedParameter<int>("first_event",1);
00187   last_event_  = ps.getUntrackedParameter<int>("last_event",
00188                                                numeric_limits<int>::max());
00189 
00190   writeDcc_ = ps.getUntrackedParameter<bool>("writeDCC",false);
00191   filename_  = ps.getUntrackedParameter<string>("filename","dump.bin");
00192   if(writeDcc_){
00193     dumpFile_.open(filename_.c_str());
00194     if(dumpFile_.bad()){
00195       /*edm::LogError("EcalDumpRaw")*/ std::cout << "Failed to open file '"
00196                                << filename_.c_str() << "' specified by "
00197                                << "parameter filename for writing. DCC data "
00198         " dump will be disabled.";
00199       writeDcc_ = false;
00200     }
00201   }
00202 }
00203 
00204 void EcalDumpRaw::endJob(){
00205 }
00206 
00207 EcalDumpRaw::~EcalDumpRaw(){
00208 }
00209 
00210 // ------------ method called to analyze the data  ------------
00211 void
00212 EcalDumpRaw::analyze(const edm::Event& event, const edm::EventSetup& es){
00213   ++iEvent_;
00214   eventId_ = event.id().event();
00215 
00216   if(eventList_.size()!=0 && find(eventList_.begin(), eventList_.end(),
00217                                   eventId_) == eventList_.end()){
00218     cout << "Skipping event " << eventId_ << ".\n";
00219     return;
00220   }
00221   
00222   if ((first_event_ > 0 && iEvent_ < first_event_) ||
00223       (last_event_ > 0 && last_event_ < iEvent_)) return;
00224   timeval start;
00225   timeval stop;
00226   gettimeofday(&start, 0);
00227 
00228   edm::Handle<FEDRawDataCollection> rawdata;
00229   event.getByLabel(fedRawDataCollectionTag_, rawdata);
00230 
00231   if(dump_ || l1aHistory_) cout << "\n======================================================================\n"
00232                                 << toNth(iEvent_)
00233                                 << " read event. "
00234                                 << "Event id: "
00235                                 << " " << eventId_
00236                                 << "\n----------------------------------------------------------------------\n";
00237   
00238   if(l1aHistory_){
00239     edm::Handle<L1AcceptBunchCrossingCollection> l1aHist;
00240     event.getByLabel(l1AcceptBunchCrossingCollectionTag_, l1aHist);
00241     if(!l1aHist.isValid()) {
00242       cout << "L1A history not found.\n";
00243     } else if (l1aHist->size() == 0) {
00244       cout << "L1A history is empty.\n";
00245     } else{
00246       cout << "L1A history: \n";
00247       for(L1AcceptBunchCrossingCollection::const_iterator it = l1aHist->begin();
00248           it != l1aHist->end();
00249             ++it){
00250         cout << "L1A offset: " <<  it->l1AcceptOffset() << "\t"
00251              << "BX: " <<  it->bunchCrossing() << "\t"
00252              << "Orbit ID: " << it->orbitNumber() << "\t"
00253              << "Trigger type: " << it->eventType() << " ("
00254              << trigNames[it->eventType()&0xF] << ")\n";
00255         }
00256     }
00257     cout << "----------------------------------------------------------------------\n";
00258   }
00259   
00260   if(eventId_ < minEventId_) minEventId_ = eventId_;
00261   if(eventId_ > maxEventId_) maxEventId_ = eventId_;
00262 
00263 #if 1
00264 
00265   bool dccIdErr = false;
00266   unsigned iFed = 0;
00267   unsigned refDccId = 0;
00268   //  static bool recordNextPhys = false;
00269   //static int bxCalib = -1;
00270   //x static int nCalib = 0;
00271 
00272   for (int id = 0; id<=FEDNumbering::lastFEDId(); ++id){
00273 
00274     if (id < beg_fed_id_ || end_fed_id_ < id) continue;
00275 
00276     const FEDRawData& data = rawdata->FEDData(id);
00277 
00278     if (data.size()>4){
00279       ++iFed;
00280       if ((data.size() % 8) !=0){
00281         cout << "***********************************************\n";
00282         cout << " Fed size in bits not multiple of 64, strange.\n";
00283         cout << "***********************************************\n";
00284       }
00285 
00286 
00287       size_t nWord32 = data.size()/4;
00288       const uint32_t * pData = ( reinterpret_cast<uint32_t*>(const_cast<unsigned char*> ( data.data())));
00289       stringstream s;
00290       srpL1a_ = -1;
00291       tccL1a_ = -1;
00292       srpBx_ = -1;
00293       tccBx_ = -1;
00294       iTow_ = 0;
00295       iRu_ = 0;
00296       nTts_ = -1;
00297       iTcc_ = 0;
00298       tccType_ = 0;
00299 
00300       for(int i = 0; i < nRu_; ++i){
00301         feL1a_[i]  = -1;
00302         feBx_[i]   = -1;
00303         feRuId_[i] = -1;
00304       }
00305 
00306       fill(nTpgs_.begin(), nTpgs_.end(), 0);
00307 
00308       fill(dccChStatus_.begin(), dccChStatus_.end(), 0);
00309       
00310       bool rc;
00311       for(size_t iWord32=0; iWord32 < nWord32; iWord32+=2){
00312         s.str("");
00313         if(id>=601 && id<=654){// ECAL DCC data
00314           rc = decode(pData+iWord32, iWord32/2, s);
00315         } else{
00316           rc = true;
00317         }
00318         if(rc && dump_){
00319           cout << setfill('0') << hex
00320                << "[" << setw(8) << iWord32*4 << "] "
00321                <<        setw(4) << (pData[iWord32+1]>>16 & 0xFFFF) << " "
00322                <<        setw(4) << (pData[iWord32+1]>>0  & 0xFFFF) << " "
00323                <<        setw(4) << (pData[iWord32]>>16 & 0xFFFF) << " "
00324                <<        setw(4) << (pData[iWord32]>>0  & 0xFFFF) << " "
00325                << setfill(' ') << dec
00326                << s.str() << "\n";
00327         }
00328       }
00329 
00330       if(iFed==1){
00331         refDccId = dccId_;
00332       } else{
00333         if(dccId_!=refDccId){
00334           dccIdErr = true;
00335         }
00336       }
00337 
00338       if(dump_) cout << flush; //flushing cout before writing to cerr
00339 
00340       if(srpBx_!=-1 && srpBx_!=bx_){
00341         cerr << "Bx discrepancy between SRP and DCC, Bx(SRP) = "
00342              << srpBx_ << ", Bx(DCC) = " << bx_
00343              << " in " << toNth(iEvent_) << " event, FED "
00344              << id << endl;
00345       }
00346 
00347       if(tccBx_!=-1 && tccBx_!=bx_){
00348         cerr << "Bx discrepancy between TCC and DCC, Bx(TCC) = "
00349              << srpBx_ << ", Bx(DCC) = " << bx_
00350              << " in " << toNth(iEvent_) << " event, FED "
00351              << id << endl;
00352       }
00353 
00354       bool feBxErr = false;
00355       for(int i=0; i < nRu_; ++i){
00356         int expectedFeBx;
00357         if(feBxOffset==0){
00358           expectedFeBx = bx_ - 1;
00359         } else{
00360           expectedFeBx = (bx_==3564) ? 0 : bx_;
00361         }
00362         if(feBx_[i]!=-1 && feBx_[i]!=expectedFeBx){
00363           cerr << "BX error for " << toNth(i+1) << " RU, RU ID "
00364                << feRuId_[i];
00365           if((unsigned) feRuId_[i] <= dccChStatus_.size()){
00366             bool detected = (dccChStatus_[feRuId_[i]-1] == 10 || dccChStatus_[feRuId_[i]-1] == 11);
00367             cerr << (detected?" ":" not ") << "detected by DCC (ch status: "
00368                  << dccChStatus_[feRuId_[i]-1] << ")";
00369           }
00370           cerr << " in " << toNth(iEvent_) << " event, FED "
00371                << id << "." << endl;
00372           
00373           feBxErr = true;
00374         }
00375       }
00376       if(feBxErr) cerr << "Bx discrepancy between DCC and at least one FE"
00377                        << " in " << toNth(iEvent_) << " event, FED "
00378                        << id << "\n";
00379 
00380 
00381       int localL1a = l1a_ & 0xFFF;
00382       if(srpL1a_!=-1 && srpL1a_!=localL1a){
00383         cerr << "Discrepancy between SRP and DCC L1a counter, L1a(SRP) = "
00384              << srpL1a_ << ", L1a(DCC) & 0xFFF = " << localL1a
00385              << " in " << toNth(iEvent_) << " event, FED "
00386              << id << endl;
00387 
00388       }
00389 
00390       if(tccL1a_!=-1 && tccL1a_!=localL1a){
00391         cerr << "Discrepancy between TCC and DCC L1a counter, L1a(TCC) = "
00392              << srpL1a_ << ", L1a(DCC) & 0xFFF = " << localL1a
00393              << " in " << toNth(iEvent_) << " event, FED "
00394              << id << endl;
00395 
00396       }
00397 
00398       bool feL1aErr = false;
00399       for(int i=0; i < nRu_; ++i){
00400         if(feL1a_[i] != -1 && feL1a_[i] != ((localL1a-1) & 0xFFF)){
00401           cerr << "FE L1A error for " << toNth(i+1) << " RU, RU ID "
00402                << feRuId_[i];
00403           if((unsigned) feRuId_[i] <= dccChStatus_.size()){
00404             bool detected = (dccChStatus_[feRuId_[i]-1] == 9 || dccChStatus_[feRuId_[i]-1] == 11);
00405             cerr << (detected?" ":" not ") << "detected by DCC (ch status: "
00406                  << dccChStatus_[feRuId_[i]-1] << ")";
00407           }
00408           cerr << " in " << toNth(iEvent_) << " event, FED "
00409                << id << "." << endl;
00410           feL1aErr = true;
00411         }
00412       }
00413       if(feL1aErr) cerr << "Discrepancy in L1a counter between DCC "
00414                      "and at least one FE (L1A(DCC) & 0xFFF = " << localL1a << ")"
00415                         << " in " << toNth(iEvent_) << " event, FED "
00416                         << id << "\n";
00417       
00418 
00419       if(iTow_>0 && iTow_< nRu_ && feRuId_[iTow_] < feRuId_[iTow_-1]){
00420         cerr << "Error in RU ID (TT/SC ID)"
00421              << " in " << toNth(iEvent_) << " event, FED "
00422              << id << endl;
00423       }
00424 
00425       if (beg_fed_id_ <= id && id <= end_fed_id_ && writeDcc_){
00426         dumpFile_.write( reinterpret_cast <const char *> (pData), nWord32*4);
00427       }
00428       
00429       if(dump_) cout << "\n";
00430     } else{
00431       //      cout << "No data for FED " <<  id << ". Size = "
00432       //     << data.size() << " byte(s).\n";
00433     }
00434   } //next fed
00435 
00436   if(dump_) cout << "Number of selected FEDs with a data block: "
00437                  << iFed << "\n";
00438 
00439   if(dccIdErr){
00440     cout << flush;
00441     cerr << "DCC ID discrepancy in detailed trigger type "
00442          << " of " << toNth(iEvent_) << " event." << endl;
00443   }
00444 
00445   if(l1a_>0 && l1a_< l1amin_) l1amin_ = l1a_;
00446   if(l1a_>l1amax_) l1amax_ = l1a_;
00447 
00448 
00449 #endif
00450 
00451   gettimeofday(&stop, 0);
00452   //  double dt  = (stop.tv_sec-start.tv_sec)*1.e3
00453   //  + (stop.tv_usec-start.tv_usec)*1.e-3;
00454   //  histo_.fillD("hCodeTime", "Code execution time;Duration (ms);Event count",
00455   //             PGXAxis(100, 0, 100),
00456   //             dt);
00457 }
00458 
00459 string EcalDumpRaw::toNth(int n){
00460   stringstream s;
00461   s << n;
00462   if(n%100<10 || n%100>20){
00463     switch(n%10){
00464     case 1:
00465       s << "st";
00466       break;
00467     case 2:
00468       s << "nd";
00469       break;
00470     case 3:
00471       s << "rd";
00472       break;
00473     default:
00474       s << "th";
00475     }
00476   } else{
00477     s << "th";
00478   }
00479   return s.str();
00480 }
00481 
00482 
00483 bool EcalDumpRaw::decode(const uint32_t* data, int iWord64, ostream& out){
00484   bool rc = true;
00485   const bool d  = dump_;
00486   if(iWord64==0){//start of event
00487     iSrWord64_ = 0;
00488     iTccWord64_ = 0;
00489     iTowerWord64_ = 0;
00490   }
00491   int dataType = (data[1] >>28) & 0xF;
00492   const int boe = 5;
00493   const int eoe = 10;
00494   if(dataType==boe){//Begin of Event header
00495     /**********************************************************************
00496      *  DAQ header
00497      *
00498      **********************************************************************/
00499     simpleTrigType_ = (data[1] >>24) & 0xF;
00500     l1a_ = (data[1]>>0 )  & 0xFFffFF;
00501     bx_ = (data[0] >>20) & 0xFFF;
00502     fedId_ = (data[0] >>8 ) & 0xFFF;
00503     if(d) out << "Trigger type: " << simpleTrigType_
00504               << "(" << trigNames[(data[1]>>24) & 0xF] << ")"
00505               << " L1A: "         << l1a_
00506               << " BX: "          << bx_
00507               << " FED ID: "      << fedId_
00508               << " FOV: "         << ((data[0] >>4 ) & 0xF)
00509               << " H: "           << ((data[0] >>3 ) & 0x1);
00510   } else if((dataType>>2)==0){//DCC header
00511     /**********************************************************************
00512      * ECAL DCC header
00513      *
00514      **********************************************************************/
00515     int dccHeaderId = (data[1] >>24) & 0x3F;
00516     switch(dccHeaderId){
00517     case 1:
00518       if(d) out << "Run #: "     << ((data[1] >>0 ) & 0xFFFFFF)
00519                 << " DCC Err: "  << ((data[0] >>24) & 0xFF)
00520                 << " Evt Len:  " << ((data[0] >>0 ) & 0xFFFFFF);
00521       break;
00522     case 2:
00523       side_ = (data[1] >>11) & 0x1;
00524       detailedTrigType_ = (data[1] >>8 ) & 0x7;
00525       dccId_ = (data[1] >>0 ) & 0x3F;
00526       if(d) out << "DCC FOV: " << ((data[1] >>16) & 0xF)
00527                 << " Side: "   << side_
00528                 << " Trig.: "   << detailedTrigType_
00529                 << " (" << detailedTrigNames[(data[1]>>8)&0x7] << ")"
00530                 << " Color: "  << ((data[1] >>6 ) & 0x3)
00531                 << " (" << colorNames[(data[1]>>6)&0x3] << ")"
00532                 << " DCC ID: " << dccId_;
00533       break;
00534     case 3:
00535       {
00536       if(d) out << "TCC Status ch<4..1>: 0x"
00537                 << hex << ((data[1]>>8) & 0xFFFF) << dec
00538                 << " SR status: " << ((data[1] >>4 ) & 0xF)
00539                 << " TZS: "       << ((data[1] >>2 ) & 0x1)
00540                 << " ZS: "        << ((data[1] >>1 ) & 0x1)
00541                 << " SR: "        << ((data[1] >>0 ) & 0x1);
00542       orbit_ = data[0];
00543       if(d) out << " Orbit: "     << orbit_;
00544       if(!orbit0Set_){
00545         orbit0_ = orbit_;
00546         orbit0Set_ = true;
00547       }
00548       int iDcc0 = fedId_-fedStart_;
00549       if((unsigned)iDcc0<nDccs_){
00550         if(lastOrbit_[iDcc0]!=numeric_limits<uint32_t>::max()){
00551           if(d) out << " (+" << (int)orbit_-(int)lastOrbit_[iDcc0] <<")";
00552         }
00553         lastOrbit_[iDcc0] = orbit_;
00554       }
00555     }
00556       break;
00557     case 4:
00558     case 5:
00559     case 6:
00560     case 7:
00561     case 8:
00562       {
00563         int chOffset = (dccHeaderId-4)*14;
00564         dccChStatus_[13+chOffset] = ((data[1] >>20) & 0xF);
00565         dccChStatus_[12+chOffset] = ((data[1] >>16) & 0xF);
00566         dccChStatus_[11+chOffset] = ((data[1] >>12) & 0xF);
00567         dccChStatus_[10+chOffset] = ((data[1] >>8 ) & 0xF);
00568         dccChStatus_[ 9+chOffset] = ((data[1] >>4 ) & 0xF);
00569         dccChStatus_[ 8+chOffset] = ((data[1] >>0)  & 0xF);
00570         dccChStatus_[ 7+chOffset] = ((data[0] >>28) & 0xF);
00571         dccChStatus_[ 6+chOffset] = ((data[0] >>24) & 0xF);
00572         dccChStatus_[ 5+chOffset] = ((data[0] >>20) & 0xF);
00573         dccChStatus_[ 4+chOffset] = ((data[0] >>16) & 0xF);
00574         dccChStatus_[ 3+chOffset] = ((data[0] >>12) & 0xF);
00575         dccChStatus_[ 2+chOffset] = ((data[0] >>8 ) & 0xF);
00576         dccChStatus_[ 1+chOffset] = ((data[0] >>4 ) & 0xF);
00577         dccChStatus_[ 0+chOffset] = ((data[0] >>0 ) & 0xF);
00578         
00579         if(d){
00580           out << "FE CH status:";
00581           for(int i = chOffset; i < chOffset + 14; ++i){
00582             out << " #" << (i+1) << ":" << dccChStatus_[i];
00583           }
00584         }
00585       }
00586       break;
00587     default:
00588       if(d) out << " bits<63..62>=0 (DCC header) bits<61..56>=" << dccHeaderId
00589                 << "(unknown=>ERROR?)";
00590     }
00591   } else if((dataType>>1)==3){//TCC block
00592     /**********************************************************************
00593      * TCC block
00594      *
00595      **********************************************************************/
00596     if(iTccWord64_==0){
00597       //header
00598       tccL1a_ = (data[1] >>0 ) & 0xFFF;
00599       tccId_  = ((data[0] >>0 ) & 0xFF);
00600       nTts_  =  ((data[1] >>16) & 0x7F);
00601       if(iTcc_ < maxTccsPerDcc_) nTpgs_[iTcc_] = nTts_;
00602       ++iTcc_;
00603       if(d) out << "LE1: "         << ((data[1] >>28) & 0x1)
00604                 << " LE0: "        << ((data[1] >>27) & 0x1)
00605                 << " N_samples: "  << ((data[1] >>23) & 0x1F)
00606                 << " N_TTs: "      << nTts_
00607                 << " E1: "         << ((data[1] >>12) & 0x1)
00608                 << " L1A: "        << tccL1a_
00609                 << " '3': "        << ((data[0] >>29) & 0x7)
00610                 << " E0: "         << ((data[0] >>28) & 0x1)
00611                 << " Bx: "         << ((data[0] >>16) & 0xFFF)
00612                 << " TTC ID: "     << tccId_;
00613       if(nTts_==68){ //EB TCC (TCC68)
00614         if(fedId_ < 628) tccType_ = ebmTcc_;
00615         else tccType_ = ebpTcc_;
00616       } else if(nTts_ == 16){//Inner EE TCC (TCC48)
00617         tccType_ = eeOuterTcc_;
00618       } else if(nTts_ == 28){//Outer EE TCC (TCC48)
00619         tccType_ = eeInnerTcc_;
00620       } else {
00621         cout << flush;
00622         cerr << "Error in #TT field of TCC block."
00623           "This field is normally used to determine type of TCC "
00624           "(TCC48 or TCC68). Type of TCC will be deduced from the TCC ID.\n";
00625         if(tccId_ < 19) tccType_ = eeInnerTcc_;
00626         else if(tccId_ <  37) tccType_ = eeOuterTcc_;
00627         else if(tccId_ <  55) tccType_ = ebmTcc_;
00628         else if(tccId_ <  73) tccType_ = ebpTcc_;
00629         else if(tccId_ <  91) tccType_ = eeOuterTcc_;
00630         else if(tccId_ < 109) tccType_ = eeInnerTcc_;
00631         else{
00632           cerr << "TCC ID is also invalid. EB- TCC type will be assumed.\n";
00633           tccType_ = ebmTcc_;
00634         }
00635         cerr << flush;
00636       }
00637       tccBlockLen64_ = (tccType_==ebmTcc_ || tccType_==ebpTcc_) ? 18 : 9;        
00638     } else{// if(iTccWord64_<18){
00639       int tpgOffset = (iTccWord64_-1)*4;
00640       if(iTcc_ > maxTccsPerDcc_){
00641         out << "Too many TCC blocks";
00642       } else if(tpgOffset > (maxTpgsPerTcc_ - 4)){
00643         out << "Too many TPG in one TCC block";
00644       } else{
00645         tpg_[iTcc_-1][3+tpgOffset] = (data[1] >>16) & 0x1FF;
00646         tpg_[iTcc_-1][2+tpgOffset] = (data[1] >>0 ) & 0x1FF;
00647         tpg_[iTcc_-1][1+tpgOffset] = (data[0] >>16) & 0x1FF;
00648         tpg_[iTcc_-1][0+tpgOffset] = (data[0] >>0 ) & 0x1FF;
00649         //int n[2][4] = {{1,2,3,4},
00650         //             {4,3,2,1}};
00651         //int iorder = (628<=fedId_ && fedId_<=645)?1:0;
00652         if(d) out << ttfTag(tccType_, 3+tpgOffset) << ":" //"TTF# " << setw(2) << ttId_[3 + tpgOffset] << ":"
00653                   << ((data[1] >>25) & 0x7) << " "
00654                   << tpgTag(tccType_, 3+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[3 + tpgOffset] << ":"
00655                   << setw(3) << tpg_[iTcc_-1][3+tpgOffset] << " "
00656                   << ttfTag(tccType_, 2+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[2 + tpgOffset] << ":"
00657                   << ((data[1] >>9 ) & 0x7) << " "
00658                   << tpgTag(tccType_, 2+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[2 + tpgOffset] << ":"
00659                   << setw(3) << tpg_[iTcc_-1][2+tpgOffset] << " "
00660                   << " '3': "                     << ((data[0] >>29) & 0x7) << " "
00661                   << ttfTag(tccType_, 1+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[1 + tpgOffset] << ":"
00662                   << ((data[0] >>25) & 0x7) << " "
00663                   << setw(3) << tpgTag(tccType_, 1+tpgOffset) << ": "//" TPG# "<< setw(2) << ttId_[1 + tpgOffset] << ":"
00664                   << tpg_[iTcc_-1][1+tpgOffset] << " "
00665                   << ttfTag(tccType_, 0+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[0 + tpgOffset] << ":"
00666                   << ((data[0] >>9 ) & 0x7) << " "
00667                   << setw(3) << tpgTag(tccType_, 0+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[0 + tpgOffset] << ":"
00668                   << tpg_[iTcc_-1][0+tpgOffset];
00669       }
00670     }// else{
00671      // if(d) out << "ERROR";
00672     //}
00673     ++iTccWord64_;
00674     if(iTccWord64_ >= (unsigned)tccBlockLen64_) iTccWord64_ = 0;
00675   } else if((dataType>>1)==4){//SRP block
00676     /**********************************************************************
00677      * SRP block
00678      *
00679      **********************************************************************/
00680     if(iSrWord64_==0){//header
00681       srpL1a_ = (data[1] >>0 ) & 0xFFF;
00682       srpBx_ = (data[0] >>16) & 0xFFF;
00683       if(d) out << "LE1: "     << ((data[1] >>28) & 0x1)
00684                 << " LE0: "    << ((data[1] >>27) & 0x1)
00685                 << " N_SRFs: " << ((data[1] >>16) & 0x7F)
00686                 << " E1: "     << ((data[1] >>12) & 0x1)
00687                 << " L1A: "    << srpL1a_
00688                 << " '4': "    << ((data[0] >>29) & 0x7)
00689                 << " E0: "     << ((data[0] >>28) & 0x1)
00690                 << " Bx: "     << srpBx_
00691                 << " SRP ID: " << ((data[0] >>0 ) & 0xFF);
00692     } else if(iSrWord64_<6){
00693       int ttfOffset = (iSrWord64_-1)*16;
00694       if(d){
00695         if(iSrWord64_<5){
00696           out <<"SRF# " << setw(6) << right << srRange(12+ttfOffset)/*16+ttfOffset << "..#" << 13+ttfOffset*/  << ": "
00697               << oct << ((data[1] >>16) & 0xFFF) << dec
00698               << " SRF# " << srRange(8+ttfOffset) /*12+ttfOffset << "..#" << 9+ttfOffset*/ << ": "
00699               << oct << ((data[1] >>0 ) & 0xFFF) << dec
00700               << " '4':" << ((data[0] >>29) & 0x7)
00701               << " SRF# " << srRange(4+ttfOffset) /*8+ttfOffset << "..#" << 5+ttfOffset*/ << ": "
00702               << oct << ((data[0] >>16) & 0xFFF) << dec;
00703         } else{//last 64-bit word has only 4 SRFs.
00704           out << "                                                           ";
00705         }
00706         out << " SRF# " << srRange(ttfOffset) /*4+ttfOffset << "..#" << 1+ttfOffset*/ << ": "
00707             << oct << ((data[0] >>0 ) & 0xFFF) << dec;
00708       }
00709     } else{
00710       if(d) out << "ERROR";
00711     }
00712     ++iSrWord64_;
00713   } else if((dataType>>2)==3){//Tower block
00714     /**********************************************************************
00715      * "Tower" block (crystal channel data from a RU (=1 FE cards))
00716      *
00717      **********************************************************************/
00718     if(iTowerWord64_==0){//header
00719       towerBlockLength_ = (data[1]>>16) & 0x1FF;
00720       int l1a;
00721       int bx;
00722       l1a = (data[1] >>0 ) & 0xFFF;
00723       bx = (data[0] >>16) & 0xFFF;
00724       dccCh_=(data[0] >>0 ) & 0xFF;
00725       if(d) out << "Block Len: "  << towerBlockLength_
00726                 << " E1: "        << ((data[1] >>12) & 0x1)
00727                 << " L1A: "       << l1a
00728                 << " '3': "       << ((data[0] >>30) & 0x3)
00729                 << " E0: "        << ((data[0] >>28) & 0x1)
00730                 << " Bx: "        << bx
00731                 << " N_samples: " << ((data[0] >>8 ) & 0x7F)
00732                 << " RU ID: "     << dccCh_;
00733       if(iRu_ < nRu_){
00734         feL1a_[iRu_] = l1a;
00735         feBx_[iRu_] = bx;
00736         feRuId_[iRu_] = dccCh_;
00737         ++iRu_;
00738       }
00739     } else if((unsigned)iTowerWord64_<towerBlockLength_){
00740       if(!dumpAdc_){
00741         //no output.
00742         rc = false;
00743       }
00744       const bool da = dumpAdc_ && dump_;
00745       switch((iTowerWord64_-1)%3){
00746         int s[4];
00747         int g[4];
00748       case 0:
00749         s[0]=(data[0] >>16) & 0xFFF;
00750         g[0]=(data[0] >>28) & 0x3;
00751         s[1]=(data[1] >>0 ) & 0xFFF;
00752         g[1]=(data[1] >>12) & 0x3;
00753         s[2]=(data[1] >>16) & 0xFFF;
00754         g[2]=(data[1] >>28) & 0x3;
00755         fill(adc_.begin(), adc_.end(), 0.);
00756         if(da) out << "GMF: "    << ((data[0] >>11) & 0x1)
00757                    << " SMF: "   << ((data[0] >>9 ) & 0x1)
00758                    << " M: "   << ((data[0] >>8 ) & 0x1)
00759                    << " XTAL: "  << ((data[0] >>4 ) & 0x7)
00760                    << " STRIP: " << ((data[0] >>0 ) & 0x7)
00761                    << " " << setw(4) << s[0]
00762                    << "G" << g[0]
00763                    << " " << setw(4) << s[1]
00764                    << "G" << g[1]
00765                    << " " << setw(4) << s[2]
00766                    << "G" << g[2];
00767         for(int i=0; i<3; ++i) adc_[i] = s[i]*mgpaGainFactors[g[i]];
00768         break;
00769       case 1:
00770         s[0]=(data[0] >>0 ) & 0xFFF;
00771         g[0]=(data[0] >>12) & 0x3;
00772         s[1]=(data[0] >>16) & 0xFFF;
00773         g[1]=(data[0] >>28) & 0x3;
00774         s[2]=(data[1] >>0 ) & 0xFFF;
00775         g[2]=(data[1] >>12) & 0x3;
00776         s[3]=(data[1] >>16) & 0xFFF;
00777         g[3]=(data[1] >>28) & 0x3;
00778         if(da) out << "                                   "
00779                    << " " << setw(4) << s[0]
00780                    << "G" << g[0]
00781                    << " " << setw(4) << s[1]
00782                    << "G" << g[1]
00783                    << " " << setw(4) << s[2]
00784                    << "G" << g[2]
00785                    << " " << setw(4) << s[3]
00786                    << "G" << g[3];
00787         for(int i=0; i<4; ++i) adc_[i+3] = s[i]*mgpaGainFactors[g[i]];
00788         break;
00789       case 2:
00790         if(da) out << "TZS: " << ((data[1] >>14) & 0x1);
00791 
00792         s[0]=(data[0] >>0 ) & 0xFFF;
00793         g[0]=(data[0] >>12) & 0x3;
00794         s[1]=(data[0] >>16) & 0xFFF;
00795         g[1]=(data[0] >>28) & 0x3;
00796         s[2]=(data[1] >>0 ) & 0xFFF;
00797         g[2]=(data[1] >>12) & 0x3  ;
00798 
00799         for(int i=0; i<3; ++i) adc_[i+7] = s[i]*mgpaGainFactors[g[i]];
00800         if(dccCh_<=68){
00801           unsigned bom0; //Bin of Maximum, starting counting from 0
00802           double ampl = max(adc_, bom0)-min(adc_);
00803           if(da) out << " Ampl: " << setw(4) << ampl
00804                       << (ampl>amplCut_?"*":" ")
00805                      << " BoM:" << setw(2) << (bom0+1)
00806                      << "          ";
00807             if(fedId_ == dccId_ + 600 //block of the read-out SM
00808                //if laser, only one side:
00809                && (detailedTrigType_!=4 || sideOfRu(dccCh_)==(int)side_)
00810                ){
00811             }
00812         } else{
00813           if(da) out << setw(29) << "";
00814         }
00815         if(da) out << " " << setw(4) << s[0]
00816                    << "G" << g[0]
00817                    << " " << setw(4) << s[1]
00818                    << "G" << g[1]
00819                    << " " << setw(4) << s[2]
00820                   << "G" << g[2];
00821         break;
00822         default:
00823           assert(false);
00824       }
00825     } else {
00826       if(d) out << "ERROR";
00827     }
00828     ++iTowerWord64_;
00829     if(iTowerWord64_>=towerBlockLength_){
00830       iTowerWord64_-=towerBlockLength_;
00831       ++dccCh_;
00832     }
00833   } else if(dataType==eoe){//End of event trailer
00834     /**********************************************************************
00835      * Event DAQ trailer
00836      *
00837      **********************************************************************/
00838     int tts = (data[0] >>4)  & 0xF;
00839     if(d) out << "Evt Len.: "    << ((data[1] >>0 ) & 0xFFFFFF)
00840               << " CRC16: "       << ((data[0] >>16) & 0xFFFF)
00841               << " Evt Status: "  << ((data[0] >>8 ) & 0xF)
00842               << " TTS: "         << tts
00843               << " (" << ttsNames[tts] << ")"
00844               << " T:"            << ((data[0] >>3)  & 0x1);
00845   } else{
00846     if(d) out << " incorrect 64-bit word type marker (see MSBs)";
00847   }
00848   return rc;
00849 }
00850 
00851 // The following method was not removed due to package maintainer 
00852 // (Philippe Gras <philippe.gras@cern.ch>) request.
00853 
00854 //int EcalDumpRaw::lme(int dcc1, int side){
00855 //  int fedid = ((dcc1-1)%600) + 600; //to handle both FED and DCC id.
00856 //   vector<int> lmes;
00857 //   // EE -
00858 //   if( fedid <= 609 ) {
00859 //     if ( fedid <= 607 ) {
00860 //       lmes.push_back(fedid-601+83);
00861 //     } else if ( fedid == 608 ) {
00862 //       lmes.push_back(90);
00863 //       lmes.push_back(91);
00864 //     } else if ( fedid == 609 ) {
00865 //       lmes.push_back(92);
00866 //     }
00867 //   } //EB
00868 //   else if ( fedid >= 610  && fedid <= 645 ) {
00869 //     lmes.push_back(2*(fedid-610)+1);
00870 //     lmes.push_back(lmes[0]+1);
00871 //   } // EE+
00872 //   else if ( fedid >= 646 ) {
00873 //     if ( fedid <= 652 ) {
00874 //       lmes.push_back(fedid-646+73);
00875 //     } else if ( fedid == 653 ) {
00876 //       lmes.push_back(80);
00877 //       lmes.push_back(81);
00878 //     } else if ( fedid == 654 ) {
00879 //       lmes.push_back(82);
00880 //     }
00881 //   }
00882 //   return lmes.size()==0?-1:lmes[std::min(lmes.size(), (size_t)side)];
00883 //}
00884 
00885 
00886 int EcalDumpRaw::sideOfRu(int ru1){
00887   if(ru1 < 5 || (ru1-5)%4 >= 2){
00888     return 0;
00889   } else{
00890     return 1;
00891   }
00892 }
00893 
00894 
00895 int EcalDumpRaw::modOfRu(int ru1){
00896   int iEta0 = (ru1-1)/4;
00897   if(iEta0<5){
00898     return 1;
00899   } else{
00900     return 2 + (iEta0-5)/4;
00901   }
00902 }
00903 
00904 int EcalDumpRaw::lmodOfRu(int ru1){
00905   int iEta0 = (ru1-1)/4;
00906   int iPhi0 = (ru1-1)%4;
00907   int rs;
00908   if(iEta0==0){
00909     rs =  1;
00910   } else{
00911     rs = 2 + ((iEta0-1)/4)*2 + (iPhi0%4)/2;
00912   }
00913   //  cout << "ru1 = " << ru1 << " -> lmod = " << rs << "\n";
00914   return rs;
00915 }
00916 
00917 std::string EcalDumpRaw::srRange(int offset) const{
00918   int min = offset+1;
00919   int max = offset+4;
00920   stringstream buf;
00921   if(628 <= fedId_ && fedId_ <= 646){//EB+
00922     buf << right << min << ".."
00923         << left  << max;
00924   } else{
00925     buf << right << max << ".."
00926         << left  << min;
00927   }
00928   string s = buf.str();
00929   buf.str("");
00930   buf << setw(6) << right << s;
00931   return buf.str();
00932 }
00933 
00934 std::string EcalDumpRaw::ttfTag(int tccType, unsigned iSeq) const{
00935   if((unsigned)iSeq > sizeof(ttId_))
00936     throw cms::Exception("OutOfRange")
00937       << __FILE__ << ":"  << __LINE__ << ": "
00938       << "parameter out of range\n";
00939                              
00940   const int ttId = ttId_[tccType][iSeq];
00941   stringstream buf;
00942   buf.str("");
00943   if(ttId==0){
00944     buf << "    '0'";
00945   } else{
00946     buf << "TTF# " << setw(2) << ttId;
00947   }
00948   return buf.str();
00949 }
00950 
00951 std::string EcalDumpRaw::tpgTag(int tccType, unsigned iSeq) const{
00952   if((unsigned)iSeq > sizeof(ttId_))
00953     throw cms::Exception("OutOfRange")
00954       << __FILE__ << ":"  << __LINE__ << ": "
00955       << "parameter out of range\n";
00956                              
00957   const int ttId = ttId_[tccType][iSeq];
00958   stringstream buf;
00959   buf.str("");
00960   if(ttId==0){
00961     buf << "    '0'";
00962   } else{
00963     buf << "TPG# " << setw(2) << ttId;
00964   }
00965   return buf.str();
00966 }