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