CMS 3D CMS Logo

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