CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/EventFilter/EcalTBRawToDigi/src/EcalTB07DaqFormatter.cc

Go to the documentation of this file.
00001 /*  
00002  *
00003  *  $Date: 2012/01/13 10:06:50 $
00004  *  $Revision: 1.29 $
00005  *  \author  N. Marinelli IASA 
00006  *  \author G. Della Ricca
00007  *  \author G. Franzoni
00008  *  \author A. Ghezzi
00009  *
00010  */
00011 
00012 #include "EcalTB07DaqFormatter.h"
00013 #include <DataFormats/FEDRawData/interface/FEDRawData.h>
00014 #include <DataFormats/EcalDetId/interface/EBDetId.h>
00015 #include <DataFormats/EcalDetId/interface/EEDetId.h>
00016 #include <DataFormats/EcalDetId/interface/EcalTrigTowerDetId.h>
00017 #include <DataFormats/EcalDigi/interface/EBDataFrame.h>
00018 #include <DataFormats/EcalDigi/interface/EEDataFrame.h>
00019 #include <DataFormats/EcalDigi/interface/EcalDigiCollections.h>
00020 
00021 #include <EventFilter/EcalTBRawToDigi/interface/EcalDCCHeaderRuntypeDecoder.h>
00022 #include <DataFormats/EcalDigi/interface/EcalTriggerPrimitiveDigi.h>
00023 #include <DataFormats/EcalDigi/interface/EcalTriggerPrimitiveSample.h>
00024 #include <FWCore/ParameterSet/interface/FileInPath.h>
00025 
00026 #include "DCCDataParser.h"
00027 #include "DCCEventBlock.h"
00028 #include "DCCTowerBlock.h"
00029 #include "DCCTCCBlock.h"
00030 #include "DCCXtalBlock.h"
00031 #include "DCCDataMapper.h"
00032 
00033 
00034 #include <iostream>
00035 #include <string>
00036 
00037 EcalTB07DaqFormatter::EcalTB07DaqFormatter (std::string tbName,
00038                                             int cryIcMap[68][5][5], 
00039                                             int tbStatusToLocation[71], 
00040                                             int tbTowerIDToLocation[201]) {
00041 
00042   LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter";
00043   std::vector<uint32_t> parameters;
00044   parameters.push_back(10); // parameters[0] is the xtal samples 
00045   parameters.push_back(1);  // parameters[1] is the number of trigger time samples for TPG's
00046   parameters.push_back(68); // parameters[2] is the number of TT
00047   parameters.push_back(68); // parameters[3] is the number of SR Flags
00048   parameters.push_back(1);  // parameters[4] is the dcc id
00049   parameters.push_back(1);  // parameters[5] is the sr id
00050   parameters.push_back(1);  // parameters[6] is the tcc1 id
00051   parameters.push_back(2);  // parameters[7] is the tcc2 id
00052   parameters.push_back(3);  // parameters[8] is the tcc3 id
00053   parameters.push_back(4);  // parameters[9] is the tcc4 id
00054 
00055   theParser_ = new DCCTBDataParser(parameters);
00056 
00057   tbName_ = tbName;
00058 
00059   for(int i=0; i<68; ++i) 
00060     for (int j=0; j<5; ++j)
00061       for (int k=0; k<5; ++k)
00062         cryIcMap_[i][j][k] = cryIcMap[i][j][k];
00063   
00064   for(int i=0; i<71; ++i)
00065     tbStatusToLocation_[i] = tbStatusToLocation[i];
00066   
00067   for(int i=0; i<201; ++i)
00068     tbTowerIDToLocation_[i] = tbTowerIDToLocation[i];
00069 
00070 
00071 }
00072  
00073 void EcalTB07DaqFormatter::interpretRawData(const FEDRawData & fedData , 
00074                                             EBDigiCollection& digicollection,
00075                                             EEDigiCollection& eeDigiCollection,
00076                                             EcalPnDiodeDigiCollection & pndigicollection, 
00077                                             EcalRawDataCollection& DCCheaderCollection, 
00078                                             EBDetIdCollection & dccsizecollection, 
00079                                             EcalElectronicsIdCollection & ttidcollection, 
00080                                             EcalElectronicsIdCollection & blocksizecollection,
00081                                             EBDetIdCollection & chidcollection , EBDetIdCollection & gaincollection, 
00082                                             EBDetIdCollection & gainswitchcollection, 
00083                                             EcalElectronicsIdCollection & memttidcollection,  
00084                                             EcalElectronicsIdCollection & memblocksizecollection,
00085                                             EcalElectronicsIdCollection & memgaincollection,  
00086                                             EcalElectronicsIdCollection & memchidcollection,
00087                                             EcalTrigPrimDigiCollection &tpcollection)
00088   {
00089 
00090 
00091   const unsigned char * pData = fedData.data();
00092   int length = fedData.size();
00093   bool shit=true;
00094   unsigned int tower=0;
00095   int ch=0;
00096   int strip=0;
00097 
00098   LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00099                               << "size " << length;
00100  
00101 
00102   // mean + 3sigma estimation needed when switching to 0suppressed data
00103   digicollection.reserve(kCrystals);
00104   eeDigiCollection.reserve(kCrystals);
00105   pnAllocated = false;
00106   
00107 
00108   theParser_->parseBuffer( reinterpret_cast<uint32_t*>(const_cast<unsigned char*>(pData)), static_cast<uint32_t>(length), shit );
00109   
00110   std::vector< DCCTBEventBlock * > &   dccEventBlocks = theParser_->dccEvents();
00111 
00112   // Access each DCCTB block
00113   for( std::vector< DCCTBEventBlock * >::iterator itEventBlock = dccEventBlocks.begin(); 
00114        itEventBlock != dccEventBlocks.end(); 
00115        itEventBlock++){
00116     
00117     bool _displayParserMessages = false;
00118     if( (*itEventBlock)->eventHasErrors() && _displayParserMessages)
00119       {
00120         edm::LogWarning("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00121                                       << "errors found from parser... ";
00122         edm::LogWarning("EcalTB07RawToDigi") << (*itEventBlock)->eventErrorString();
00123         edm::LogWarning("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00124                                       << "... errors from parser notified";
00125       }
00126 
00127     // getting the fields of the DCC header
00128     EcalDCCHeaderBlock theDCCheader;
00129 
00130     theDCCheader.setId(46);                                                      // tb EE unpacker: forced to 46 to match EE region used at h2
00131     int fedId = (*itEventBlock)->getDataField("FED/DCC ID");
00132     theDCCheader.setFedId( fedId );                                             // fed id as found in raw data (0... 35 at tb )
00133 
00134     theDCCheader.setRunNumber((*itEventBlock)->getDataField("RUN NUMBER"));
00135     short trigger_type = (*itEventBlock)->getDataField("TRIGGER TYPE");
00136     short zs  = (*itEventBlock)->getDataField("ZS");
00137     short tzs = (*itEventBlock)->getDataField("TZS");
00138     short sr  = (*itEventBlock)->getDataField("SR");
00139     bool  dataIsSuppressed;
00140 
00141     // if zs&&tzs the suppression algo is used in DCC, the data are not suppressed and zs-bits are set
00142     if ( zs && !(tzs) ) dataIsSuppressed = true;
00143     else  dataIsSuppressed = false;
00144 
00145     if(trigger_type >0 && trigger_type <5){theDCCheader.setBasicTriggerType(trigger_type);}
00146     else{ edm::LogWarning("EcalTB07RawToDigiTriggerType") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00147                                                         << "unrecognized TRIGGER TYPE: "<<trigger_type;}
00148     theDCCheader.setLV1((*itEventBlock)->getDataField("LV1"));
00149     theDCCheader.setOrbit((*itEventBlock)->getDataField("ORBIT COUNTER"));
00150     theDCCheader.setBX((*itEventBlock)->getDataField("BX"));
00151     theDCCheader.setErrors((*itEventBlock)->getDataField("DCC ERRORS"));
00152     theDCCheader.setSelectiveReadout( sr );
00153     theDCCheader.setZeroSuppression( zs );
00154     theDCCheader.setTestZeroSuppression( tzs );
00155     theDCCheader.setSrpStatus((*itEventBlock)->getDataField("SR_CHSTATUS"));
00156 
00157 
00158 
00159 
00160     std::vector<short> theTCCs;
00161     for(int i=0; i<MAX_TCC_SIZE; i++){
00162       
00163       char TCCnum[20]; sprintf(TCCnum,"TCC_CHSTATUS#%d",i+1); std::string TCCnumS(TCCnum);
00164       theTCCs.push_back ((*itEventBlock)->getDataField(TCCnumS) );
00165     }
00166     theDCCheader.setTccStatus(theTCCs);
00167 
00168 
00169     std::vector< DCCTBTCCBlock * > tccBlocks = (*itEventBlock)->tccBlocks();
00170     
00171     for(    std::vector< DCCTBTCCBlock * >::iterator itTCCBlock = tccBlocks.begin(); 
00172             itTCCBlock != tccBlocks.end(); 
00173             itTCCBlock ++)
00174       {
00175 
00176         std::vector< std::pair<int,bool> > TpSamples = (* itTCCBlock) -> triggerSamples() ;
00177         // std::vector of 3 bits
00178         std::vector<int> TpFlags      = (* itTCCBlock) -> triggerFlags() ;
00179         
00180         // there have always to be 68 primitives and flags, per FED
00181         if (TpSamples.size()==68   && TpFlags.size()==68)
00182           {
00183             for(int i=0; i<((int)TpSamples.size()); i++)        
00184               {
00185                 
00186                 int etaTT = (i)  / kTowersInPhi +1;
00187                 int phiTT = (i) % kTowersInPhi +1;
00188 
00189                 // follow HB convention in iphi
00190                 phiTT=3-phiTT;
00191                 if(phiTT<=0)phiTT=phiTT+72;
00192 
00193                 EcalTriggerPrimitiveSample theSample(TpSamples[i].first, TpSamples[i].second, TpFlags[i]);
00194 
00195                 EcalTrigTowerDetId idtt(2, EcalBarrel, etaTT, phiTT, 0);
00196                 EcalTriggerPrimitiveDigi thePrimitive(idtt);
00197                 thePrimitive.setSize(1);                          // hard coded
00198                 thePrimitive.setSample(0, theSample);
00199                 
00200                 tpcollection.push_back(thePrimitive);
00201                 
00202                 LogDebug("EcalTB07RawToDigiTpg") << "@SUBS=EcalTB07DaqFormatter::interpretRawData"
00203                                                << "tower: " << (i+1) 
00204                                                << " primitive: " << TpSamples[i].first
00205                                                << " flag: " << TpSamples[i].second;
00206 
00207                 LogDebug("EcalTB07RawToDigiTpg") << "@SUBS=EcalTB07DaqFormatter::interpretRawData"<<
00208                   "tower: " << (i+1) << " flag: " << TpFlags[i];
00209               }// end loop on tower primitives
00210             
00211           }// end if
00212         else
00213           {
00214             edm::LogWarning("EcalTB07RawToDigiTpg") << "68 elements not found for TpFlags or TpSamples, collection will be empty";
00215           }
00216       }  
00217     
00218     
00219     
00220     
00221     short TowerStatus[MAX_TT_SIZE+1];
00222     char buffer[20];
00223     std::vector<short> theTTstatus;
00224     for(int i=1;i<MAX_TT_SIZE+1;i++)
00225       { 
00226         sprintf(buffer, "FE_CHSTATUS#%d", i);
00227         std::string Tower(buffer);
00228         TowerStatus[i]= (*itEventBlock)->getDataField(Tower);
00229         theTTstatus.push_back(TowerStatus[i]);
00230         //std::cout << "tower " << i << " has status " <<  TowerStatus[i] << std::endl;  
00231       }
00232     bool checkTowerStatus = TowerStatus[1] == 0 && TowerStatus[2] == 0 && TowerStatus[3] == 0 && TowerStatus[4] == 0;
00233     for (int i=5; i < MAX_TT_SIZE+1; ++i) checkTowerStatus = checkTowerStatus && TowerStatus[i] == 1;
00234     if (!checkTowerStatus) {
00235       for(int i=1; i<MAX_TT_SIZE+1; ++i) {
00236         std::cout << "tower " << i << " has status " << TowerStatus[i] << std::endl;
00237       }
00238     }
00239 
00240     theDCCheader.setFEStatus(theTTstatus);
00241 
00242     EcalDCCTBHeaderRuntypeDecoder theRuntypeDecoder;
00243     uint32_t DCCruntype = (*itEventBlock)->getDataField("RUN TYPE");
00244     theRuntypeDecoder.Decode(DCCruntype, &theDCCheader);
00245     //DCCHeader filled!
00246     DCCheaderCollection.push_back(theDCCheader);
00247     
00248     // add three more DCC headers (EE region used at h4)
00249     EcalDCCHeaderBlock hdr = theDCCheader;
00250     hdr.setId(04);
00251     DCCheaderCollection.push_back(hdr);
00252     hdr.setId(05);
00253     DCCheaderCollection.push_back(hdr);
00254     hdr.setId(06);
00255     DCCheaderCollection.push_back(hdr);
00256 
00257     std::vector< DCCTBTowerBlock * > dccTowerBlocks = (*itEventBlock)->towerBlocks();
00258     LogDebug("EcalTB07RawToDigi") << "@SUBS=EcalTB07DaqFormatter::interpretRawData"
00259                                 << "dccTowerBlocks size " << dccTowerBlocks.size();
00260 
00261 
00262 
00263     _expTowersIndex=0;_numExpectedTowers=0;
00264     for (int v=0; v<71; v++){
00265       _ExpectedTowers[v]=99999;
00266     }
00267 
00268     // note: these are the tower statuses handled at the moment - to be completed
00269     // staus==0:   tower expected;
00270     // staus==9:   Synk error LV1, tower expected;
00271     // staus==10:  Synk error BX, tower expected;
00272     // status==1, 2, 3, 4, 5:  tower not expected
00273     for (int u=1; u< (kTriggerTowersAndMem+1); u++)
00274       {
00275         // map status array to expected tower array
00276         //int towerMap[kTriggerTowersAndMem+1];
00277         //for (int i=0; i<kTriggerTowersAndMem; ++i ) towerMap[i] = i;
00278         //towerMap[1] = 6;
00279         //towerMap[2] = 2;
00280         //towerMap[3] = 1;
00281         //towerMap[4] = 5;
00282 
00283         if(   TowerStatus[u] ==0 || TowerStatus[u] ==9 || TowerStatus[u] ==10  ) 
00284           {_ExpectedTowers[_expTowersIndex]= tbStatusToLocation_[u];
00285             _expTowersIndex++;
00286             _numExpectedTowers++;
00287           }
00288       }
00289     // resetting counter of expected towers
00290     _expTowersIndex=0;
00291       
00292       
00293     // if number of dccEventBlocks NOT same as expected stop
00294     if (!      (dccTowerBlocks.size() == _numExpectedTowers)      )
00295       {
00296         // we probably always want to know if this happens
00297         edm::LogWarning("EcalTB07RawToDigiNumTowerBlocks") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00298                                       << "number of TowerBlocks found (" << dccTowerBlocks.size()
00299                                       << ") differs from expected (" << _numExpectedTowers 
00300                                       << ") skipping event"; 
00301 
00302         EBDetId idsm(1, 1);
00303         dccsizecollection.push_back(idsm);
00304         
00305         return;
00306         
00307       }
00308       
00309 
00310 
00311 
00312 
00313     // Access the Tower block    
00314     for( std::vector< DCCTBTowerBlock * >::iterator itTowerBlock = dccTowerBlocks.begin(); 
00315          itTowerBlock!= dccTowerBlocks.end(); 
00316          itTowerBlock++){
00317 
00318       tower=(*itTowerBlock)->towerID();
00319       // here is "correct" h2 map
00320       //if ( tower == 1  ) tower = 6;
00321       //if ( tower == 71 ) tower = 2;
00322       //if ( tower == 80 ) tower = 1;
00323       //if ( tower == 45 ) tower = 5;
00324       tower = tbTowerIDToLocation_[tower];
00325 
00326       // checking if tt in data is the same as tt expected 
00327       // else skip tower and increment problem counter
00328             
00329       // dccId set to 46 in order to match 'real' CMS positio at H2
00330 
00331       EcalElectronicsId idtt(46, _ExpectedTowers[_expTowersIndex], 1, 1);
00332     
00333 
00334       if (  !(tower == _ExpectedTowers[_expTowersIndex])          )
00335         {       
00336           
00337           if (_ExpectedTowers[_expTowersIndex] <= 68){
00338             edm::LogWarning("EcalTB07RawToDigiTowerId") << "@SUBS=EcalTB07DaqFormatter::interpretRawData"
00339                                                         << "TTower id found (=" << tower 
00340                                                         << ") different from expected (=" <<  _ExpectedTowers[_expTowersIndex] 
00341                                                         << ") " << (_expTowersIndex+1) << "-th tower checked"
00342                                                         << "\n Real hardware id is " << (*itTowerBlock)->towerID();
00343 
00344             //  report on failed tt_id for regular tower block
00345             ttidcollection.push_back(idtt);
00346           }
00347           else
00348             {
00349               edm::LogWarning("EcalTB07RawToDigiTowerId") << "@SUB=EcalTB07DaqFormatter:interpretRawData"
00350                                                         << "DecodeMEM: tower " << tower  
00351                                                         << " is not the same as expected " << ((int)_ExpectedTowers[_expTowersIndex])
00352                                                         << " (according to DCC header channel status)";
00353               
00354               // report on failed tt_id for mem tower block
00355               // chosing channel 1 as representative
00356               EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], 1, 1);
00357               memttidcollection.push_back(id);
00358             }
00359 
00360           ++ _expTowersIndex;
00361           continue;     
00362         }// if TT id found  different than expected 
00363         
00364 
00365 
00366       /*********************************
00367        //    tt: 1 ... 68: crystal data
00368        *********************************/
00369       if (  0<  (*itTowerBlock)->towerID() &&
00370             ((*itTowerBlock)->towerID() < (kTriggerTowers+1)  || 
00371              (*itTowerBlock)->towerID() == 71 || 
00372              (*itTowerBlock)->towerID() == 80)
00373             )
00374         {
00375           
00376           std::vector<DCCTBXtalBlock * > & xtalDataBlocks = (*itTowerBlock)->xtalBlocks();      
00377           
00378           // if there is no zero suppression, tower block must have have 25 channels in it
00379           if (  (!dataIsSuppressed)   &&   (xtalDataBlocks.size() != kChannelsPerTower)   )
00380             {     
00381               edm::LogWarning("EcalTB07RawToDigiTowerSize") << "EcalTB07DaqFormatter::interpretRawData, no zero suppression "
00382                                             << "wrong tower block size is: "  << xtalDataBlocks.size() 
00383                                             << " at LV1 " << (*itEventBlock)->getDataField("LV1")
00384                                             << " for TT " << _ExpectedTowers[_expTowersIndex];
00385               // report on wrong tt block size
00386               blocksizecollection.push_back(idtt);
00387 
00388               ++ _expTowersIndex;             continue; 
00389 
00390             }
00391           
00392 
00393           short cryInTower =0;
00394 
00395           short expStripInTower;
00396           short expCryInStrip;
00397           short expCryInTower =0;
00398 
00399           // Access the Xstal data
00400           for( std::vector< DCCTBXtalBlock * >::iterator itXtalBlock = xtalDataBlocks.begin(); 
00401                itXtalBlock!= xtalDataBlocks.end(); 
00402                itXtalBlock++){ //loop on crys of a  tower
00403 
00404             strip              =(*itXtalBlock)->stripID();
00405             ch                 =(*itXtalBlock)->xtalID();
00406             cryInTower  =(strip-1)* kChannelsPerCard + (ch -1);
00407 
00408             expStripInTower   =  expCryInTower/5 +1;
00409             expCryInStrip     =  expCryInTower%5 +1;
00410             
00411             
00412             // FIXME: waiting for geometry to do (TT, strip,chNum) <--> (SMChId)
00413             // short abscissa = (_ExpectedTowers[_expTowersIndex]-1)  /4;
00414             // short ordinate = (_ExpectedTowers[_expTowersIndex]-1)  %4;
00415             // temporarily choosing central crystal in trigger tower
00416             // int cryIdInSM  = 45 + ordinate*5 + abscissa * 100;
00417             
00418             
00419             // in case of 0 zuppressed data, check that cryInTower constantly grows
00420             if (dataIsSuppressed)
00421               {
00422                 
00423                 if ( strip < 1 || 5<strip || ch <1 || 5 < ch)
00424                   {
00425                     int  sm = 1; // hardcoded because of test  beam
00426                     for (int StripInTower_ =1;  StripInTower_ < 6; StripInTower_++){
00427                       for (int  CryInStrip_ =1;  CryInStrip_ < 6; CryInStrip_++){
00428                         int  ic        = cryIc(tower, StripInTower_,  CryInStrip_) ;
00429                         EBDetId               idExp(sm, ic,1);
00430                         chidcollection.push_back(idExp);
00431                       }
00432                     }
00433                     
00434                     edm::LogWarning("EcalTB07RawToDigiChId") << "EcalTB07DaqFormatter::interpretRawData with zero suppression, "
00435                                                            << " wrong channel id, since out of range: "
00436                                                            << "\t strip: "  << strip  << "\t channel: " << ch
00437                                                            << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
00438                                                            << "\t at LV1 : " << (*itEventBlock)->getDataField("LV1");
00439                     
00440                     expCryInTower++;
00441                     continue;
00442                   }
00443 
00444 
00445                 // correct ordering
00446                 if(  cryInTower >= expCryInTower ){
00447                   expCryInTower = cryInTower +1;
00448                 }
00449                 
00450                 
00451                 // cry_id wrong because of incorrect ordering within trigger tower
00452                 else
00453                   {
00454                     edm::LogWarning("EcalTB07RawToDigiChId") << "EcalTB07DaqFormatter::interpretRawData with zero suppression, "
00455                                                   << " based on ch ordering within tt, wrong channel id: "
00456                                                   << "\t strip: "  << strip  << "\t channel: " << ch
00457                                                   << "\t cryInTower "  << cryInTower
00458                                                   << "\t expCryInTower: " << expCryInTower
00459                                                   << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
00460                                                   << "\t at LV1: " << (*itEventBlock)->getDataField("LV1");
00461                     
00462                     int  sm = 1; // hardcoded because of test  beam
00463                     for (int StripInTower_ =1;  StripInTower_ < 6; StripInTower_++){
00464                       for (int  CryInStrip_ =1;  CryInStrip_ < 6; CryInStrip_++){
00465                         int  ic        = cryIc(tower, StripInTower_,  CryInStrip_) ;
00466                         EBDetId               idExp(sm, ic,1);
00467                         chidcollection.push_back(idExp);
00468                       }
00469                     }
00470                     
00471                     // chennel with id which does not follow correct odering
00472                     expCryInTower++;                continue;
00473                     
00474                   }// end 'ch_id does not respect growing order'
00475                 
00476               }// end   if zero supression
00477             
00478             
00479 
00480             else {
00481               
00482               // checking that ch and strip are within range and cryInTower is as expected
00483               if(   cryInTower != expCryInTower   ||  
00484                     strip < 1 ||   kStripsPerTower <strip  ||
00485                     ch <1  ||   kChannelsPerStrip < ch    ) 
00486                 {
00487                   
00488                   int ic        = cryIc(tower, expStripInTower,  expCryInStrip) ;
00489                   int  sm = 1; // hardcoded because of test  beam
00490                   EBDetId  idExp(sm, ic,1);
00491                   
00492                   edm::LogWarning("EcalTB07RawToDigiChId") << "EcalTB07DaqFormatter::interpretRawData no zero suppression "
00493                                                     << " wrong channel id for channel: "  << expCryInStrip
00494                                                     << "\t strip: " << expStripInTower
00495                                                     << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
00496                                                     << "\t at LV1: " << (*itEventBlock)->getDataField("LV1")
00497                                                     << "\t   (in the data, found channel:  " << ch
00498                                                     << "\t strip:  " << strip << " ).";
00499 
00500                   
00501                   // report on wrong channel id
00502                   chidcollection.push_back(idExp);
00503 
00504                   // there has been unexpected crystal id, dataframe not to go to the Event
00505                   expCryInTower++;                continue;
00506                   
00507                 } // if channel in data does not equal expected channel
00508 
00509               expCryInTower++;
00510 
00511             } // end 'not zero suppression'
00512             
00513             
00514             
00515             // data  to be stored in EBDataFrame, identified by EBDetId
00516             int  ic = cryIc(tower, strip, ch) ;
00517             int  sm = 1;
00518             EBDetId  id(sm, ic,1);      
00519             // EE data to be stored in EEDataFrame, identified by EEDetId
00520             // eeId(int i, int j, int iz (+1/-1), int mode = XYMODE)
00521             int ix = getEE_ix(tower, strip, ch);
00522             int iy = getEE_iy(tower, strip, ch);
00523 
00524             int iz = 1;
00525             if ( tbName_ == "h4" ) iz = -1;
00526             EEDetId  eeId(ix, iy, iz);
00527                 
00528             // here data frame go into the Event
00529             // removed later on (with a pop_back()) if gain==0 or if forbidden-gain-switch
00530             digicollection.push_back( id );
00531             eeDigiCollection.push_back( eeId );
00532             EBDataFrame theFrame ( digicollection.back() );
00533             EEDataFrame eeFrame ( eeDigiCollection.back() );
00534 
00535             std::vector<int> xtalDataSamples = (*itXtalBlock)->xtalDataSamples();   
00536             //theFrame.setSize(xtalDataSamples.size()); // if needed, to be changed when constructing digicollection
00537             //eeFrame. setSize(xtalDataSamples.size()); // if needed, to be changed when constructing eeDigicollection
00538       
00539 
00540             // gain cannot be 0, checking for that
00541             bool        gainIsOk =true;
00542             unsigned gain_mask      = 12288;    //12th and 13th bit
00543             std::vector <int> xtalGain;
00544 
00545             for (unsigned short i=0; i<xtalDataSamples.size(); ++i ) {
00546               
00547               theFrame.setSample (i, xtalDataSamples[i] );
00548               eeFrame .setSample (i, xtalDataSamples[i] );
00549               
00550               if((xtalDataSamples[i] & gain_mask) == 0){gainIsOk =false;}
00551               
00552               xtalGain.push_back(0);
00553               xtalGain[i] |= (xtalDataSamples[i] >> 12);
00554             }
00555             
00556             if (! gainIsOk) {
00557               
00558               edm::LogWarning("EcalTB07RawToDigiGainZero") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00559                                             << " gain==0 for strip: "  << expStripInTower
00560                                             << "\t channel: " << expCryInStrip
00561                                             << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
00562                                             << "\t ic: " << ic
00563                                             << "\t at LV1: " << (*itEventBlock)->getDataField("LV1");
00564               // report on gain==0
00565               gaincollection.push_back(id);
00566               
00567               // there has been a gain==0, dataframe not to go to the Event
00568               digicollection.pop_back();
00569               eeDigiCollection.pop_back();
00570               continue; //            expCryInTower already incremented
00571             }
00572 
00573 
00574             
00575             
00576             // looking for forbidden gain transitions
00577             
00578             short firstGainWrong=-1;
00579             short numGainWrong=0;
00580             
00581             for (unsigned short i=0; i<xtalGain.size(); i++ ) {
00582               
00583               if (i>0 && xtalGain[i-1]>xtalGain[i]) {
00584                 
00585                 numGainWrong++;// counting forbidden gain transitions
00586                 
00587                 if (firstGainWrong == -1) {
00588                   firstGainWrong=i;
00589                   edm::LogWarning("EcalTB07RawToDigiGainSwitch") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00590                                                           << "channelHasGainSwitchProblem: crystal eta = " 
00591                                                           << id.ieta() << " phi = " << id.iphi();
00592                 }
00593                 edm::LogWarning("EcalTB07RawToDigiGainSwitch") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00594                                                         << "channelHasGainSwitchProblem: sample = " << (i-1) 
00595                                                         << " gain: " << xtalGain[i-1] << " sample: " 
00596                                                         << i << " gain: " << xtalGain[i];
00597               }
00598             }
00599 
00600             if (numGainWrong>0) {
00601               gainswitchcollection.push_back(id);
00602 
00603               edm::LogWarning("EcalTB07RawToDigiGainSwitch") << "@SUB=EcalTB07DaqFormatter:interpretRawData"
00604                                                         << "channelHasGainSwitchProblem: more than 1 wrong transition";
00605                 
00606               for (unsigned short i1=0; i1<xtalDataSamples.size(); ++i1 ) {
00607                 int countADC = 0x00000FFF;
00608                 countADC &= xtalDataSamples[i1];
00609                 LogDebug("EcalTB07RawToDigi") << "Sample " << i1 << " ADC " << countADC << " Gain " << xtalGain[i1];
00610               }
00611 
00612               // there has been a forbidden gain transition,  dataframe not to go to the Event
00613               digicollection.pop_back();
00614               eeDigiCollection.pop_back();
00615               continue; //            expCryInTower already incremented
00616 
00617             }// END of:   'if there is a forbidden gain transition'
00618 
00619           }// end loop on crystals within a tower block
00620           
00621           _expTowersIndex++;
00622         }// end: tt1 ... tt68, crystal data
00623       
00624 
00625 
00626       
00627       
00628       /******************************************************************
00629        //    tt 69 and 70:  two mem boxes, holding PN0 ... PN9
00630        ******************************************************************/      
00631       else if (       (*itTowerBlock)->towerID() == 69 
00632                       ||           (*itTowerBlock)->towerID() == 70       )     
00633         {
00634           
00635           LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
00636                                       << "processing mem box num: " << (*itTowerBlock)->towerID();
00637 
00638           // if tt 69 or 70 found, allocate Pn digi collection
00639           if(! pnAllocated) 
00640             {
00641               pndigicollection.reserve(kPns);
00642               pnAllocated = true;
00643             }
00644 
00645           DecodeMEM( (*itTowerBlock),  pndigicollection , 
00646                      memttidcollection,  memblocksizecollection,
00647                      memgaincollection,  memchidcollection);
00648           
00649         }// end of < if it is a mem box>
00650       
00651       
00652     
00653 
00654 
00655       // wrong tt id
00656       else  {
00657         edm::LogWarning("EcalTB07RawToDigiTowerId") <<"@SUB=EcalTB07DaqFormatter::interpretRawData"
00658                                       << " processing tt with ID not existing ( "
00659                                       <<  (*itTowerBlock)->towerID() << ")";
00660         ++ _expTowersIndex;
00661         continue; 
00662       }// end: tt id error
00663 
00664     }// end loop on trigger towers
00665       
00666   }// end loop on events
00667 }
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 void EcalTB07DaqFormatter::DecodeMEM( DCCTBTowerBlock *  towerblock,  EcalPnDiodeDigiCollection & pndigicollection ,
00677                                     EcalElectronicsIdCollection & memttidcollection,  EcalElectronicsIdCollection &  memblocksizecollection,
00678                                     EcalElectronicsIdCollection & memgaincollection,  EcalElectronicsIdCollection & memchidcollection)
00679 {
00680   
00681   LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::DecodeMEM"
00682                               << "in mem " << towerblock->towerID();  
00683   
00684   int  tower_id = towerblock ->towerID() ;
00685   int  mem_id   = tower_id-69;
00686 
00687   // initializing container
00688   for (int st_id=0; st_id< kStripsPerTower; st_id++){
00689     for (int ch_id=0; ch_id<kChannelsPerStrip; ch_id++){
00690       for (int sa=0; sa<11; sa++){      
00691         memRawSample_[st_id][ch_id][sa] = -1;}    } }
00692 
00693   
00694   // check that tower block id corresponds to mem boxes
00695   if(tower_id != 69 && tower_id != 70) 
00696     {
00697       edm::LogWarning("EcalTB07RawToDigiTowerId") << "@SUB=EcalTB07DaqFormatter:decodeMem"
00698                                     << "DecodeMEM: this is not a mem box tower (" << tower_id << ")";
00699       ++ _expTowersIndex;
00700       return;
00701     }
00702 
00703      
00704   /******************************************************************************
00705    // getting the raw hits from towerBlock while checking tt and ch data structure 
00706    ******************************************************************************/
00707   std::vector<DCCTBXtalBlock *> & dccXtalBlocks = towerblock->xtalBlocks();
00708   std::vector<DCCTBXtalBlock*>::iterator itXtal;
00709 
00710   // checking mem tower block fo size
00711   if (dccXtalBlocks.size() != kChannelsPerTower)
00712     {     
00713       LogDebug("EcalTB07RawToDigiDccBlockSize") << "@SUB=EcalTB07DaqFormatter:decodeMem"
00714                                   << " wrong dccBlock size, namely: "  << dccXtalBlocks.size() 
00715                                   << ", for mem " << _ExpectedTowers[_expTowersIndex];
00716 
00717       // reporting mem-tt block size problem
00718       // chosing channel 1 as representative as a dummy...
00719       EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], 1, 1);
00720       memblocksizecollection.push_back(id);
00721 
00722       ++ _expTowersIndex;
00723       return;  // if mem tt block size not ok - do not build any Pn digis
00724     }
00725   
00726 
00727   // loop on channels of the mem block
00728   int  cryCounter = 0;   int  strip_id  = 0;   int  xtal_id   = 0;  
00729 
00730   for ( itXtal = dccXtalBlocks.begin(); itXtal < dccXtalBlocks.end(); itXtal++ ) {
00731     strip_id                     = (*itXtal) ->getDataField("STRIP ID");
00732     xtal_id                      = (*itXtal) ->getDataField("XTAL ID");
00733     int wished_strip_id  = cryCounter/ kStripsPerTower;
00734     int wished_ch_id     = cryCounter% kStripsPerTower;
00735     
00736     if( (wished_strip_id+1) != ((int)strip_id) ||
00737         (wished_ch_id+1) != ((int)xtal_id) )
00738       {
00739         
00740         LogDebug("EcalTB07RawToDigiChId") << "@SUB=EcalTB07DaqFormatter:decodeMem"
00741                                     << " in mem " <<  towerblock->towerID()
00742                                     << ", expected:\t strip"
00743                                     << (wished_strip_id+1)  << " cry " << (wished_ch_id+1) << "\tfound: "
00744                                     << "  strip " <<  strip_id << "  cry " << xtal_id;
00745         
00746         // report on crystal with unexpected indices
00747         EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], wished_strip_id,  wished_ch_id);
00748         memchidcollection.push_back(id);
00749       }
00750     
00751     
00752     // Accessing the 10 time samples per Xtal:
00753     memRawSample_[wished_strip_id][wished_ch_id][1] = (*itXtal)->getDataField("ADC#1");
00754     memRawSample_[wished_strip_id][wished_ch_id][2] = (*itXtal)->getDataField("ADC#2");
00755     memRawSample_[wished_strip_id][wished_ch_id][3] = (*itXtal)->getDataField("ADC#3");
00756     memRawSample_[wished_strip_id][wished_ch_id][4] = (*itXtal)->getDataField("ADC#4");
00757     memRawSample_[wished_strip_id][wished_ch_id][5] = (*itXtal)->getDataField("ADC#5");
00758     memRawSample_[wished_strip_id][wished_ch_id][6] = (*itXtal)->getDataField("ADC#6");
00759     memRawSample_[wished_strip_id][wished_ch_id][7] = (*itXtal)->getDataField("ADC#7");
00760     memRawSample_[wished_strip_id][wished_ch_id][8] = (*itXtal)->getDataField("ADC#8");
00761     memRawSample_[wished_strip_id][wished_ch_id][9] = (*itXtal)->getDataField("ADC#9");
00762     memRawSample_[wished_strip_id][wished_ch_id][10] = (*itXtal)->getDataField("ADC#10");
00763       
00764     cryCounter++;
00765   }// end loop on crystals of mem dccXtalBlock
00766   
00767   // tower accepted and digi read from all 25 channels.
00768   // Increase counter of expected towers before unpacking in the 5 PNs
00769   ++ _expTowersIndex;
00770 
00771 
00772 
00773   /************************************************************
00774    // unpacking and 'cooking' the raw numbers to get PN sample
00775    ************************************************************/
00776   int tempSample=0;
00777   int memStoreIndex=0;
00778   int ipn=0;
00779   for (memStoreIndex=0; memStoreIndex<500; memStoreIndex++)    {
00780     data_MEM[memStoreIndex]= -1;   }
00781   
00782   
00783   for(int strip=0; strip<kStripsPerTower; strip++) {// loop on strips
00784     for(int channel=0; channel<kChannelsPerStrip; channel++) {// loop on channels
00785 
00786       if(strip%2 == 0) 
00787         {ipn= mem_id*5+channel;}
00788       else 
00789         {ipn=mem_id*5+4-channel;}
00790 
00791       for(int sample=0;sample< kSamplesPerChannel ;sample++) {
00792         tempSample= memRawSample_[strip][channel][sample+1];
00793 
00794         int new_data=0;
00795         if(strip%2 == 1) {
00796           // 1) if strip number is even, 14 bits are reversed in order
00797           for(int ib=0;ib<14;ib++)
00798             { 
00799               new_data <<= 1;
00800               new_data=new_data | (tempSample&1);
00801               tempSample >>= 1;
00802             }
00803         } else {
00804           new_data=tempSample;
00805         }
00806 
00807         // 2) flip 11th bit for AD9052 still there on MEM !
00808         // 3) mask with 1 1111 1111 1111
00809         new_data = (new_data ^ 0x800) & 0x3fff;    // (new_data  XOR 1000 0000 0000) & 11 1111 1111 1111
00810         // new_data = (new_data ^ 0x800) & 0x1fff;    // (new_data  XOR 1000 0000 0000) & 1 1111 1111 1111
00811 
00812         //(Bit 12) == 1 -> Gain 16;    (Bit 12) == 0 -> Gain 1  
00813         // gain in mem can be 1 or 16 encoded resp. with 0 ir 1 in the 13th bit.
00814         // checking and reporting if there is any sample with gain==2,3
00815         short sampleGain = (new_data &0x3000)/4096;
00816         if (  sampleGain==2 || sampleGain==3) 
00817           {
00818             EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], strip, channel);
00819             memgaincollection.push_back(id);
00820             
00821             edm::LogWarning("EcalTB07RawToDigiGainZero")  << "@SUB=EcalTB07DaqFormatter:decodeMem"
00822                                            << "in mem " <<  towerblock->towerID()
00823                                            << " :\t strip: "
00824                                            << (strip +1)  << " cry: " << (channel+1) 
00825                                            << " has 14th bit non zero! Gain results: "
00826                                            << sampleGain << ".";
00827             
00828             continue;
00829           }// end 'if gain is zero'
00830 
00831         memStoreIndex= ipn*50+strip*kSamplesPerChannel+sample;
00832         // storing in data_MEM also the gain bits
00833         data_MEM[memStoreIndex]= new_data & 0x3fff;
00834 
00835       }// loop on samples
00836     }// loop on strips
00837   }// loop on channels
00838   
00839 
00840 
00841 
00842   for (int pnId=0; pnId<kPnPerTowerBlock; pnId++) pnIsOkInBlock[pnId]=true;
00843   // if anything was wrong with mem_tt_id or mem_tt_size: you would have already exited
00844   // otherwise, if any problem with ch_gain or ch_id: must not produce digis for the pertaining Pn
00845 
00846   if (!      (memgaincollection.size()==0 && memchidcollection.size()==0)          )
00847     {
00848       for ( EcalElectronicsIdCollection::const_iterator idItr = memgaincollection.begin();
00849             idItr != memgaincollection.end();
00850             ++ idItr ) {
00851         int ch = (*idItr).channelId();
00852         ch = (ch-1)/5;
00853         pnIsOkInBlock [ch] = false;
00854       }
00855 
00856       for ( EcalElectronicsIdCollection::const_iterator idItr = memchidcollection.begin();
00857             idItr != memchidcollection.end();
00858             ++ idItr ) {
00859         int ch = (*idItr).channelId();
00860         ch = (ch-1)/5;
00861         pnIsOkInBlock [ch] = false;
00862       }
00863 
00864     }// end: if any ch_gain or ch_id problems exclude the Pn's from digi production
00865 
00866 
00867 
00868 
00869   // looping on PN's of current mem box
00870   for (int pnId = 1;  pnId <  (kPnPerTowerBlock+1); pnId++){
00871 
00872     // if present Pn has any of its 5 channels with problems, do not produce digi for it
00873     if (! pnIsOkInBlock [pnId-1] ) continue;
00874 
00875     // second argument is DccId which is set to 46 to match h2 data in global CMS geometry
00876     EcalPnDiodeDetId PnId(2, 46, pnId +  kPnPerTowerBlock*mem_id);
00877     EcalPnDiodeDigi thePnDigi(PnId );
00878 
00879     thePnDigi.setSize(kSamplesPerPn);
00880 
00881     for (int sample =0; sample<kSamplesPerPn; sample++)
00882       {
00883         EcalFEMSample thePnSample( data_MEM[(mem_id)*250 + (pnId-1)*kSamplesPerPn + sample ] );
00884         thePnDigi.setSample(sample,  thePnSample );  
00885       }
00886     pndigicollection.push_back(thePnDigi);
00887   }
00888   
00889   
00890 }
00891 
00892 
00893 std::pair<int,int>  EcalTB07DaqFormatter::cellIndex(int tower_id, int strip, int ch) {
00894   
00895   int xtal= (strip-1)*5+ch-1;
00896   //  std::cout << " cellIndex input xtal " << xtal << std::endl;
00897   std::pair<int,int> ind;
00898   
00899   int eta = (tower_id - 1)/kTowersInPhi*kCardsPerTower;
00900   int phi = (tower_id - 1)%kTowersInPhi*kChannelsPerCard;
00901 
00902   if (rightTower(tower_id))
00903     eta += xtal/kCardsPerTower;
00904   else
00905     eta += (kCrystalsPerTower - 1 - xtal)/kCardsPerTower;
00906 
00907   if ((rightTower(tower_id) && (xtal/kCardsPerTower)%2 == 1) ||
00908       (!rightTower(tower_id) && (xtal/kCardsPerTower)%2 == 0))
00909 
00910     phi += (kChannelsPerCard - 1 - xtal%kChannelsPerCard);
00911   else
00912     phi += xtal%kChannelsPerCard;
00913 
00914 
00915   ind.first =eta+1;  
00916   ind.second=phi+1; 
00917 
00918   //  std::cout << "  EcalTB07DaqFormatter::cell_index eta " << ind.first << " phi " << ind.second << " " << std::endl;
00919 
00920   return ind;
00921 
00922 }
00923 
00924 int EcalTB07DaqFormatter::getEE_ix(int tower, int strip, int ch){
00925   // H2 -- ix is in [-90, -80], and iy is in [-5; 5]
00926   int ic = cryIc(tower, strip, ch);
00927   int ix = 0;
00928   if ( tbName_ == "h2" ) 
00929     ix = 95 - (ic-1)/20;
00930 
00931   if ( tbName_ == "h4" )
00932     ix = 35 - (ic-1)%20;
00933 
00934   return ix;
00935 
00936 }
00937 int EcalTB07DaqFormatter::getEE_iy(int tower, int strip, int ch){
00938   int ic = cryIc(tower, strip, ch);
00939   int iy = 0;
00940   if ( tbName_ == "h2" ) 
00941     iy = 46 + (ic-1)%20;
00942 
00943   if ( tbName_ == "h4" )
00944     iy = 51 + (int)((ic-1)/20);
00945 
00946   return iy;
00947 }
00948 
00949 int  EcalTB07DaqFormatter::cryIc(int tower, int strip, int ch) {
00950 
00951   if ( strip < 1 || 5<strip || ch <1 || 5 < ch || 68<tower)
00952     {
00953       edm::LogWarning("EcalTB07RawToDigiChId") << "EcalTB07DaqFormatter::interpretRawData (cryIc) "
00954                                              << " wrong channel id, since out of range: "
00955                                              << "\t strip: "  << strip  << "\t channel: " << ch
00956                                              << "\t in TT: " << tower;
00957       return -1;
00958     }
00959   
00960   // YM
00961   return cryIcMap_[tower-1][strip-1][ch-1];
00962   //std::pair<int,int> cellInd= EcalTB07DaqFormatter::cellIndex(tower, strip, ch); 
00963   //return cellInd.second + (cellInd.first-1)*kCrystalsInPhi;
00964 }
00965 
00966 
00967 
00968 bool EcalTB07DaqFormatter::rightTower(int tower) const {
00969   
00970   if ((tower>12 && tower<21) || (tower>28 && tower<37) ||
00971       (tower>44 && tower<53) || (tower>60 && tower<69))
00972     return true;
00973   else
00974     return false;
00975 }
00976 
00977 
00978 
00979 bool EcalTB07DaqFormatter::leftTower(int tower) const
00980 {
00981   return !rightTower(tower);
00982 }
00983 
00984