CMS 3D CMS Logo

EcalTBDaqFormatter.cc

Go to the documentation of this file.
00001 /*
00002  *
00003  *  $Date: 2007/12/10 19:55:42 $
00004  *  $Revision: 1.71 $
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<ulong> 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, EBDetIdCollection & gainswitchstaycollection, 
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<ulong*>(const_cast<unsigned char*>(pData)), static_cast<ulong>(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         //cout << "tower " << i << " has status " <<  TowerStatus[i] << endl;  
00205       }
00206 
00207     theDCCheader.setFEStatus(theTTstatus);
00208     
00209     EcalDCCTBHeaderRuntypeDecoder theRuntypeDecoder;
00210     ulong 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             // only discriminating if gain stays the same after the forbidden gain transition
00529             bool wrongGainStaysTheSame=false;
00530             if (firstGainWrong!=-1 && firstGainWrong<9){
00531               short gainWrong = xtalGain[firstGainWrong];
00532     
00533               // does wrong gain stay the same after the forbidden transition?
00534               for (unsigned short u=firstGainWrong+1; u<xtalGain.size(); u++){
00535 
00536                 if( gainWrong == xtalGain[u]) 
00537                   wrongGainStaysTheSame=true; 
00538                 else
00539                   wrongGainStaysTheSame=false; 
00540 
00541               }// END loop on samples after forbidden transition
00542             
00543             }// END OF if firstGainWrong!=0 && firstGainWrong<8
00544 
00545 
00546             if (numGainWrong>0) {
00547               gainswitchcollection.push_back(id);
00548 
00549               if (numGainWrong == 1 && (wrongGainStaysTheSame)) {
00550               
00551                 edm::LogWarning("EcalTBRawToDigiGainSwitch") << "@SUB=EcalTBDaqFormatter:interpretRawData"
00552                                                         << "channelHasGainSwitchProblem: wrong transition stays till last sample";
00553                 
00554                 gainswitchstaycollection.push_back(id);              
00555               }
00556               else if (numGainWrong>1) {
00557                 edm::LogWarning("EcalTBRawToDigiGainSwitch") << "@SUB=EcalTBDaqFormatter:interpretRawData"
00558                                                         << "channelHasGainSwitchProblem: more than 1 wrong transition";
00559                 
00560                 for (unsigned short i1=0; i1<xtalDataSamples.size(); ++i1 ) {
00561                   int countADC = 0x00000FFF;
00562                   countADC &= xtalDataSamples[i1];
00563                   LogDebug("EcalTBRawToDigi") << "Sample " << i1 << " ADC " << countADC << " Gain " << xtalGain[i1];
00564                 }
00565 
00566               }// end 'if there is multiple transition'
00567              
00568 
00569               // there has been a forbidden gain transition,  dataframe not to go to the Event
00570               digicollection.pop_back();
00571               continue; //            expCryInTower already incremented
00572 
00573             }// END of:   'if there is a forbidden gain transition'
00574 
00575 
00576             
00577           }// end loop on crystals within a tower block
00578           
00579           
00580           _expTowersIndex++;
00581         }// end: tt1 ... tt68, crystal data
00582       
00583 
00584 
00585       
00586       
00587       /******************************************************************
00588        //    tt 69 and 70:  two mem boxes, holding PN0 ... PN9
00589        ******************************************************************/      
00590       else if (       (*itTowerBlock)->towerID() == 69 
00591                       ||           (*itTowerBlock)->towerID() == 70       )     
00592         {
00593           
00594           LogDebug("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter::interpretRawData"
00595                                       << "processing mem box num: " << (*itTowerBlock)->towerID();
00596 
00597           // if tt 69 or 70 found, allocate Pn digi collection
00598           if(! pnAllocated) 
00599             {
00600               pndigicollection.reserve(kPns);
00601               pnAllocated = true;
00602             }
00603 
00604           DecodeMEM( (*itTowerBlock),  pndigicollection , 
00605                      memttidcollection,  memblocksizecollection,
00606                      memgaincollection,  memchidcollection);
00607           
00608         }// end of < if it is a mem box>
00609       
00610       
00611     
00612 
00613 
00614       // wrong tt id
00615       else  {
00616         edm::LogWarning("EcalTBRawToDigiTowerId") <<"@SUB=EcalTBDaqFormatter::interpretRawData"
00617                                       << " processing tt with ID not existing ( "
00618                                       <<  (*itTowerBlock)->towerID() << ")";
00619         ++ _expTowersIndex;continue; 
00620       }// end: tt id error
00621 
00622     }// end loop on trigger towers
00623       
00624   }// end loop on events
00625 }
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 void EcalTBDaqFormatter::DecodeMEM( DCCTBTowerBlock *  towerblock,  EcalPnDiodeDigiCollection & pndigicollection ,
00635                                     EcalElectronicsIdCollection & memttidcollection,  EcalElectronicsIdCollection &  memblocksizecollection,
00636                                     EcalElectronicsIdCollection & memgaincollection,  EcalElectronicsIdCollection & memchidcollection)
00637 {
00638   
00639   LogDebug("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter::DecodeMEM"
00640                               << "in mem " << towerblock->towerID();  
00641   
00642   int  tower_id = towerblock ->towerID() ;
00643   int  mem_id   = tower_id-69;
00644 
00645   // initializing container
00646   for (int st_id=0; st_id< kStripsPerTower; st_id++){
00647     for (int ch_id=0; ch_id<kChannelsPerStrip; ch_id++){
00648       for (int sa=0; sa<11; sa++){      
00649         memRawSample_[st_id][ch_id][sa] = -1;}    } }
00650 
00651   
00652   // check that tower block id corresponds to mem boxes
00653   if(tower_id != 69 && tower_id != 70) 
00654     {
00655       edm::LogWarning("EcalTBRawToDigiTowerId") << "@SUB=EcalTBDaqFormatter:decodeMem"
00656                                     << "DecodeMEM: this is not a mem box tower (" << tower_id << ")";
00657       ++ _expTowersIndex;
00658       return;
00659     }
00660 
00661      
00662   /******************************************************************************
00663    // getting the raw hits from towerBlock while checking tt and ch data structure 
00664    ******************************************************************************/
00665   std::vector<DCCTBXtalBlock *> & dccXtalBlocks = towerblock->xtalBlocks();
00666   std::vector<DCCTBXtalBlock*>::iterator itXtal;
00667 
00668   // checking mem tower block fo size
00669   if (dccXtalBlocks.size() != kChannelsPerTower)
00670     {     
00671       LogDebug("EcalTBRawToDigiDccBlockSize") << "@SUB=EcalTBDaqFormatter:decodeMem"
00672                                   << " wrong dccBlock size, namely: "  << dccXtalBlocks.size() 
00673                                   << ", for mem " << _ExpectedTowers[_expTowersIndex];
00674 
00675       // reporting mem-tt block size problem
00676       // chosing channel 1 as representative as a dummy...
00677       EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], 1, 1);
00678       memblocksizecollection.push_back(id);
00679 
00680       ++ _expTowersIndex;
00681       return;  // if mem tt block size not ok - do not build any Pn digis
00682     }
00683   
00684 
00685   // loop on channels of the mem block
00686   int  cryCounter = 0;   int  strip_id  = 0;   int  xtal_id   = 0;  
00687 
00688   for ( itXtal = dccXtalBlocks.begin(); itXtal < dccXtalBlocks.end(); itXtal++ ) {
00689     strip_id                     = (*itXtal) ->getDataField("STRIP ID");
00690     xtal_id                      = (*itXtal) ->getDataField("XTAL ID");
00691     int wished_strip_id  = cryCounter/ kStripsPerTower;
00692     int wished_ch_id     = cryCounter% kStripsPerTower;
00693     
00694     if( (wished_strip_id+1) != ((int)strip_id) ||
00695         (wished_ch_id+1) != ((int)xtal_id) )
00696       {
00697         
00698         LogDebug("EcalTBRawToDigiChId") << "@SUB=EcalTBDaqFormatter:decodeMem"
00699                                     << " in mem " <<  towerblock->towerID()
00700                                     << ", expected:\t strip"
00701                                     << (wished_strip_id+1)  << " cry " << (wished_ch_id+1) << "\tfound: "
00702                                     << "  strip " <<  strip_id << "  cry " << xtal_id;
00703         
00704         // report on crystal with unexpected indices
00705         EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], wished_strip_id,  wished_ch_id);
00706         memchidcollection.push_back(id);
00707       }
00708     
00709     
00710     // Accessing the 10 time samples per Xtal:
00711     memRawSample_[wished_strip_id][wished_ch_id][1] = (*itXtal)->getDataField("ADC#1");
00712     memRawSample_[wished_strip_id][wished_ch_id][2] = (*itXtal)->getDataField("ADC#2");
00713     memRawSample_[wished_strip_id][wished_ch_id][3] = (*itXtal)->getDataField("ADC#3");
00714     memRawSample_[wished_strip_id][wished_ch_id][4] = (*itXtal)->getDataField("ADC#4");
00715     memRawSample_[wished_strip_id][wished_ch_id][5] = (*itXtal)->getDataField("ADC#5");
00716     memRawSample_[wished_strip_id][wished_ch_id][6] = (*itXtal)->getDataField("ADC#6");
00717     memRawSample_[wished_strip_id][wished_ch_id][7] = (*itXtal)->getDataField("ADC#7");
00718     memRawSample_[wished_strip_id][wished_ch_id][8] = (*itXtal)->getDataField("ADC#8");
00719     memRawSample_[wished_strip_id][wished_ch_id][9] = (*itXtal)->getDataField("ADC#9");
00720     memRawSample_[wished_strip_id][wished_ch_id][10] = (*itXtal)->getDataField("ADC#10");
00721       
00722     cryCounter++;
00723   }// end loop on crystals of mem dccXtalBlock
00724   
00725   // tower accepted and digi read from all 25 channels.
00726   // Increase counter of expected towers before unpacking in the 5 PNs
00727   ++ _expTowersIndex;
00728 
00729 
00730 
00731   /************************************************************
00732    // unpacking and 'cooking' the raw numbers to get PN sample
00733    ************************************************************/
00734   int tempSample=0;
00735   int memStoreIndex=0;
00736   int ipn=0;
00737   for (memStoreIndex=0; memStoreIndex<500; memStoreIndex++)    {
00738     data_MEM[memStoreIndex]= -1;   }
00739   
00740   
00741   for(int strip=0; strip<kStripsPerTower; strip++) {// loop on strips
00742     for(int channel=0; channel<kChannelsPerStrip; channel++) {// loop on channels
00743 
00744       if(strip%2 == 0) 
00745         {ipn= mem_id*5+channel;}
00746       else 
00747         {ipn=mem_id*5+4-channel;}
00748 
00749       for(int sample=0;sample< kSamplesPerChannel ;sample++) {
00750         tempSample= memRawSample_[strip][channel][sample+1];
00751 
00752         int new_data=0;
00753         if(strip%2 == 1) {
00754           // 1) if strip number is even, 14 bits are reversed in order
00755           for(int ib=0;ib<14;ib++)
00756             { 
00757               new_data <<= 1;
00758               new_data=new_data | (tempSample&1);
00759               tempSample >>= 1;
00760             }
00761         } else {
00762           new_data=tempSample;
00763         }
00764 
00765         // 2) flip 11th bit for AD9052 still there on MEM !
00766         // 3) mask with 1 1111 1111 1111
00767         new_data = (new_data ^ 0x800) & 0x3fff;    // (new_data  XOR 1000 0000 0000) & 11 1111 1111 1111
00768         // new_data = (new_data ^ 0x800) & 0x1fff;    // (new_data  XOR 1000 0000 0000) & 1 1111 1111 1111
00769 
00770         //(Bit 12) == 1 -> Gain 16;    (Bit 12) == 0 -> Gain 1  
00771         // gain in mem can be 1 or 16 encoded resp. with 0 ir 1 in the 13th bit.
00772         // checking and reporting if there is any sample with gain==2,3
00773         short sampleGain = (new_data &0x3000)/4096;
00774         if (  sampleGain==2 || sampleGain==3) 
00775           {
00776             EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], strip, channel);
00777             memgaincollection.push_back(id);
00778             
00779             edm::LogWarning("EcalTBRawToDigiGainZero")  << "@SUB=EcalTBDaqFormatter:decodeMem"
00780                                            << "in mem " <<  towerblock->towerID()
00781                                            << " :\t strip: "
00782                                            << (strip +1)  << " cry: " << (channel+1) 
00783                                            << " has 14th bit non zero! Gain results: "
00784                                            << sampleGain << ".";
00785             
00786             continue;
00787           }// end 'if gain is zero'
00788 
00789         memStoreIndex= ipn*50+strip*kSamplesPerChannel+sample;
00790         // storing in data_MEM also the gain bits
00791         data_MEM[memStoreIndex]= new_data & 0x3fff;
00792 
00793       }// loop on samples
00794     }// loop on strips
00795   }// loop on channels
00796   
00797 
00798 
00799 
00800   for (int pnId=0; pnId<kPnPerTowerBlock; pnId++) pnIsOkInBlock[pnId]=true;
00801   // if anything was wrong with mem_tt_id or mem_tt_size: you would have already exited
00802   // otherwise, if any problem with ch_gain or ch_id: must not produce digis for the pertaining Pn
00803 
00804   if (!      (memgaincollection.size()==0 && memchidcollection.size()==0)          )
00805     {
00806       for ( EcalElectronicsIdCollection::const_iterator idItr = memgaincollection.begin();
00807             idItr != memgaincollection.end();
00808             ++ idItr ) {
00809         int ch = (*idItr).channelId();
00810         ch = (ch-1)/5;
00811         pnIsOkInBlock [ch] = false;
00812       }
00813 
00814       for ( EcalElectronicsIdCollection::const_iterator idItr = memchidcollection.begin();
00815             idItr != memchidcollection.end();
00816             ++ idItr ) {
00817         int ch = (*idItr).channelId();
00818         ch = (ch-1)/5;
00819         pnIsOkInBlock [ch] = false;
00820       }
00821 
00822     }// end: if any ch_gain or ch_id problems exclude the Pn's from digi production
00823 
00824 
00825 
00826 
00827   // looping on PN's of current mem box
00828   for (int pnId = 1;  pnId <  (kPnPerTowerBlock+1); pnId++){
00829 
00830     // if present Pn has any of its 5 channels with problems, do not produce digi for it
00831     if (! pnIsOkInBlock [pnId-1] ) continue;
00832 
00833     // DccId set to 28 to be consistent with ism==1
00834     EcalPnDiodeDetId PnId(1, 28, pnId +  kPnPerTowerBlock*mem_id);
00835     EcalPnDiodeDigi thePnDigi(PnId );
00836 
00837     thePnDigi.setSize(kSamplesPerPn);
00838 
00839     for (int sample =0; sample<kSamplesPerPn; sample++)
00840       {
00841         EcalFEMSample thePnSample( data_MEM[(mem_id)*250 + (pnId-1)*kSamplesPerPn + sample ] );
00842         thePnDigi.setSample(sample,  thePnSample );  
00843       }
00844     pndigicollection.push_back(thePnDigi);
00845   }
00846   
00847   
00848 }
00849 
00850 
00851 
00852 
00853 
00854 
00855 
00856 
00857 
00858 
00859 
00860 
00861 
00862 
00863 std::pair<int,int>  EcalTBDaqFormatter::cellIndex(int tower_id, int strip, int ch) {
00864   
00865   int xtal= (strip-1)*5+ch-1;
00866   //  cout << " cellIndex input xtal " << xtal << endl;
00867   std::pair<int,int> ind;
00868   
00869   int eta = (tower_id - 1)/kTowersInPhi*kCardsPerTower;
00870   int phi = (tower_id - 1)%kTowersInPhi*kChannelsPerCard;
00871 
00872   if (rightTower(tower_id))
00873     eta += xtal/kCardsPerTower;
00874   else
00875     eta += (kCrystalsPerTower - 1 - xtal)/kCardsPerTower;
00876 
00877   if (rightTower(tower_id) && (xtal/kCardsPerTower)%2 == 1 ||
00878       !rightTower(tower_id) && (xtal/kCardsPerTower)%2 == 0)
00879 
00880     phi += (kChannelsPerCard - 1 - xtal%kChannelsPerCard);
00881   else
00882     phi += xtal%kChannelsPerCard;
00883 
00884 
00885   ind.first =eta+1;  
00886   ind.second=phi+1; 
00887 
00888   //  cout << "  EcalTBDaqFormatter::cell_index eta " << ind.first << " phi " << ind.second << " " << endl;
00889 
00890   return ind;
00891 
00892 }
00893 
00894 
00895 
00896 int  EcalTBDaqFormatter::cryIc(int tower, int strip, int ch) {
00897 
00898   if ( strip < 1 || 5<strip || ch <1 || 5 < ch || 68<tower)
00899     {
00900       edm::LogWarning("EcalTBRawToDigiChId") << "EcalTBDaqFormatter::interpretRawData (cryIc) "
00901                                              << " wrong channel id, since out of range: "
00902                                              << "\t strip: "  << strip  << "\t channel: " << ch
00903                                              << "\t in TT: " << tower;
00904       return -1;
00905     }
00906   
00907   std::pair<int,int> cellInd= EcalTBDaqFormatter::cellIndex(tower, strip, ch); 
00908   return cellInd.second + (cellInd.first-1)*kCrystalsInPhi;
00909 }
00910 
00911 
00912 
00913 bool EcalTBDaqFormatter::rightTower(int tower) const {
00914   
00915   if ((tower>12 && tower<21) || (tower>28 && tower<37) ||
00916       (tower>44 && tower<53) || (tower>60 && tower<69))
00917     return true;
00918   else
00919     return false;
00920 }
00921 
00922 
00923 
00924 bool EcalTBDaqFormatter::leftTower(int tower) const
00925 {
00926   return !rightTower(tower);
00927 }
00928 
00929 

Generated on Tue Jun 9 17:34:39 2009 for CMSSW by  doxygen 1.5.4