CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #include <vector>
00002 
00003 #include "RecoTauTag/RecoTau/interface/RecoTauBuilderPlugins.h"
00004 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00005 
00006 #include "RecoTauTag/RecoTau/interface/CombinatoricGenerator.h"
00007 #include "RecoTauTag/RecoTau/interface/RecoTauCrossCleaning.h"
00008 #include "RecoTauTag/RecoTau/interface/ConeTools.h"
00009 
00010 #include "DataFormats/TauReco/interface/PFTau.h"
00011 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
00012 #include "RecoTauTag/RecoTau/interface/RecoTauConstructor.h"
00013 #include "RecoTauTag/RecoTau/interface/RecoTauQualityCuts.h"
00014 
00015 namespace reco { namespace tau {
00016 
00017 class RecoTauBuilderCombinatoricPlugin : public RecoTauBuilderPlugin {
00018   public:
00019     explicit RecoTauBuilderCombinatoricPlugin(const edm::ParameterSet& pset);
00020     virtual ~RecoTauBuilderCombinatoricPlugin() {}
00021     virtual return_type operator() (const reco::PFJetRef& jet,
00022          const std::vector<RecoTauPiZero>& piZeros,
00023          const std::vector<PFCandidatePtr>& regionalExtras) const;
00024   private:
00025     RecoTauQualityCuts qcuts_;
00026     bool usePFLeptonsAsChargedHadrons_;
00027     double isolationConeSize_;
00028     struct decayModeInfo {
00029       uint32_t maxPiZeros_;
00030       uint32_t maxPFCHs_;
00031       uint32_t nCharged_;
00032       uint32_t nPiZeros_;
00033     };
00034     std::vector<decayModeInfo> decayModesToBuild_;
00035 };
00036 
00037 RecoTauBuilderCombinatoricPlugin::RecoTauBuilderCombinatoricPlugin(
00038     const edm::ParameterSet& pset): RecoTauBuilderPlugin(pset),
00039     qcuts_(pset.getParameter<edm::ParameterSet>("qualityCuts")),
00040     usePFLeptonsAsChargedHadrons_(pset.getParameter<bool>("usePFLeptons")),
00041     isolationConeSize_(pset.getParameter<double>("isolationConeSize")) {
00042   typedef std::vector<edm::ParameterSet> VPSet;
00043   const VPSet& decayModes = pset.getParameter<VPSet>("decayModes");
00044   for (VPSet::const_iterator dm = decayModes.begin();
00045        dm != decayModes.end(); ++dm) {
00046     decayModeInfo info;
00047     info.nCharged_ = dm->getParameter<uint32_t>("nCharged");
00048     info.nPiZeros_ = dm->getParameter<uint32_t>("nPiZeros");
00049     info.maxPFCHs_ = dm->getParameter<uint32_t>("maxTracks");
00050     info.maxPiZeros_ = dm->getParameter<uint32_t>("maxPiZeros");
00051     decayModesToBuild_.push_back(info);
00052   }
00053 }
00054 
00055 RecoTauBuilderCombinatoricPlugin::return_type
00056 RecoTauBuilderCombinatoricPlugin::operator()(
00057     const reco::PFJetRef& jet,
00058     const std::vector<RecoTauPiZero>& piZeros,
00059     const std::vector<PFCandidatePtr>& regionalExtras) const {
00060 
00061   typedef std::vector<PFCandidatePtr> PFCandPtrs;
00062   typedef std::vector<RecoTauPiZero> PiZeroList;
00063 
00064   output_type output;
00065 
00066   // Update the primary vertex used by the quality cuts.  The PV is supplied by
00067   // the base class.
00068   qcuts_.setPV(primaryVertex());
00069 
00070   // Get PFCHs from this jet.  They are already sorted by descending Pt
00071   PFCandPtrs pfchs;
00072   if (!usePFLeptonsAsChargedHadrons_) {
00073     pfchs = qcuts_.filterRefs(pfCandidates(*jet, reco::PFCandidate::h));
00074   } else {
00075     // Check if we want to include electrons in muons in "charged hadron"
00076     // collection.  This is the preferred behavior, as the PF lepton selections
00077     // are very loose.
00078     pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
00079   }
00080 
00081   PFCandPtrs pfnhs = qcuts_.filterRefs(
00082       pfCandidates(*jet, reco::PFCandidate::h0));
00083 
00086   PFCandPtrs regionalJunk = qcuts_.filterRefs(regionalExtras);
00087 
00088   // Loop over the decay modes we want to build
00089   for (std::vector<decayModeInfo>::const_iterator
00090        decayMode = decayModesToBuild_.begin();
00091        decayMode != decayModesToBuild_.end(); ++decayMode) {
00092     // Find how many piZeros are in this decay mode
00093     size_t piZerosToBuild = decayMode->nPiZeros_;
00094     // Find how many tracks are in this decay mode
00095     size_t tracksToBuild = decayMode->nCharged_;
00096 
00097     // Skip decay mode if jet doesn't have the multiplicity to support it
00098     if (pfchs.size() < tracksToBuild)
00099       continue;
00100 
00101     // Find the start and end of potential signal tracks
00102     PFCandPtrs::iterator pfch_begin = pfchs.begin();
00103     PFCandPtrs::iterator pfch_end =  pfchs.end();
00104     pfch_end = takeNElements(pfch_begin, pfch_end, decayMode->maxPFCHs_);
00105 
00106     // Build our track combo generator
00107     typedef tau::CombinatoricGenerator<PFCandPtrs> PFCombo;
00108     PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
00109 
00110     /*
00111      * Begin combinatoric loop for this decay mode
00112      */
00113 
00114     // Loop over the different combinations of tracks
00115     for (PFCombo::iterator trackCombo = trackCombos.begin();
00116          trackCombo != trackCombos.end(); ++trackCombo) {
00117 
00118       xclean::CrossCleanPiZeros<PFCombo::combo_iterator>
00119         xCleaner(trackCombo->combo_begin(), trackCombo->combo_end());
00120 
00121       PiZeroList cleanPiZeros = xCleaner(piZeros);
00122 
00123       // Skip decay mode if we don't have enough remaining clean pizeros to
00124       // build it.
00125       if (cleanPiZeros.size() < piZerosToBuild)
00126         continue;
00127 
00128       // Find the start and end of potential signal tracks
00129       PiZeroList::iterator piZero_begin = cleanPiZeros.begin();
00130       PiZeroList::iterator piZero_end = cleanPiZeros.end();
00131 
00132       piZero_end = takeNElements(piZero_begin, piZero_end,
00133                                  decayMode->maxPiZeros_);
00134 
00135       // Build our piZero combo generator
00136       typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
00137       PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
00138 
00139       // Loop over the different combinations of PiZeros
00140       for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
00141            piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
00142 
00143         // Output tau
00144         RecoTauConstructor tau(jet, getPFCands(), true);
00145         // Reserve space in our collections
00146         tau.reserve(RecoTauConstructor::kSignal,
00147                     RecoTauConstructor::kChargedHadron, tracksToBuild);
00148         tau.reserve(
00149             RecoTauConstructor::kSignal,
00150             RecoTauConstructor::kGamma, 2*piZerosToBuild);  // k-factor = 2
00151         tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
00152 
00153         // FIXME - are all these reserves okay?  will they get propagated to the
00154         // dataformat size if they are wrong?
00155         tau.reserve(
00156             RecoTauConstructor::kIsolation,
00157             RecoTauConstructor::kChargedHadron, pfchs.size() - tracksToBuild);
00158         tau.reserve(RecoTauConstructor::kIsolation,
00159                     RecoTauConstructor::kGamma,
00160                     (cleanPiZeros.size() - piZerosToBuild)*2);
00161         tau.reservePiZero(RecoTauConstructor::kIsolation,
00162                           (cleanPiZeros.size() - piZerosToBuild));
00163 
00164         // Set signal and isolation components for charged hadrons, after
00165         // converting them to a PFCandidateRefVector
00166         tau.addPFCands(
00167             RecoTauConstructor::kSignal, RecoTauConstructor::kChargedHadron,
00168             trackCombo->combo_begin(), trackCombo->combo_end()
00169             );
00170 
00171         // Get signal PiZero constituents and add them to the tau.
00172         // The sub-gammas are automatically added.
00173         tau.addPiZeros(
00174             RecoTauConstructor::kSignal,
00175             piZeroCombo->combo_begin(), piZeroCombo->combo_end()
00176             );
00177 
00178         // Now build isolation collections
00179         // Load our isolation tools
00180         using namespace reco::tau::cone;
00181         PFCandPtrDRFilter isolationConeFilter(tau.p4(), 0, isolationConeSize_);
00182 
00183         // Cross cleaning predicate.  Remove any PFCandidatePtrs that are
00184         // contained within existing PiZeros.  This predicate will return false
00185         // for any object that overlaps with cleanPiZeros.
00186         xclean::CrossCleanPtrs pfCandXCleaner(cleanPiZeros);
00187         // And this cleaning filter predicate with our Iso cone filter
00188         xclean::PredicateAND<PFCandPtrDRFilter, xclean::CrossCleanPtrs>
00189           pfCandFilter(isolationConeFilter, pfCandXCleaner);
00190 
00191         PiZeroDRFilter isolationConeFilterPiZero(
00192             tau.p4(), 0, isolationConeSize_);
00193 
00194         // Additionally make predicates to select the different PF object types
00195         // of the regional junk objects to add
00196         typedef xclean::PredicateAND<xclean::FilterPFCandByParticleId,
00197                 PFCandPtrDRFilter> RegionalJunkConeAndIdFilter;
00198 
00199         xclean::FilterPFCandByParticleId
00200           pfchCandSelector(reco::PFCandidate::h);
00201         xclean::FilterPFCandByParticleId
00202           pfgammaCandSelector(reco::PFCandidate::gamma);
00203         xclean::FilterPFCandByParticleId
00204           pfnhCandSelector(reco::PFCandidate::h0);
00205 
00206         RegionalJunkConeAndIdFilter pfChargedJunk(
00207             pfchCandSelector, // select charged stuff from junk
00208             isolationConeFilter // only take those in iso cone
00209             );
00210 
00211         RegionalJunkConeAndIdFilter pfGammaJunk(
00212             pfgammaCandSelector, // select gammas from junk
00213             isolationConeFilter // only take those in iso cone
00214             );
00215 
00216         RegionalJunkConeAndIdFilter pfNeutralJunk(
00217             pfnhCandSelector, // select neutral stuff from junk
00218             isolationConeFilter // select stuff in iso cone
00219             );
00220 
00221         // Filter the isolation candidates in a DR cone
00222         tau.addPFCands(
00223             RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00224             boost::make_filter_iterator(
00225                 pfCandFilter,
00226                 trackCombo->remainder_begin(), trackCombo->remainder_end()),
00227             boost::make_filter_iterator(
00228                 pfCandFilter,
00229                 trackCombo->remainder_end(), trackCombo->remainder_end())
00230             );
00231 
00232         // Add all the candidates that weren't included in the combinatoric
00233         // generation
00234         tau.addPFCands(
00235             RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00236             boost::make_filter_iterator(
00237                 pfCandFilter,
00238                 pfch_end, pfchs.end()),
00239             boost::make_filter_iterator(
00240                 pfCandFilter,
00241                 pfchs.end(), pfchs.end())
00242             );
00243         // Add all charged candidates that are in the iso cone but weren't in the
00244         // original PFJet
00245         tau.addPFCands(
00246             RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00247             boost::make_filter_iterator(
00248                 pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
00249             boost::make_filter_iterator(
00250                 pfChargedJunk, regionalJunk.end(), regionalJunk.end())
00251             );
00252 
00253         // Add all gammas that are in the iso cone but weren't in the
00254         // orginal PFJet
00255         tau.addPFCands(
00256             RecoTauConstructor::kIsolation, RecoTauConstructor::kGamma,
00257             boost::make_filter_iterator(
00258                 pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
00259             boost::make_filter_iterator(
00260                 pfGammaJunk, regionalJunk.end(), regionalJunk.end())
00261             );
00262 
00263         // Add all the netural hadron candidates to the isolation collection
00264         tau.addPFCands(
00265             RecoTauConstructor::kIsolation, RecoTauConstructor::kNeutralHadron,
00266             boost::make_filter_iterator(
00267                 pfCandFilter,
00268                 pfnhs.begin(), pfnhs.end()),
00269             boost::make_filter_iterator(
00270                 pfCandFilter,
00271                 pfnhs.end(), pfnhs.end())
00272             );
00273         // Add all the netural hadrons from the region collection that are in
00274         // the iso cone to the tau
00275         tau.addPFCands(
00276             RecoTauConstructor::kIsolation,  RecoTauConstructor::kNeutralHadron,
00277             boost::make_filter_iterator(
00278               pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
00279             boost::make_filter_iterator(
00280               pfNeutralJunk, regionalJunk.end(), regionalJunk.end())
00281             );
00282 
00283         tau.addPiZeros(
00284             RecoTauConstructor::kIsolation,
00285             boost::make_filter_iterator(
00286                 isolationConeFilterPiZero,
00287                 piZeroCombo->remainder_begin(), piZeroCombo->remainder_end()),
00288             boost::make_filter_iterator(
00289                 isolationConeFilterPiZero,
00290                 piZeroCombo->remainder_end(), piZeroCombo->remainder_end())
00291             );
00292 
00293         tau.addPiZeros(
00294             RecoTauConstructor::kIsolation,
00295             boost::make_filter_iterator(
00296                 isolationConeFilterPiZero,
00297                 piZero_end, cleanPiZeros.end()),
00298             boost::make_filter_iterator(
00299                 isolationConeFilterPiZero,
00300                 cleanPiZeros.end(), cleanPiZeros.end())
00301             );
00302 
00303         output.push_back(tau.get(true));
00304       }
00305     }
00306   }
00307   return output.release();
00308 }
00309 }}  // end namespace reco::tau
00310 
00311 #include "FWCore/Framework/interface/MakerMacros.h"
00312 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory,
00313                   reco::tau::RecoTauBuilderCombinatoricPlugin,
00314                   "RecoTauBuilderCombinatoricPlugin");