CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoTauTag/RecoTau/plugins/PFRecoTauDiscriminationAgainstElectronDeadECAL.cc

Go to the documentation of this file.
00001 
00019 #include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h"
00020 #include "FWCore/Framework/interface/ESHandle.h"
00021 #include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h"
00022 #include "CondFormats/EcalObjects/interface/EcalChannelStatus.h"
00023 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00024 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00025 #include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h"
00026 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00027 #include "DataFormats/DetId/interface/DetId.h"
00028 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00029 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00030 #include "DataFormats/Math/interface/deltaR.h"
00031 #include "DataFormats/TauReco/interface/PFTauDiscriminator.h"
00032 
00033 #include <TMath.h>
00034 
00035 using namespace reco;
00036 
00037 class PFRecoTauDiscriminationAgainstElectronDeadECAL : public PFTauDiscriminationProducerBase  
00038 {
00039  public:
00040   explicit PFRecoTauDiscriminationAgainstElectronDeadECAL(const edm::ParameterSet& cfg)
00041     : PFTauDiscriminationProducerBase(cfg),
00042       moduleLabel_(cfg.getParameter<std::string>("@module_label")),
00043       isFirstEvent_(true)
00044   {
00045     minStatus_ = cfg.getParameter<uint32_t>("minStatus");
00046     dR_ = cfg.getParameter<double>("dR");
00047   }
00048   ~PFRecoTauDiscriminationAgainstElectronDeadECAL() {}
00049 
00050   void beginEvent(const edm::Event& evt, const edm::EventSetup& es)
00051   {
00052     updateBadTowers(es);
00053   }
00054 
00055   double discriminate(const PFTauRef& pfTau)
00056   {
00057     //std::cout << "<PFRecoTauDiscriminationAgainstElectronDeadECAL::discriminate>:" << std::endl;
00058     //std::cout << " moduleLabel = " << moduleLabel_ << std::endl;
00059     //std::cout << " #badTowers = " << badTowers_.size() << std::endl;
00060     double discriminator = 1.;
00061     for ( std::vector<towerInfo>::const_iterator badTower = badTowers_.begin();
00062           badTower != badTowers_.end(); ++badTower ) {
00063       if ( deltaR(badTower->eta_, badTower->phi_, pfTau->eta(), pfTau->phi()) < dR_ ) discriminator = 0.;
00064     }
00065     //std::cout << "--> discriminator = " << discriminator << std::endl;
00066     return discriminator;
00067   }
00068 
00069  private:
00070   void updateBadTowers(const edm::EventSetup& es) 
00071   {
00072     // NOTE: modified version of SUSY CAF code
00073     //         UserCode/SusyCAF/plugins/SusyCAF_EcalDeadChannels.cc
00074     const uint32_t channelStatusId = es.get<EcalChannelStatusRcd>().cacheIdentifier();
00075     const uint32_t caloGeometryId  = es.get<CaloGeometryRecord>().cacheIdentifier();
00076     const uint32_t idealGeometryId = es.get<IdealGeometryRecord>().cacheIdentifier();
00077     
00078     if ( channelStatusId == channelStatusId_cache_ && caloGeometryId == caloGeometryId_cache_ && idealGeometryId == idealGeometryId_cache_ && !isFirstEvent_ ) return;
00079 
00080     edm::ESHandle<EcalChannelStatus> channelStatus;    
00081     es.get<EcalChannelStatusRcd>().get(channelStatus);
00082     channelStatusId_cache_ = channelStatusId;  
00083 
00084     edm::ESHandle<CaloGeometry> caloGeometry;         
00085     es.get<CaloGeometryRecord>().get(caloGeometry);
00086     caloGeometryId_cache_ = caloGeometryId;  
00087 
00088     edm::ESHandle<EcalTrigTowerConstituentsMap> ttMap;
00089     es.get<IdealGeometryRecord>().get(ttMap);
00090     idealGeometryId_cache_ = idealGeometryId;
00091 
00092     std::map<uint32_t,unsigned> nBadCrystals, maxStatus;
00093     std::map<uint32_t,double> sumEta, sumPhi;
00094     
00095     loopXtals<EBDetId>(nBadCrystals, maxStatus, sumEta, sumPhi, channelStatus.product(), caloGeometry.product(), ttMap.product());
00096     loopXtals<EEDetId>(nBadCrystals, maxStatus, sumEta, sumPhi, channelStatus.product(), caloGeometry.product(), ttMap.product());
00097     
00098     badTowers_.clear();
00099     for ( std::map<uint32_t, unsigned>::const_iterator it = nBadCrystals.begin(); 
00100           it != nBadCrystals.end(); ++it ) {
00101       uint32_t key = it->first;
00102       badTowers_.push_back(towerInfo(key, it->second, maxStatus[key], sumEta[key]/it->second, sumPhi[key]/it->second));
00103     }
00104 
00105     isFirstEvent_ = false;
00106   }
00107   
00108   template <class Id>
00109   void loopXtals(std::map<uint32_t, unsigned>& nBadCrystals,
00110                  std::map<uint32_t, unsigned>& maxStatus,
00111                  std::map<uint32_t, double>& sumEta,
00112                  std::map<uint32_t, double>& sumPhi ,
00113                  const EcalChannelStatus* channelStatus,
00114                  const CaloGeometry* caloGeometry,
00115                  const EcalTrigTowerConstituentsMap* ttMap) const 
00116   {
00117     // NOTE: modified version of SUSY CAF code
00118     //         UserCode/SusyCAF/plugins/SusyCAF_EcalDeadChannels.cc
00119     for ( int i = 0; i < Id::kSizeForDenseIndexing; ++i ) {
00120       Id id = Id::unhashIndex(i);  
00121       if ( id == Id(0) ) continue;
00122       EcalChannelStatusMap::const_iterator it = channelStatus->getMap().find(id.rawId());
00123       unsigned status = ( it == channelStatus->end() ) ? 
00124         0 : (it->getStatusCode() & statusMask_);
00125       if ( status >= minStatus_ ) {
00126         const GlobalPoint& point = caloGeometry->getPosition(id);
00127         uint32_t key = ttMap->towerOf(id);
00128         maxStatus[key] = TMath::Max(status, maxStatus[key]);
00129         ++nBadCrystals[key];
00130         sumEta[key] += point.eta();
00131         sumPhi[key] += point.phi();
00132       }
00133     }
00134   }
00135 
00136   struct towerInfo 
00137   {
00138     towerInfo(uint32_t id, unsigned nBad, unsigned maxStatus, double eta, double phi)
00139       : id_(id), 
00140         nBad_(nBad), 
00141         maxStatus_(maxStatus), 
00142         eta_(eta), 
00143         phi_(phi) 
00144     {}
00145     uint32_t id_;
00146     unsigned nBad_;
00147     unsigned maxStatus_;
00148     double eta_;
00149     double phi_;
00150   };
00151   typedef ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiE4D<double> > PolarLorentzVector;
00152 
00153   std::string moduleLabel_;
00154   unsigned minStatus_;
00155   double dR_;
00156 
00157   std::vector<towerInfo> badTowers_;
00158   static const uint16_t statusMask_ = 0x1F;
00159 
00160   uint32_t channelStatusId_cache_;
00161   uint32_t caloGeometryId_cache_;
00162   uint32_t idealGeometryId_cache_;
00163   bool isFirstEvent_;
00164 };
00165 
00166 DEFINE_FWK_MODULE(PFRecoTauDiscriminationAgainstElectronDeadECAL);