CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/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.10 2012/02/26 20:19:46 pgras 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 {
00178   verbosity_= ps.getUntrackedParameter<int>("verbosity",1);
00179 
00180   beg_fed_id_= ps.getUntrackedParameter<int>("beg_fed_id",601);
00181   end_fed_id_= ps.getUntrackedParameter<int>("end_fed_id",654);
00182 
00183 
00184   first_event_ = ps.getUntrackedParameter<int>("first_event",1);
00185   last_event_  = ps.getUntrackedParameter<int>("last_event",
00186                                                numeric_limits<int>::max());
00187 
00188   writeDcc_ = ps.getUntrackedParameter<bool>("writeDCC",false);
00189   filename_  = ps.getUntrackedParameter<string>("filename","dump.bin");
00190   if(writeDcc_){
00191     dumpFile_.open(filename_.c_str());
00192     if(dumpFile_.bad()){
00193       /*edm::LogError("EcalDumpRaw")*/ std::cout << "Failed to open file '"
00194                                << filename_.c_str() << "' specified by "
00195                                << "parameter filename for writing. DCC data "
00196         " dump will be disabled.";
00197       writeDcc_ = false;
00198     }
00199   }
00200 }
00201 
00202 void EcalDumpRaw::endJob(){
00203 }
00204 
00205 EcalDumpRaw::~EcalDumpRaw(){
00206 }
00207 
00208 // ------------ method called to analyze the data  ------------
00209 void
00210 EcalDumpRaw::analyze(const edm::Event& event, const edm::EventSetup& es){
00211   ++iEvent_;
00212   eventId_ = event.id().event();
00213 
00214   if(eventList_.size()!=0 && find(eventList_.begin(), eventList_.end(),
00215                                   eventId_) == eventList_.end()){
00216     cout << "Skipping event " << eventId_ << ".\n";
00217     return;
00218   }
00219   
00220   if ((first_event_ > 0 && iEvent_ < first_event_) ||
00221       (last_event_ > 0 && last_event_ < iEvent_)) return;
00222   timeval start;
00223   timeval stop;
00224   gettimeofday(&start, 0);
00225 
00226   edm::Handle<FEDRawDataCollection> rawdata;
00227   event.getByType(rawdata);
00228 
00229   if(dump_ || l1aHistory_) cout << "\n======================================================================\n"
00230                                 << toNth(iEvent_)
00231                                 << " read event. "
00232                                 << "Event id: "
00233                                 << " " << eventId_
00234                                 << "\n----------------------------------------------------------------------\n";
00235   
00236   if(l1aHistory_){
00237     edm::Handle<L1AcceptBunchCrossingCollection> l1aHist;
00238     event.getByType(l1aHist);
00239     if(!l1aHist.isValid() || l1aHist->size() == 0){
00240       cout << "L1A history not found.\n";
00241     } else{
00242       cout << "L1A history: \n";
00243       for(L1AcceptBunchCrossingCollection::const_iterator it = l1aHist->begin();
00244           it != l1aHist->end();
00245             ++it){
00246         cout << "L1A offset: " <<  it->l1AcceptOffset() << "\t"
00247              << "BX: " <<  it->bunchCrossing() << "\t"
00248              << "Orbit ID: " << it->orbitNumber() << "\t"
00249              << "Trigger type: " << it->eventType() << " ("
00250              << trigNames[it->eventType()&0xF] << ")\n";
00251         }
00252     }
00253     cout << "----------------------------------------------------------------------\n";
00254   }
00255   
00256   if(eventId_ < minEventId_) minEventId_ = eventId_;
00257   if(eventId_ > maxEventId_) maxEventId_ = eventId_;
00258 
00259 #if 1
00260 
00261   bool dccIdErr = false;
00262   unsigned iFed = 0;
00263   unsigned refDccId = 0;
00264   //  static bool recordNextPhys = false;
00265   //static int bxCalib = -1;
00266   //x static int nCalib = 0;
00267 
00268   for (int id = 0; id<=FEDNumbering::lastFEDId(); ++id){
00269 
00270     if (id < beg_fed_id_ || end_fed_id_ < id) continue;
00271 
00272     const FEDRawData& data = rawdata->FEDData(id);
00273 
00274     if (data.size()>4){
00275       ++iFed;
00276       if ((data.size() % 8) !=0){
00277         cout << "***********************************************\n";
00278         cout << " Fed size in bits not multiple of 64, strange.\n";
00279         cout << "***********************************************\n";
00280       }
00281 
00282 
00283       size_t nWord32 = data.size()/4;
00284       const uint32_t * pData = ( reinterpret_cast<uint32_t*>(const_cast<unsigned char*> ( data.data())));
00285       stringstream s;
00286       srpL1a_ = -1;
00287       tccL1a_ = -1;
00288       srpBx_ = -1;
00289       tccBx_ = -1;
00290       iTow_ = 0;
00291       iRu_ = 0;
00292       nTts_ = -1;
00293       iTcc_ = 0;
00294       tccType_ = 0;
00295 
00296       for(int i = 0; i < nRu_; ++i){
00297         feL1a_[i]  = -1;
00298         feBx_[i]   = -1;
00299         feRuId_[i] = -1;
00300       }
00301 
00302       fill(nTpgs_.begin(), nTpgs_.end(), 0);
00303 
00304       fill(dccChStatus_.begin(), dccChStatus_.end(), 0);
00305       
00306       bool rc;
00307       for(size_t iWord32=0; iWord32 < nWord32; iWord32+=2){
00308         s.str("");
00309         if(id>=601 && id<=654){// ECAL DCC data
00310           rc = decode(pData+iWord32, iWord32/2, s);
00311         } else{
00312           rc = true;
00313         }
00314         if(rc && dump_){
00315           cout << setfill('0') << hex
00316                << "[" << setw(8) << iWord32*4 << "] "
00317                <<        setw(4) << (pData[iWord32+1]>>16 & 0xFFFF) << " "
00318                <<        setw(4) << (pData[iWord32+1]>>0  & 0xFFFF) << " "
00319                <<        setw(4) << (pData[iWord32]>>16 & 0xFFFF) << " "
00320                <<        setw(4) << (pData[iWord32]>>0  & 0xFFFF) << " "
00321                << setfill(' ') << dec
00322                << s.str() << "\n";
00323         }
00324       }
00325 
00326       if(iFed==1){
00327         refDccId = dccId_;
00328       } else{
00329         if(dccId_!=refDccId){
00330           dccIdErr = true;
00331         }
00332       }
00333 
00334       if(dump_) cout << flush; //flushing cout before writing to cerr
00335 
00336       if(srpBx_!=-1 && srpBx_!=bx_){
00337         cerr << "Bx discrepancy between SRP and DCC, Bx(SRP) = "
00338              << srpBx_ << ", Bx(DCC) = " << bx_
00339              << " in " << toNth(iEvent_) << " event, FED "
00340              << id << endl;
00341       }
00342 
00343       if(tccBx_!=-1 && tccBx_!=bx_){
00344         cerr << "Bx discrepancy between TCC and DCC, Bx(TCC) = "
00345              << srpBx_ << ", Bx(DCC) = " << bx_
00346              << " in " << toNth(iEvent_) << " event, FED "
00347              << id << endl;
00348       }
00349 
00350       bool feBxErr = false;
00351       for(int i=0; i < nRu_; ++i){
00352         int expectedFeBx;
00353         if(feBxOffset==0){
00354           expectedFeBx = bx_ - 1;
00355         } else{
00356           expectedFeBx = (bx_==3564) ? 0 : bx_;
00357         }
00358         if(feBx_[i]!=-1 && feBx_[i]!=expectedFeBx){
00359           cerr << "BX error for " << toNth(i+1) << " RU, RU ID "
00360                << feRuId_[i];
00361           if((unsigned) feRuId_[i] <= dccChStatus_.size()){
00362             bool detected = (dccChStatus_[feRuId_[i]-1] == 10 || dccChStatus_[feRuId_[i]-1] == 11);
00363             cerr << (detected?" ":" not ") << "detected by DCC (ch status: "
00364                  << dccChStatus_[feRuId_[i]-1] << ")";
00365           }
00366           cerr << " in " << toNth(iEvent_) << " event, FED "
00367                << id << "." << endl;
00368           
00369           feBxErr = true;
00370         }
00371       }
00372       if(feBxErr) cerr << "Bx discrepancy between DCC and at least one FE"
00373                        << " in " << toNth(iEvent_) << " event, FED "
00374                        << id << "\n";
00375 
00376 
00377       int localL1a = l1a_ & 0xFFF;
00378       if(srpL1a_!=-1 && srpL1a_!=localL1a){
00379         cerr << "Discrepancy between SRP and DCC L1a counter, L1a(SRP) = "
00380              << srpL1a_ << ", L1a(DCC) & 0xFFF = " << localL1a
00381              << " in " << toNth(iEvent_) << " event, FED "
00382              << id << endl;
00383 
00384       }
00385 
00386       if(tccL1a_!=-1 && tccL1a_!=localL1a){
00387         cerr << "Discrepancy between TCC and DCC L1a counter, L1a(TCC) = "
00388              << srpL1a_ << ", L1a(DCC) & 0xFFF = " << localL1a
00389              << " in " << toNth(iEvent_) << " event, FED "
00390              << id << endl;
00391 
00392       }
00393 
00394       bool feL1aErr = false;
00395       for(int i=0; i < nRu_; ++i){
00396         if(feL1a_[i] != -1 && feL1a_[i] != ((localL1a-1) & 0xFFF)){
00397           cerr << "FE L1A error for " << toNth(i+1) << " RU, RU ID "
00398                << feRuId_[i];
00399           if((unsigned) feRuId_[i] <= dccChStatus_.size()){
00400             bool detected = (dccChStatus_[feRuId_[i]-1] == 9 || dccChStatus_[feRuId_[i]-1] == 11);
00401             cerr << (detected?" ":" not ") << "detected by DCC (ch status: "
00402                  << dccChStatus_[feRuId_[i]-1] << ")";
00403           }
00404           cerr << " in " << toNth(iEvent_) << " event, FED "
00405                << id << "." << endl;
00406           feL1aErr = true;
00407         }
00408       }
00409       if(feL1aErr) cerr << "Discrepancy in L1a counter between DCC "
00410                      "and at least one FE (L1A(DCC) & 0xFFF = " << localL1a << ")"
00411                         << " in " << toNth(iEvent_) << " event, FED "
00412                         << id << "\n";
00413       
00414 
00415       if(iTow_>0 && iTow_< nRu_ && feRuId_[iTow_] < feRuId_[iTow_-1]){
00416         cerr << "Error in RU ID (TT/SC ID)"
00417              << " in " << toNth(iEvent_) << " event, FED "
00418              << id << endl;
00419       }
00420 
00421       if (beg_fed_id_ <= id && id <= end_fed_id_ && writeDcc_){
00422         dumpFile_.write( reinterpret_cast <const char *> (pData), nWord32*4);
00423       }
00424       
00425       if(dump_) cout << "\n";
00426     } else{
00427       //      cout << "No data for FED " <<  id << ". Size = "
00428       //     << data.size() << " byte(s).\n";
00429     }
00430   } //next fed
00431 
00432   if(dump_) cout << "Number of selected FEDs with a data block: "
00433                  << iFed << "\n";
00434 
00435   if(dccIdErr){
00436     cout << flush;
00437     cerr << "DCC ID discrepancy in detailed trigger type "
00438          << " of " << toNth(iEvent_) << " event." << endl;
00439   }
00440 
00441   if(l1a_>0 && l1a_< l1amin_) l1amin_ = l1a_;
00442   if(l1a_>l1amax_) l1amax_ = l1a_;
00443 
00444 
00445 #endif
00446 
00447   gettimeofday(&stop, 0);
00448   //  double dt  = (stop.tv_sec-start.tv_sec)*1.e3
00449   //  + (stop.tv_usec-start.tv_usec)*1.e-3;
00450   //  histo_.fillD("hCodeTime", "Code execution time;Duration (ms);Event count",
00451   //             PGXAxis(100, 0, 100),
00452   //             dt);
00453 }
00454 
00455 string EcalDumpRaw::toNth(int n){
00456   stringstream s;
00457   s << n;
00458   if(n%100<10 || n%100>20){
00459     switch(n%10){
00460     case 1:
00461       s << "st";
00462       break;
00463     case 2:
00464       s << "nd";
00465       break;
00466     case 3:
00467       s << "rd";
00468       break;
00469     default:
00470       s << "th";
00471     }
00472   } else{
00473     s << "th";
00474   }
00475   return s.str();
00476 }
00477 
00478 
00479 bool EcalDumpRaw::decode(const uint32_t* data, int iWord64, ostream& out){
00480   bool rc = true;
00481   const bool d  = dump_;
00482   if(iWord64==0){//start of event
00483     iSrWord64_ = 0;
00484     iTccWord64_ = 0;
00485     iTowerWord64_ = 0;
00486   }
00487   int dataType = (data[1] >>28) & 0xF;
00488   const int boe = 5;
00489   const int eoe = 10;
00490   if(dataType==boe){//Begin of Event header
00491     /**********************************************************************
00492      *  DAQ header
00493      *
00494      **********************************************************************/
00495     simpleTrigType_ = (data[1] >>24) & 0xF;
00496     l1a_ = (data[1]>>0 )  & 0xFFffFF;
00497     bx_ = (data[0] >>20) & 0xFFF;
00498     fedId_ = (data[0] >>8 ) & 0xFFF;
00499     if(d) out << "Trigger type: " << simpleTrigType_
00500               << "(" << trigNames[(data[1]>>24) & 0xF] << ")"
00501               << " L1A: "         << l1a_
00502               << " BX: "          << bx_
00503               << " FED ID: "      << fedId_
00504               << " FOV: "         << ((data[0] >>4 ) & 0xF)
00505               << " H: "           << ((data[0] >>3 ) & 0x1);
00506   } else if((dataType>>2)==0){//DCC header
00507     /**********************************************************************
00508      * ECAL DCC header
00509      *
00510      **********************************************************************/
00511     int dccHeaderId = (data[1] >>24) & 0x3F;
00512     switch(dccHeaderId){
00513     case 1:
00514       if(d) out << "Run #: "     << ((data[1] >>0 ) & 0xFFFFFF)
00515                 << " DCC Err: "  << ((data[0] >>24) & 0xFF)
00516                 << " Evt Len:  " << ((data[0] >>0 ) & 0xFFFFFF);
00517       break;
00518     case 2:
00519       side_ = (data[1] >>11) & 0x1;
00520       detailedTrigType_ = (data[1] >>8 ) & 0x7;
00521       dccId_ = (data[1] >>0 ) & 0x3F;
00522       if(d) out << "DCC FOV: " << ((data[1] >>16) & 0xF)
00523                 << " Side: "   << side_
00524                 << " Trig.: "   << detailedTrigType_
00525                 << " (" << detailedTrigNames[(data[1]>>8)&0x7] << ")"
00526                 << " Color: "  << ((data[1] >>6 ) & 0x3)
00527                 << " (" << colorNames[(data[1]>>6)&0x3] << ")"
00528                 << " DCC ID: " << dccId_;
00529       break;
00530     case 3:
00531       {
00532       if(d) out << "TCC Status ch<4..1>: 0x"
00533                 << hex << ((data[1]>>8) & 0xFFFF) << dec
00534                 << " SR status: " << ((data[1] >>4 ) & 0xF)
00535                 << " TZS: "       << ((data[1] >>2 ) & 0x1)
00536                 << " ZS: "        << ((data[1] >>1 ) & 0x1)
00537                 << " SR: "        << ((data[1] >>0 ) & 0x1);
00538       orbit_ = data[0];
00539       if(d) out << " Orbit: "     << orbit_;
00540       if(!orbit0Set_){
00541         orbit0_ = orbit_;
00542         orbit0Set_ = true;
00543       }
00544       int iDcc0 = fedId_-fedStart_;
00545       if((unsigned)iDcc0<nDccs_){
00546         if(lastOrbit_[iDcc0]!=numeric_limits<uint32_t>::max()){
00547           if(d) out << " (+" << (int)orbit_-(int)lastOrbit_[iDcc0] <<")";
00548         }
00549         lastOrbit_[iDcc0] = orbit_;
00550       }
00551     }
00552       break;
00553     case 4:
00554     case 5:
00555     case 6:
00556     case 7:
00557     case 8:
00558       {
00559         int chOffset = (dccHeaderId-4)*14;
00560         dccChStatus_[13+chOffset] = ((data[1] >>20) & 0xF);
00561         dccChStatus_[12+chOffset] = ((data[1] >>16) & 0xF);
00562         dccChStatus_[11+chOffset] = ((data[1] >>12) & 0xF);
00563         dccChStatus_[10+chOffset] = ((data[1] >>8 ) & 0xF);
00564         dccChStatus_[ 9+chOffset] = ((data[1] >>4 ) & 0xF);
00565         dccChStatus_[ 8+chOffset] = ((data[1] >>0)  & 0xF);
00566         dccChStatus_[ 7+chOffset] = ((data[0] >>28) & 0xF);
00567         dccChStatus_[ 6+chOffset] = ((data[0] >>24) & 0xF);
00568         dccChStatus_[ 5+chOffset] = ((data[0] >>20) & 0xF);
00569         dccChStatus_[ 4+chOffset] = ((data[0] >>16) & 0xF);
00570         dccChStatus_[ 3+chOffset] = ((data[0] >>12) & 0xF);
00571         dccChStatus_[ 2+chOffset] = ((data[0] >>8 ) & 0xF);
00572         dccChStatus_[ 1+chOffset] = ((data[0] >>4 ) & 0xF);
00573         dccChStatus_[ 0+chOffset] = ((data[0] >>0 ) & 0xF);
00574         
00575         if(d){
00576           out << "FE CH status:";
00577           for(int i = chOffset; i < chOffset + 14; ++i){
00578             out << " #" << (i+1) << ":" << dccChStatus_[i];
00579           }
00580         }
00581       }
00582       break;
00583     default:
00584       if(d) out << " bits<63..62>=0 (DCC header) bits<61..56>=" << dccHeaderId
00585                 << "(unknown=>ERROR?)";
00586     }
00587   } else if((dataType>>1)==3){//TCC block
00588     /**********************************************************************
00589      * TCC block
00590      *
00591      **********************************************************************/
00592     if(iTccWord64_==0){
00593       //header
00594       tccL1a_ = (data[1] >>0 ) & 0xFFF;
00595       tccId_  = ((data[0] >>0 ) & 0xFF);
00596       nTts_  =  ((data[1] >>16) & 0x7F);
00597       if(iTcc_ < maxTccsPerDcc_) nTpgs_[iTcc_] = nTts_;
00598       ++iTcc_;
00599       if(d) out << "LE1: "         << ((data[1] >>28) & 0x1)
00600                 << " LE0: "        << ((data[1] >>27) & 0x1)
00601                 << " N_samples: "  << ((data[1] >>23) & 0x1F)
00602                 << " N_TTs: "      << nTts_
00603                 << " E1: "         << ((data[1] >>12) & 0x1)
00604                 << " L1A: "        << tccL1a_
00605                 << " '3': "        << ((data[0] >>29) & 0x7)
00606                 << " E0: "         << ((data[0] >>28) & 0x1)
00607                 << " Bx: "         << ((data[0] >>16) & 0xFFF)
00608                 << " TTC ID: "     << tccId_;
00609       if(nTts_==68){ //EB TCC (TCC68)
00610         if(fedId_ < 628) tccType_ = ebmTcc_;
00611         else tccType_ = ebpTcc_;
00612       } else if(nTts_ == 16){//Inner EE TCC (TCC48)
00613         tccType_ = eeOuterTcc_;
00614       } else if(nTts_ == 28){//Outer EE TCC (TCC48)
00615         tccType_ = eeInnerTcc_;
00616       } else {
00617         cout << flush;
00618         cerr << "Error in #TT field of TCC block."
00619           "This field is normally used to determine type of TCC "
00620           "(TCC48 or TCC68). Type of TCC will be deduced from the TCC ID.\n";
00621         if(tccId_ < 19) tccType_ = eeInnerTcc_;
00622         else if(tccId_ <  37) tccType_ = eeOuterTcc_;
00623         else if(tccId_ <  55) tccType_ = ebmTcc_;
00624         else if(tccId_ <  73) tccType_ = ebpTcc_;
00625         else if(tccId_ <  91) tccType_ = eeOuterTcc_;
00626         else if(tccId_ < 109) tccType_ = eeInnerTcc_;
00627         else{
00628           cerr << "TCC ID is also invalid. EB- TCC type will be assumed.\n";
00629           tccType_ = ebmTcc_;
00630         }
00631         cerr << flush;
00632       }
00633       tccBlockLen64_ = (tccType_==ebmTcc_ || tccType_==ebpTcc_) ? 18 : 9;        
00634     } else{// if(iTccWord64_<18){
00635       int tpgOffset = (iTccWord64_-1)*4;
00636       if(iTcc_ > maxTccsPerDcc_){
00637         out << "Too many TCC blocks";
00638       } else if(tpgOffset > (maxTpgsPerTcc_ - 4)){
00639         out << "Too many TPG in one TCC block";
00640       } else{
00641         tpg_[iTcc_-1][3+tpgOffset] = (data[1] >>16) & 0x1FF;
00642         tpg_[iTcc_-1][2+tpgOffset] = (data[1] >>0 ) & 0x1FF;
00643         tpg_[iTcc_-1][1+tpgOffset] = (data[0] >>16) & 0x1FF;
00644         tpg_[iTcc_-1][0+tpgOffset] = (data[0] >>0 ) & 0x1FF;
00645         //int n[2][4] = {{1,2,3,4},
00646         //             {4,3,2,1}};
00647         //int iorder = (628<=fedId_ && fedId_<=645)?1:0;
00648         if(d) out << ttfTag(tccType_, 3+tpgOffset) << ":" //"TTF# " << setw(2) << ttId_[3 + tpgOffset] << ":"
00649                   << ((data[1] >>25) & 0x7) << " "
00650                   << tpgTag(tccType_, 3+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[3 + tpgOffset] << ":"
00651                   << setw(3) << tpg_[iTcc_-1][3+tpgOffset] << " "
00652                   << ttfTag(tccType_, 2+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[2 + tpgOffset] << ":"
00653                   << ((data[1] >>9 ) & 0x7) << " "
00654                   << tpgTag(tccType_, 2+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[2 + tpgOffset] << ":"
00655                   << setw(3) << tpg_[iTcc_-1][2+tpgOffset] << " "
00656                   << " '3': "                     << ((data[0] >>29) & 0x7) << " "
00657                   << ttfTag(tccType_, 1+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[1 + tpgOffset] << ":"
00658                   << ((data[0] >>25) & 0x7) << " "
00659                   << setw(3) << tpgTag(tccType_, 1+tpgOffset) << ": "//" TPG# "<< setw(2) << ttId_[1 + tpgOffset] << ":"
00660                   << tpg_[iTcc_-1][1+tpgOffset] << " "
00661                   << ttfTag(tccType_, 0+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[0 + tpgOffset] << ":"
00662                   << ((data[0] >>9 ) & 0x7) << " "
00663                   << setw(3) << tpgTag(tccType_, 0+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[0 + tpgOffset] << ":"
00664                   << tpg_[iTcc_-1][0+tpgOffset];
00665       }
00666     }// else{
00667      // if(d) out << "ERROR";
00668     //}
00669     ++iTccWord64_;
00670     if(iTccWord64_ >= (unsigned)tccBlockLen64_) iTccWord64_ = 0;
00671   } else if((dataType>>1)==4){//SRP block
00672     /**********************************************************************
00673      * SRP block
00674      *
00675      **********************************************************************/
00676     if(iSrWord64_==0){//header
00677       srpL1a_ = (data[1] >>0 ) & 0xFFF;
00678       srpBx_ = (data[0] >>16) & 0xFFF;
00679       if(d) out << "LE1: "     << ((data[1] >>28) & 0x1)
00680                 << " LE0: "    << ((data[1] >>27) & 0x1)
00681                 << " N_SRFs: " << ((data[1] >>16) & 0x7F)
00682                 << " E1: "     << ((data[1] >>12) & 0x1)
00683                 << " L1A: "    << srpL1a_
00684                 << " '4': "    << ((data[0] >>29) & 0x7)
00685                 << " E0: "     << ((data[0] >>28) & 0x1)
00686                 << " Bx: "     << srpBx_
00687                 << " SRP ID: " << ((data[0] >>0 ) & 0xFF);
00688     } else if(iSrWord64_<6){
00689       int ttfOffset = (iSrWord64_-1)*16;
00690       if(d){
00691         if(iSrWord64_<5){
00692           out <<"SRF# " << setw(6) << right << srRange(12+ttfOffset)/*16+ttfOffset << "..#" << 13+ttfOffset*/  << ": "
00693               << oct << ((data[1] >>16) & 0xFFF) << dec
00694               << " SRF# " << srRange(8+ttfOffset) /*12+ttfOffset << "..#" << 9+ttfOffset*/ << ": "
00695               << oct << ((data[1] >>0 ) & 0xFFF) << dec
00696               << " '4':" << ((data[0] >>29) & 0x7)
00697               << " SRF# " << srRange(4+ttfOffset) /*8+ttfOffset << "..#" << 5+ttfOffset*/ << ": "
00698               << oct << ((data[0] >>16) & 0xFFF) << dec;
00699         } else{//last 64-bit word has only 4 SRFs.
00700           out << "                                                           ";
00701         }
00702         out << " SRF# " << srRange(ttfOffset) /*4+ttfOffset << "..#" << 1+ttfOffset*/ << ": "
00703             << oct << ((data[0] >>0 ) & 0xFFF) << dec;
00704       }
00705     } else{
00706       if(d) out << "ERROR";
00707     }
00708     ++iSrWord64_;
00709   } else if((dataType>>2)==3){//Tower block
00710     /**********************************************************************
00711      * "Tower" block (crystal channel data from a RU (=1 FE cards))
00712      *
00713      **********************************************************************/
00714     if(iTowerWord64_==0){//header
00715       towerBlockLength_ = (data[1]>>16) & 0x1FF;
00716       int l1a;
00717       int bx;
00718       l1a = (data[1] >>0 ) & 0xFFF;
00719       bx = (data[0] >>16) & 0xFFF;
00720       dccCh_=(data[0] >>0 ) & 0xFF;
00721       if(d) out << "Block Len: "  << towerBlockLength_
00722                 << " E1: "        << ((data[1] >>12) & 0x1)
00723                 << " L1A: "       << l1a
00724                 << " '3': "       << ((data[0] >>30) & 0x3)
00725                 << " E0: "        << ((data[0] >>28) & 0x1)
00726                 << " Bx: "        << bx
00727                 << " N_samples: " << ((data[0] >>8 ) & 0x7F)
00728                 << " RU ID: "     << dccCh_;
00729       if(iRu_ < nRu_){
00730         feL1a_[iRu_] = l1a;
00731         feBx_[iRu_] = bx;
00732         feRuId_[iRu_] = dccCh_;
00733         ++iRu_;
00734       }
00735     } else if((unsigned)iTowerWord64_<towerBlockLength_){
00736       if(!dumpAdc_){
00737         //no output.
00738         rc = false;
00739       }
00740       const bool da = dumpAdc_ && dump_;
00741       switch((iTowerWord64_-1)%3){
00742         int s[4];
00743         int g[4];
00744       case 0:
00745         s[0]=(data[0] >>16) & 0xFFF;
00746         g[0]=(data[0] >>28) & 0x3;
00747         s[1]=(data[1] >>0 ) & 0xFFF;
00748         g[1]=(data[1] >>12) & 0x3;
00749         s[2]=(data[1] >>16) & 0xFFF;
00750         g[2]=(data[1] >>28) & 0x3;
00751         fill(adc_.begin(), adc_.end(), 0.);
00752         if(da) out << "GMF: "    << ((data[0] >>11) & 0x1)
00753                    << " SMF: "   << ((data[0] >>9 ) & 0x1)
00754                    << " M: "   << ((data[0] >>8 ) & 0x1)
00755                    << " XTAL: "  << ((data[0] >>4 ) & 0x7)
00756                    << " STRIP: " << ((data[0] >>0 ) & 0x7)
00757                    << " " << setw(4) << s[0]
00758                    << "G" << g[0]
00759                    << " " << setw(4) << s[1]
00760                    << "G" << g[1]
00761                    << " " << setw(4) << s[2]
00762                    << "G" << g[2];
00763         for(int i=0; i<3; ++i) adc_[i] = s[i]*mgpaGainFactors[g[i]];
00764         break;
00765       case 1:
00766         s[0]=(data[0] >>0 ) & 0xFFF;
00767         g[0]=(data[0] >>12) & 0x3;
00768         s[1]=(data[0] >>16) & 0xFFF;
00769         g[1]=(data[0] >>28) & 0x3;
00770         s[2]=(data[1] >>0 ) & 0xFFF;
00771         g[2]=(data[1] >>12) & 0x3;
00772         s[3]=(data[1] >>16) & 0xFFF;
00773         g[3]=(data[1] >>28) & 0x3;
00774         if(da) out << "                                   "
00775                    << " " << setw(4) << s[0]
00776                    << "G" << g[0]
00777                    << " " << setw(4) << s[1]
00778                    << "G" << g[1]
00779                    << " " << setw(4) << s[2]
00780                    << "G" << g[2]
00781                    << " " << setw(4) << s[3]
00782                    << "G" << g[3];
00783         for(int i=0; i<4; ++i) adc_[i+3] = s[i]*mgpaGainFactors[g[i]];
00784         break;
00785       case 2:
00786         if(da) out << "TZS: " << ((data[1] >>14) & 0x1);
00787 
00788         s[0]=(data[0] >>0 ) & 0xFFF;
00789         g[0]=(data[0] >>12) & 0x3;
00790         s[1]=(data[0] >>16) & 0xFFF;
00791         g[1]=(data[0] >>28) & 0x3;
00792         s[2]=(data[1] >>0 ) & 0xFFF;
00793         g[2]=(data[1] >>12) & 0x3  ;
00794 
00795         for(int i=0; i<3; ++i) adc_[i+7] = s[i]*mgpaGainFactors[g[i]];
00796         if(dccCh_<=68){
00797           unsigned bom0; //Bin of Maximum, starting counting from 0
00798           double ampl = max(adc_, bom0)-min(adc_);
00799           if(da) out << " Ampl: " << setw(4) << ampl
00800                       << (ampl>amplCut_?"*":" ")
00801                      << " BoM:" << setw(2) << (bom0+1)
00802                      << "          ";
00803             if(fedId_ == dccId_ + 600 //block of the read-out SM
00804                //if laser, only one side:
00805                && (detailedTrigType_!=4 || sideOfRu(dccCh_)==(int)side_)
00806                ){
00807             }
00808         } else{
00809           if(da) out << setw(29) << "";
00810         }
00811         if(da) out << " " << setw(4) << s[0]
00812                    << "G" << g[0]
00813                    << " " << setw(4) << s[1]
00814                    << "G" << g[1]
00815                    << " " << setw(4) << s[2]
00816                   << "G" << g[2];
00817         break;
00818         default:
00819           assert(false);
00820       }
00821     } else {
00822       if(d) out << "ERROR";
00823     }
00824     ++iTowerWord64_;
00825     if(iTowerWord64_>=towerBlockLength_){
00826       iTowerWord64_-=towerBlockLength_;
00827       ++dccCh_;
00828     }
00829   } else if(dataType==eoe){//End of event trailer
00830     /**********************************************************************
00831      * Event DAQ trailer
00832      *
00833      **********************************************************************/
00834     int tts = (data[0] >>4)  & 0xF;
00835     if(d) out << "Evt Len.: "    << ((data[1] >>0 ) & 0xFFFFFF)
00836               << " CRC16: "       << ((data[0] >>16) & 0xFFFF)
00837               << " Evt Status: "  << ((data[0] >>8 ) & 0xF)
00838               << " TTS: "         << tts
00839               << " (" << ttsNames[tts] << ")"
00840               << " T:"            << ((data[0] >>3)  & 0x1);
00841   } else{
00842     if(d) out << " incorrect 64-bit word type marker (see MSBs)";
00843   }
00844   return rc;
00845 }
00846 
00847 // The following method was not removed due to package maintainer 
00848 // (Philippe Gras <philippe.gras@cern.ch>) request.
00849 
00850 //int EcalDumpRaw::lme(int dcc1, int side){
00851 //  int fedid = ((dcc1-1)%600) + 600; //to handle both FED and DCC id.
00852 //   vector<int> lmes;
00853 //   // EE -
00854 //   if( fedid <= 609 ) {
00855 //     if ( fedid <= 607 ) {
00856 //       lmes.push_back(fedid-601+83);
00857 //     } else if ( fedid == 608 ) {
00858 //       lmes.push_back(90);
00859 //       lmes.push_back(91);
00860 //     } else if ( fedid == 609 ) {
00861 //       lmes.push_back(92);
00862 //     }
00863 //   } //EB
00864 //   else if ( fedid >= 610  && fedid <= 645 ) {
00865 //     lmes.push_back(2*(fedid-610)+1);
00866 //     lmes.push_back(lmes[0]+1);
00867 //   } // EE+
00868 //   else if ( fedid >= 646 ) {
00869 //     if ( fedid <= 652 ) {
00870 //       lmes.push_back(fedid-646+73);
00871 //     } else if ( fedid == 653 ) {
00872 //       lmes.push_back(80);
00873 //       lmes.push_back(81);
00874 //     } else if ( fedid == 654 ) {
00875 //       lmes.push_back(82);
00876 //     }
00877 //   }
00878 //   return lmes.size()==0?-1:lmes[std::min(lmes.size(), (size_t)side)];
00879 //}
00880 
00881 
00882 int EcalDumpRaw::sideOfRu(int ru1){
00883   if(ru1 < 5 || (ru1-5)%4 >= 2){
00884     return 0;
00885   } else{
00886     return 1;
00887   }
00888 }
00889 
00890 
00891 int EcalDumpRaw::modOfRu(int ru1){
00892   int iEta0 = (ru1-1)/4;
00893   if(iEta0<5){
00894     return 1;
00895   } else{
00896     return 2 + (iEta0-5)/4;
00897   }
00898 }
00899 
00900 int EcalDumpRaw::lmodOfRu(int ru1){
00901   int iEta0 = (ru1-1)/4;
00902   int iPhi0 = (ru1-1)%4;
00903   int rs;
00904   if(iEta0==0){
00905     rs =  1;
00906   } else{
00907     rs = 2 + ((iEta0-1)/4)*2 + (iPhi0%4)/2;
00908   }
00909   //  cout << "ru1 = " << ru1 << " -> lmod = " << rs << "\n";
00910   return rs;
00911 }
00912 
00913 std::string EcalDumpRaw::srRange(int offset) const{
00914   int min = offset+1;
00915   int max = offset+4;
00916   stringstream buf;
00917   if(628 <= fedId_ && fedId_ <= 646){//EB+
00918     buf << right << min << ".."
00919         << left  << max;
00920   } else{
00921     buf << right << max << ".."
00922         << left  << min;
00923   }
00924   string s = buf.str();
00925   buf.str("");
00926   buf << setw(6) << right << s;
00927   return buf.str();
00928 }
00929 
00930 std::string EcalDumpRaw::ttfTag(int tccType, unsigned iSeq) const{
00931   if((unsigned)iSeq > sizeof(ttId_))
00932     throw cms::Exception("OutOfRange")
00933       << __FILE__ << ":"  << __LINE__ << ": "
00934       << "parameter out of range\n";
00935                              
00936   const int ttId = ttId_[tccType][iSeq];
00937   stringstream buf;
00938   buf.str("");
00939   if(ttId==0){
00940     buf << "    '0'";
00941   } else{
00942     buf << "TTF# " << setw(2) << ttId;
00943   }
00944   return buf.str();
00945 }
00946 
00947 std::string EcalDumpRaw::tpgTag(int tccType, unsigned iSeq) const{
00948   if((unsigned)iSeq > sizeof(ttId_))
00949     throw cms::Exception("OutOfRange")
00950       << __FILE__ << ":"  << __LINE__ << ": "
00951       << "parameter out of range\n";
00952                              
00953   const int ttId = ttId_[tccType][iSeq];
00954   stringstream buf;
00955   buf.str("");
00956   if(ttId==0){
00957     buf << "    '0'";
00958   } else{
00959     buf << "TPG# " << setw(2) << ttId;
00960   }
00961   return buf.str();
00962 }