00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <vector>
00010 #include <functional>
00011
00012
00013 #include <Math/VectorUtil.h>
00014
00015
00016 #include "RecoEgamma/EgammaIsolationAlgos/plugins/EgammaRecHitExtractor.h"
00017 #include "DataFormats/DetId/interface/DetId.h"
00018 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00019 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00020 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00021 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00022 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00023 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00024 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
00025 #include "RecoCaloTools/MetaCollections/interface/CaloRecHitMetaCollections.h"
00026 #include "DataFormats/Math/interface/deltaPhi.h"
00027 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
00028 #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h"
00029 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00030 #include "DataFormats/EgammaReco/interface/BasicClusterFwd.h"
00031
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033
00034 using namespace std;
00035 using namespace egammaisolation;
00036 using namespace reco::isodeposit;
00037
00038 EgammaRecHitExtractor::EgammaRecHitExtractor(const edm::ParameterSet& par) :
00039 etMin_(par.getParameter<double>("etMin")),
00040 energyMin_(par.getParameter<double>("energyMin")),
00041 extRadius_(par.getParameter<double>("extRadius")),
00042 intRadius_(par.getParameter<double>("intRadius")),
00043 intStrip_(par.getParameter<double>("intStrip")),
00044 barrelEcalHitsTag_(par.getParameter<edm::InputTag>("barrelEcalHits")),
00045 endcapEcalHitsTag_(par.getParameter<edm::InputTag>("endcapEcalHits")),
00046 fakeNegativeDeposit_(par.getParameter<bool>("subtractSuperClusterEnergy")),
00047 tryBoth_(par.getParameter<bool>("tryBoth")),
00048 vetoClustered_(par.getParameter<bool>("vetoClustered")),
00049 sameTag_(false),
00050 severityLevelCut_(par.getParameter<int>("severityLevelCut")),
00051 severityRecHitThreshold_(par.getParameter<double>("severityRecHitThreshold")),
00052 spIdString_(par.getParameter<std::string>("spikeIdString")),
00053 spIdThreshold_(par.getParameter<double>("spikeIdThreshold")),
00054 v_chstatus_(par.getParameter<std::vector<int> >("recHitFlagsToBeExcluded"))
00055 {
00056
00057 if ( !spIdString_.compare("kE1OverE9") ) spId_ = EcalSeverityLevelAlgo::kE1OverE9;
00058 else if( !spIdString_.compare("kSwissCross") ) spId_ = EcalSeverityLevelAlgo::kSwissCross;
00059 else if( !spIdString_.compare("kSwissCrossBordersIncluded") ) spId_ = EcalSeverityLevelAlgo::kSwissCrossBordersIncluded;
00060 else spId_ = EcalSeverityLevelAlgo::kSwissCross;
00061
00062 if ((intRadius_ != 0.0) && (fakeNegativeDeposit_)) {
00063 throw cms::Exception("Configuration Error") << "EgammaRecHitExtractor: " <<
00064 "If you use 'subtractSuperClusterEnergy', you *must* set 'intRadius' to ZERO; it does not make sense, otherwise.";
00065 }
00066 std::string isoVariable = par.getParameter<std::string>("isolationVariable");
00067 if (isoVariable == "et") {
00068 useEt_ = true;
00069 } else if (isoVariable == "energy") {
00070 useEt_ = false;
00071 } else {
00072 throw cms::Exception("Configuration Error") << "EgammaRecHitExtractor: isolationVariable '" << isoVariable << "' not known. "
00073 << " Supported values are 'et', 'energy'. ";
00074 }
00075 if (endcapEcalHitsTag_.encode() == barrelEcalHitsTag_.encode()) {
00076 sameTag_ = true;
00077 if (tryBoth_) {
00078 edm::LogWarning("EgammaRecHitExtractor") << "If you have configured 'barrelRecHits' == 'endcapRecHits', so I'm switching 'tryBoth' to FALSE.";
00079 tryBoth_ = false;
00080 }
00081 }
00082
00083 }
00084
00085 EgammaRecHitExtractor::~EgammaRecHitExtractor() { }
00086
00087 reco::IsoDeposit EgammaRecHitExtractor::deposit(const edm::Event & iEvent,
00088 const edm::EventSetup & iSetup, const reco::Candidate &emObject ) const {
00089 edm::ESHandle<CaloGeometry> pG;
00090 iSetup.get<CaloGeometryRecord>().get(pG);
00091
00092
00093 edm::ESHandle<EcalChannelStatus> chStatus;
00094 iSetup.get<EcalChannelStatusRcd>().get(chStatus);
00095
00096 const CaloGeometry* caloGeom = pG.product();
00097 const CaloSubdetectorGeometry* barrelgeom = caloGeom->getSubdetectorGeometry(DetId::Ecal,EcalBarrel);
00098 const CaloSubdetectorGeometry* endcapgeom = caloGeom->getSubdetectorGeometry(DetId::Ecal,EcalEndcap);
00099
00100 static std::string metname = "EgammaIsolationAlgos|EgammaRecHitExtractor";
00101
00102 std::auto_ptr<const CaloRecHitMetaCollectionV> barrelRecHits(0), endcapRecHits(0);
00103
00104
00105 edm::Handle<EcalRecHitCollection> barrelEcalRecHitsH;
00106 iEvent.getByLabel(barrelEcalHitsTag_, barrelEcalRecHitsH);
00107
00108
00109 edm::Handle<EcalRecHitCollection> endcapEcalRecHitsH;
00110 iEvent.getByLabel(endcapEcalHitsTag_, endcapEcalRecHitsH);
00111
00112
00113
00114 reco::SuperClusterRef sc = emObject.get<reco::SuperClusterRef>();
00115 math::XYZPoint caloPosition = sc->position();
00116
00117 Direction candDir(caloPosition.eta(), caloPosition.phi());
00118 reco::IsoDeposit deposit( candDir );
00119 deposit.setVeto( reco::IsoDeposit::Veto(candDir, intRadius_) );
00120 double sinTheta = sin(2*atan(exp(-sc->eta())));
00121 deposit.addCandEnergy(sc->energy() * (useEt_ ? sinTheta : 1.0)) ;
00122
00123
00124 double fakeEnergy = -sc->rawEnergy();
00125 if (fakeNegativeDeposit_) {
00126 deposit.addDeposit(candDir, fakeEnergy * (useEt_ ? sinTheta : 1.0));
00127 }
00128
00129
00130 bool inBarrel = sameTag_ || ( abs(sc->eta()) < 1.479 );
00131 if (inBarrel || tryBoth_) {
00132 collect(deposit, sc, barrelgeom, caloGeom, *barrelEcalRecHitsH, chStatus.product(), true);
00133 }
00134 if ((!inBarrel) || tryBoth_) {
00135 collect(deposit, sc, endcapgeom, caloGeom, *endcapEcalRecHitsH, chStatus.product(), false);
00136 }
00137
00138 return deposit;
00139 }
00140
00141 void EgammaRecHitExtractor::collect(reco::IsoDeposit &deposit,
00142 const reco::SuperClusterRef& sc, const CaloSubdetectorGeometry* subdet,
00143 const CaloGeometry* caloGeom,
00144 const EcalRecHitCollection &hits,
00145 const EcalChannelStatus* chStatus,
00146 bool barrel) const
00147 {
00148
00149 GlobalPoint caloPosition(sc->position().x(), sc->position().y() , sc->position().z());
00150 CaloSubdetectorGeometry::DetIdSet chosen = subdet->getCells(caloPosition,extRadius_);
00151 EcalRecHitCollection::const_iterator j=hits.end();
00152 double caloeta=caloPosition.eta();
00153 double calophi=caloPosition.phi();
00154 double r2 = intRadius_*intRadius_;
00155
00156 std::vector< std::pair<DetId, float> >::const_iterator rhIt;
00157
00158
00159 for (CaloSubdetectorGeometry::DetIdSet::const_iterator i = chosen.begin(), end = chosen.end() ; i != end; ++i) {
00160 j=hits.find(*i);
00161 if(j != hits.end()){
00162 const GlobalPoint & position = caloGeom->getPosition(*i);
00163 double eta = position.eta();
00164 double phi = position.phi();
00165 double energy = j->energy();
00166 double et = energy*position.perp()/position.mag();
00167 double phiDiff= reco::deltaPhi(phi,calophi);
00168
00169
00170 if(vetoClustered_) {
00171
00172
00173 bool isClustered = false;
00174 for( reco::CaloCluster_iterator bcIt = sc->clustersBegin();bcIt != sc->clustersEnd(); ++bcIt) {
00175 for(rhIt = (*bcIt)->hitsAndFractions().begin();rhIt != (*bcIt)->hitsAndFractions().end(); ++rhIt) {
00176 if( rhIt->first == *i ) isClustered = true;
00177 if( isClustered ) break;
00178 }
00179 if( isClustered ) break;
00180 }
00181
00182 if(isClustered) continue;
00183 }
00184
00185
00186 if(barrel &&
00187
00188 EcalSeverityLevelAlgo::severityLevel(
00189 EBDetId(j->id()),
00190 hits,
00191 *chStatus,
00192 severityRecHitThreshold_,
00193 spId_,
00194 spIdThreshold_
00195 ) >= severityLevelCut_) continue;
00196
00197
00198
00199 std::vector<int>::const_iterator vit = std::find( v_chstatus_.begin(), v_chstatus_.end(), ((EcalRecHit*)(&*j))->recoFlag() );
00200 if ( vit != v_chstatus_.end() ) continue;
00201
00202
00203 if( fabs(et) > etMin_
00204 && fabs(energy) > energyMin_
00205 && fabs(eta-caloeta) > intStrip_
00206 && (eta-caloeta)*(eta-caloeta) + phiDiff*phiDiff >r2 ) {
00207
00208 deposit.addDeposit( Direction(eta, phi), (useEt_ ? et : energy) );
00209
00210 }
00211 }
00212 }
00213 }
00214
00215