CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoTauTag/RecoTau/plugins/RecoTauBuilderConePlugin.cc

Go to the documentation of this file.
00001 /*
00002  * RecoTauBuilderConePlugin
00003  *
00004  * Build a PFTau using cones defined in DeltaR.
00005  *
00006  * Original Authors: Ludovic Houchu, Simone Gennai
00007  * Modifications: Evan K. Friis
00008  *
00009  * $Id $
00010  */
00011 
00012 #include <vector>
00013 #include <algorithm>
00014 
00015 #include "RecoTauTag/RecoTau/interface/RecoTauBuilderPlugins.h"
00016 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00017 #include "RecoTauTag/RecoTau/interface/RecoTauConstructor.h"
00018 #include "RecoTauTag/RecoTau/interface/RecoTauQualityCuts.h"
00019 
00020 #include "RecoTauTag/RecoTau/interface/ConeTools.h"
00021 #include "RecoTauTag/RecoTau/interface/RecoTauCrossCleaning.h"
00022 
00023 #include "DataFormats/TauReco/interface/PFTau.h"
00024 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
00025 #include "DataFormats/Math/interface/deltaR.h"
00026 
00027 #include "CommonTools/Utils/interface/StringObjectFunction.h"
00028 
00029 namespace reco { namespace tau {
00030 
00031 class RecoTauBuilderConePlugin : public RecoTauBuilderPlugin {
00032   public:
00033     explicit RecoTauBuilderConePlugin(const edm::ParameterSet& pset);
00034     ~RecoTauBuilderConePlugin() {}
00035     // Build a tau from a jet
00036     return_type operator()(const reco::PFJetRef& jet,
00037         const std::vector<RecoTauPiZero>& piZeros,
00038         const std::vector<PFCandidatePtr>& regionalExtras) const;
00039   private:
00040     RecoTauQualityCuts qcuts_;
00041     bool usePFLeptonsAsChargedHadrons_;
00042     double leadObjecPtThreshold_;
00043     /* String function to extract values from PFJets */
00044     typedef StringObjectFunction<reco::PFJet> JetFunc;
00045     // Cone defintions
00046     JetFunc matchingCone_;
00047     JetFunc signalConeChargedHadrons_;
00048     JetFunc isoConeChargedHadrons_;
00049     JetFunc signalConePiZeros_;
00050     JetFunc isoConePiZeros_;
00051     JetFunc signalConeNeutralHadrons_;
00052     JetFunc isoConeNeutralHadrons_;
00053 };
00054 
00055 // ctor - initialize all of our variables
00056 RecoTauBuilderConePlugin::RecoTauBuilderConePlugin(
00057     const edm::ParameterSet& pset):RecoTauBuilderPlugin(pset),
00058     qcuts_(pset.getParameter<edm::ParameterSet>("qualityCuts")),
00059     usePFLeptonsAsChargedHadrons_(pset.getParameter<bool>("usePFLeptons")),
00060     leadObjecPtThreshold_(pset.getParameter<double>("leadObjectPt")),
00061     matchingCone_(pset.getParameter<std::string>("matchingCone")),
00062     signalConeChargedHadrons_(pset.getParameter<std::string>(
00063             "signalConeChargedHadrons")),
00064     isoConeChargedHadrons_(
00065         pset.getParameter<std::string>("isoConeChargedHadrons")),
00066     signalConePiZeros_(
00067         pset.getParameter<std::string>("signalConePiZeros")),
00068     isoConePiZeros_(
00069         pset.getParameter<std::string>("isoConePiZeros")),
00070     signalConeNeutralHadrons_(
00071         pset.getParameter<std::string>("signalConeNeutralHadrons")),
00072     isoConeNeutralHadrons_(
00073         pset.getParameter<std::string>("isoConeNeutralHadrons")) {}
00074 
00075 RecoTauBuilderConePlugin::return_type RecoTauBuilderConePlugin::operator()(
00076     const reco::PFJetRef& jet,
00077     const std::vector<RecoTauPiZero>& piZeros,
00078     const std::vector<PFCandidatePtr>& regionalExtras) const {
00079   // Get access to our cone tools
00080   using namespace cone;
00081   // Define output.  We only produce one tau per jet for the cone algo.
00082   output_type output;
00083 
00084   // Our tau builder - the true indicates to automatically copy gamma candidates
00085   // from the pizeros.
00086   RecoTauConstructor tau(jet, getPFCands(), true);
00087   // Setup our quality cuts to use the current vertex (supplied by base class)
00088   qcuts_.setPV(primaryVertex());
00089 
00090   typedef std::vector<PFCandidatePtr> PFCandPtrs;
00091 
00092   // Get the PF Charged hadrons + quality cuts
00093   PFCandPtrs pfchs;
00094   if (!usePFLeptonsAsChargedHadrons_) {
00095     pfchs = qcuts_.filterRefs(pfCandidates(*jet, reco::PFCandidate::h));
00096   } else {
00097     // Check if we want to include electrons in muons in "charged hadron"
00098     // collection.  This is the preferred behavior, as the PF lepton selections
00099     // are very loose.
00100     pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
00101   }
00102 
00103   // Get the PF gammas
00104   PFCandPtrs pfGammas = qcuts_.filterRefs(
00105       pfCandidates(*jet, reco::PFCandidate::gamma));
00106   // Neutral hadrons
00107   PFCandPtrs pfnhs = qcuts_.filterRefs(
00108       pfCandidates(*jet, reco::PFCandidate::h0));
00109 
00110   // All the extra junk
00111   PFCandPtrs regionalJunk = qcuts_.filterRefs(regionalExtras);
00112 
00113   /***********************************************
00114    ******     Lead Candidate Finding    **********
00115    ***********************************************/
00116 
00117   // Define our matching cone and filters
00118   double matchingCone = matchingCone_(*jet);
00119   PFCandPtrDRFilter matchingConeFilter(jet->p4(), 0, matchingCone);
00120 
00121   // Find the maximum PFCharged hadron in the matching cone.  The call to
00122   // PFCandidates always a sorted list, so we can just take the first if it
00123   // if it exists.
00124   PFCandidatePtr leadPFCH;
00125   PFCandPtrs::iterator leadPFCH_iter =
00126       std::find_if(pfchs.begin(), pfchs.end(), matchingConeFilter);
00127 
00128   if (leadPFCH_iter != pfchs.end()) {
00129     leadPFCH = *leadPFCH_iter;
00130     // Set leading candidate
00131     tau.setleadPFChargedHadrCand(leadPFCH);
00132   } else {
00133     // If there is no leading charged candidate at all, return nothing - the
00134     // producer class that owns the plugin will build a null tau if desired.
00135     return output.release();
00136   }
00137 
00138   // Find the leading neutral candidate
00139   PFCandidatePtr leadPFGamma;
00140   PFCandPtrs::iterator leadPFGamma_iter =
00141       std::find_if(pfGammas.begin(), pfGammas.end(), matchingConeFilter);
00142 
00143   if (leadPFGamma_iter != pfGammas.end()) {
00144     leadPFGamma = *leadPFGamma_iter;
00145     // Set leading neutral candidate
00146     tau.setleadPFNeutralCand(leadPFGamma);
00147   }
00148 
00149   PFCandidatePtr leadPFCand;
00150   // Always use the leadPFCH if it is above our threshold
00151   if (leadPFCH.isNonnull() && leadPFCH->pt() > leadObjecPtThreshold_) {
00152     leadPFCand = leadPFCH;
00153   } else if (leadPFGamma.isNonnull() &&
00154              leadPFGamma->pt() > leadObjecPtThreshold_) {
00155     // Otherwise use the lead Gamma if it is above threshold
00156     leadPFCand = leadPFGamma;
00157   } else {
00158     // If both are too low PT, just take the charged one
00159     leadPFCand = leadPFCH;
00160   }
00161 
00162   tau.setleadPFCand(leadPFCand);
00163 
00164   // Our cone axis is defined about the lead charged hadron
00165   reco::Candidate::LorentzVector coneAxis = leadPFCH->p4();
00166 
00167   /***********************************************
00168    ******     Cone Construction         **********
00169    ***********************************************/
00170 
00171   // Define the signal and isolation cone sizes for this jet and build filters
00172   // to select elements in the given DeltaR regions
00173 
00174   PFCandPtrDRFilter signalConePFCHFilter(
00175       coneAxis, -0.1, signalConeChargedHadrons_(*jet));
00176   PFCandPtrDRFilter signalConePFNHFilter(
00177       coneAxis, -0.1, signalConeNeutralHadrons_(*jet));
00178   PiZeroDRFilter signalConePiZeroFilter(
00179       coneAxis, -0.1, signalConePiZeros_(*jet));
00180 
00181   PFCandPtrDRFilter isoConePFCHFilter(
00182       coneAxis, signalConeChargedHadrons_(*jet), isoConeChargedHadrons_(*jet));
00183   PFCandPtrDRFilter isoConePFGammaFilter(
00184       coneAxis, signalConePiZeros_(*jet), isoConePiZeros_(*jet));
00185   PFCandPtrDRFilter isoConePFNHFilter(
00186       coneAxis, signalConeNeutralHadrons_(*jet), isoConeNeutralHadrons_(*jet));
00187   PiZeroDRFilter isoConePiZeroFilter(
00188       coneAxis, signalConePiZeros_(*jet), isoConePiZeros_(*jet));
00189 
00190   // Additionally make predicates to select the different PF object types
00191   // of the regional junk objects to add to the iso cone.
00192   typedef xclean::PredicateAND<xclean::FilterPFCandByParticleId,
00193           PFCandPtrDRFilter> RegionalJunkConeAndIdFilter;
00194 
00195   xclean::FilterPFCandByParticleId
00196     pfchCandSelector(reco::PFCandidate::h);
00197   xclean::FilterPFCandByParticleId
00198     pfgammaCandSelector(reco::PFCandidate::gamma);
00199   xclean::FilterPFCandByParticleId
00200     pfnhCandSelector(reco::PFCandidate::h0);
00201 
00202   // Predicate to select the regional junk in the iso cone by PF id
00203   RegionalJunkConeAndIdFilter pfChargedJunk(
00204       pfchCandSelector, // select charged stuff from junk
00205       isoConePFCHFilter // only take those in iso cone
00206       );
00207 
00208   RegionalJunkConeAndIdFilter pfGammaJunk(
00209       pfgammaCandSelector, // select gammas from junk
00210       isoConePFGammaFilter // only take those in iso cone
00211       );
00212 
00213   RegionalJunkConeAndIdFilter pfNeutralJunk(
00214       pfnhCandSelector, // select neutral stuff from junk
00215       isoConePFNHFilter // select stuff in iso cone
00216       );
00217 
00218   // Build filter iterators select the signal charged stuff.
00219   PFCandPtrDRFilterIter signalPFCHs_begin(
00220       signalConePFCHFilter, pfchs.begin(), pfchs.end());
00221   PFCandPtrDRFilterIter signalPFCHs_end(
00222       signalConePFCHFilter, pfchs.end(), pfchs.end());
00223 
00224   // Cross clean pi zero content using signal cone charged hadron constituents.
00225   xclean::CrossCleanPiZeros<PFCandPtrDRFilterIter> xCleaner(
00226       signalPFCHs_begin, signalPFCHs_end);
00227   std::vector<reco::RecoTauPiZero> cleanPiZeros = xCleaner(piZeros);
00228 
00229   // For the rest of the constituents, we need to filter any constituents that
00230   // are already contained in the pizeros (i.e. electrons)
00231   xclean::CrossCleanPtrs pfCandXCleaner(cleanPiZeros);
00232 
00233   // Build signal charged hadrons
00234   tau.addPFCands(RecoTauConstructor::kSignal,
00235                  RecoTauConstructor::kChargedHadron,
00236                  signalPFCHs_begin, signalPFCHs_end);
00237 
00238   tau.addPFCands(RecoTauConstructor::kSignal,
00239                  RecoTauConstructor::kNeutralHadron,
00240                  boost::make_filter_iterator(
00241                    xclean::makePredicateAND(signalConePFNHFilter, pfCandXCleaner),
00242                    pfnhs.begin(), pfnhs.end()),
00243                  boost::make_filter_iterator(
00244                    xclean::makePredicateAND(signalConePFNHFilter, pfCandXCleaner),
00245                    pfnhs.end(), pfnhs.end()));
00246 
00247   // Build signal PiZeros
00248   tau.addPiZeros(RecoTauConstructor::kSignal,
00249                  PiZeroDRFilterIter(signalConePiZeroFilter,
00250                                     cleanPiZeros.begin(), cleanPiZeros.end()),
00251                  PiZeroDRFilterIter(signalConePiZeroFilter,
00252                                     cleanPiZeros.end(), cleanPiZeros.end()));
00253 
00254   // Build isolation charged hadrons
00255   tau.addPFCands(RecoTauConstructor::kIsolation,
00256                  RecoTauConstructor::kChargedHadron,
00257                  boost::make_filter_iterator(
00258                    xclean::makePredicateAND(isoConePFCHFilter, pfCandXCleaner),
00259                    pfchs.begin(), pfchs.end()),
00260                  boost::make_filter_iterator(
00261                    xclean::makePredicateAND(isoConePFCHFilter, pfCandXCleaner),
00262                    pfchs.end(), pfchs.end()));
00263 
00264   // Add all the stuff in the isolation cone that wasn't in the jet constituents
00265   tau.addPFCands(RecoTauConstructor::kIsolation,
00266                  RecoTauConstructor::kChargedHadron,
00267                  boost::make_filter_iterator(
00268                    pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
00269                  boost::make_filter_iterator(
00270                    pfChargedJunk, regionalJunk.end(), regionalJunk.end())
00271       );
00272 
00273   // Build isolation neutral hadrons
00274   tau.addPFCands(RecoTauConstructor::kIsolation,
00275                  RecoTauConstructor::kNeutralHadron,
00276                  boost::make_filter_iterator(
00277                    xclean::makePredicateAND(isoConePFNHFilter, pfCandXCleaner),
00278                    pfnhs.begin(), pfnhs.end()),
00279                  boost::make_filter_iterator(
00280                    xclean::makePredicateAND(isoConePFNHFilter, pfCandXCleaner),
00281                    pfnhs.end(), pfnhs.end()));
00282 
00283   // Add regional stuff not in jet
00284   tau.addPFCands(RecoTauConstructor::kIsolation,
00285                  RecoTauConstructor::kNeutralHadron,
00286                  boost::make_filter_iterator(
00287                    pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
00288                  boost::make_filter_iterator(
00289                    pfNeutralJunk, regionalJunk.end(), regionalJunk.end())
00290       );
00291 
00292   // Build isolation PiZeros
00293   tau.addPiZeros(RecoTauConstructor::kIsolation,
00294                  PiZeroDRFilterIter(isoConePiZeroFilter, cleanPiZeros.begin(),
00295                                     cleanPiZeros.end()),
00296                  PiZeroDRFilterIter(isoConePiZeroFilter, cleanPiZeros.end(),
00297                                     cleanPiZeros.end()));
00298 
00299   // Add regional stuff not in jet
00300   tau.addPFCands(RecoTauConstructor::kIsolation,
00301                  RecoTauConstructor::kGamma,
00302                  boost::make_filter_iterator(
00303                    pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
00304                  boost::make_filter_iterator(
00305                    pfGammaJunk, regionalJunk.end(), regionalJunk.end())
00306       );
00307 
00308   // Put our built tau in the output - 'false' indicates don't build the
00309   // leading candidtes, we already did that explicitly above.
00310 
00311   output.push_back(tau.get(false));
00312   return output.release();
00313 }
00314 }}  // end namespace reco::tauk
00315 
00316 #include "FWCore/Framework/interface/MakerMacros.h"
00317 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory,
00318                   reco::tau::RecoTauBuilderConePlugin,
00319                   "RecoTauBuilderConePlugin");