CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoLocalCalo/EcalRecProducers/plugins/EcalRecHitWorkerRecover.cc

Go to the documentation of this file.
00001 #include "RecoLocalCalo/EcalRecProducers/plugins/EcalRecHitWorkerRecover.h"
00002 
00003 #include "FWCore/Framework/interface/EventSetup.h"
00004 #include "FWCore/Framework/interface/Event.h"
00005 #include "CondFormats/DataRecord/interface/EcalIntercalibConstantsRcd.h"
00006 #include "CondFormats/DataRecord/interface/EcalTimeCalibConstantsRcd.h"
00007 #include "CondFormats/DataRecord/interface/EcalADCToGeVConstantRcd.h"
00008 #include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h"
00009 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
00010 #include "DataFormats/EcalDetId/interface/EcalScDetId.h"
00011 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00012 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00013 #include "Geometry/EcalMapping/interface/EcalMappingRcd.h"
00014 
00015 #include "CondFormats/EcalObjects/interface/EcalTimeCalibConstants.h"
00016 #include "CalibCalorimetry/EcalLaserCorrection/interface/EcalLaserDbRecord.h"
00017 
00018 #include "RecoLocalCalo/EcalDeadChannelRecoveryAlgos/interface/EcalDeadChannelRecoveryAlgos.h"
00019 
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021 
00022 //$Id: EcalRecHitWorkerRecover.cc,v 1.30 2011/08/03 21:37:38 argiro Exp $
00023 
00024 EcalRecHitWorkerRecover::EcalRecHitWorkerRecover(const edm::ParameterSet&ps) :
00025         EcalRecHitWorkerBaseClass(ps)
00026 {
00027         rechitMaker_ = new EcalRecHitSimpleAlgo();
00028         // isolated channel recovery
00029         singleRecoveryMethod_    = ps.getParameter<std::string>("singleChannelRecoveryMethod");
00030         singleRecoveryThreshold_ = ps.getParameter<double>("singleChannelRecoveryThreshold");
00031         killDeadChannels_        = ps.getParameter<bool>("killDeadChannels");
00032         recoverEBIsolatedChannels_ = ps.getParameter<bool>("recoverEBIsolatedChannels");
00033         recoverEEIsolatedChannels_ = ps.getParameter<bool>("recoverEEIsolatedChannels");
00034         recoverEBVFE_ = ps.getParameter<bool>("recoverEBVFE");
00035         recoverEEVFE_ = ps.getParameter<bool>("recoverEEVFE");
00036         recoverEBFE_ = ps.getParameter<bool>("recoverEBFE");
00037         recoverEEFE_ = ps.getParameter<bool>("recoverEEFE");
00038 
00039         dbStatusToBeExcludedEE_ = ps.getParameter<std::vector<int> >("dbStatusToBeExcludedEE");
00040 
00041         tpDigiCollection_        = ps.getParameter<edm::InputTag>("triggerPrimitiveDigiCollection");
00042         logWarningEtThreshold_EB_FE_ = ps.getParameter<double>("logWarningEtThreshold_EB_FE");
00043         logWarningEtThreshold_EE_FE_ = ps.getParameter<double>("logWarningEtThreshold_EE_FE");
00044 }
00045 
00046 
00047 void EcalRecHitWorkerRecover::set(const edm::EventSetup& es)
00048 {
00049  
00050         es.get<EcalLaserDbRecord>().get(laser);
00051         es.get<CaloTopologyRecord>().get(caloTopology_);
00052         ecalScale_.setEventSetup( es );
00053         es.get<EcalMappingRcd>().get(pEcalMapping_);
00054         ecalMapping_ = pEcalMapping_.product();
00055         // geometry...
00056         es.get<EcalBarrelGeometryRecord>().get("EcalBarrel",pEBGeom_);
00057         es.get<EcalEndcapGeometryRecord>().get("EcalEndcap",pEEGeom_);
00058         es.get<CaloGeometryRecord>().get(caloGeometry_);
00059         es.get<EcalChannelStatusRcd>().get(chStatus_);
00060         geo_ = caloGeometry_.product();
00061         ebGeom_ = pEBGeom_.product();
00062         eeGeom_ = pEEGeom_.product();
00063         es.get<IdealGeometryRecord>().get(ttMap_);
00064         recoveredDetIds_EB_.clear();
00065         recoveredDetIds_EE_.clear();
00066         tpgscale_.setEventSetup(es);
00067 }
00068 
00069 
00070 bool
00071 EcalRecHitWorkerRecover::run( const edm::Event & evt, 
00072                 const EcalUncalibratedRecHit& uncalibRH,
00073                 EcalRecHitCollection & result )
00074 {
00075         DetId detId=uncalibRH.id();
00076         uint32_t flags = uncalibRH.recoFlag();
00077 
00078         // get laser coefficient
00079         //float lasercalib = laser->getLaserCorrection( detId, evt.time());
00080 
00081         // killDeadChannels_ = true, means explicitely kill dead channels even if the recovered energies are computed in the code
00082         // if you don't want to store the recovered energies in the rechit you can produce LogWarnings if logWarningEtThreshold_EB(EE)_FE>0 
00083         // logWarningEtThreshold_EB(EE)_FE_<0 will not compute the recovered energies at all (faster)
00084 
00085         if ( killDeadChannels_ ) {
00086                 if (    (flags == EcalRecHitWorkerRecover::EB_single && !recoverEBIsolatedChannels_)
00087                      || (flags == EcalRecHitWorkerRecover::EE_single && !recoverEEIsolatedChannels_)
00088                      || (flags == EcalRecHitWorkerRecover::EB_VFE && !recoverEBVFE_)
00089                      || (flags == EcalRecHitWorkerRecover::EE_VFE && !recoverEEVFE_)
00090                      ) {
00091                         EcalRecHit hit( detId, 0., 0., EcalRecHit::kDead );
00092                         hit.setFlag( EcalRecHit::kDead)  ;
00093                         insertRecHit( hit, result); // insert trivial rechit with kDead flag
00094                         return true;
00095                 } 
00096                 if ( flags == EcalRecHitWorkerRecover::EB_FE && !recoverEBFE_) {
00097                         EcalTrigTowerDetId ttDetId( ((EBDetId)detId).tower() );
00098                         std::vector<DetId> vid = ttMap_->constituentsOf( ttDetId );
00099                         for ( std::vector<DetId>::const_iterator dit = vid.begin(); dit != vid.end(); ++dit ) {
00100                                 EcalRecHit hit( (*dit), 0., 0., EcalRecHit::kDead );
00101                                 hit.setFlag( EcalRecHit::kDead ) ;
00102                                 insertRecHit( hit, result ); // insert trivial rechit with kDead flag
00103                         }
00104                         if(logWarningEtThreshold_EB_FE_<0)return true; // if you don't want log warning just return true
00105                 }
00106                 if ( flags == EcalRecHitWorkerRecover::EE_FE && !recoverEEFE_) {
00107                         EEDetId id( detId );
00108                         EcalScDetId sc( 1+(id.ix()-1)/5, 1+(id.iy()-1)/5, id.zside() );
00109                         std::vector<DetId> eeC;
00110                         for(int dx=1; dx<=5; ++dx){
00111                                 for(int dy=1; dy<=5; ++dy){
00112                                         int ix = (sc.ix()-1)*5 + dx;
00113                                         int iy = (sc.iy()-1)*5 + dy;
00114                                         int iz = sc.zside();
00115                                         if(EEDetId::validDetId(ix, iy, iz)){
00116                                                 eeC.push_back(EEDetId(ix, iy, iz));
00117                                         }
00118                                 }
00119                         }
00120                         for ( size_t i = 0; i < eeC.size(); ++i ) {
00121                                 EcalRecHit hit( eeC[i], 0., 0., EcalRecHit::kDead );
00122                                 hit.setFlag( EcalRecHit::kDead ) ;
00123                                 insertRecHit( hit, result ); // insert trivial rechit with kDead flag
00124                         }
00125                         if(logWarningEtThreshold_EE_FE_<0)   return true; // if you don't want log warning just return true
00126                 }
00127         }
00128 
00129         if ( flags == EcalRecHitWorkerRecover::EB_single ) {
00130                 // recover as single dead channel
00131                 const EcalRecHitCollection * hit_collection = &result;
00132                 EcalDeadChannelRecoveryAlgos deadChannelCorrector(caloTopology_.product());
00133 
00134                 // channel recovery
00135                 EcalRecHit hit = deadChannelCorrector.correct( detId, hit_collection, singleRecoveryMethod_, singleRecoveryThreshold_ );
00136                 EcalRecHitCollection::const_iterator ti = result.find( detId );
00137                 if ( hit.energy() != 0 ) {
00138                   hit.setFlag( EcalRecHit::kNeighboursRecovered ) ;
00139                 } else {
00140                   // recovery failed
00141                   hit.setFlag( EcalRecHit::kDead ) ;
00142                 }
00143                 insertRecHit( hit, result );
00144         } else if ( flags == EcalRecHitWorkerRecover::EB_VFE ) {
00145                 // recover as dead VFE
00146                 EcalRecHit hit( detId, 0., 0.);
00147                 hit.setFlag( EcalRecHit::kDead ) ;
00148                 // recovery not implemented
00149                 insertRecHit( hit, result );
00150         } else if ( flags == EcalRecHitWorkerRecover::EB_FE ) {
00151                 // recover as dead TT
00152                 EcalTrigTowerDetId ttDetId( ((EBDetId)detId).tower() );
00153                 edm::Handle<EcalTrigPrimDigiCollection> pTPDigis;
00154                 evt.getByLabel(tpDigiCollection_, pTPDigis);
00155                 const EcalTrigPrimDigiCollection * tpDigis = 0;
00156                 if ( pTPDigis.isValid() ) {
00157                         tpDigis = pTPDigis.product();
00158                 } else {
00159                         edm::LogError("EcalRecHitWorkerRecover") << "Can't get the product " << tpDigiCollection_.instance() 
00160                                 << " with label " << tpDigiCollection_.label();
00161                         return false;
00162                 }
00163                 EcalTrigPrimDigiCollection::const_iterator tp = tpDigis->find( ttDetId );
00164                 // recover the whole trigger tower
00165                 if ( tp != tpDigis->end() ) {
00166                         //std::vector<DetId> vid = ecalMapping_->dccTowerConstituents( ecalMapping_->DCCid( ttDetId ), ecalMapping_->iTT( ttDetId ) );
00167                         std::vector<DetId> vid = ttMap_->constituentsOf( ttDetId );
00168                         float tpEt  = ecalScale_.getTPGInGeV( tp->compressedEt(), tp->id() );
00169                         float tpEtThreshEB = logWarningEtThreshold_EB_FE_;
00170                         if(tpEt>tpEtThreshEB){
00171                                 edm::LogWarning("EnergyInDeadEB_FE")<<"TP energy in the dead TT = "<<tpEt<<" at "<<ttDetId;
00172                         }
00173                         if ( !killDeadChannels_ || recoverEBFE_ ) {  
00174                                 // democratic energy sharing
00175                                 for ( std::vector<DetId>::const_iterator dit = vid.begin(); dit != vid.end(); ++dit ) {
00176                                         if (alreadyInserted(*dit)) continue;
00177                                         float theta = ebGeom_->getGeometry(*dit)->getPosition().theta();
00178                                         float tpEt  = ecalScale_.getTPGInGeV( tp->compressedEt(), tp->id() );
00179                                         EcalRecHit hit( *dit, tpEt / (float)vid.size() / sin(theta), 0.);
00180                                         hit.setFlag( EcalRecHit::kTowerRecovered ) ;
00181                                         if ( tp->compressedEt() == 0xFF ) hit.setFlag( EcalRecHit::kTPSaturated );
00182                                         if ( tp->sFGVB() ) hit.setFlag( EcalRecHit::kL1SpikeFlag );
00183                                         insertRecHit( hit, result );
00184                                 }
00185                         }
00186                 } else {
00187                         // tp not found => recovery failed
00188                         std::vector<DetId> vid = ttMap_->constituentsOf( ttDetId );
00189                         for ( std::vector<DetId>::const_iterator dit = vid.begin(); dit != vid.end(); ++dit ) {
00190                           if (alreadyInserted(*dit)) continue;
00191                           EcalRecHit hit( *dit,0., 0. );
00192                                 hit.setFlag( EcalRecHit::kDead ) ;
00193                                 EcalRecHitCollection::iterator it = result.find( *dit );
00194                                 insertRecHit( hit, result );
00195                         }
00196                 }
00197         } else if ( flags == EcalRecHitWorkerRecover::EE_FE ) {
00198                         // Structure for recovery:
00199                         // ** SC --> EEDetId constituents (eeC) --> associated Trigger Towers (aTT) --> EEDetId constituents (aTTC)
00200                         // ** energy for a SC EEDetId = [ sum_aTT(energy) - sum_aTTC(energy) ] / N_eeC
00201                         // .. i.e. the total energy of the TTs covering the SC minus 
00202                         // .. the energy of the recHits in the TTs but not in the SC
00203                         //std::vector<DetId> vid = ecalMapping_->dccTowerConstituents( ecalMapping_->DCCid( ttDetId ), ecalMapping_->iTT( ttDetId ) );
00204                         // due to lack of implementation of the EcalTrigTowerDetId ix,iy methods in EE we compute Et recovered energies (in EB we compute E)
00205 
00206                         EEDetId eeId( detId );
00207                         EcalScDetId sc( (eeId.ix()-1)/5+1, (eeId.iy()-1)/5+1, eeId.zside() );
00208                         std::set<DetId> eeC;
00209                         for(int dx=1; dx<=5; ++dx){
00210                                 for(int dy=1; dy<=5; ++dy){
00211                                         int ix = (sc.ix()-1)*5 + dx;
00212                                         int iy = (sc.iy()-1)*5 + dy;
00213                                         int iz = sc.zside();
00214                                         if(EEDetId::validDetId(ix, iy, iz)){
00215                                           EEDetId id(ix, iy, iz);
00216                                           if (checkChannelStatus(id,dbStatusToBeExcludedEE_)){
00217                                                 eeC.insert(id);
00218                                           } // check status
00219                                         }
00220                                 }
00221                         }
00222                         
00223                         edm::Handle<EcalTrigPrimDigiCollection> pTPDigis;
00224                         evt.getByLabel(tpDigiCollection_, pTPDigis);
00225                         const EcalTrigPrimDigiCollection * tpDigis = 0;
00226                         if ( pTPDigis.isValid() ) {
00227                                 tpDigis = pTPDigis.product();
00228                         } else {
00229                                 edm::LogError("EcalRecHitWorkerRecover") << "Can't get the product " << tpDigiCollection_.instance() 
00230                                         << " with label " << tpDigiCollection_.label();
00231                                 return false;
00232                         }
00233                         // associated trigger towers
00234                         std::set<EcalTrigTowerDetId> aTT;
00235                         for ( std::set<DetId>::const_iterator it = eeC.begin(); it!=eeC.end(); ++it ) {
00236                                 aTT.insert( ttMap_->towerOf( *it ) );
00237                         }
00238                         // associated trigger towers: total energy
00239                         float totE = 0;
00240                         // associated trigger towers: EEDetId constituents
00241                         std::set<DetId> aTTC;
00242                         bool atLeastOneTPSaturated = false;
00243                         for ( std::set<EcalTrigTowerDetId>::const_iterator it = aTT.begin(); it != aTT.end(); ++it ) {
00244                                 // add the energy of this trigger tower
00245                                 EcalTrigPrimDigiCollection::const_iterator itTP = tpDigis->find( *it );
00246                                 if ( itTP != tpDigis->end() ) {
00247                                         EcalTrigTowerDetId ttId = itTP->id();
00248 
00249                                         std::vector<DetId> v = ttMap_->constituentsOf( *it );
00250 
00251                                         // from the constituents, remove dead channels
00252                                         std::vector<DetId>::iterator ttcons = v.begin();
00253                                         while (ttcons != v.end()){
00254                                           if (!checkChannelStatus(*ttcons,dbStatusToBeExcludedEE_)){
00255                                                 ttcons=v.erase(ttcons);
00256                                           } else {
00257                                             ++ttcons;
00258                                           }
00259                                         }// while 
00260 
00261                                         if ( itTP->compressedEt() == 0xFF ){ // In the case of a saturated trigger tower, a fraction
00262                                           atLeastOneTPSaturated = true; //of the saturated energy is put in: number of xtals in dead region/total xtals in TT *63.75
00263                                                 
00264                                           //Alternative recovery algorithm that I will now investigate.
00265                                           //Estimate energy sums the energy in the working channels, then decides how much energy
00266                                           //to put here depending on that. Duncan 20101203
00267                                           
00268                                           totE += estimateEnergy(itTP->id().ietaAbs(), &result, eeC, v);
00269                                           
00270                                           /* 
00271                                              These commented out lines use
00272                                              64GeV*fraction of the TT overlapping the dead FE
00273                                             
00274                                           int count = 0;
00275                                           for (std::vector<DetId>::const_iterator idsit = v.begin(); idsit != v.end(); ++ idsit){
00276                                           std::set<DetId>::const_iterator itFind = eeC.find(*idsit);
00277                                           if (itFind != eeC.end())
00278                                           ++count;
00279                                           }
00280                                           //std::cout << count << ", " << v.size() << std::endl;
00281                                           totE+=((float)count/(float)v.size())* ((it->ietaAbs()>26)?2*ecalScale_.getTPGInGeV( itTP->compressedEt(), itTP->id() ):ecalScale_.getTPGInGeV( itTP->compressedEt(), itTP->id() ));*/
00282                                         }
00283                                         else {totE += ((it->ietaAbs()>26)?2:1)*ecalScale_.getTPGInGeV( itTP->compressedEt(), itTP->id() );}
00284                                         
00285                                 
00286                                         // get the trigger tower constituents
00287                                         
00288                                         if (itTP->compressedEt() == 0){ // If there's no energy in TT, the constituents are removed from the recovery.
00289                                                  for (size_t i = 0 ; i < v.size(); ++i)
00290                                                          eeC.erase(v[i]);
00291                                         }
00292                                         else if (itTP->compressedEt()!=0xFF){ //If it's saturated the energy has already been determined, so we do not want to subtract any channels
00293                                          for ( size_t j = 0; j < v.size(); ++j ) {
00294                                                  aTTC.insert( v[j] );
00295                                          }
00296                                         }
00297                                     
00298                                 }
00299                         }
00300                         // remove crystals of dead SC
00301                         // (this step is not needed if sure that SC crystals are not 
00302                         // in the recHit collection)
00303                         
00304                         for ( std::set<DetId>::const_iterator it = eeC.begin(); it != eeC.end(); ++it ) {
00305                           aTTC.erase(*it);
00306                         }
00307                         // compute the total energy for the dead SC
00308                         const EcalRecHitCollection * hits = &result;
00309                         for ( std::set<DetId>::const_iterator it = aTTC.begin(); it != aTTC.end(); ++it ) {
00310                                 EcalRecHitCollection::const_iterator jt = hits->find( *it );
00311                                 if ( jt != hits->end() ) {
00312                                   float energy = jt->energy(); // Correct conversion to Et
00313                                   float eta = geo_->getPosition(jt->id()).eta();
00314                                   float pf = 1.0/cosh(eta);
00315                                   //float theta = eeGeom_->getGeometry( *it )->getPosition().theta();
00316                                   // use Et instead of E, consistent with the Et estimation of the associated TT
00317                                   totE -= energy*pf;
00318                                 }
00319                         }
00320                         
00321 
00322                         float scEt = totE;
00323                         float scEtThreshEE = logWarningEtThreshold_EE_FE_;
00324                         if(scEt>scEtThreshEE){
00325                                 edm::LogWarning("EnergyInDeadEE_FE")<<"TP energy in the dead TT = "<<scEt<<" at "<<sc;
00326                         }
00327 
00328                         // assign the energy to the SC crystals
00329                         if ( !killDeadChannels_ || recoverEEFE_ ) { // if eeC is empty, i.e. there are no hits 
00330                                                                     // in the tower, nothing is returned. No negative values from noise.
00331                           for ( std::set<DetId>::const_iterator it = eeC.begin(); it != eeC.end(); ++it ) {
00332 
00333                             float eta = geo_->getPosition(*it).eta(); //Convert back to E from Et for the recovered hits
00334                             float pf = 1.0/cosh(eta);
00335                             EcalRecHit hit( *it, totE / ((float)eeC.size()*pf), 0);
00336                             
00337                             if (atLeastOneTPSaturated) hit.setFlag(EcalRecHit::kTPSaturated );                            
00338                             hit.setFlag(EcalRecHit::kTowerRecovered); 
00339                             insertRecHit( hit, result );
00340                             
00341                           }// for
00342                         }// if 
00343         }
00344         return true;
00345 }
00346 
00347 float EcalRecHitWorkerRecover::estimateEnergy(int ieta, EcalRecHitCollection* hits, std::set<DetId> sId, std::vector<DetId> vId  ) {
00348         
00349         float xtalE=0;
00350         int count = 0;
00351         for (std::vector<DetId>::const_iterator vIdit = vId.begin(); vIdit != vId.end(); ++ vIdit){
00352                 std::set<DetId>::const_iterator sIdit = sId.find(*vIdit);
00353                 if (sIdit==sId.end()){
00354                         float energy = hits->find(*vIdit)->energy();
00355                         float eta = geo_->getPosition(*vIdit).eta();
00356                         float pf = 1.0/cosh(eta);
00357                         xtalE += energy*pf;
00358                         count++;
00359                 }
00360         }
00361         
00362         if (count==0) {                    // If there are no overlapping crystals return saturated value.
00363 
00364           double etsat = tpgscale_.getTPGInGeV(0xFF,
00365                                                ttMap_->towerOf(*vId.begin())); // get saturation value for the first
00366                                                                                // constituent, for the others it's the same 
00367 
00368           return etsat/cosh(ieta)*(ieta>26?2:1); // account for duplicated TT in EE for ieta>26
00369         }
00370         else return xtalE*((vId.size()/(float)count) - 1)*(ieta>26?2:1);
00371         
00372         
00373 }
00374 
00375 
00376 void EcalRecHitWorkerRecover::insertRecHit( const EcalRecHit &hit, EcalRecHitCollection &collection )
00377 {
00378         // skip already inserted DetId's and raise a log warning
00379         if ( alreadyInserted( hit.id() ) ) {
00380           edm::LogWarning("EcalRecHitWorkerRecover") << "DetId already recovered! Skipping...";
00381                 return;
00382         }
00383         EcalRecHitCollection::iterator it = collection.find( hit.id() );
00384         if ( it == collection.end() ) {
00385                 // insert the hit in the collection
00386                 collection.push_back( hit );
00387         } else {
00388                 // overwrite existing recHit
00389                 *it = hit;
00390         }
00391         if ( hit.id().subdetId() == EcalBarrel ) {
00392                 recoveredDetIds_EB_.insert( hit.id() );
00393         } else if ( hit.id().subdetId() == EcalEndcap ) {
00394                 recoveredDetIds_EE_.insert( hit.id() );
00395         } else {
00396                 edm::LogError("EcalRecHitWorkerRecover::InvalidDetId") << "Invalid DetId " << hit.id().rawId();
00397         }
00398 }
00399 
00400 
00401 bool EcalRecHitWorkerRecover::alreadyInserted( const DetId & id )
00402 {
00403         bool res = false;
00404         if ( id.subdetId() == EcalBarrel ) {
00405                 res = ( recoveredDetIds_EB_.find( id ) != recoveredDetIds_EB_.end() );
00406         } else if ( id.subdetId() == EcalEndcap ) {
00407                 res = ( recoveredDetIds_EE_.find( id ) != recoveredDetIds_EE_.end() );
00408         } else {
00409                 edm::LogError("EcalRecHitWorkerRecover::InvalidDetId") << "Invalid DetId " << id.rawId();
00410         }
00411         return res;
00412 }
00413 
00414 // In the future, this will be used to calibrate the TT energy. There is a dependance on
00415 // eta at lower energies that can be corrected for here after more validation.
00416 float EcalRecHitWorkerRecover::recCheckCalib(float eTT, int ieta){
00417          
00418          return eTT;
00419          
00420 }
00421 
00422 // return false is the channel has status  in the list of statusestoexclude
00423 // true otherwise (channel ok)
00424 bool EcalRecHitWorkerRecover::checkChannelStatus(const DetId& id, 
00425                                                  const std::vector<int>& statusestoexclude){
00426   
00427 
00428   if (!chStatus_.isValid())     
00429     edm::LogError("ObjectNotFound") << "Channel Status not set"; 
00430   
00431   
00432   EcalChannelStatus::const_iterator chIt = chStatus_->find( id );
00433   uint16_t dbStatus = 0;
00434   if ( chIt != chStatus_->end() ) {
00435     dbStatus = chIt->getStatusCode();
00436   } else {
00437     edm::LogError("ObjectNotFound") << "No channel status found for xtal " 
00438                                     << id.rawId() 
00439                                     << "! something wrong with EcalChannelStatus in your DB? ";
00440   }
00441   
00442   for (std::vector<int>::const_iterator status = statusestoexclude.begin();
00443        status!= statusestoexclude.end(); ++status){
00444     
00445     if ( *status == dbStatus) return false;
00446     
00447   }
00448 
00449   return true;
00450 }
00451 
00452 
00453 #include "FWCore/Framework/interface/MakerMacros.h"
00454 #include "RecoLocalCalo/EcalRecProducers/interface/EcalRecHitWorkerFactory.h"
00455 DEFINE_EDM_PLUGIN( EcalRecHitWorkerFactory, EcalRecHitWorkerRecover, "EcalRecHitWorkerRecover" );