00001 #include "PhysicsTools/IsolationAlgos/plugins/CandIsolatorFromDeposits.h"
00002
00003
00004 #include "FWCore/Framework/interface/EDProducer.h"
00005 #include "FWCore/Framework/interface/Event.h"
00006 #include "FWCore/Framework/interface/EventSetup.h"
00007 #include "DataFormats/Common/interface/Handle.h"
00008 #include "FWCore/Framework/interface/MakerMacros.h"
00009
00010 #include "FWCore/Framework/interface/ESHandle.h"
00011
00012 #include "DataFormats/TrackReco/interface/Track.h"
00013 #include "DataFormats/MuonReco/interface/Muon.h"
00014 #include "DataFormats/RecoCandidate/interface/IsoDepositDirection.h"
00015 #include "DataFormats/RecoCandidate/interface/IsoDeposit.h"
00016 #include "DataFormats/RecoCandidate/interface/IsoDepositFwd.h"
00017 #include "DataFormats/RecoCandidate/interface/IsoDepositVetos.h"
00018
00019 #include "DataFormats/Candidate/interface/CandAssociation.h"
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021 #include <string>
00022 #include <boost/regex.hpp>
00023
00024 #include "PhysicsTools/IsolationAlgos/interface/IsoDepositVetoFactory.h"
00025
00026 using namespace edm;
00027 using namespace reco;
00028 using namespace reco::isodeposit;
00029
00030 bool isNumber(const std::string &str) {
00031 static boost::regex re("^[+-]?(\\d+\\.?|\\d*\\.\\d*)$");
00032 return regex_match(str.c_str(), re);
00033 }
00034 double toNumber(const std::string &str) {
00035 return atof(str.c_str());
00036 }
00037
00038 CandIsolatorFromDeposits::SingleDeposit::SingleDeposit(const edm::ParameterSet &iConfig) :
00039 src_(iConfig.getParameter<edm::InputTag>("src")),
00040 deltaR_(iConfig.getParameter<double>("deltaR")),
00041 weightExpr_(iConfig.getParameter<std::string>("weight")),
00042 skipDefaultVeto_(iConfig.getParameter<bool>("skipDefaultVeto"))
00043
00044 {
00045 std::string mode = iConfig.getParameter<std::string>("mode");
00046 if (mode == "sum") mode_ = Sum;
00047 else if (mode == "sumRelative") mode_ = SumRelative;
00048 else if (mode == "sum2") mode_ = Sum2;
00049 else if (mode == "sum2Relative") mode_ = Sum2Relative;
00050 else if (mode == "max") mode_ = Max;
00051 else if (mode == "maxRelative") mode_ = MaxRelative;
00052 else if (mode == "nearestDR") mode_ = NearestDR;
00053 else if (mode == "count") mode_ = Count;
00054 else throw cms::Exception("Not Implemented") << "Mode '" << mode << "' not implemented. " <<
00055 "Supported modes are 'sum', 'sumRelative', 'count'." <<
00056
00057 "New methods can be easily implemented if requested.";
00058 typedef std::vector<std::string> vstring;
00059 vstring vetos = iConfig.getParameter< vstring >("vetos");
00060 reco::isodeposit::EventDependentAbsVeto *evdep;
00061 for (vstring::const_iterator it = vetos.begin(), ed = vetos.end(); it != ed; ++it) {
00062 vetos_.push_back(IsoDepositVetoFactory::make(it->c_str(), evdep));
00063 if (evdep) evdepVetos_.push_back(evdep);
00064 }
00065 std::string weight = iConfig.getParameter<std::string>("weight");
00066 if (isNumber(weight)) {
00067
00068 weight_ = toNumber(weight);
00069 usesFunction_ = false;
00070 } else {
00071 usesFunction_ = true;
00072
00073 }
00074
00075 }
00076 void CandIsolatorFromDeposits::SingleDeposit::cleanup() {
00077 for (AbsVetos::iterator it = vetos_.begin(), ed = vetos_.end(); it != ed; ++it) {
00078 delete *it;
00079 }
00080 vetos_.clear();
00081
00082 evdepVetos_.clear();
00083 }
00084 void CandIsolatorFromDeposits::SingleDeposit::open(const edm::Event &iEvent, const edm::EventSetup &iSetup) {
00085 iEvent.getByLabel(src_, hDeps_);
00086 for (EventDependentAbsVetos::iterator it = evdepVetos_.begin(), ed = evdepVetos_.end(); it != ed; ++it) {
00087 (*it)->setEvent(iEvent,iSetup);
00088 }
00089 }
00090
00091 double CandIsolatorFromDeposits::SingleDeposit::compute(const reco::CandidateBaseRef &cand) {
00092 const IsoDeposit &dep = (*hDeps_)[cand];
00093 double eta = dep.eta(), phi = dep.phi();
00094
00095 for (AbsVetos::iterator it = vetos_.begin(), ed = vetos_.end(); it != ed; ++it) {
00096 (*it)->centerOn(eta, phi);
00097 }
00098 double weight = (usesFunction_ ? weightExpr_(*cand) : weight_);
00099 switch (mode_) {
00100 case Count: return weight * dep.countWithin(deltaR_, vetos_, skipDefaultVeto_);
00101 case Sum: return weight * dep.sumWithin(deltaR_, vetos_, skipDefaultVeto_);
00102 case SumRelative: return weight * dep.sumWithin(deltaR_, vetos_, skipDefaultVeto_) / dep.candEnergy() ;
00103 case Sum2: return weight * dep.sum2Within(deltaR_, vetos_, skipDefaultVeto_);
00104 case Sum2Relative: return weight * dep.sum2Within(deltaR_, vetos_, skipDefaultVeto_) / (dep.candEnergy() * dep.candEnergy()) ;
00105 case Max: return weight * dep.maxWithin(deltaR_, vetos_, skipDefaultVeto_);
00106 case NearestDR: return weight * dep.nearestDR(deltaR_, vetos_, skipDefaultVeto_);
00107 case MaxRelative: return weight * dep.maxWithin(deltaR_, vetos_, skipDefaultVeto_) / dep.candEnergy() ;
00108 }
00109 throw cms::Exception("Logic error") << "Should not happen at " << __FILE__ << ", line " << __LINE__;
00110 }
00111
00112
00114 CandIsolatorFromDeposits::CandIsolatorFromDeposits(const ParameterSet& par) {
00115 typedef std::vector<edm::ParameterSet> VPSet;
00116 VPSet depPSets = par.getParameter<VPSet>("deposits");
00117 for (VPSet::const_iterator it = depPSets.begin(), ed = depPSets.end(); it != ed; ++it) {
00118 sources_.push_back(SingleDeposit(*it));
00119 }
00120 if (sources_.size() == 0) throw cms::Exception("Configuration Error") << "Please specify at least one deposit!";
00121 produces<CandDoubleMap>();
00122 }
00123
00125 CandIsolatorFromDeposits::~CandIsolatorFromDeposits() {
00126 std::vector<SingleDeposit>::iterator it, begin = sources_.begin(), end = sources_.end();
00127 for (it = begin; it != end; ++it) it->cleanup();
00128 }
00129
00131 void CandIsolatorFromDeposits::produce(Event& event, const EventSetup& eventSetup){
00132
00133 std::vector<SingleDeposit>::iterator it, begin = sources_.begin(), end = sources_.end();
00134 for (it = begin; it != end; ++it) it->open(event, eventSetup);
00135
00136 const IsoDepositMap & map = begin->map();
00137
00138 if (map.size()==0) {
00139 event.put(std::auto_ptr<CandDoubleMap>(new CandDoubleMap()));
00140 return;
00141 }
00142 std::auto_ptr<CandDoubleMap> ret(new CandDoubleMap());
00143 CandDoubleMap::Filler filler(*ret);
00144
00145 typedef reco::IsoDepositMap::const_iterator iterator_i;
00146 typedef reco::IsoDepositMap::container::const_iterator iterator_ii;
00147 iterator_i depI = map.begin();
00148 iterator_i depIEnd = map.end();
00149 for (; depI != depIEnd; ++depI){
00150 std::vector<double> retV(depI.size(),0);
00151 edm::Handle<edm::View<reco::Candidate> > candH;
00152 event.get(depI.id(), candH);
00153 const edm::View<reco::Candidate>& candV = *candH;
00154
00155 iterator_ii depII = depI.begin();
00156 iterator_ii depIIEnd = depI.end();
00157 size_t iRet = 0;
00158 for (; depII != depIIEnd; ++depII,++iRet){
00159 double sum=0;
00160 for (it = begin; it != end; ++it) sum += it->compute(candV.refAt(iRet));
00161 retV[iRet] = sum;
00162 }
00163 filler.insert(candH, retV.begin(), retV.end());
00164 }
00165 filler.fill();
00166 event.put(ret);
00167 }
00168
00169 DEFINE_FWK_MODULE( CandIsolatorFromDeposits );