CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/EcalTBRawToDigi/src/EcalTBDaqFormatter.cc

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