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
00023
00024 EcalRecHitWorkerRecover::EcalRecHitWorkerRecover(const edm::ParameterSet&ps) :
00025 EcalRecHitWorkerBaseClass(ps)
00026 {
00027 rechitMaker_ = new EcalRecHitSimpleAlgo();
00028
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
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
00079
00080
00081
00082
00083
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);
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 );
00103 }
00104 if(logWarningEtThreshold_EB_FE_<0)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 );
00124 }
00125 if(logWarningEtThreshold_EE_FE_<0) return true;
00126 }
00127 }
00128
00129 if ( flags == EcalRecHitWorkerRecover::EB_single ) {
00130
00131 const EcalRecHitCollection * hit_collection = &result;
00132 EcalDeadChannelRecoveryAlgos deadChannelCorrector(caloTopology_.product());
00133
00134
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
00141 hit.setFlag( EcalRecHit::kDead ) ;
00142 }
00143 insertRecHit( hit, result );
00144 } else if ( flags == EcalRecHitWorkerRecover::EB_VFE ) {
00145
00146 EcalRecHit hit( detId, 0., 0.);
00147 hit.setFlag( EcalRecHit::kDead ) ;
00148
00149 insertRecHit( hit, result );
00150 } else if ( flags == EcalRecHitWorkerRecover::EB_FE ) {
00151
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
00165 if ( tp != tpDigis->end() ) {
00166
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
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
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
00199
00200
00201
00202
00203
00204
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 }
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
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
00239 float totE = 0;
00240
00241 std::set<DetId> aTTC;
00242 bool atLeastOneTPSaturated = false;
00243 for ( std::set<EcalTrigTowerDetId>::const_iterator it = aTT.begin(); it != aTT.end(); ++it ) {
00244
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
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 }
00260
00261 if ( itTP->compressedEt() == 0xFF ){
00262 atLeastOneTPSaturated = true;
00263
00264
00265
00266
00267
00268 totE += estimateEnergy(itTP->id().ietaAbs(), &result, eeC, v);
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 }
00283 else {totE += ((it->ietaAbs()>26)?2:1)*ecalScale_.getTPGInGeV( itTP->compressedEt(), itTP->id() );}
00284
00285
00286
00287
00288 if (itTP->compressedEt() == 0){
00289 for (size_t i = 0 ; i < v.size(); ++i)
00290 eeC.erase(v[i]);
00291 }
00292 else if (itTP->compressedEt()!=0xFF){
00293 for ( size_t j = 0; j < v.size(); ++j ) {
00294 aTTC.insert( v[j] );
00295 }
00296 }
00297
00298 }
00299 }
00300
00301
00302
00303
00304 for ( std::set<DetId>::const_iterator it = eeC.begin(); it != eeC.end(); ++it ) {
00305 aTTC.erase(*it);
00306 }
00307
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();
00313 float eta = geo_->getPosition(jt->id()).eta();
00314 float pf = 1.0/cosh(eta);
00315
00316
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
00329 if ( !killDeadChannels_ || recoverEEFE_ ) {
00330
00331 for ( std::set<DetId>::const_iterator it = eeC.begin(); it != eeC.end(); ++it ) {
00332
00333 float eta = geo_->getPosition(*it).eta();
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 }
00342 }
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) {
00363
00364 double etsat = tpgscale_.getTPGInGeV(0xFF,
00365 ttMap_->towerOf(*vId.begin()));
00366
00367
00368 return etsat/cosh(ieta)*(ieta>26?2:1);
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
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
00386 collection.push_back( hit );
00387 } else {
00388
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
00415
00416 float EcalRecHitWorkerRecover::recCheckCalib(float eTT, int ieta){
00417
00418 return eTT;
00419
00420 }
00421
00422
00423
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" );