CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_8_patch3/src/CommonTools/ParticleFlow/plugins/PFCandIsolatorFromDeposit.cc

Go to the documentation of this file.
00001 #include "CommonTools/ParticleFlow/plugins/PFCandIsolatorFromDeposit.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 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00019 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
00020 #include "DataFormats/Candidate/interface/CandAssociation.h"
00021 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00023 #include <string>
00024 #include <boost/regex.hpp>
00025 
00026 #include "PhysicsTools/IsolationAlgos/interface/IsoDepositVetoFactory.h"
00027 
00028 using namespace edm;
00029 using namespace reco;
00030 using namespace reco::isodeposit;
00031 
00032 bool PFCandIsolatorFromDeposits::SingleDeposit::isNumber(const std::string &str) const {
00033    static boost::regex re("^[+-]?(\\d+\\.?|\\d*\\.\\d*)$");
00034    return regex_match(str.c_str(), re);
00035 }
00036 double PFCandIsolatorFromDeposits::SingleDeposit::toNumber(const std::string &str) const {
00037     return atof(str.c_str());
00038 }
00039 
00040 PFCandIsolatorFromDeposits::SingleDeposit::SingleDeposit(const edm::ParameterSet &iConfig) :
00041   src_(iConfig.getParameter<edm::InputTag>("src")),
00042   deltaR_(iConfig.getParameter<double>("deltaR")),
00043   weightExpr_(iConfig.getParameter<std::string>("weight")),
00044   skipDefaultVeto_(iConfig.getParameter<bool>("skipDefaultVeto")),
00045   usePivotForBarrelEndcaps_(iConfig.getParameter<bool>("PivotCoordinatesForEBEE"))
00046                                                       //,vetos_(new AbsVetos())
00047 {
00048   std::string mode = iConfig.getParameter<std::string>("mode");
00049   if (mode == "sum") mode_ = Sum; 
00050   else if (mode == "sumRelative") mode_ = SumRelative; 
00051   else if (mode == "sum2") mode_ = Sum2;                  
00052   else if (mode == "sum2Relative") mode_ = Sum2Relative;
00053   else if (mode == "max") mode_ = Max;                  
00054   else if (mode == "maxRelative") mode_ = MaxRelative;
00055   else if (mode == "nearestDR") mode_ = NearestDR;
00056   else if (mode == "count") mode_ = Count;
00057   else throw cms::Exception("Not Implemented") << "Mode '" << mode << "' not implemented. " <<
00058     "Supported modes are 'sum', 'sumRelative', 'count'." << 
00059     //"Supported modes are 'sum', 'sumRelative', 'max', 'maxRelative', 'count'." << // TODO: on request only
00060     "New methods can be easily implemented if requested.";
00061   typedef std::vector<std::string> vstring;
00062   vstring vetos = iConfig.getParameter< vstring >("vetos");
00063   reco::isodeposit::EventDependentAbsVeto *evdep=0; 
00064   static boost::regex ecalSwitch("^Ecal(Barrel|Endcaps):(.*)");
00065     
00066   for (vstring::const_iterator it = vetos.begin(), ed = vetos.end(); it != ed; ++it) {
00067     boost::cmatch match;
00068     // in that case, make two series of vetoes
00069     if( usePivotForBarrelEndcaps_) {
00070       if (regex_match(it->c_str(), match, ecalSwitch))
00071         {
00072           if(match[1] == "Barrel") {
00073             //      std::cout << " Adding Barrel veto " << std::string(match[2]) << std::endl;
00074             barrelVetos_.push_back(IsoDepositVetoFactory::make(std::string(match[2]).c_str(), evdep)); // I don't know a better syntax
00075           }
00076           if(match[1] == "Endcaps") {
00077             //      std::cout << " Adding Endcap veto " << std::string(match[2]) << std::endl;
00078             endcapVetos_.push_back(IsoDepositVetoFactory::make(std::string(match[2]).c_str(), evdep));
00079           }
00080         }
00081       else
00082         {
00083           barrelVetos_.push_back(IsoDepositVetoFactory::make(it->c_str(), evdep));
00084           endcapVetos_.push_back(IsoDepositVetoFactory::make(it->c_str(), evdep));
00085         }
00086     } else {
00087       //only one serie of vetoes, just barrel
00088       barrelVetos_.push_back(IsoDepositVetoFactory::make(it->c_str(), evdep));
00089     }
00090     if (evdep) evdepVetos_.push_back(evdep);
00091   }
00092 
00093   std::string weight = iConfig.getParameter<std::string>("weight");
00094   if (isNumber(weight)) {
00095     //std::cout << "Weight is a simple number, " << toNumber(weight) << std::endl;
00096     weight_ = toNumber(weight);
00097     usesFunction_ = false;
00098   } else {
00099     usesFunction_ = true;
00100     //std::cout << "Weight is a function, this might slow you down... " << std::endl;
00101   }
00102   //std::cout << "PFCandIsolatorFromDeposits::SingleDeposit::SingleDeposit: Total of " << vetos_.size() << " vetos" << std::endl;
00103 }
00104 void PFCandIsolatorFromDeposits::SingleDeposit::cleanup() {
00105     for (AbsVetos::iterator it = barrelVetos_.begin(), ed = barrelVetos_.end(); it != ed; ++it) {
00106         delete *it;
00107     }
00108     for (AbsVetos::iterator it = endcapVetos_.begin(), ed = endcapVetos_.end(); it != ed; ++it) {
00109         delete *it;
00110     }
00111     barrelVetos_.clear();
00112     endcapVetos_.clear();
00113     // NOTE: we DON'T have to delete the evdepVetos_, they have already been deleted above. We just clear the vectors
00114     evdepVetos_.clear();
00115 }
00116 void PFCandIsolatorFromDeposits::SingleDeposit::open(const edm::Event &iEvent, const edm::EventSetup &iSetup) {
00117     iEvent.getByLabel(src_, hDeps_);
00118     for (EventDependentAbsVetos::iterator it = evdepVetos_.begin(), ed = evdepVetos_.end(); it != ed; ++it) {
00119         (*it)->setEvent(iEvent,iSetup);
00120     }
00121 }
00122 
00123 double PFCandIsolatorFromDeposits::SingleDeposit::compute(const reco::CandidateBaseRef &cand) {
00124     const IsoDeposit &dep = (*hDeps_)[cand];
00125     double eta = dep.eta(), phi = dep.phi(); // better to center on the deposit direction
00126                                              // that could be, e.g., the impact point at calo
00127     bool barrel=true;
00128     if( usePivotForBarrelEndcaps_) {
00129       const reco::PFCandidate * myPFCand = dynamic_cast<const reco::PFCandidate*>(&(*cand));
00130       if(myPFCand)  {
00131         // exact barrel boundary 
00132         barrel = fabs(myPFCand->positionAtECALEntrance().eta())<1.479;
00133       }
00134       else {
00135         const reco::RecoCandidate * myRecoCand = dynamic_cast<const reco::RecoCandidate*>(&(*cand));
00136         if(myRecoCand) {
00137           // not optimal. isEB should be used. 
00138           barrel = ( fabs(myRecoCand->superCluster()->eta())<1.479 );      
00139         }
00140       }
00141     }
00142     // if ! usePivotForBarrelEndcaps_ only the barrel series is used, which does not prevent the vetoes do be different in barrel & endcaps
00143     reco::isodeposit::AbsVetos * vetos = (barrel) ? &barrelVetos_ : &endcapVetos_;
00144 
00145     for (AbsVetos::iterator it = vetos->begin(), ed = vetos->end(); it != ed; ++it) {
00146         (*it)->centerOn(eta, phi);
00147     }
00148     double weight = (usesFunction_ ? weightExpr_(*cand) : weight_);
00149     switch (mode_) {
00150         case Count:        return weight * dep.countWithin(deltaR_, *vetos, skipDefaultVeto_);
00151         case Sum:          return weight * dep.sumWithin(deltaR_, *vetos, skipDefaultVeto_);
00152         case SumRelative:  return weight * dep.sumWithin(deltaR_, *vetos, skipDefaultVeto_) / dep.candEnergy() ;
00153         case Sum2:         return weight * dep.sum2Within(deltaR_, *vetos, skipDefaultVeto_);
00154         case Sum2Relative: return weight * dep.sum2Within(deltaR_, *vetos, skipDefaultVeto_) / (dep.candEnergy() * dep.candEnergy()) ;
00155         case Max:          return weight * dep.maxWithin(deltaR_, *vetos, skipDefaultVeto_);
00156         case NearestDR:    return weight * dep.nearestDR(deltaR_, *vetos, skipDefaultVeto_);
00157         case MaxRelative:  return weight * dep.maxWithin(deltaR_, *vetos, skipDefaultVeto_) / dep.candEnergy() ;
00158     }
00159     throw cms::Exception("Logic error") << "Should not happen at " << __FILE__ << ", line " << __LINE__; // avoid gcc warning
00160 }
00161 
00163 PFCandIsolatorFromDeposits::PFCandIsolatorFromDeposits(const ParameterSet& par) {
00164   typedef std::vector<edm::ParameterSet> VPSet;
00165   VPSet depPSets = par.getParameter<VPSet>("deposits");
00166   for (VPSet::const_iterator it = depPSets.begin(), ed = depPSets.end(); it != ed; ++it) {
00167     sources_.push_back(SingleDeposit(*it));
00168   }
00169   if (sources_.size() == 0) throw cms::Exception("Configuration Error") << "Please specify at least one deposit!";
00170   produces<CandDoubleMap>();
00171 }
00172 
00174 PFCandIsolatorFromDeposits::~PFCandIsolatorFromDeposits() {
00175   std::vector<SingleDeposit>::iterator it, begin = sources_.begin(), end = sources_.end();
00176   for (it = begin; it != end; ++it) it->cleanup();
00177 }
00178 
00180 void PFCandIsolatorFromDeposits::produce(Event& event, const EventSetup& eventSetup){
00181 
00182   std::vector<SingleDeposit>::iterator it, begin = sources_.begin(), end = sources_.end();
00183   for (it = begin; it != end; ++it) it->open(event, eventSetup);
00184 
00185   const IsoDepositMap & map = begin->map();
00186 
00187   if (map.size()==0) { // !!???
00188         event.put(std::auto_ptr<CandDoubleMap>(new CandDoubleMap()));
00189         return;
00190   }
00191   std::auto_ptr<CandDoubleMap> ret(new CandDoubleMap());
00192   CandDoubleMap::Filler filler(*ret);
00193 
00194   typedef reco::IsoDepositMap::const_iterator iterator_i; 
00195   typedef reco::IsoDepositMap::container::const_iterator iterator_ii; 
00196   iterator_i depI = map.begin(); 
00197   iterator_i depIEnd = map.end(); 
00198   for (; depI != depIEnd; ++depI){ 
00199     std::vector<double> retV(depI.size(),0);
00200     edm::Handle<edm::View<reco::Candidate> > candH;
00201     event.get(depI.id(), candH);
00202     const edm::View<reco::Candidate>& candV = *candH;
00203 
00204     iterator_ii depII = depI.begin(); 
00205     iterator_ii depIIEnd = depI.end(); 
00206     size_t iRet = 0;
00207     for (; depII != depIIEnd; ++depII,++iRet){ 
00208       double sum=0;
00209       for (it = begin; it != end; ++it) sum += it->compute(candV.refAt(iRet)); 
00210       retV[iRet] = sum;
00211     }
00212     filler.insert(candH, retV.begin(), retV.end());
00213   }
00214   filler.fill();
00215   event.put(ret);
00216 }
00217 
00218 DEFINE_FWK_MODULE( PFCandIsolatorFromDeposits );