CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoTauTag/RecoTau/plugins/RecoTauPiZeroProducer.cc

Go to the documentation of this file.
00001 /*
00002  * RecoTauPiZeroProducer
00003  *
00004  * Author: Evan K. Friis, UC Davis
00005  *
00006  * Associates reconstructed PiZeros to PFJets.  The PiZeros are built using one
00007  * or more RecoTauBuilder plugins.  Any overlaps (PiZeros sharing constituents)
00008  * are removed, with the best PiZero candidates taken.  The 'best' are defined
00009  * via the input list of RecoTauPiZeroQualityPlugins, which form a
00010  * lexicograpical ranking.
00011  *
00012  * $Id $
00013  */
00014 
00015 #include <boost/ptr_container/ptr_vector.hpp>
00016 #include <boost/ptr_container/ptr_list.hpp>
00017 #include <boost/foreach.hpp>
00018 #include <algorithm>
00019 #include <functional>
00020 
00021 #include "FWCore/Framework/interface/EDProducer.h"
00022 #include "FWCore/Framework/interface/EventSetup.h"
00023 #include "FWCore/Framework/interface/ESHandle.h"
00024 #include "FWCore/Framework/interface/Event.h"
00025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00026 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00027 
00028 #include "RecoTauTag/RecoTau/interface/RecoTauPiZeroPlugins.h"
00029 #include "RecoTauTag/RecoTau/interface/RecoTauCleaningTools.h"
00030 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00031 
00032 #include "DataFormats/JetReco/interface/PFJetCollection.h"
00033 #include "DataFormats/TauReco/interface/JetPiZeroAssociation.h"
00034 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
00035 
00036 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
00037 
00038 class RecoTauPiZeroProducer : public edm::EDProducer {
00039   public:
00040     typedef reco::tau::RecoTauPiZeroBuilderPlugin Builder;
00041     typedef reco::tau::RecoTauPiZeroQualityPlugin Ranker;
00042 
00043     explicit RecoTauPiZeroProducer(const edm::ParameterSet& pset);
00044     ~RecoTauPiZeroProducer() {}
00045     void produce(edm::Event& evt, const edm::EventSetup& es);
00046     void print(const std::vector<reco::RecoTauPiZero>& piZeros,
00047                std::ostream& out);
00048 
00049   private:
00050     typedef boost::ptr_vector<Builder> builderList;
00051     typedef boost::ptr_vector<Ranker> rankerList;
00052     typedef boost::ptr_vector<reco::RecoTauPiZero> PiZeroVector;
00053     typedef boost::ptr_list<reco::RecoTauPiZero> PiZeroList;
00054 
00055     typedef reco::tau::RecoTauLexicographicalRanking<rankerList,
00056             reco::RecoTauPiZero> PiZeroPredicate;
00057 
00058     edm::InputTag src_;
00059     builderList builders_;
00060     rankerList rankers_;
00061     std::auto_ptr<PiZeroPredicate> predicate_;
00062     double piZeroMass_;
00063 };
00064 
00065 RecoTauPiZeroProducer::RecoTauPiZeroProducer(const edm::ParameterSet& pset) {
00066   src_ = pset.getParameter<edm::InputTag>("src");
00067 
00068   typedef std::vector<edm::ParameterSet> VPSet;
00069   // Get the mass hypothesis for the pizeros
00070   piZeroMass_ = pset.getParameter<double>("massHypothesis");
00071 
00072   // Get each of our PiZero builders
00073   const VPSet& builders = pset.getParameter<VPSet>("builders");
00074 
00075   for (VPSet::const_iterator builderPSet = builders.begin();
00076       builderPSet != builders.end(); ++builderPSet) {
00077     // Get plugin name
00078     const std::string& pluginType =
00079       builderPSet->getParameter<std::string>("plugin");
00080     // Build the plugin
00081     builders_.push_back(RecoTauPiZeroBuilderPluginFactory::get()->create(
00082           pluginType, *builderPSet));
00083   }
00084 
00085   // Get each of our quality rankers
00086   const VPSet& rankers = pset.getParameter<VPSet>("ranking");
00087   for (VPSet::const_iterator rankerPSet = rankers.begin();
00088       rankerPSet != rankers.end(); ++rankerPSet) {
00089     const std::string& pluginType =
00090       rankerPSet->getParameter<std::string>("plugin");
00091     rankers_.push_back(RecoTauPiZeroQualityPluginFactory::get()->create(
00092           pluginType, *rankerPSet));
00093   }
00094 
00095   // Build the sorting predicate
00096   predicate_ = std::auto_ptr<PiZeroPredicate>(new PiZeroPredicate(rankers_));
00097 
00098   produces<reco::JetPiZeroAssociation>();
00099 }
00100 
00101 void RecoTauPiZeroProducer::produce(edm::Event& evt,
00102                                     const edm::EventSetup& es) {
00103   // Get a view of our jets via the base candidates
00104   edm::Handle<reco::CandidateView> jetView;
00105   evt.getByLabel(src_, jetView);
00106 
00107   // Give each of our plugins a chance at doing something with the edm::Event
00108   BOOST_FOREACH(Builder& builder, builders_) {
00109     builder.setup(evt, es);
00110   }
00111 
00112   // Convert the view to a RefVector of actual PFJets
00113   reco::PFJetRefVector jetRefs =
00114       reco::tau::castView<reco::PFJetRefVector>(jetView);
00115   // Make our association
00116   std::auto_ptr<reco::JetPiZeroAssociation> association;
00117 
00118   if (jetRefs.size()) {
00119     association.reset(
00120         new reco::JetPiZeroAssociation(reco::PFJetRefProd(jetRefs)));
00121   } else {
00122     association.reset(new reco::JetPiZeroAssociation);
00123   }
00124 
00125   // Loop over our jets
00126   BOOST_FOREACH(const reco::PFJetRef& jet, jetRefs) {
00127     // Build our global list of RecoTauPiZero
00128     PiZeroList dirtyPiZeros;
00129 
00130     // Compute the pi zeros from this jet for all the desired algorithms
00131     BOOST_FOREACH(const Builder& builder, builders_) {
00132       try {
00133         PiZeroVector result(builder(*jet));
00134         dirtyPiZeros.transfer(dirtyPiZeros.end(), result);
00135       } catch ( cms::Exception &exception) {
00136         edm::LogError("BuilderPluginException")
00137             << "Exception caught in builder plugin " << builder.name()
00138             << ", rethrowing" << std::endl;
00139         throw exception;
00140       }
00141     }
00142     // Rank the candidates according to our quality plugins
00143     dirtyPiZeros.sort(*predicate_);
00144 
00145     // Keep track of the photons in the clean collection
00146     std::vector<reco::RecoTauPiZero> cleanPiZeros;
00147     std::set<reco::CandidatePtr> photonsInCleanCollection;
00148     while (dirtyPiZeros.size()) {
00149       // Pull our candidate pi zero from the front of the list
00150       std::auto_ptr<reco::RecoTauPiZero> toAdd(
00151           dirtyPiZeros.pop_front().release());
00152       // Find the sub-gammas that are not already in the cleaned collection
00153       std::vector<reco::CandidatePtr> uniqueGammas;
00154       std::set_difference(toAdd->daughterPtrVector().begin(),
00155                           toAdd->daughterPtrVector().end(),
00156                           photonsInCleanCollection.begin(),
00157                           photonsInCleanCollection.end(),
00158                           std::back_inserter(uniqueGammas));
00159       // If the pi zero has no unique gammas, discard it.  Note toAdd is deleted
00160       // when it goes out of scope.
00161       if (!uniqueGammas.size()) {
00162         continue;
00163       } else if (uniqueGammas.size() == toAdd->daughterPtrVector().size()) {
00164         // Check if it is composed entirely of unique gammas.  In this case
00165         // immediately add it to the clean collection.
00166         photonsInCleanCollection.insert(toAdd->daughterPtrVector().begin(),
00167                                         toAdd->daughterPtrVector().end());
00168         cleanPiZeros.push_back(*toAdd);
00169       } else {
00170         // Otherwise update the pizero that contains only the unique gammas and
00171         // add it back into the sorted list of dirty PiZeros
00172         toAdd->clearDaughters();
00173         // Add each of the unique daughters back to the pizero
00174         BOOST_FOREACH(const reco::CandidatePtr& gamma, uniqueGammas) {
00175           toAdd->addDaughter(gamma);
00176         }
00177         // Update the four vector
00178         AddFourMomenta p4Builder_;
00179         p4Builder_.set(*toAdd);
00180         // Put this pi zero back into the collection of sorted dirty pizeros
00181         PiZeroList::iterator insertionPoint = std::lower_bound(
00182             dirtyPiZeros.begin(), dirtyPiZeros.end(), *toAdd, *predicate_);
00183         dirtyPiZeros.insert(insertionPoint, toAdd);
00184       }
00185     }
00186     // Apply the mass hypothesis if desired
00187     if (piZeroMass_ >= 0) {
00188       std::for_each(
00189           cleanPiZeros.begin(), cleanPiZeros.end(),
00190           std::bind2nd(
00191               std::mem_fun_ref(&reco::RecoTauPiZero::setMass), piZeroMass_));
00192     }
00193     // Add to association
00194     //print(cleanPiZeros, std::cout);
00195     association->setValue(jet.key(), cleanPiZeros);
00196   }
00197   evt.put(association);
00198 }
00199 
00200 // Print some helpful information
00201 void RecoTauPiZeroProducer::print(
00202     const std::vector<reco::RecoTauPiZero>& piZeros, std::ostream& out) {
00203   const unsigned int width = 25;
00204   BOOST_FOREACH(const reco::RecoTauPiZero& piZero, piZeros) {
00205     out << piZero;
00206     out << "* Rankers:" << std::endl;
00207     for (rankerList::const_iterator ranker = rankers_.begin();
00208         ranker != rankers_.end(); ++ranker) {
00209       out << "* " << std::setiosflags(std::ios::left)
00210         << std::setw(width) << ranker->name()
00211         << " " << std::resetiosflags(std::ios::left)
00212         << std::setprecision(3) << (*ranker)(piZero);
00213       out << std::endl;
00214     }
00215   }
00216 }
00217 
00218 #include "FWCore/Framework/interface/MakerMacros.h"
00219 DEFINE_FWK_MODULE(RecoTauPiZeroProducer);