CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_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.8 2010/12/07 00:31:21 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/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   bool simpleTrigTypeErr = false;
00263   bool outOfSync = false;
00264   unsigned iFed = 0;
00265   unsigned refDccId = 0;
00266   int refSimpleTrigType = -1;
00267   int refBx = -1;
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         refSimpleTrigType = simpleTrigType_;
00333         refBx = bx_;
00334       } else{
00335         if(dccId_!=refDccId){
00336           dccIdErr = true;
00337         }
00338         if(simpleTrigType_!=refSimpleTrigType){
00339           simpleTrigTypeErr = true;
00340         }
00341         if(refBx!=bx_){
00342           outOfSync = true;
00343         }
00344       }
00345 
00346       if(dump_) cout << flush; //flushing cout before writing to cerr
00347 
00348       if(srpBx_!=-1 && srpBx_!=bx_){
00349         cerr << "Bx discrepancy between SRP and DCC, Bx(SRP) = "
00350              << srpBx_ << ", Bx(DCC) = " << bx_
00351              << " in " << toNth(iEvent_) << " event, FED "
00352              << id << endl;
00353       }
00354 
00355       if(tccBx_!=-1 && tccBx_!=bx_){
00356         cerr << "Bx discrepancy between TCC and DCC, Bx(TCC) = "
00357              << srpBx_ << ", Bx(DCC) = " << bx_
00358              << " in " << toNth(iEvent_) << " event, FED "
00359              << id << endl;
00360       }
00361 
00362       bool feBxErr = false;
00363       for(int i=0; i < nRu_; ++i){
00364         int expectedFeBx;
00365         if(feBxOffset==0){
00366           expectedFeBx = bx_ - 1;
00367         } else{
00368           expectedFeBx = (bx_==3564) ? 0 : bx_;
00369         }
00370         if(feBx_[i]!=-1 && feBx_[i]!=expectedFeBx){
00371           cerr << "BX error for " << toNth(i+1) << " RU, RU ID "
00372                << feRuId_[i];
00373           if((unsigned) feRuId_[i] <= dccChStatus_.size()){
00374             bool detected = (dccChStatus_[feRuId_[i]-1] == 10 || dccChStatus_[feRuId_[i]-1] == 11);
00375             cerr << (detected?" ":" not ") << "detected by DCC (ch status: "
00376                  << dccChStatus_[feRuId_[i]-1] << ")";
00377           }
00378           cerr << " in " << toNth(iEvent_) << " event, FED "
00379                << id << "." << endl;
00380           
00381           feBxErr = true;
00382         }
00383       }
00384       if(feBxErr) cerr << "Bx discrepancy between DCC and at least one FE"
00385                        << " in " << toNth(iEvent_) << " event, FED "
00386                        << id << "\n";
00387 
00388 
00389       int localL1a = l1a_ & 0xFFF;
00390       if(srpL1a_!=-1 && srpL1a_!=localL1a){
00391         cerr << "Discrepancy between SRP and DCC L1a counter, L1a(SRP) = "
00392              << srpL1a_ << ", L1a(DCC) & 0xFFF = " << localL1a
00393              << " in " << toNth(iEvent_) << " event, FED "
00394              << id << endl;
00395 
00396       }
00397 
00398       if(tccL1a_!=-1 && tccL1a_!=localL1a){
00399         cerr << "Discrepancy between TCC and DCC L1a counter, L1a(TCC) = "
00400              << srpL1a_ << ", L1a(DCC) & 0xFFF = " << localL1a
00401              << " in " << toNth(iEvent_) << " event, FED "
00402              << id << endl;
00403 
00404       }
00405 
00406       bool feL1aErr = false;
00407       for(int i=0; i < nRu_; ++i){
00408         if(feL1a_[i]!=-1 && feL1a_[i]!=localL1a-1){
00409           cerr << "FE L1A error for " << toNth(i+1) << " RU, RU ID "
00410                << feRuId_[i];
00411           if((unsigned) feRuId_[i] <= dccChStatus_.size()){
00412             bool detected = (dccChStatus_[feRuId_[i]-1] == 9 || dccChStatus_[feRuId_[i]-1] == 11);
00413             cerr << (detected?" ":" not ") << "detected by DCC (ch status: "
00414                  << dccChStatus_[feRuId_[i]-1] << ")";
00415           }
00416           cerr << " in " << toNth(iEvent_) << " event, FED "
00417                << id << "." << endl;
00418           feL1aErr = true;
00419         }
00420       }
00421       if(feL1aErr) cerr << "Discrepancy in L1a counter between DCC "
00422                      "and at least one FE (L1A(DCC) & 0xFFF = " << localL1a << ")"
00423                         << " in " << toNth(iEvent_) << " event, FED "
00424                         << id << "\n";
00425       
00426 
00427       if(iTow_>0 && iTow_< nRu_ && feRuId_[iTow_] < feRuId_[iTow_-1]){
00428         cerr << "Error in RU ID (TT/SC ID)"
00429              << " in " << toNth(iEvent_) << " event, FED "
00430              << id << endl;
00431       }
00432 
00433       if (beg_fed_id_ <= id && id <= end_fed_id_ && writeDcc_){
00434         dumpFile_.write( reinterpret_cast <const char *> (pData), nWord32*4);
00435       }
00436       
00437       if(dump_) cout << "\n";
00438     } else{
00439       //      cout << "No data for FED " <<  id << ". Size = "
00440       //     << data.size() << " byte(s).\n";
00441     }
00442   } //next fed
00443 
00444   if(dump_) cout << "Number of selected FEDs with a data block: "
00445                  << iFed << "\n";
00446 
00447   if(dccIdErr){
00448     cout << flush;
00449     cerr << "DCC ID discrepancy in detailed trigger type "
00450          << " of " << toNth(iEvent_) << " event." << endl;
00451   }
00452   int bx = -1;
00453   if(!outOfSync){
00454     bx = bx_;
00455   }
00456 
00457   if(l1a_>0 && l1a_< l1amin_) l1amin_ = l1a_;
00458   if(l1a_>l1amax_) l1amax_ = l1a_;
00459 
00460 
00461 #endif
00462 
00463   gettimeofday(&stop, 0);
00464   //  double dt  = (stop.tv_sec-start.tv_sec)*1.e3
00465   //  + (stop.tv_usec-start.tv_usec)*1.e-3;
00466   //  histo_.fillD("hCodeTime", "Code execution time;Duration (ms);Event count",
00467   //             PGXAxis(100, 0, 100),
00468   //             dt);
00469 }
00470 
00471 string EcalDumpRaw::toNth(int n){
00472   stringstream s;
00473   s << n;
00474   if(n%100<10 || n%100>20){
00475     switch(n%10){
00476     case 1:
00477       s << "st";
00478       break;
00479     case 2:
00480       s << "nd";
00481       break;
00482     case 3:
00483       s << "rd";
00484       break;
00485     default:
00486       s << "th";
00487     }
00488   } else{
00489     s << "th";
00490   }
00491   return s.str();
00492 }
00493 
00494 
00495 bool EcalDumpRaw::decode(const uint32_t* data, int iWord64, ostream& out){
00496   bool rc = true;
00497   const bool d  = dump_;
00498   if(iWord64==0){//start of event
00499     iSrWord64_ = 0;
00500     iTccWord64_ = 0;
00501     iTowerWord64_ = 0;
00502   }
00503   int dataType = (data[1] >>28) & 0xF;
00504   const int boe = 5;
00505   const int eoe = 10;
00506   if(dataType==boe){//Begin of Event header
00507     /**********************************************************************
00508      *  DAQ header
00509      *
00510      **********************************************************************/
00511     simpleTrigType_ = (data[1] >>24) & 0xF;
00512     l1a_ = (data[1]>>0 )  & 0xFFffFF;
00513     bx_ = (data[0] >>20) & 0xFFF;
00514     fedId_ = (data[0] >>8 ) & 0xFFF;
00515     if(d) out << "Trigger type: " << simpleTrigType_
00516               << "(" << trigNames[(data[1]>>24) & 0xF] << ")"
00517               << " L1A: "         << l1a_
00518               << " BX: "          << bx_
00519               << " FED ID: "      << fedId_
00520               << " FOV: "         << ((data[0] >>4 ) & 0xF)
00521               << " H: "           << ((data[0] >>3 ) & 0x1);
00522   } else if((dataType>>2)==0){//DCC header
00523     /**********************************************************************
00524      * ECAL DCC header
00525      *
00526      **********************************************************************/
00527     int dccHeaderId = (data[1] >>24) & 0x3F;
00528     switch(dccHeaderId){
00529     case 1:
00530       if(d) out << "Run #: "     << ((data[1] >>0 ) & 0xFFFFFF)
00531                 << " DCC Err: "  << ((data[0] >>24) & 0xFF)
00532                 << " Evt Len:  " << ((data[0] >>0 ) & 0xFFFFFF);
00533       break;
00534     case 2:
00535       side_ = (data[1] >>11) & 0x1;
00536       detailedTrigType_ = (data[1] >>8 ) & 0x7;
00537       dccId_ = (data[1] >>0 ) & 0x3F;
00538       if(d) out << "DCC FOV: " << ((data[1] >>16) & 0xF)
00539                 << " Side: "   << side_
00540                 << " Trig.: "   << detailedTrigType_
00541                 << " (" << detailedTrigNames[(data[1]>>8)&0x7] << ")"
00542                 << " Color: "  << ((data[1] >>6 ) & 0x3)
00543                 << " (" << colorNames[(data[1]>>6)&0x3] << ")"
00544                 << " DCC ID: " << dccId_;
00545       int l;
00546       if(dccId_>=10 && dccId_<=46 && side_ <= 1){ // side_ >=0, since side is unsigned
00547         l = lme(dccId_, side_);
00548       } else{
00549         l = -1;//indicates error
00550       }
00551       break;
00552     case 3:
00553       {
00554       if(d) out << "TCC Status ch<4..1>: 0x"
00555                 << hex << ((data[1]>>8) & 0xFFFF) << dec
00556                 << " SR status: " << ((data[1] >>4 ) & 0xF)
00557                 << " TZS: "       << ((data[1] >>2 ) & 0x1)
00558                 << " ZS: "        << ((data[1] >>1 ) & 0x1)
00559                 << " SR: "        << ((data[1] >>0 ) & 0x1);
00560       orbit_ = data[0];
00561       if(d) out << " Orbit: "     << orbit_;
00562       if(!orbit0Set_){
00563         orbit0_ = orbit_;
00564         orbit0Set_ = true;
00565       }
00566       int iDcc0 = fedId_-fedStart_;
00567       if((unsigned)iDcc0<nDccs_){
00568         if(lastOrbit_[iDcc0]!=numeric_limits<uint32_t>::max()){
00569           if(d) out << " (+" << (int)orbit_-(int)lastOrbit_[iDcc0] <<")";
00570         }
00571         lastOrbit_[iDcc0] = orbit_;
00572       }
00573     }
00574       break;
00575     case 4:
00576     case 5:
00577     case 6:
00578     case 7:
00579     case 8:
00580       {
00581         int chOffset = (dccHeaderId-4)*14;
00582         dccChStatus_[13+chOffset] = ((data[1] >>20) & 0xF);
00583         dccChStatus_[12+chOffset] = ((data[1] >>16) & 0xF);
00584         dccChStatus_[11+chOffset] = ((data[1] >>12) & 0xF);
00585         dccChStatus_[10+chOffset] = ((data[1] >>8 ) & 0xF);
00586         dccChStatus_[ 9+chOffset] = ((data[1] >>4 ) & 0xF);
00587         dccChStatus_[ 8+chOffset] = ((data[1] >>0)  & 0xF);
00588         dccChStatus_[ 7+chOffset] = ((data[0] >>28) & 0xF);
00589         dccChStatus_[ 6+chOffset] = ((data[0] >>24) & 0xF);
00590         dccChStatus_[ 5+chOffset] = ((data[0] >>20) & 0xF);
00591         dccChStatus_[ 4+chOffset] = ((data[0] >>16) & 0xF);
00592         dccChStatus_[ 3+chOffset] = ((data[0] >>12) & 0xF);
00593         dccChStatus_[ 2+chOffset] = ((data[0] >>8 ) & 0xF);
00594         dccChStatus_[ 1+chOffset] = ((data[0] >>4 ) & 0xF);
00595         dccChStatus_[ 0+chOffset] = ((data[0] >>0 ) & 0xF);
00596         
00597         if(d){
00598           out << "FE CH status:";
00599           for(int i = chOffset; i < chOffset + 14; ++i){
00600             out << " #" << (i+1) << ":" << dccChStatus_[i];
00601           }
00602         }
00603       }
00604       break;
00605     default:
00606       if(d) out << " bits<63..62>=0 (DCC header) bits<61..56>=" << dccHeaderId
00607                 << "(unknown=>ERROR?)";
00608     }
00609   } else if((dataType>>1)==3){//TCC block
00610     /**********************************************************************
00611      * TCC block
00612      *
00613      **********************************************************************/
00614     if(iTccWord64_==0){
00615       //header
00616       tccL1a_ = (data[1] >>0 ) & 0xFFF;
00617       tccId_  = ((data[0] >>0 ) & 0xFF);
00618       nTts_  =  ((data[1] >>16) & 0x7F);
00619       if(iTcc_ < maxTccsPerDcc_) nTpgs_[iTcc_] = nTts_;
00620       ++iTcc_;
00621       if(d) out << "LE1: "         << ((data[1] >>28) & 0x1)
00622                 << " LE0: "        << ((data[1] >>27) & 0x1)
00623                 << " N_samples: "  << ((data[1] >>23) & 0x1F)
00624                 << " N_TTs: "      << nTts_
00625                 << " E1: "         << ((data[1] >>12) & 0x1)
00626                 << " L1A: "        << tccL1a_
00627                 << " '3': "        << ((data[0] >>29) & 0x7)
00628                 << " E0: "         << ((data[0] >>28) & 0x1)
00629                 << " Bx: "         << ((data[0] >>16) & 0xFFF)
00630                 << " TTC ID: "     << tccId_;
00631       if(nTts_==68){ //EB TCC (TCC68)
00632         if(fedId_ < 628) tccType_ = ebmTcc_;
00633         else tccType_ = ebpTcc_;
00634       } else if(nTts_ == 16){//Inner EE TCC (TCC48)
00635         tccType_ = eeOuterTcc_;
00636       } else if(nTts_ == 28){//Outer EE TCC (TCC48)
00637         tccType_ = eeInnerTcc_;
00638       } else {
00639         cout << flush;
00640         cerr << "Error in #TT field of TCC block."
00641           "This field is normally used to determine type of TCC "
00642           "(TCC48 or TCC68). Type of TCC will be deduced from the TCC ID.\n";
00643         if(tccId_ < 19) tccType_ = eeInnerTcc_;
00644         else if(tccId_ <  37) tccType_ = eeOuterTcc_;
00645         else if(tccId_ <  55) tccType_ = ebmTcc_;
00646         else if(tccId_ <  73) tccType_ = ebpTcc_;
00647         else if(tccId_ <  91) tccType_ = eeOuterTcc_;
00648         else if(tccId_ < 109) tccType_ = eeInnerTcc_;
00649         else{
00650           cerr << "TCC ID is also invalid. EB- TCC type will be assumed.\n";
00651           tccType_ = ebmTcc_;
00652         }
00653         cerr << flush;
00654       }
00655       tccBlockLen64_ = (tccType_==ebmTcc_ || tccType_==ebpTcc_) ? 18 : 9;        
00656     } else{// if(iTccWord64_<18){
00657       int tpgOffset = (iTccWord64_-1)*4;
00658       if(iTcc_ > maxTccsPerDcc_){
00659         out << "Too many TCC blocks";
00660       } else if(tpgOffset > (maxTpgsPerTcc_ - 4)){
00661         out << "Too many TPG in one TCC block";
00662       } else{
00663         tpg_[iTcc_-1][3+tpgOffset] = (data[1] >>16) & 0x1FF;
00664         tpg_[iTcc_-1][2+tpgOffset] = (data[1] >>0 ) & 0x1FF;
00665         tpg_[iTcc_-1][1+tpgOffset] = (data[0] >>16) & 0x1FF;
00666         tpg_[iTcc_-1][0+tpgOffset] = (data[0] >>0 ) & 0x1FF;
00667         //int n[2][4] = {{1,2,3,4},
00668         //             {4,3,2,1}};
00669         //int iorder = (628<=fedId_ && fedId_<=645)?1:0;
00670         if(d) out << ttfTag(tccType_, 3+tpgOffset) << ":" //"TTF# " << setw(2) << ttId_[3 + tpgOffset] << ":"
00671                   << ((data[1] >>25) & 0x7) << " "
00672                   << tpgTag(tccType_, 3+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[3 + tpgOffset] << ":"
00673                   << setw(3) << tpg_[iTcc_-1][3+tpgOffset] << " "
00674                   << ttfTag(tccType_, 2+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[2 + tpgOffset] << ":"
00675                   << ((data[1] >>9 ) & 0x7) << " "
00676                   << tpgTag(tccType_, 2+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[2 + tpgOffset] << ":"
00677                   << setw(3) << tpg_[iTcc_-1][2+tpgOffset] << " "
00678                   << " '3': "                     << ((data[0] >>29) & 0x7) << " "
00679                   << ttfTag(tccType_, 1+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[1 + tpgOffset] << ":"
00680                   << ((data[0] >>25) & 0x7) << " "
00681                   << setw(3) << tpgTag(tccType_, 1+tpgOffset) << ": "//" TPG# "<< setw(2) << ttId_[1 + tpgOffset] << ":"
00682                   << tpg_[iTcc_-1][1+tpgOffset] << " "
00683                   << ttfTag(tccType_, 0+tpgOffset) << ":" //" TTF# "<< setw(2) << ttId_[0 + tpgOffset] << ":"
00684                   << ((data[0] >>9 ) & 0x7) << " "
00685                   << setw(3) << tpgTag(tccType_, 0+tpgOffset) << ":" //" TPG# "<< setw(2) << ttId_[0 + tpgOffset] << ":"
00686                   << tpg_[iTcc_-1][0+tpgOffset];
00687       }
00688     }// else{
00689      // if(d) out << "ERROR";
00690     //}
00691     ++iTccWord64_;
00692     if(iTccWord64_ >= (unsigned)tccBlockLen64_) iTccWord64_ = 0;
00693   } else if((dataType>>1)==4){//SRP block
00694     /**********************************************************************
00695      * SRP block
00696      *
00697      **********************************************************************/
00698     if(iSrWord64_==0){//header
00699       srpL1a_ = (data[1] >>0 ) & 0xFFF;
00700       srpBx_ = (data[0] >>16) & 0xFFF;
00701       if(d) out << "LE1: "     << ((data[1] >>28) & 0x1)
00702                 << " LE0: "    << ((data[1] >>27) & 0x1)
00703                 << " N_SRFs: " << ((data[1] >>16) & 0x7F)
00704                 << " E1: "     << ((data[1] >>12) & 0x1)
00705                 << " L1A: "    << srpL1a_
00706                 << " '4': "    << ((data[0] >>29) & 0x7)
00707                 << " E0: "     << ((data[0] >>28) & 0x1)
00708                 << " Bx: "     << srpBx_
00709                 << " SRP ID: " << ((data[0] >>0 ) & 0xFF);
00710     } else if(iSrWord64_<6){
00711       int ttfOffset = (iSrWord64_-1)*16;
00712       if(d){
00713         if(iSrWord64_<5){
00714           out <<"SRF# " << setw(6) << right << srRange(12+ttfOffset)/*16+ttfOffset << "..#" << 13+ttfOffset*/  << ": "
00715               << oct << ((data[1] >>16) & 0xFFF) << dec
00716               << " SRF# " << srRange(8+ttfOffset) /*12+ttfOffset << "..#" << 9+ttfOffset*/ << ": "
00717               << oct << ((data[1] >>0 ) & 0xFFF) << dec
00718               << " '4':" << ((data[0] >>29) & 0x7)
00719               << " SRF# " << srRange(4+ttfOffset) /*8+ttfOffset << "..#" << 5+ttfOffset*/ << ": "
00720               << oct << ((data[0] >>16) & 0xFFF) << dec;
00721         } else{//last 64-bit word has only 4 SRFs.
00722           out << "                                                           ";
00723         }
00724         out << " SRF# " << srRange(ttfOffset) /*4+ttfOffset << "..#" << 1+ttfOffset*/ << ": "
00725             << oct << ((data[0] >>0 ) & 0xFFF) << dec;
00726       }
00727     } else{
00728       if(d) out << "ERROR";
00729     }
00730     ++iSrWord64_;
00731   } else if((dataType>>2)==3){//Tower block
00732     /**********************************************************************
00733      * "Tower" block (crystal channel data from a RU (=1 FE cards))
00734      *
00735      **********************************************************************/
00736     if(iTowerWord64_==0){//header
00737       towerBlockLength_ = (data[1]>>16) & 0x1FF;
00738       int l1a;
00739       int bx;
00740       l1a = (data[1] >>0 ) & 0xFFF;
00741       bx = (data[0] >>16) & 0xFFF;
00742       dccCh_=(data[0] >>0 ) & 0xFF;
00743       if(d) out << "Block Len: "  << towerBlockLength_
00744                 << " E1: "        << ((data[1] >>12) & 0x1)
00745                 << " L1A: "       << l1a
00746                 << " '3': "       << ((data[0] >>30) & 0x3)
00747                 << " E0: "        << ((data[0] >>28) & 0x1)
00748                 << " Bx: "        << bx
00749                 << " N_samples: " << ((data[0] >>8 ) & 0x7F)
00750                 << " RU ID: "     << dccCh_;
00751       if(iRu_ < nRu_){
00752         feL1a_[iRu_] = l1a;
00753         feBx_[iRu_] = bx;
00754         feRuId_[iRu_] = dccCh_;
00755         ++iRu_;
00756       }
00757     } else if((unsigned)iTowerWord64_<towerBlockLength_){
00758       if(!dumpAdc_){
00759         //no output.
00760         rc = false;
00761       }
00762       const bool da = dumpAdc_ && dump_;
00763       switch((iTowerWord64_-1)%3){
00764         int s[4];
00765         int g[4];
00766       case 0:
00767         s[0]=(data[0] >>16) & 0xFFF;
00768         g[0]=(data[0] >>28) & 0x3;
00769         s[1]=(data[1] >>0 ) & 0xFFF;
00770         g[1]=(data[1] >>12) & 0x3;
00771         s[2]=(data[1] >>16) & 0xFFF;
00772         g[2]=(data[1] >>28) & 0x3;
00773         fill(adc_.begin(), adc_.end(), 0.);
00774         if(da) out << "GMF: "    << ((data[0] >>11) & 0x1)
00775                    << " SMF: "   << ((data[0] >>9 ) & 0x1)
00776                    << " M: "   << ((data[0] >>8 ) & 0x1)
00777                    << " XTAL: "  << ((data[0] >>4 ) & 0x7)
00778                    << " STRIP: " << ((data[0] >>0 ) & 0x7)
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         for(int i=0; i<3; ++i) adc_[i] = s[i]*mgpaGainFactors[g[i]];
00786         break;
00787       case 1:
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         s[3]=(data[1] >>16) & 0xFFF;
00795         g[3]=(data[1] >>28) & 0x3;
00796         if(da) out << "                                   "
00797                    << " " << setw(4) << s[0]
00798                    << "G" << g[0]
00799                    << " " << setw(4) << s[1]
00800                    << "G" << g[1]
00801                    << " " << setw(4) << s[2]
00802                    << "G" << g[2]
00803                    << " " << setw(4) << s[3]
00804                    << "G" << g[3];
00805         for(int i=0; i<4; ++i) adc_[i+3] = s[i]*mgpaGainFactors[g[i]];
00806         break;
00807       case 2:
00808         if(da) out << "TZS: " << ((data[1] >>14) & 0x1);
00809 
00810         s[0]=(data[0] >>0 ) & 0xFFF;
00811         g[0]=(data[0] >>12) & 0x3;
00812         s[1]=(data[0] >>16) & 0xFFF;
00813         g[1]=(data[0] >>28) & 0x3;
00814         s[2]=(data[1] >>0 ) & 0xFFF;
00815         g[2]=(data[1] >>12) & 0x3  ;
00816 
00817         for(int i=0; i<3; ++i) adc_[i+7] = s[i]*mgpaGainFactors[g[i]];
00818         if(dccCh_<=68){
00819           unsigned bom0; //Bin of Maximum, starting counting from 0
00820           double ampl = max(adc_, bom0)-min(adc_);
00821           if(da) out << " Ampl: " << setw(4) << ampl
00822                       << (ampl>amplCut_?"*":" ")
00823                      << " BoM:" << setw(2) << (bom0+1)
00824                      << "          ";
00825             if(fedId_ == dccId_ + 600 //block of the read-out SM
00826                //if laser, only one side:
00827                && (detailedTrigType_!=4 || sideOfRu(dccCh_)==(int)side_)
00828                ){
00829             }
00830         } else{
00831           if(da) out << setw(29) << "";
00832         }
00833         if(da) out << " " << setw(4) << s[0]
00834                    << "G" << g[0]
00835                    << " " << setw(4) << s[1]
00836                    << "G" << g[1]
00837                    << " " << setw(4) << s[2]
00838                   << "G" << g[2];
00839         break;
00840         default:
00841           assert(false);
00842       }
00843     } else {
00844       if(d) out << "ERROR";
00845     }
00846     ++iTowerWord64_;
00847     if(iTowerWord64_>=towerBlockLength_){
00848       iTowerWord64_-=towerBlockLength_;
00849       ++dccCh_;
00850     }
00851   } else if(dataType==eoe){//End of event trailer
00852     /**********************************************************************
00853      * Event DAQ trailer
00854      *
00855      **********************************************************************/
00856     int tts = (data[0] >>4)  & 0xF;
00857     if(d) out << "Evt Len.: "    << ((data[1] >>0 ) & 0xFFFFFF)
00858               << " CRC16: "       << ((data[0] >>16) & 0xFFFF)
00859               << " Evt Status: "  << ((data[0] >>8 ) & 0xF)
00860               << " TTS: "         << tts
00861               << " (" << ttsNames[tts] << ")"
00862               << " T:"            << ((data[0] >>3)  & 0x1);
00863   } else{
00864     if(d) out << " incorrect 64-bit word type marker (see MSBs)";
00865   }
00866   return rc;
00867 }
00868 
00869 int EcalDumpRaw::lme(int dcc1, int side){
00870   int fedid = ((dcc1-1)%600) + 600; //to handle both FED and DCC id.
00871    vector<int> lmes;
00872    // EE -
00873    if( fedid <= 609 ) {
00874      if ( fedid <= 607 ) {
00875        lmes.push_back(fedid-601+83);
00876      } else if ( fedid == 608 ) {
00877        lmes.push_back(90);
00878        lmes.push_back(91);
00879      } else if ( fedid == 609 ) {
00880        lmes.push_back(92);
00881      }
00882    } //EB
00883    else if ( fedid >= 610  && fedid <= 645 ) {
00884      lmes.push_back(2*(fedid-610)+1);
00885      lmes.push_back(lmes[0]+1);
00886    } // EE+
00887    else if ( fedid >= 646 ) {
00888      if ( fedid <= 652 ) {
00889        lmes.push_back(fedid-646+73);
00890      } else if ( fedid == 653 ) {
00891        lmes.push_back(80);
00892        lmes.push_back(81);
00893      } else if ( fedid == 654 ) {
00894        lmes.push_back(82);
00895      }
00896    }
00897    return lmes.size()==0?-1:lmes[std::min(lmes.size(), (size_t)side)];
00898 }
00899 
00900 
00901 int EcalDumpRaw::sideOfRu(int ru1){
00902   if(ru1 < 5 || (ru1-5)%4 >= 2){
00903     return 0;
00904   } else{
00905     return 1;
00906   }
00907 }
00908 
00909 
00910 int EcalDumpRaw::modOfRu(int ru1){
00911   int iEta0 = (ru1-1)/4;
00912   if(iEta0<5){
00913     return 1;
00914   } else{
00915     return 2 + (iEta0-5)/4;
00916   }
00917 }
00918 
00919 int EcalDumpRaw::lmodOfRu(int ru1){
00920   int iEta0 = (ru1-1)/4;
00921   int iPhi0 = (ru1-1)%4;
00922   int rs;
00923   if(iEta0==0){
00924     rs =  1;
00925   } else{
00926     rs = 2 + ((iEta0-1)/4)*2 + (iPhi0%4)/2;
00927   }
00928   //  cout << "ru1 = " << ru1 << " -> lmod = " << rs << "\n";
00929   return rs;
00930 }
00931 
00932 std::string EcalDumpRaw::srRange(int offset) const{
00933   int min = offset+1;
00934   int max = offset+4;
00935   stringstream buf;
00936   if(628 <= fedId_ && fedId_ <= 646){//EB+
00937     buf << right << min << ".."
00938         << left  << max;
00939   } else{
00940     buf << right << max << ".."
00941         << left  << min;
00942   }
00943   string s = buf.str();
00944   buf.str("");
00945   buf << setw(6) << right << s;
00946   return buf.str();
00947 }
00948 
00949 std::string EcalDumpRaw::ttfTag(int tccType, unsigned iSeq) const{
00950   if((unsigned)iSeq > sizeof(ttId_))
00951     throw cms::Exception("OutOfRange")
00952       << __FILE__ << ":"  << __LINE__ << ": "
00953       << "parameter out of range\n";
00954                              
00955   const int ttId = ttId_[tccType][iSeq];
00956   stringstream buf;
00957   buf.str("");
00958   if(ttId==0){
00959     buf << "    '0'";
00960   } else{
00961     buf << "TTF# " << setw(2) << ttId;
00962   }
00963   return buf.str();
00964 }
00965 
00966 std::string EcalDumpRaw::tpgTag(int tccType, unsigned iSeq) const{
00967   if((unsigned)iSeq > sizeof(ttId_))
00968     throw cms::Exception("OutOfRange")
00969       << __FILE__ << ":"  << __LINE__ << ": "
00970       << "parameter out of range\n";
00971                              
00972   const int ttId = ttId_[tccType][iSeq];
00973   stringstream buf;
00974   buf.str("");
00975   if(ttId==0){
00976     buf << "    '0'";
00977   } else{
00978     buf << "TPG# " << setw(2) << ttId;
00979   }
00980   return buf.str();
00981 }