CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/SimCalorimetry/EcalSelectiveReadoutAlgos/src/EcalSelectiveReadout.cc

Go to the documentation of this file.
00001 //emacs settings:-*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-"
00002 /*
00003  * $Id: EcalSelectiveReadout.cc,v 1.17 2009/10/26 10:41:26 pgras Exp $
00004  */
00005 
00006 #include "SimCalorimetry/EcalSelectiveReadoutAlgos/src/EcalSelectiveReadout.h"
00007 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00008 #include "DataFormats/EcalDetId/interface/EcalElectronicsId.h"
00009 #include "FWCore/Utilities/interface/EDMException.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include <string>
00012 #include <iomanip>
00013 //#include <iostream> //for debugging
00014 
00015 using std::vector;
00016 
00017 const char EcalSelectiveReadout::srpFlagMarker[] = {'.', 'S', 'N', 'C',
00018                                                     '4', '5', '6', '7'};
00019 
00020 EcalSelectiveReadout::EcalSelectiveReadout(int dEta_, int dPhi_):
00021   theTriggerMap(0), theElecMap(0), dEta(dEta_), dPhi(dPhi_) {
00022 }
00023 
00024 void EcalSelectiveReadout::resetEeRuInterest(){
00025   //init superCrystalInterest (sets all elts to 'UNKNOWN'):
00026   for(size_t iCap=0; iCap < nEndcaps; ++iCap){
00027     for(int iDccPhi = 0; iDccPhi < nDccPerEe; ++iDccPhi){
00028       for(int iDccCh = 0; iDccCh < maxDccChs; ++iDccCh){
00029         eeRuInterest_[iCap][iDccPhi][iDccCh] = UNKNOWN;
00030       }
00031     }
00032   }
00033 }
00034 
00035 void
00036 EcalSelectiveReadout::runSelectiveReadout0(const ttFlag_t ttFlags[nTriggerTowersInEta][nTriggerTowersInPhi]) {
00037 
00038   //printDccChMap(std::cout);
00039   
00040   //classifies the trigger towers (single,center,neighbor,low interest)
00041   classifyTriggerTowers(ttFlags);
00042   
00043   //count number of TT in each interest class for debugging display
00044   int nTriggerTowerE[] = {0, 0, 0, 0, 0, 0, 0, 0};
00045   int nTriggerTowerB[] = {0, 0, 0, 0, 0, 0, 0, 0};
00046 
00047   static int ncall = 0;
00048   if(ncall < 10){
00049     ++ncall;
00050     for(size_t iPhi = 0; iPhi < nTriggerTowersInPhi; ++iPhi){
00051       for(size_t iEta = 0; iEta < nTriggerTowersInEta; ++iEta){
00052         if(iEta < nEndcapTriggerTowersInEta
00053            || iEta >= nBarrelTriggerTowersInEta + nEndcapTriggerTowersInEta){
00054           //in endcaps
00055           ++nTriggerTowerE[towerInterest[iEta][iPhi]];
00056         } else{//in barrel
00057           ++nTriggerTowerB[towerInterest[iEta][iPhi]];
00058         }
00059 
00060         assert(towerInterest[iEta][iPhi] >= 0
00061                && towerInterest[iEta][iPhi] <= 0x7);
00062       }
00063     }
00064     edm::LogInfo("EcalSelectiveReadout")
00065       << "without forced bit + with forced bit set:\n"
00066       << nTriggerTowerB[LOWINTEREST] << " + "
00067       << nTriggerTowerB[LOWINTEREST | FORCED_MASK]
00068       << " low interest TT(s) in barrel\n"
00069       << nTriggerTowerB[SINGLE]       << " + "
00070       << nTriggerTowerB[SINGLE | FORCED_MASK]
00071       << " single TT(s) in barrel\n"
00072       << nTriggerTowerB[NEIGHBOUR]   << " + "
00073       << nTriggerTowerB[NEIGHBOUR | FORCED_MASK]
00074       << " neighbor interest TT(s) in barrel\n"
00075       << nTriggerTowerB[CENTER]      << " + "
00076       << nTriggerTowerB[CENTER | FORCED_MASK]
00077       << " centre interest TT(s) in barrel\n"
00078       << nTriggerTowerE[LOWINTEREST] << " + "
00079       << nTriggerTowerE[LOWINTEREST | FORCED_MASK]
00080       << " low interest TT(s) in endcap\n"
00081       << nTriggerTowerE[SINGLE]      << " + "
00082       << nTriggerTowerE[SINGLE | FORCED_MASK]
00083       << " single TT(s) in endcap\n"
00084       << nTriggerTowerE[NEIGHBOUR]   << " + "
00085       << nTriggerTowerE[NEIGHBOUR | FORCED_MASK]
00086       << " neighbor TT(s) in endcap\n"
00087       << nTriggerTowerE[CENTER]      << " + "
00088       << nTriggerTowerE[CENTER | FORCED_MASK]
00089       << " center TT(s) in endcap\n";
00090   }
00091   //end TT interest class composition debugging display
00092   
00093   //For the endcap the TT classification must be mapped to the SC:  
00094   resetEeRuInterest();
00095   
00096 #ifndef ECALSELECTIVEREADOUT_NOGEOM
00097   const std::vector<DetId>& endcapDetIds = theGeometry->getValidDetIds(DetId::Ecal, EcalEndcap);
00098   for(std::vector<DetId>::const_iterator eeDetIdItr = endcapDetIds.begin();
00099       eeDetIdItr != endcapDetIds.end(); ++eeDetIdItr){
00100     // for each superCrystal, the interest is the highest interest
00101     // of any trigger tower associated with at least one crystal from this SC.
00102     // The forced bit must be set if the flag of one of these trigger towers has
00103     // the forced bit set.
00104     EcalTrigTowerDetId trigTower = theTriggerMap->towerOf(*eeDetIdItr);
00105     assert(trigTower.rawId() != 0); 
00106     EEDetId eeDetId(*eeDetIdItr);
00107     int iz = (eeDetId.zside() > 0) ? 1 : 0;
00108     //Following statement will set properly the actual 2-bit flag value
00109     //and the forced bit: TTF forced bit is propagated to every RU that
00110     //overlaps with the corresponding TT.
00111     combineFlags(eeRuInterest(eeDetId), getTowerInterest(trigTower));
00112   }
00113 #else //ECALSELECTIVEREADOUT_NOGEOM defined
00114   EEDetId xtal;
00115   for(int iZ0=0; iZ0<2; ++iZ0){//0->EE-, 1->EE+
00116     for(unsigned iX0=0; iX0<nEndcapXBins; ++iX0){
00117       for(unsigned iY0=0; iY0<nEndcapYBins; ++iY0){
00118 
00119         if (!(xtal.validDetId(iX0+1, iY0+1, (iZ0>0?1:-1)))){ 
00120           continue; 
00121         }
00122         xtal = EEDetId(iX0+1, iY0+1, (iZ0>0?1:-1));
00123         //works around a EEDetId bug. To remove once the bug fixed.
00124         if(39 <= iX0 && iX0 <= 60 && 45 <= iY0 && iY0 <= 54){
00125           continue;
00126         }
00127         // for each superCrystal, the interest is the highest interest
00128         // of any trigger tower associated with any crystal in this SC
00129         EcalTrigTowerDetId trigTower = theTriggerMap->towerOf(xtal);
00130         assert(trigTower.rawId() != 0); 
00131         //Following statement will set properly the actual 2-bit flag value
00132         //and the forced bit: TTF forced bit is propagated to every RU that
00133         //overlaps with the corresponding TT.
00134         combineFlags(eeRuInterest(xtal), getTowerInterest(trigTower));
00135 
00136         assert(0<= eeRuInterest(xtal)  && eeRuInterest(xtal) <= 0x7);
00137         
00138       } //next iY0
00139     } //next iX0
00140   } //next iZ0
00141 #endif //ECALSELECTIVEREADOUT_NOGEOM not defined
00142 }
00143 
00144 EcalSelectiveReadout::towerInterest_t 
00145 EcalSelectiveReadout::getCrystalInterest(const EBDetId & ebDetId) const
00146 {
00147   EcalTrigTowerDetId thisTower = theTriggerMap->towerOf(ebDetId);
00148   return getTowerInterest(thisTower);
00149 }
00150 
00151 
00152 EcalSelectiveReadout::towerInterest_t 
00153 EcalSelectiveReadout::getCrystalInterest(const EEDetId & eeDetId) const 
00154 {
00155   //   int iz = (eeDetId.zside() > 0) ? 1 : 0;
00156   //   int superCrystalX = (eeDetId.ix()-1) / 5;
00157   //   int superCrystalY = (eeDetId.iy()-1) / 5;
00158   //   return supercrystalInterest[iz][superCrystalX][superCrystalY];
00159   return const_cast<EcalSelectiveReadout*>(this)->eeRuInterest(eeDetId);
00160 }
00161 
00162 EcalSelectiveReadout::towerInterest_t 
00163 EcalSelectiveReadout::getSuperCrystalInterest(const EcalScDetId& scDetId) const 
00164 {
00165   return const_cast<EcalSelectiveReadout*>(this)->eeRuInterest(scDetId);
00166 }
00167 
00168 EcalSelectiveReadout::towerInterest_t&
00169 EcalSelectiveReadout::eeRuInterest(const EEDetId& eeDetId){
00170   const EcalElectronicsId& id = theElecMap->getElectronicsId(eeDetId);
00171   const int iZ0 = id.zside()>0 ? 1 : 0;
00172   const int iDcc0 = id.dccId()-1;
00173   const int iDccPhi0 = (iDcc0<9)?iDcc0:(iDcc0-45);
00174   const int iDccCh0 = id.towerId()-1;
00175   assert(0 <= iDccPhi0 && iDccPhi0 < nDccPerEe);
00176   assert(0 <= iDccCh0  && iDccCh0 < maxDccChs);
00177 
00178   assert(eeRuInterest_[iZ0][iDccPhi0][iDccCh0] == UNKNOWN
00179          || (0<= eeRuInterest_[iZ0][iDccPhi0][iDccCh0]
00180              && eeRuInterest_[iZ0][iDccPhi0][iDccCh0] <=7));
00181   
00182   return eeRuInterest_[iZ0][iDccPhi0][iDccCh0];
00183 }
00184 
00185 EcalSelectiveReadout::towerInterest_t&
00186 EcalSelectiveReadout::eeRuInterest(const EcalScDetId& scDetId){
00187   std::pair<int, int> dccAndDccCh = theElecMap->getDCCandSC(scDetId);
00188   const int iZ0 = (scDetId.zside()>0) ? 1: 0;
00189   const int iDcc0 = dccAndDccCh.first-1;
00190   const int iDccPhi0 = (iDcc0<9)?iDcc0:(iDcc0-45);
00191   const int iDccCh0 = dccAndDccCh.second-1;
00192   assert(0 <= iDccPhi0 && iDccPhi0 <= nDccPerEe);
00193   assert(0 <= iDccCh0  && iDccCh0 <= maxDccChs);
00194 
00195   assert(-1<= eeRuInterest_[iZ0][iDccPhi0][iDccCh0] && eeRuInterest_[iZ0][iDccPhi0][iDccCh0] <=7);
00196   
00197   return eeRuInterest_[iZ0][iDccPhi0][iDccCh0];
00198 }
00199 
00200 
00201 EcalSelectiveReadout::towerInterest_t
00202 EcalSelectiveReadout::getTowerInterest(const EcalTrigTowerDetId & tower) const 
00203 {
00204   // remember, array indices start at zero
00205   int iEta = tower.ieta()<0? tower.ieta() + nTriggerTowersInEta/2
00206     : tower.ieta() + nTriggerTowersInEta/2 -1;
00207   int iPhi = tower.iphi() - 1;
00208 
00209   assert(-1 <= towerInterest[iEta][iPhi] && towerInterest[iEta][iPhi] < 8);
00210   
00211   return towerInterest[iEta][iPhi];
00212 }
00213 
00214 void
00215 EcalSelectiveReadout::classifyTriggerTowers(const ttFlag_t ttFlags[nTriggerTowersInEta][nTriggerTowersInPhi])
00216 {
00217   //starts with a all low interest map:
00218   for(int iEta=0; iEta < (int)nTriggerTowersInEta; ++iEta){
00219     for(int iPhi=0; iPhi < (int)nTriggerTowersInPhi; ++iPhi){
00220       towerInterest[iEta][iPhi] = LOWINTEREST;
00221     }
00222   }
00223 
00224   for(int iEta=0; iEta < (int)nTriggerTowersInEta; ++iEta){
00225     for(int iPhi=0; iPhi < (int)nTriggerTowersInPhi; ++iPhi){
00226       //copy forced bit from ttFlags to towerInterests:
00227       towerInterest[iEta][iPhi] =  (towerInterest_t) (towerInterest[iEta][iPhi]
00228                                                       | (ttFlags[iEta][iPhi] & FORCED_MASK)) ;
00229       if((ttFlags[iEta][iPhi] & ~FORCED_MASK) == TTF_HIGH_INTEREST){
00230         //flags this tower as a center tower
00231         towerInterest[iEta][iPhi] = CENTER;
00232         //flags the neighbours of this tower
00233         for(int iEtaNeigh = std::max<int>(0,iEta-dEta);
00234             iEtaNeigh <= std::min<int>(nTriggerTowersInEta-1, iEta+dEta);
00235             ++iEtaNeigh){
00236           for(int iPhiNeigh = iPhi-dPhi;
00237               iPhiNeigh <= iPhi+dPhi;
00238               ++iPhiNeigh){
00239             //beware, iPhiNeigh must be moved to [0,72] interval
00240             //=> %nTriggerTowersInPhi required
00241             int iPhiNeigh_ = iPhiNeigh%(int)nTriggerTowersInPhi;
00242             if(iPhiNeigh_<0) {
00243               iPhiNeigh_ += nTriggerTowersInPhi;
00244             }
00245             combineFlags(towerInterest[iEtaNeigh][iPhiNeigh_],
00246                          NEIGHBOUR);
00247           }
00248         }
00249       } else if((ttFlags[iEta][iPhi] & ~FORCED_MASK) == TTF_MID_INTEREST){
00250         combineFlags(towerInterest[iEta][iPhi], SINGLE);
00251       }
00252     }
00253   }
00254 
00255   //dealing with pseudo-TT in the two innest eta-ring of the endcaps
00256   //=>choose the highest priority  SRF of the 2 pseudo-TT constituting
00257   //a TT. Note that for S and C, the 2 pseudo-TT must already have the
00258   //same mask.
00259   const size_t innerEtas[] = {0, 1,
00260                               nTriggerTowersInEta-2, nTriggerTowersInEta-1};
00261   for(size_t i=0; i < 4; ++i){
00262     size_t iEta = innerEtas[i];
00263     for(size_t iPhi = 0 ; iPhi < nTriggerTowersInPhi; iPhi+=2){
00264       const towerInterest_t srf = std::max(towerInterest[iEta][iPhi],
00265                                            towerInterest[iEta][iPhi+1]);
00266       towerInterest[iEta][iPhi] = srf;
00267       towerInterest[iEta][iPhi+1] = srf;
00268     }
00269   }
00270 }
00271 
00272 void EcalSelectiveReadout::printHeader(std::ostream & os) const{
00273   os << "#SRP flag map\n#\n"
00274     "# +-->Phi/Y " << srpFlagMarker[0] << ": low interest\n"
00275     "# |         " << srpFlagMarker[1] << ": single\n"
00276     "# |         " << srpFlagMarker[2] << ": neighbour\n"
00277     "# V Eta/X   " << srpFlagMarker[3] << ": center\n"
00278     "#           " << srpFlagMarker[4] << ": forced low interest\n"
00279     "#           " << srpFlagMarker[5] << ": forced single\n"
00280     "#           " << srpFlagMarker[6] << ": forced neighbout\n"
00281     "#           " << srpFlagMarker[7] << ": forced center\n"
00282     "#\n";
00283 }
00284 
00285 void EcalSelectiveReadout::print(std::ostream & os) const
00286 {
00287   //EE-
00288   printEndcap(0, os);
00289 
00290   //EB
00291   printBarrel(os);
00292 
00293   //EE+
00294   printEndcap(1, os);
00295 }
00296 
00297 
00298 void EcalSelectiveReadout::printBarrel(std::ostream & os) const
00299 {
00300   for(size_t iEta = nEndcapTriggerTowersInEta;
00301       iEta < nEndcapTriggerTowersInEta
00302         + nBarrelTriggerTowersInEta;
00303       ++iEta){
00304     for(size_t iPhi = 0; iPhi < nTriggerTowersInPhi; ++iPhi){
00305       towerInterest_t srFlag
00306         = towerInterest[iEta][iPhi];
00307       os << srpFlagMarker[srFlag];
00308     }
00309     os << "\n"; //one phi per line
00310   }
00311 }
00312 
00313 
00314 void EcalSelectiveReadout::printEndcap(int endcap, std::ostream & os) const
00315 {  
00316   for(size_t iX=0; iX<nSupercrystalXBins; ++iX){
00317     for(size_t iY=0; iY<nSupercrystalYBins; ++iY){
00318       towerInterest_t srFlag;
00319       char c;
00320       if(!EcalScDetId::validDetId(iX+1,iY+1,endcap>=1?1:-1)){
00321         //        srFlag = UNKNOWN;
00322         c = ' ';
00323       } else{
00324         srFlag
00325           = getSuperCrystalInterest(EcalScDetId(iX+1, iY+1, endcap>=1?1:-1));//supercrystalInterest[endcap][iX][iY];
00326         c = srFlag==UNKNOWN ? '?' : srpFlagMarker[srFlag];
00327       }
00328       os << c;
00329     }
00330     os << "\n"; //one Y supercystal column per line
00331   } //next supercrystal X-index
00332 }
00333 
00334 
00335 std::ostream & operator<<(std::ostream & os, const EcalSelectiveReadout & selectiveReadout)
00336 {
00337   selectiveReadout.print(os);
00338   return os;
00339 }
00340 
00341 
00342 void
00343 EcalSelectiveReadout::printDccChMap(std::ostream& os) const{
00344   for(int i=-1; i<=68; ++i){
00345     if((i+1)%10==0) os << "//";
00346     os << std::setw(2) << i << ": " << (char)('0'+i);
00347     if(i%10==9) os << "\n"; else os << " ";
00348   }
00349   
00350   os << "\n";
00351   
00352   for(int endcap = 0; endcap < 2; ++endcap){
00353     os << "Sc2DCCch0: " << (endcap?"EE+":"EE-") << "\n";
00354     for(size_t iY=0; iY<nSupercrystalYBins; ++iY){
00355       os << "Sc2DCCch0: ";
00356       for(size_t iX=0; iX<nSupercrystalXBins; ++iX){
00357         //if(iX) os << ",";
00358         if(!EcalScDetId::validDetId(iX+1,iY+1,endcap>=1?1:-1)){
00359           //os << std::setw(2) << -1;
00360           os << (char)('0'-1);
00361         } else{
00362           //os << std::setw(2) << theElecMap->getDCCandSC(EcalScDetId(iX+1, iY+1, endcap>0?1:-1)).second-1;
00363           os << (char)('0'+(theElecMap->getDCCandSC(EcalScDetId(iX+1, iY+1, endcap>0?1:-1)).second-1));
00364         }
00365       }
00366       os << "\n";
00367     }
00368     os << "\n";
00369   }
00370   os << "\n";
00371 }