CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoTauTag/RecoTau/plugins/RecoTauProducer.cc

Go to the documentation of this file.
00001 /*
00002  * RecoTauProducer
00003  *
00004  * Interface between the various tau algorithms and the edm::Event.  The
00005  * RecoTauProducer takes as data input is a collection (view) of reco::PFJets,
00006  * and Jet-PiZero assoications that give the reco::RecoTauPiZeros for those
00007  * jets.  The actaul building of taus is done by the list of builders - each of
00008  * which constructs a PFTau for each PFJet.  The output collection may have
00009  * multiple taus for each PFJet - these overlaps are to be resolved by the
00010  * RecoTauCleaner module.
00011  *
00012  * Additionally, there are "modifier" plugins, which can do things like add the
00013  * lead track significance, or electron rejection variables.
00014  *
00015  * Author: Evan K. Friis (UC Davis)
00016  *
00017  */
00018 #include <boost/ptr_container/ptr_vector.hpp>
00019 #include <boost/foreach.hpp>
00020 
00021 #include <algorithm>
00022 #include <functional>
00023 
00024 #include "FWCore/Framework/interface/EDProducer.h"
00025 #include "FWCore/Framework/interface/EventSetup.h"
00026 #include "FWCore/Framework/interface/ESHandle.h"
00027 #include "FWCore/Framework/interface/Event.h"
00028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00029 
00030 #include "RecoTauTag/RecoTau/interface/RecoTauBuilderPlugins.h"
00031 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00032 
00033 #include "DataFormats/JetReco/interface/PFJetCollection.h"
00034 #include "DataFormats/TauReco/interface/JetPiZeroAssociation.h"
00035 #include "DataFormats/TauReco/interface/PFTau.h"
00036 #include "DataFormats/Candidate/interface/CandidateFwd.h"
00037 #include "DataFormats/Common/interface/Association.h"
00038 
00039 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
00040 
00041 class RecoTauProducer : public edm::EDProducer {
00042   public:
00043     typedef reco::tau::RecoTauBuilderPlugin Builder;
00044     typedef reco::tau::RecoTauModifierPlugin Modifier;
00045     typedef boost::ptr_vector<Builder> BuilderList;
00046     typedef boost::ptr_vector<Modifier> ModifierList;
00047 
00048     explicit RecoTauProducer(const edm::ParameterSet& pset);
00049     ~RecoTauProducer() {}
00050     void produce(edm::Event& evt, const edm::EventSetup& es);
00051 
00052   private:
00053     edm::InputTag jetSrc_;
00054     edm::InputTag jetRegionSrc_;
00055     edm::InputTag piZeroSrc_;
00056     BuilderList builders_;
00057     ModifierList modifiers_;
00058     // Optional selection on the output of the taus
00059     std::auto_ptr<StringCutObjectSelector<reco::PFTau> > outputSelector_;
00060     // Whether or not to add build a tau from a jet for which the builders
00061     // return no taus.  The tau will have no content, only the four vector of
00062     // the orginal jet.
00063     bool buildNullTaus_;
00064 };
00065 
00066 RecoTauProducer::RecoTauProducer(const edm::ParameterSet& pset) {
00067   jetSrc_ = pset.getParameter<edm::InputTag>("jetSrc");
00068   jetRegionSrc_ = pset.getParameter<edm::InputTag>("jetRegionSrc");
00069   piZeroSrc_ = pset.getParameter<edm::InputTag>("piZeroSrc");
00070 
00071   typedef std::vector<edm::ParameterSet> VPSet;
00072   // Get each of our tau builders
00073   const VPSet& builders = pset.getParameter<VPSet>("builders");
00074   for (VPSet::const_iterator builderPSet = builders.begin();
00075       builderPSet != builders.end(); ++builderPSet) {
00076     // Get plugin name
00077     const std::string& pluginType =
00078         builderPSet->getParameter<std::string>("plugin");
00079     const std::string& pluginName =
00080         builderPSet->getParameter<std::string>("name");
00081     // Build the plugin
00082     try {
00083       builders_.push_back(
00084           RecoTauBuilderPluginFactory::get()->create(
00085             pluginType, *builderPSet));
00086     } catch (...) {
00087       edm::LogError("RecoTauBuilderException")
00088         << "Exception when building a RecoTauBuilder plugin of type: "
00089         << pluginType << " name: " << pluginName << std::endl;
00090       throw; // rethrow
00091     }
00092   }
00093 
00094   const VPSet& modfiers = pset.getParameter<VPSet>("modifiers");
00095   for (VPSet::const_iterator modfierPSet = modfiers.begin();
00096       modfierPSet != modfiers.end(); ++modfierPSet) {
00097     // Get plugin name
00098     const std::string& pluginType =
00099         modfierPSet->getParameter<std::string>("plugin");
00100     const std::string& pluginName =
00101         modfierPSet->getParameter<std::string>("name");
00102     // Build the plugin
00103     try {
00104       modifiers_.push_back(
00105           RecoTauModifierPluginFactory::get()->create(
00106             pluginType, *modfierPSet));
00107     } catch (...) {
00108       edm::LogError("RecoTauModifierException")
00109         << "Exception when building a RecoTauModifier plugin of type: "
00110         << pluginType << " name: " << pluginName << std::endl;
00111       throw; // rethrow
00112     }
00113   }
00114 
00115   // Check if we want to apply a final output selection
00116   if (pset.exists("outputSelection")) {
00117     std::string selection = pset.getParameter<std::string>("outputSelection");
00118     if (selection != "") {
00119       outputSelector_.reset(
00120           new StringCutObjectSelector<reco::PFTau>(selection));
00121     }
00122   }
00123   buildNullTaus_ = pset.getParameter<bool>("buildNullTaus");
00124   produces<reco::PFTauCollection>();
00125 }
00126 
00127 void RecoTauProducer::produce(edm::Event& evt, const edm::EventSetup& es) {
00128   // Get the jet input collection via a view of Candidates
00129   edm::Handle<reco::CandidateView> jetView;
00130   evt.getByLabel(jetSrc_, jetView);
00131 
00132   // Convert to a vector of PFJetRefs
00133   reco::PFJetRefVector jets =
00134       reco::tau::castView<reco::PFJetRefVector>(jetView);
00135 
00136   // Get the jet region producer
00137   edm::Handle<edm::Association<reco::PFJetCollection> > jetRegionHandle;
00138   evt.getByLabel(jetRegionSrc_, jetRegionHandle);
00139 
00140   // Get the pizero input collection
00141   edm::Handle<reco::JetPiZeroAssociation> piZeroAssoc;
00142   evt.getByLabel(piZeroSrc_, piZeroAssoc);
00143 
00144   // Update all our builders and modifiers with the event info
00145   for (BuilderList::iterator builder = builders_.begin();
00146       builder != builders_.end(); ++builder) {
00147     builder->setup(evt, es);
00148   }
00149   for (ModifierList::iterator modifier = modifiers_.begin();
00150       modifier != modifiers_.end(); ++modifier) {
00151     modifier->setup(evt, es);
00152   }
00153 
00154   // Create output collection
00155   std::auto_ptr<reco::PFTauCollection> output(new reco::PFTauCollection());
00156 
00157   // Loop over the jets and build the taus for each jet
00158   BOOST_FOREACH(reco::PFJetRef jetRef, jets) {
00159     // Get the jet with extra constituents from an area around the jet
00160     reco::PFJetRef jetRegionRef = (*jetRegionHandle)[jetRef];
00161     if (jetRegionRef.isNull()) {
00162       throw cms::Exception("BadJetRegionRef") << "No jet region can be"
00163         << " found for the current jet: " << jetRef.id();
00164     }
00165     // Remove all the jet constituents from the jet extras
00166     std::vector<reco::PFCandidatePtr> jetCands = jetRef->getPFConstituents();
00167     std::vector<reco::PFCandidatePtr> allRegionalCands =
00168       jetRegionRef->getPFConstituents();
00169     // Sort both by ref key
00170     std::sort(jetCands.begin(), jetCands.end());
00171     std::sort(allRegionalCands.begin(), allRegionalCands.end());
00172     // Get the regional junk candidates not in the jet.
00173     std::vector<reco::PFCandidatePtr> uniqueRegionalCands;
00174 
00175     // This can actually be less than zero, if the jet has really crazy soft
00176     // stuff really far away from the jet axis.
00177     if (allRegionalCands.size() > jetCands.size())
00178       uniqueRegionalCands.reserve(allRegionalCands.size() - jetCands.size());
00179 
00180     // Subtract the jet cands from the regional cands
00181     std::set_difference(allRegionalCands.begin(), allRegionalCands.end(),
00182         jetCands.begin(), jetCands.end(),
00183         std::back_inserter(uniqueRegionalCands));
00184 
00185     // Get the PiZeros associated with this jet
00186     const std::vector<reco::RecoTauPiZero>& piZeros = (*piZeroAssoc)[jetRef];
00187     // Loop over our builders and create the set of taus for this jet
00188     unsigned int nTausBuilt = 0;
00189     for (BuilderList::const_iterator builder = builders_.begin();
00190         builder != builders_.end(); ++builder) {
00191       // Get a ptr_vector of taus from the builder
00192       reco::tau::RecoTauBuilderPlugin::output_type taus(
00193           (*builder)(jetRef, piZeros, uniqueRegionalCands));
00194       // Make sure all taus have their jetref set correctly
00195       std::for_each(taus.begin(), taus.end(),
00196           boost::bind(&reco::PFTau::setjetRef, _1, jetRef));
00197       // Check this size of the taus built.
00198       // Grow the vector if necessary
00199       output->reserve(output->size() + taus.size());
00200       // Copy without selection
00201       if (!outputSelector_.get()) {
00202         output->insert(output->end(), taus.begin(), taus.end());
00203         nTausBuilt += taus.size();
00204       } else {
00205         // Copy only those that pass the selection.
00206         BOOST_FOREACH(const reco::PFTau& tau, taus) {
00207           if ((*outputSelector_)(tau)) {
00208             nTausBuilt++;
00209             output->push_back(tau);
00210           }
00211         }
00212       }
00213     }
00214     // If we didn't build *any* taus for this jet, build a null tau if desired.
00215     // The null PFTau has no content, but it's four vector is set to that of the
00216     // jet.
00217     if (!nTausBuilt && buildNullTaus_) {
00218       reco::PFTau nullTau(std::numeric_limits<int>::quiet_NaN(), jetRef->p4());
00219       nullTau.setjetRef(jetRef);
00220       output->push_back(nullTau);
00221     }
00222   }
00223 
00224   // Loop over the taus we have created and apply our modifiers to the taus
00225   for (reco::PFTauCollection::iterator tau = output->begin();
00226       tau != output->end(); ++tau) {
00227     for (ModifierList::const_iterator modifier = modifiers_.begin();
00228         modifier != modifiers_.end(); ++modifier) {
00229       (*modifier)(*tau);
00230     }
00231   }
00232   evt.put(output);
00233 }
00234 
00235 #include "FWCore/Framework/interface/MakerMacros.h"
00236 DEFINE_FWK_MODULE(RecoTauProducer);