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 "CommonTools/Utils/interface/StringToEnumValue.h"
00017
00018 #include "RecoEgamma/EgammaIsolationAlgos/plugins/EgammaRecHitExtractor.h"
00019 #include "DataFormats/DetId/interface/DetId.h"
00020 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00021 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00022 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00023 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00024 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00025 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00026 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
00027 #include "RecoCaloTools/MetaCollections/interface/CaloRecHitMetaCollections.h"
00028 #include "DataFormats/Math/interface/deltaPhi.h"
00029 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
00030 #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h"
00031 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00032 #include "DataFormats/EgammaReco/interface/BasicClusterFwd.h"
00033
00034 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgoRcd.h"
00035
00036 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00037
00038 using namespace std;
00039 using namespace egammaisolation;
00040 using namespace reco::isodeposit;
00041
00042 EgammaRecHitExtractor::EgammaRecHitExtractor(const edm::ParameterSet& par) :
00043 etMin_(par.getParameter<double>("etMin")),
00044 energyMin_(par.getParameter<double>("energyMin")),
00045 extRadius_(par.getParameter<double>("extRadius")),
00046 intRadius_(par.getParameter<double>("intRadius")),
00047 intStrip_(par.getParameter<double>("intStrip")),
00048 barrelEcalHitsTag_(par.getParameter<edm::InputTag>("barrelEcalHits")),
00049 endcapEcalHitsTag_(par.getParameter<edm::InputTag>("endcapEcalHits")),
00050 fakeNegativeDeposit_(par.getParameter<bool>("subtractSuperClusterEnergy")),
00051 tryBoth_(par.getParameter<bool>("tryBoth")),
00052 vetoClustered_(par.getParameter<bool>("vetoClustered")),
00053 sameTag_(false)
00054
00055
00056
00057
00058 {
00059
00060 const std::vector<std::string> flagnamesEB =
00061 par.getParameter<std::vector<std::string> >("RecHitFlagToBeExcludedEB");
00062
00063 const std::vector<std::string> flagnamesEE =
00064 par.getParameter<std::vector<std::string> >("RecHitFlagToBeExcludedEE");
00065
00066 flagsexclEB_=
00067 StringToEnumValue<EcalRecHit::Flags>(flagnamesEB);
00068
00069 flagsexclEE_=
00070 StringToEnumValue<EcalRecHit::Flags>(flagnamesEE);
00071
00072 const std::vector<std::string> severitynamesEB =
00073 par.getParameter<std::vector<std::string> >("RecHitSeverityToBeExcludedEB");
00074
00075 severitiesexclEB_=
00076 StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEB);
00077
00078 const std::vector<std::string> severitynamesEE =
00079 par.getParameter<std::vector<std::string> >("RecHitSeverityToBeExcludedEE");
00080
00081 severitiesexclEE_=
00082 StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEE);
00083
00084 if ((intRadius_ != 0.0) && (fakeNegativeDeposit_)) {
00085 throw cms::Exception("Configuration Error") << "EgammaRecHitExtractor: " <<
00086 "If you use 'subtractSuperClusterEnergy', you *must* set 'intRadius' to ZERO; it does not make sense, otherwise.";
00087 }
00088 std::string isoVariable = par.getParameter<std::string>("isolationVariable");
00089 if (isoVariable == "et") {
00090 useEt_ = true;
00091 } else if (isoVariable == "energy") {
00092 useEt_ = false;
00093 } else {
00094 throw cms::Exception("Configuration Error") << "EgammaRecHitExtractor: isolationVariable '" << isoVariable << "' not known. "
00095 << " Supported values are 'et', 'energy'. ";
00096 }
00097 if (endcapEcalHitsTag_.encode() == barrelEcalHitsTag_.encode()) {
00098 sameTag_ = true;
00099 if (tryBoth_) {
00100 edm::LogWarning("EgammaRecHitExtractor") << "If you have configured 'barrelRecHits' == 'endcapRecHits', so I'm switching 'tryBoth' to FALSE.";
00101 tryBoth_ = false;
00102 }
00103 }
00104 }
00105
00106 EgammaRecHitExtractor::~EgammaRecHitExtractor()
00107 {}
00108
00109 reco::IsoDeposit EgammaRecHitExtractor::deposit(const edm::Event & iEvent,
00110 const edm::EventSetup & iSetup, const reco::Candidate &emObject ) const {
00111 edm::ESHandle<CaloGeometry> pG;
00112 iSetup.get<CaloGeometryRecord>().get(pG);
00113
00114
00115
00116
00117
00118 edm::ESHandle<EcalSeverityLevelAlgo> sevlv;
00119 iSetup.get<EcalSeverityLevelAlgoRcd>().get(sevlv);
00120 const EcalSeverityLevelAlgo* sevLevel = sevlv.product();
00121
00122 const CaloGeometry* caloGeom = pG.product();
00123 const CaloSubdetectorGeometry* barrelgeom = caloGeom->getSubdetectorGeometry(DetId::Ecal,EcalBarrel);
00124 const CaloSubdetectorGeometry* endcapgeom = caloGeom->getSubdetectorGeometry(DetId::Ecal,EcalEndcap);
00125
00126 static std::string metname = "EgammaIsolationAlgos|EgammaRecHitExtractor";
00127
00128 std::auto_ptr<const CaloRecHitMetaCollectionV> barrelRecHits(0), endcapRecHits(0);
00129
00130
00131 edm::Handle<EcalRecHitCollection> barrelEcalRecHitsH;
00132 iEvent.getByLabel(barrelEcalHitsTag_, barrelEcalRecHitsH);
00133
00134
00135 edm::Handle<EcalRecHitCollection> endcapEcalRecHitsH;
00136 iEvent.getByLabel(endcapEcalHitsTag_, endcapEcalRecHitsH);
00137
00138
00139 reco::SuperClusterRef sc = emObject.get<reco::SuperClusterRef>();
00140 math::XYZPoint caloPosition = sc->position();
00141
00142 Direction candDir(caloPosition.eta(), caloPosition.phi());
00143 reco::IsoDeposit deposit( candDir );
00144 deposit.setVeto( reco::IsoDeposit::Veto(candDir, intRadius_) );
00145 double sinTheta = sin(2*atan(exp(-sc->eta())));
00146 deposit.addCandEnergy(sc->energy() * (useEt_ ? sinTheta : 1.0)) ;
00147
00148
00149 double fakeEnergy = -sc->rawEnergy();
00150 if (fakeNegativeDeposit_) {
00151 deposit.addDeposit(candDir, fakeEnergy * (useEt_ ? sinTheta : 1.0));
00152 }
00153
00154
00155 bool inBarrel = sameTag_ || ( abs(sc->eta()) < 1.479 );
00156 if (inBarrel || tryBoth_) {
00157 collect(deposit, sc, barrelgeom, caloGeom, *barrelEcalRecHitsH, sevLevel, true);
00158 }
00159
00160 if ((!inBarrel) || tryBoth_) {
00161 collect(deposit, sc, endcapgeom, caloGeom, *endcapEcalRecHitsH, sevLevel, false);
00162 }
00163
00164 return deposit;
00165 }
00166
00167 void EgammaRecHitExtractor::collect(reco::IsoDeposit &deposit,
00168 const reco::SuperClusterRef& sc, const CaloSubdetectorGeometry* subdet,
00169 const CaloGeometry* caloGeom,
00170 const EcalRecHitCollection &hits,
00171
00172 const EcalSeverityLevelAlgo* sevLevel,
00173 bool barrel) const {
00174
00175 GlobalPoint caloPosition(sc->position().x(), sc->position().y() , sc->position().z());
00176 CaloSubdetectorGeometry::DetIdSet chosen = subdet->getCells(caloPosition,extRadius_);
00177 EcalRecHitCollection::const_iterator j=hits.end();
00178 double caloeta=caloPosition.eta();
00179 double calophi=caloPosition.phi();
00180 double r2 = intRadius_*intRadius_;
00181
00182 std::vector< std::pair<DetId, float> >::const_iterator rhIt;
00183
00184
00185 for (CaloSubdetectorGeometry::DetIdSet::const_iterator i = chosen.begin(), end = chosen.end() ; i != end; ++i) {
00186 j = hits.find(*i);
00187 if (j != hits.end()) {
00188 const GlobalPoint & position = caloGeom->getPosition(*i);
00189 double eta = position.eta();
00190 double phi = position.phi();
00191 double energy = j->energy();
00192 double et = energy*position.perp()/position.mag();
00193 double phiDiff= reco::deltaPhi(phi,calophi);
00194
00195
00196 if(vetoClustered_) {
00197
00198
00199 bool isClustered = false;
00200 for( reco::CaloCluster_iterator bcIt = sc->clustersBegin();bcIt != sc->clustersEnd(); ++bcIt) {
00201 for(rhIt = (*bcIt)->hitsAndFractions().begin();rhIt != (*bcIt)->hitsAndFractions().end(); ++rhIt) {
00202 if( rhIt->first == *i ) isClustered = true;
00203 if( isClustered ) break;
00204 }
00205 if( isClustered ) break;
00206 }
00207
00208 if(isClustered) continue;
00209 }
00210
00211 std::vector<int>::const_iterator sit;
00212 int severityFlag = sevLevel->severityLevel(j->detid(), hits);
00213 if (barrel) {
00214 sit = std::find(severitiesexclEB_.begin(), severitiesexclEB_.end(), severityFlag);
00215 if (sit != severitiesexclEB_.end())
00216 continue;
00217 } else {
00218 sit = std::find(severitiesexclEE_.begin(), severitiesexclEE_.end(), severityFlag);
00219 if (sit != severitiesexclEE_.end())
00220 continue;
00221 }
00222
00223 std::vector<int>::const_iterator vit;
00224 if (barrel) {
00225
00226
00227
00228
00229 if (!((EcalRecHit*)(&*j))->checkFlag(EcalRecHit::kGood)) {
00230 if (((EcalRecHit*)(&*j))->checkFlags(flagsexclEB_)) {
00231 continue;
00232 }
00233 }
00234 } else {
00235
00236
00237
00238
00239 if (!((EcalRecHit*)(&*j))->checkFlag(EcalRecHit::kGood)) {
00240 if (((EcalRecHit*)(&*j))->checkFlags(flagsexclEE_)) {
00241 continue;
00242 }
00243 }
00244 }
00245
00246 if(et > etMin_
00247 && energy > energyMin_
00248 && fabs(eta-caloeta) > intStrip_
00249 && (eta-caloeta)*(eta-caloeta) + phiDiff*phiDiff >r2 ) {
00250
00251 deposit.addDeposit( Direction(eta, phi), (useEt_ ? et : energy));
00252 }
00253 }
00254 }
00255 }
00256
00257