CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoTauTag/RecoTau/plugins/RecoTauCleaner.cc

Go to the documentation of this file.
00001 /*
00002  * RecoTauCleaner
00003  *
00004  * Author: Evan K. Friis, UC Davis
00005  *
00006  * Given a input collection of PFTaus, produces an output collection of PFTaus
00007  * such that no two PFTaus come from the same PFJet.  If multiple taus in the
00008  * collection come from the same PFJet, (dirty) they are ordered according to a
00009  * list of cleaners.  Each cleaner is a RecoTauCleanerPlugin, and returns a
00010  * double corresponding to the 'quality' for a given tau - an example would be
00011  * the level of isolation.  The set of dirty taus is then ranked
00012  * lexicographically by these cleaners, and the best one is placed in the
00013  * output collection.
00014  *
00015  * $Id $
00016  */
00017 
00018 #include <boost/ptr_container/ptr_vector.hpp>
00019 #include <algorithm>
00020 #include <memory>
00021 
00022 #include "FWCore/Framework/interface/EDProducer.h"
00023 #include "FWCore/Framework/interface/EventSetup.h"
00024 #include "FWCore/Framework/interface/ESHandle.h"
00025 #include "FWCore/Framework/interface/Event.h"
00026 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00027 
00028 #include "RecoTauTag/RecoTau/interface/RecoTauBuilderPlugins.h"
00029 #include "RecoTauTag/RecoTau/interface/RecoTauCleaningTools.h"
00030 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00031 
00032 #include "DataFormats/TauReco/interface/PFTau.h"
00033 #include "DataFormats/TauReco/interface/PFTauFwd.h"
00034 
00035 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
00036 
00037 template<typename Prod>
00038 class RecoTauCleanerImpl : public edm::EDProducer {
00039   typedef reco::tau::RecoTauCleanerPlugin Cleaner;
00040   typedef boost::ptr_vector<Cleaner> CleanerList;
00041   // Define our output type - i.e. reco::PFTau OR reco::PFTauRef
00042   typedef typename Prod::value_type output_type;
00043 
00044   // Predicate that determines if two taus 'overlap' i.e. share a base PFJet
00045   class RemoveDuplicateJets {
00046     public:
00047       bool operator()(const reco::PFTauRef& a, const reco::PFTauRef& b)
00048       { return a->jetRef() == b->jetRef(); }
00049   };
00050 
00051   public:
00052     explicit RecoTauCleanerImpl(const edm::ParameterSet& pset);
00053     ~RecoTauCleanerImpl() {}
00054     void produce(edm::Event& evt, const edm::EventSetup& es);
00055 
00056   private:
00057     // Define scoring predicate for taus
00058     typedef reco::tau::RecoTauLexicographicalRanking<
00059       CleanerList, reco::PFTauRef> Predicate;
00060     std::auto_ptr<Predicate> predicate_;
00061     edm::InputTag tauSrc_;
00062     CleanerList cleaners_;
00063     // Optional selection on the output of the taus
00064     std::auto_ptr<StringCutObjectSelector<reco::PFTau> > outputSelector_;
00065 };
00066 
00067 template<typename Prod>
00068 RecoTauCleanerImpl<Prod>::RecoTauCleanerImpl(const edm::ParameterSet& pset) {
00069   tauSrc_ = pset.getParameter<edm::InputTag>("src");
00070   // Build our list of quality plugins
00071   typedef std::vector<edm::ParameterSet> VPSet;
00072   // Get each of our tau builders
00073   const VPSet& cleaners = pset.getParameter<VPSet>("cleaners");
00074   for (VPSet::const_iterator cleanerPSet = cleaners.begin();
00075       cleanerPSet != cleaners.end(); ++cleanerPSet) {
00076     // Get plugin name
00077     const std::string& pluginType =
00078       cleanerPSet->getParameter<std::string>("plugin");
00079     // Build the plugin
00080     cleaners_.push_back(
00081         RecoTauCleanerPluginFactory::get()->create(pluginType, *cleanerPSet));
00082   }
00083 
00084   // Check if we want to apply a final output selection
00085   if (pset.exists("outputSelection")) {
00086     std::string selection = pset.getParameter<std::string>("outputSelection");
00087     if (selection != "") {
00088       outputSelector_.reset(
00089           new StringCutObjectSelector<reco::PFTau>(selection));
00090     }
00091   }
00092 
00093   // Build the predicate that ranks our taus.  The predicate takes a list of
00094   // cleaners, and uses them to create a lexicographic ranking.
00095   predicate_ = std::auto_ptr<Predicate>(new Predicate(cleaners_));
00096   produces<Prod>();
00097 }
00098 
00099 namespace {
00100 // Template to convert a ref to desired output type
00101 template<typename T> const T convert(const reco::PFTauRef &tau);
00102 
00103 template<> const edm::RefToBase<reco::PFTau>
00104 convert<edm::RefToBase<reco::PFTau> >(const reco::PFTauRef &tau) {
00105   return edm::RefToBase<reco::PFTau>(tau);
00106 }
00107 
00108 template<> const reco::PFTauRef
00109 convert<reco::PFTauRef>(const reco::PFTauRef &tau) { return tau; }
00110 
00111 template<> const reco::PFTau
00112 convert<reco::PFTau>(const reco::PFTauRef &tau) { return *tau; }
00113 }
00114 
00115 template<typename Prod>
00116 void RecoTauCleanerImpl<Prod>::produce(edm::Event& evt,
00117                                    const edm::EventSetup& es) {
00118   // Update all our cleaners with the event info if they need it
00119   for (CleanerList::iterator cleaner = cleaners_.begin();
00120       cleaner != cleaners_.end(); ++cleaner) {
00121     cleaner->setup(evt, es);
00122   }
00123 
00124   // Get the input collection to clean
00125   edm::Handle<reco::CandidateView> input;
00126   evt.getByLabel(tauSrc_, input);
00127 
00128   // Cast the input candidates to Refs to real taus
00129   reco::PFTauRefVector inputRefs =
00130       reco::tau::castView<reco::PFTauRefVector>(input);
00131 
00132   // Make an STL algorithm friendly vector of refs
00133   typedef std::vector<reco::PFTauRef> PFTauRefs;
00134   // Collection of all taus. Some are from the same PFJet. We must clean them.
00135   PFTauRefs dirty;
00136   dirty.reserve(inputRefs.size());
00137   std::copy(inputRefs.begin(), inputRefs.end(), std::back_inserter(dirty));
00138 
00139   // Sort the input tau refs according to our predicate
00140   std::sort(dirty.begin(), dirty.end(), *predicate_);
00141 
00142   // Clean the taus, ensuring that only one tau per jet is produced
00143   PFTauRefs cleanTaus = reco::tau::cleanOverlaps<PFTauRefs,
00144             RemoveDuplicateJets>(dirty);
00145 
00146   // create output collection
00147   std::auto_ptr<Prod> output(new Prod());
00148   //output->reserve(cleanTaus.size());
00149 
00150   // Copy clean refs into output
00151   for (PFTauRefs::const_iterator tau = cleanTaus.begin();
00152        tau != cleanTaus.end(); ++tau) {
00153     // If we are applying an output selection, check if it passes
00154     bool selected = true;
00155     if (outputSelector_.get() && !(*outputSelector_)(**tau)) {
00156       selected = false;
00157     }
00158     if (selected) {
00159       output->push_back(convert<output_type>(*tau));
00160     }
00161   }
00162   evt.put(output);
00163 }
00164 
00165 typedef RecoTauCleanerImpl<reco::PFTauCollection> RecoTauCleaner;
00166 typedef RecoTauCleanerImpl<reco::PFTauRefVector> RecoTauRefCleaner;
00167 
00168 #include "FWCore/Framework/interface/MakerMacros.h"
00169 DEFINE_FWK_MODULE(RecoTauCleaner);
00170 DEFINE_FWK_MODULE(RecoTauRefCleaner);
00171