CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/PhysicsTools/IsolationAlgos/plugins/CandIsolatorFromDeposits.cc

Go to the documentation of this file.
00001 #include "PhysicsTools/IsolationAlgos/plugins/CandIsolatorFromDeposits.h"
00002 
00003 // Framework
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                                                       //,vetos_(new AbsVetos())
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 if (mode == "meanDR") mode_ = MeanDR;
00055   else if (mode == "sumDR") mode_ = SumDR;
00056   else throw cms::Exception("Not Implemented") << "Mode '" << mode << "' not implemented. " <<
00057     "Supported modes are 'sum', 'sumRelative', 'count'." << 
00058     //"Supported modes are 'sum', 'sumRelative', 'max', 'maxRelative', 'count'." << // TODO: on request only
00059     "New methods can be easily implemented if requested.";
00060   typedef std::vector<std::string> vstring;
00061   vstring vetos = iConfig.getParameter< vstring >("vetos");
00062   reco::isodeposit::EventDependentAbsVeto *evdep; 
00063   for (vstring::const_iterator it = vetos.begin(), ed = vetos.end(); it != ed; ++it) {
00064     vetos_.push_back(IsoDepositVetoFactory::make(it->c_str(), evdep));
00065     if (evdep) evdepVetos_.push_back(evdep);
00066   }
00067   std::string weight = iConfig.getParameter<std::string>("weight");
00068   if (isNumber(weight)) {
00069     //std::cout << "Weight is a simple number, " << toNumber(weight) << std::endl;
00070     weight_ = toNumber(weight);
00071     usesFunction_ = false;
00072   } else {
00073     usesFunction_ = true;
00074     //std::cout << "Weight is a function, this might slow you down... " << std::endl;
00075   }
00076   //std::cout << "CandIsolatorFromDeposits::SingleDeposit::SingleDeposit: Total of " << vetos_.size() << " vetos" << std::endl;
00077 }
00078 void CandIsolatorFromDeposits::SingleDeposit::cleanup() {
00079     for (AbsVetos::iterator it = vetos_.begin(), ed = vetos_.end(); it != ed; ++it) {
00080         delete *it;
00081     }
00082     vetos_.clear();
00083     // NOTE: we DON'T have to delete the evdepVetos_, they have already been deleted above. We just clear the vectors
00084     evdepVetos_.clear();
00085 }
00086 void CandIsolatorFromDeposits::SingleDeposit::open(const edm::Event &iEvent, const edm::EventSetup &iSetup) {
00087     iEvent.getByLabel(src_, hDeps_);
00088     for (EventDependentAbsVetos::iterator it = evdepVetos_.begin(), ed = evdepVetos_.end(); it != ed; ++it) {
00089         (*it)->setEvent(iEvent,iSetup);
00090     }
00091 }
00092 
00093 double CandIsolatorFromDeposits::SingleDeposit::compute(const reco::CandidateBaseRef &cand) {
00094     const IsoDeposit &dep = (*hDeps_)[cand];
00095     double eta = dep.eta(), phi = dep.phi(); // better to center on the deposit direction
00096                                              // that could be, e.g., the impact point at calo
00097     for (AbsVetos::iterator it = vetos_.begin(), ed = vetos_.end(); it != ed; ++it) {
00098         (*it)->centerOn(eta, phi);
00099     }
00100     double weight = (usesFunction_ ? weightExpr_(*cand) : weight_);
00101     switch (mode_) {
00102         case Count:        return weight * dep.countWithin(deltaR_, vetos_, skipDefaultVeto_);
00103         case Sum:          return weight * dep.sumWithin(deltaR_, vetos_, skipDefaultVeto_);
00104         case SumRelative:  return weight * dep.sumWithin(deltaR_, vetos_, skipDefaultVeto_) / dep.candEnergy() ;
00105         case Sum2:         return weight * dep.sum2Within(deltaR_, vetos_, skipDefaultVeto_);
00106         case Sum2Relative: return weight * dep.sum2Within(deltaR_, vetos_, skipDefaultVeto_) / (dep.candEnergy() * dep.candEnergy()) ;
00107         case Max:          return weight * dep.maxWithin(deltaR_, vetos_, skipDefaultVeto_);
00108         case NearestDR:    return weight * dep.nearestDR(deltaR_, vetos_, skipDefaultVeto_);
00109         case MaxRelative:  return weight * dep.maxWithin(deltaR_, vetos_, skipDefaultVeto_) / dep.candEnergy() ;
00110         case MeanDR:  return weight * dep.algoWithin<reco::IsoDeposit::MeanDRAlgo>(deltaR_, vetos_, skipDefaultVeto_);
00111         case SumDR:  return weight * dep.algoWithin<reco::IsoDeposit::SumDRAlgo>(deltaR_, vetos_, skipDefaultVeto_);
00112     }
00113     throw cms::Exception("Logic error") << "Should not happen at " << __FILE__ << ", line " << __LINE__; // avoid gcc warning
00114 }
00115 
00116 
00118 CandIsolatorFromDeposits::CandIsolatorFromDeposits(const ParameterSet& par) {
00119   typedef std::vector<edm::ParameterSet> VPSet;
00120   VPSet depPSets = par.getParameter<VPSet>("deposits");
00121   for (VPSet::const_iterator it = depPSets.begin(), ed = depPSets.end(); it != ed; ++it) {
00122     sources_.push_back(SingleDeposit(*it));
00123   }
00124   if (sources_.size() == 0) throw cms::Exception("Configuration Error") << "Please specify at least one deposit!";
00125   produces<CandDoubleMap>();
00126 }
00127 
00129 CandIsolatorFromDeposits::~CandIsolatorFromDeposits() {
00130   std::vector<SingleDeposit>::iterator it, begin = sources_.begin(), end = sources_.end();
00131   for (it = begin; it != end; ++it) it->cleanup();
00132 }
00133 
00135 void CandIsolatorFromDeposits::produce(Event& event, const EventSetup& eventSetup){
00136 
00137   std::vector<SingleDeposit>::iterator it, begin = sources_.begin(), end = sources_.end();
00138   for (it = begin; it != end; ++it) it->open(event, eventSetup);
00139 
00140   const IsoDepositMap & map = begin->map();
00141 
00142   if (map.size()==0) { // !!???
00143         event.put(std::auto_ptr<CandDoubleMap>(new CandDoubleMap()));
00144         return;
00145   }
00146   std::auto_ptr<CandDoubleMap> ret(new CandDoubleMap());
00147   CandDoubleMap::Filler filler(*ret);
00148 
00149   typedef reco::IsoDepositMap::const_iterator iterator_i; 
00150   typedef reco::IsoDepositMap::container::const_iterator iterator_ii; 
00151   iterator_i depI = map.begin(); 
00152   iterator_i depIEnd = map.end(); 
00153   for (; depI != depIEnd; ++depI){ 
00154     std::vector<double> retV(depI.size(),0);
00155     edm::Handle<edm::View<reco::Candidate> > candH;
00156     event.get(depI.id(), candH);
00157     const edm::View<reco::Candidate>& candV = *candH;
00158 
00159     iterator_ii depII = depI.begin(); 
00160     iterator_ii depIIEnd = depI.end(); 
00161     size_t iRet = 0;
00162     for (; depII != depIIEnd; ++depII,++iRet){ 
00163       double sum=0;
00164       for (it = begin; it != end; ++it) sum += it->compute(candV.refAt(iRet)); 
00165       retV[iRet] = sum;
00166     }
00167     filler.insert(candH, retV.begin(), retV.end());
00168   }
00169   filler.fill();
00170   event.put(ret);
00171 }
00172 
00173 DEFINE_FWK_MODULE( CandIsolatorFromDeposits );