CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_4/src/EventFilter/EcalRawToDigi/src/DCCEventBlock.cc

Go to the documentation of this file.
00001 #include "EventFilter/EcalRawToDigi/interface/DCCEventBlock.h"
00002 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
00003 #include "EventFilter/EcalRawToDigi/interface/EcalDCCHeaderRuntypeDecoder.h"
00004 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
00005 #include "EventFilter/EcalRawToDigi/interface/DCCFEBlock.h"
00006 #include "EventFilter/EcalRawToDigi/interface/DCCMemBlock.h"
00007 #include "EventFilter/EcalRawToDigi/interface/DCCTCCBlock.h"
00008 #include "EventFilter/EcalRawToDigi/interface/DCCSRPBlock.h"
00009 #include <sys/time.h>
00010 
00011 #include <iomanip>
00012 #include <sstream>
00013 
00014 DCCEventBlock::DCCEventBlock( DCCDataUnpacker * u , EcalElectronicsMapper * m ,  bool hU, bool srpU, bool tccU, bool feU, bool memU, bool forceToKeepFRdata) : 
00015   unpacker_(u), mapper_(m), headerUnpacking_(hU), srpUnpacking_(srpU), tccUnpacking_(tccU), feUnpacking_(feU),memUnpacking_(memU), forceToKeepFRdata_(forceToKeepFRdata)
00016 {
00017   
00018   // Build a Mem Unpacker Block
00019   memBlock_   = new DCCMemBlock(u,m,this);
00020  
00021   // setup and initialize ch status vectors
00022   for( int feChannel=1;  feChannel <= 70;  feChannel++) { feChStatus_.push_back(0); hlt_.push_back(1);}
00023   for( int tccChannel=1; tccChannel <= 4 ; tccChannel++){ tccChStatus_.push_back(0);}
00024   
00025   // setup and initialize sync vectors
00026   for( int feChannel=1;  feChannel <= 70;  feChannel++) { feBx_.push_back(-1);  feLv1_.push_back(-1); }
00027   for( int tccChannel=1; tccChannel <= 4 ; tccChannel++){ tccBx_.push_back(-1); tccLv1_.push_back(-1);}
00028   srpBx_=-1;
00029   srpLv1_=-1;
00030   
00031 }
00032 
00033 
00034 void DCCEventBlock::reset(){
00035 
00036   // reset sync vectors
00037   for( int feChannel=1;  feChannel <= 70;  feChannel++) {   feBx_[feChannel-1]=-1;   feLv1_[feChannel-1]=-1; }
00038   for( int tccChannel=1; tccChannel <= 4 ; tccChannel++){ tccBx_[tccChannel-1]=-1; tccLv1_[tccChannel-1]=-1;}
00039   srpBx_=-1;
00040   srpLv1_=-1;
00041 
00042 
00043 }
00044 
00045 void DCCEventBlock::enableSyncChecks(){
00046    towerBlock_   ->enableSyncChecks();
00047    tccBlock_     ->enableSyncChecks();
00048    memBlock_     ->enableSyncChecks();
00049    srpBlock_     ->enableSyncChecks();
00050 }
00051 
00052 
00053 
00054 void DCCEventBlock::enableFeIdChecks(){
00055    towerBlock_   ->enableFeIdChecks();
00056 }
00057 
00058 
00059 
00060 unsigned int DCCEventBlock::next_tower_search(const unsigned int current_tower_id)
00061 {
00062   const uint64_t* const prev_data = data_;
00063   const unsigned int prev_dwToEnd = dwToEnd_;
00064   
00065   // expected LV1, BX, #TS
00066   const uint32_t lv1 = ((l1_ - 1) & 0xFFF);
00067   const uint32_t bx = (bx_ != 3564) ? bx_ : 0;
00068   const uint32_t ts = mapper_->numbXtalTSamples();
00069   
00070   // construct tower header and mask
00071   const uint64_t s_hi = 0xC0000000 + lv1;
00072   const uint64_t s_lo = 0xC0000000 + (bx << 16) + (ts << 8);
00073   
00074   const uint64_t sign = (s_hi << 32) + s_lo;
00075   const uint64_t mask = 0xC0001FFFDFFF7F00;
00076   
00077   // step forward to skip header word of problematic tower
00078   data_++;
00079   dwToEnd_--;
00080   
00081   //std::cerr << "header of bad tower = " << current_tower_id << " #" << dwToEnd_ << " 0x" << std::hex << *data_ << std::dec << std::endl;
00082   //std::cerr << "mask and sign = 0x" << std::hex << mask << " 0x" << sign << std::dec << std::endl;
00083   
00084   // navigate through tower data blocks to find tower block header
00085   while (dwToEnd_ > 0) {
00086     data_++;
00087     dwToEnd_--;
00088     
00089     //std::cerr << current_tower_id << " #" << dwToEnd_ << " 0x" << std::hex << *data_ << " 0x" << (*data_ & mask) << std::dec << std::endl;
00090     
00091     if ((*data_ & mask) == sign) {
00092       const unsigned int next_tower_id = (*data_) & 0xFF;
00093       
00094       if (next_tower_id <= current_tower_id) continue;
00095       
00096       //std::cerr << "next tower = " << next_tower_id << std::endl;
00097       
00098       // step back one word of the next tower header
00099       data_--;
00100       dwToEnd_++;
00101       
00102       return next_tower_id;
00103     }
00104   }
00105   
00106   // can't find next tower header
00107   // restore data pointer
00108   data_ = prev_data;
00109   dwToEnd_ = prev_dwToEnd;
00110   return 1000;
00111 }
00112 
00113 void DCCEventBlock::updateCollectors(){
00114 
00115   dccHeaders_  = unpacker_->dccHeadersCollection();
00116 
00117   memBlock_    ->updateCollectors(); 
00118   tccBlock_    ->updateCollectors();
00119   srpBlock_    ->updateCollectors();
00120   towerBlock_  ->updateCollectors();
00121   
00122 }
00123 
00124 
00125 
00126 
00127 void DCCEventBlock::addHeaderToCollection(){
00128   
00129   
00130   EcalDCCHeaderBlock theDCCheader;
00131 
00132   // container for fed_id (601-654 for ECAL) 
00133   theDCCheader.setFedId(fedId_);
00134   
00135   
00136   // this needs to be migrated to the ECAL mapping package
00137 
00138   // dccId is number internal to ECAL running 1.. 54.
00139   // convention is that dccId = (fed_id - 600)
00140   int dccId = mapper_->getActiveSM();
00141   // DCCHeaders follow  the same convenction
00142   theDCCheader.setId(dccId);
00143   
00144 
00145   theDCCheader.setRunNumber(runNumber_);  
00146   theDCCheader.setBasicTriggerType(triggerType_);
00147   theDCCheader.setLV1(l1_);
00148   theDCCheader.setBX(bx_);
00149   theDCCheader.setOrbit(orbitCounter_);
00150   theDCCheader.setErrors(dccErrors_);
00151   theDCCheader.setSelectiveReadout(sr_);
00152   theDCCheader.setZeroSuppression(zs_);
00153   theDCCheader.setTestZeroSuppression(tzs_);
00154   theDCCheader.setSrpStatus(srChStatus_);
00155   theDCCheader.setTccStatus(tccChStatus_);
00156   theDCCheader.setFEStatus(feChStatus_);
00157   
00158   
00159   theDCCheader.setSRPLv1(srpLv1_);
00160   theDCCheader.setSRPBx(srpBx_);
00161   theDCCheader.setFELv1(feLv1_);
00162   theDCCheader.setFEBx(feBx_);
00163   theDCCheader.setTCCLv1(tccLv1_);
00164   theDCCheader.setTCCBx(tccBx_);
00165   
00166 
00167   EcalDCCHeaderRuntypeDecoder theRuntypeDecoder;
00168   unsigned int DCCruntype              = runType_;
00169   unsigned int DCCdetTriggerType = detailedTriggerType_;
00170   theRuntypeDecoder.Decode(triggerType_, DCCdetTriggerType , DCCruntype, &theDCCheader);
00171 
00172   // Add Header to collection 
00173   (*dccHeaders_)->push_back(theDCCheader);
00174    
00175 }
00176 
00177 void DCCEventBlock::display(std::ostream& o){
00178   o<<"\n Unpacked Info for DCC Event Class"
00179    <<"\n DW1 ============================="
00180    <<"\n Fed Id "<<fedId_
00181    <<"\n Bx "<<bx_
00182    <<"\n L1 "<<l1_
00183    <<"\n Trigger Type "<<triggerType_
00184    <<"\n DW2 ============================="     
00185    <<"\n Length "<<blockLength_
00186    <<"\n Dcc errors "<<dccErrors_
00187    <<"\n Run number "<<runNumber_
00188    <<"\n DW3 ============================="
00189    <<"\n SR "<<sr_
00190    <<"\n ZS "<<zs_
00191    <<"\n TZS "<<tzs_
00192    <<"\n SRStatus "<<srChStatus_;
00193         
00194   std::vector<short>::iterator it;
00195   int i(0),k(0);
00196   for(it = tccChStatus_.begin(); it!=tccChStatus_.end();it++,i++){
00197     o<<"\n TCCStatus#"<<i<<" "<<(*it);
00198   } 
00199   
00200   i=0;
00201   for(it = feChStatus_.begin();it!=feChStatus_.end();it++ ,i++){
00202     if(!(i%14)){ o<<"\n DW"<<(k+3)<<" ============================="; k++; }
00203     o<<"\n FEStatus#"<<i<<" "<<(*it);           
00204   }
00205 
00206   o<<"\n";  
00207 } 
00208     
00209 
00210 DCCEventBlock::~DCCEventBlock(){
00211   if(towerBlock_){ delete towerBlock_; } 
00212   if(tccBlock_)  { delete tccBlock_;   }
00213   if(memBlock_)  { delete memBlock_;   }
00214   if(srpBlock_)  { delete srpBlock_;   }
00215 }
00216 
00217 
00218 // -----------------------------------------------------------------------
00219 // sync checking
00220 
00221 bool isSynced(const unsigned int dccBx,
00222               const unsigned int bx,
00223               const unsigned int dccL1,
00224               const unsigned int l1,
00225               const BlockType type,
00226               const unsigned int fov)
00227 {
00228   // avoid checking for MC until EcalDigiToRaw bugfixed
00229   // and to guarantee backward compatibility on RAW data
00230   if ( fov < 1 ) return true;
00231   // check the BX sync according the following rule:
00232   //
00233   //   FE Block     MEM Block     TCC Block  SRP Block  DCC
00234   // ------------------------------------------------------------------
00235   //   fe_bx     == mem_bx == 0   tcc_bx ==  srp_bx ==  DCC_bx == 3564
00236   //   fe_bx     == mem_bx     == tcc_bx ==  srp_bx ==  DCC_bx != 3564
00237   
00238   const bool bxSynced =
00239     ((type ==  FE_MEM) && (bx ==     0) && (dccBx == 3564)) ||
00240     ((type ==  FE_MEM) && (bx == dccBx) && (dccBx != 3564)) ||
00241     ((type == TCC_SRP) && (bx == dccBx));
00242   
00243   // check the L1A sync:
00244   //
00245   // L1A counter relation is valid modulo 0xFFF:
00246   // fe_l1  == mem_l1 == (DCC_l1-1) & 0xFFF
00247   // tcc_l1 == srp_l1 ==  DCC_l1    & 0xFFF
00248   
00249   const bool l1Synced =
00250     ((type ==  FE_MEM) && (l1 == ((dccL1 - 1) & 0xFFF))) ||
00251     ((type == TCC_SRP) && (l1 == ( dccL1      & 0xFFF)));
00252   
00253   return (bxSynced && l1Synced);
00254 }