CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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 #include "DataFormats/Common/interface/Association.h"
00036 
00037 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
00038 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
00039 
00040 class RecoTauPiZeroProducer : public edm::EDProducer {
00041   public:
00042     typedef reco::tau::RecoTauPiZeroBuilderPlugin Builder;
00043     typedef reco::tau::RecoTauPiZeroQualityPlugin Ranker;
00044 
00045     explicit RecoTauPiZeroProducer(const edm::ParameterSet& pset);
00046     ~RecoTauPiZeroProducer() {}
00047     void produce(edm::Event& evt, const edm::EventSetup& es);
00048     void print(const std::vector<reco::RecoTauPiZero>& piZeros,
00049                std::ostream& out);
00050 
00051   private:
00052     typedef boost::ptr_vector<Builder> builderList;
00053     typedef boost::ptr_vector<Ranker> rankerList;
00054     typedef boost::ptr_vector<reco::RecoTauPiZero> PiZeroVector;
00055     typedef boost::ptr_list<reco::RecoTauPiZero> PiZeroList;
00056 
00057     typedef reco::tau::RecoTauLexicographicalRanking<rankerList,
00058             reco::RecoTauPiZero> PiZeroPredicate;
00059 
00060     edm::InputTag src_;
00061     builderList builders_;
00062     rankerList rankers_;
00063     std::auto_ptr<PiZeroPredicate> predicate_;
00064     double piZeroMass_;
00065 
00066     // Output selector
00067     std::auto_ptr<StringCutObjectSelector<reco::RecoTauPiZero> >
00068       outputSelector_;
00069 };
00070 
00071 RecoTauPiZeroProducer::RecoTauPiZeroProducer(const edm::ParameterSet& pset) {
00072   src_ = pset.getParameter<edm::InputTag>("jetSrc");
00073 
00074   typedef std::vector<edm::ParameterSet> VPSet;
00075   // Get the mass hypothesis for the pizeros
00076   piZeroMass_ = pset.getParameter<double>("massHypothesis");
00077 
00078   // Get each of our PiZero builders
00079   const VPSet& builders = pset.getParameter<VPSet>("builders");
00080 
00081   for (VPSet::const_iterator builderPSet = builders.begin();
00082       builderPSet != builders.end(); ++builderPSet) {
00083     // Get plugin name
00084     const std::string& pluginType =
00085       builderPSet->getParameter<std::string>("plugin");
00086     // Build the plugin
00087     builders_.push_back(RecoTauPiZeroBuilderPluginFactory::get()->create(
00088           pluginType, *builderPSet));
00089   }
00090 
00091   // Get each of our quality rankers
00092   const VPSet& rankers = pset.getParameter<VPSet>("ranking");
00093   for (VPSet::const_iterator rankerPSet = rankers.begin();
00094       rankerPSet != rankers.end(); ++rankerPSet) {
00095     const std::string& pluginType =
00096       rankerPSet->getParameter<std::string>("plugin");
00097     rankers_.push_back(RecoTauPiZeroQualityPluginFactory::get()->create(
00098           pluginType, *rankerPSet));
00099   }
00100 
00101   // Build the sorting predicate
00102   predicate_ = std::auto_ptr<PiZeroPredicate>(new PiZeroPredicate(rankers_));
00103 
00104   // Check if we want to apply a final output selection
00105   if (pset.exists("outputSelection")) {
00106     std::string selection = pset.getParameter<std::string>("outputSelection");
00107     if (selection != "") {
00108       outputSelector_.reset(
00109           new StringCutObjectSelector<reco::RecoTauPiZero>(selection));
00110     }
00111   }
00112 
00113   produces<reco::JetPiZeroAssociation>();
00114 }
00115 
00116 void RecoTauPiZeroProducer::produce(edm::Event& evt,
00117                                     const edm::EventSetup& es) {
00118   // Get a view of our jets via the base candidates
00119   edm::Handle<reco::CandidateView> jetView;
00120   evt.getByLabel(src_, jetView);
00121 
00122   // Give each of our plugins a chance at doing something with the edm::Event
00123   BOOST_FOREACH(Builder& builder, builders_) {
00124     builder.setup(evt, es);
00125   }
00126 
00127   // Convert the view to a RefVector of actual PFJets
00128   reco::PFJetRefVector jetRefs =
00129       reco::tau::castView<reco::PFJetRefVector>(jetView);
00130   // Make our association
00131   std::auto_ptr<reco::JetPiZeroAssociation> association;
00132 
00133   if (jetRefs.size()) {
00134     association.reset(
00135         new reco::JetPiZeroAssociation(reco::PFJetRefProd(jetRefs)));
00136   } else {
00137     association.reset(new reco::JetPiZeroAssociation);
00138   }
00139 
00140   // Loop over our jets
00141   BOOST_FOREACH(const reco::PFJetRef& jet, jetRefs) {
00142     // Build our global list of RecoTauPiZero
00143     PiZeroList dirtyPiZeros;
00144 
00145     // Compute the pi zeros from this jet for all the desired algorithms
00146     BOOST_FOREACH(const Builder& builder, builders_) {
00147       try {
00148         PiZeroVector result(builder(*jet));
00149         dirtyPiZeros.transfer(dirtyPiZeros.end(), result);
00150       } catch ( cms::Exception &exception) {
00151         edm::LogError("BuilderPluginException")
00152             << "Exception caught in builder plugin " << builder.name()
00153             << ", rethrowing" << std::endl;
00154         throw exception;
00155       }
00156     }
00157     // Rank the candidates according to our quality plugins
00158     dirtyPiZeros.sort(*predicate_);
00159 
00160     // Keep track of the photons in the clean collection
00161     std::vector<reco::RecoTauPiZero> cleanPiZeros;
00162     std::set<reco::CandidatePtr> photonsInCleanCollection;
00163     while (dirtyPiZeros.size()) {
00164       // Pull our candidate pi zero from the front of the list
00165       std::auto_ptr<reco::RecoTauPiZero> toAdd(
00166           dirtyPiZeros.pop_front().release());
00167       // If this doesn't pass our basic selection, discard it.
00168       if (!(*outputSelector_)(*toAdd)) {
00169         continue;
00170       }
00171       // Find the sub-gammas that are not already in the cleaned collection
00172       std::vector<reco::CandidatePtr> uniqueGammas;
00173       std::set_difference(toAdd->daughterPtrVector().begin(),
00174                           toAdd->daughterPtrVector().end(),
00175                           photonsInCleanCollection.begin(),
00176                           photonsInCleanCollection.end(),
00177                           std::back_inserter(uniqueGammas));
00178       // If the pi zero has no unique gammas, discard it.  Note toAdd is deleted
00179       // when it goes out of scope.
00180       if (!uniqueGammas.size()) {
00181         continue;
00182       } else if (uniqueGammas.size() == toAdd->daughterPtrVector().size()) {
00183         // Check if it is composed entirely of unique gammas.  In this case
00184         // immediately add it to the clean collection.
00185         photonsInCleanCollection.insert(toAdd->daughterPtrVector().begin(),
00186                                         toAdd->daughterPtrVector().end());
00187         cleanPiZeros.push_back(*toAdd);
00188       } else {
00189         // Otherwise update the pizero that contains only the unique gammas and
00190         // add it back into the sorted list of dirty PiZeros
00191         toAdd->clearDaughters();
00192         // Add each of the unique daughters back to the pizero
00193         BOOST_FOREACH(const reco::CandidatePtr& gamma, uniqueGammas) {
00194           toAdd->addDaughter(gamma);
00195         }
00196         // Update the four vector
00197         AddFourMomenta p4Builder_;
00198         p4Builder_.set(*toAdd);
00199         // Put this pi zero back into the collection of sorted dirty pizeros
00200         PiZeroList::iterator insertionPoint = std::lower_bound(
00201             dirtyPiZeros.begin(), dirtyPiZeros.end(), *toAdd, *predicate_);
00202         dirtyPiZeros.insert(insertionPoint, toAdd);
00203       }
00204     }
00205     // Apply the mass hypothesis if desired
00206     if (piZeroMass_ >= 0) {
00207       std::for_each(
00208           cleanPiZeros.begin(), cleanPiZeros.end(),
00209           std::bind2nd(
00210               std::mem_fun_ref(&reco::RecoTauPiZero::setMass), piZeroMass_));
00211     }
00212     // Add to association
00213     //print(cleanPiZeros, std::cout);
00214     association->setValue(jet.key(), cleanPiZeros);
00215   }
00216   evt.put(association);
00217 }
00218 
00219 // Print some helpful information
00220 void RecoTauPiZeroProducer::print(
00221     const std::vector<reco::RecoTauPiZero>& piZeros, std::ostream& out) {
00222   const unsigned int width = 25;
00223   BOOST_FOREACH(const reco::RecoTauPiZero& piZero, piZeros) {
00224     out << piZero;
00225     out << "* Rankers:" << std::endl;
00226     for (rankerList::const_iterator ranker = rankers_.begin();
00227         ranker != rankers_.end(); ++ranker) {
00228       out << "* " << std::setiosflags(std::ios::left)
00229         << std::setw(width) << ranker->name()
00230         << " " << std::resetiosflags(std::ios::left)
00231         << std::setprecision(3) << (*ranker)(piZero);
00232       out << std::endl;
00233     }
00234   }
00235 }
00236 
00237 #include "FWCore/Framework/interface/MakerMacros.h"
00238 DEFINE_FWK_MODULE(RecoTauPiZeroProducer);