CMS 3D CMS Logo

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