CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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 "DataFormats/TauReco/interface/PFTau.h"
00007 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
00008 #include "RecoTauTag/RecoTau/interface/CombinatoricGenerator.h"
00009 #include "RecoTauTag/RecoTau/interface/RecoTauConstructor.h"
00010 #include "RecoTauTag/RecoTau/interface/RecoTauQualityCuts.h"
00011 #include "RecoTauTag/RecoTau/interface/ConeTools.h"
00012 
00013 namespace reco { namespace tau {
00014 
00015 class RecoTauBuilderCombinatoricPlugin : public RecoTauBuilderPlugin {
00016   public:
00017     explicit RecoTauBuilderCombinatoricPlugin(const edm::ParameterSet& pset);
00018     virtual ~RecoTauBuilderCombinatoricPlugin() {}
00019     virtual return_type operator() (const reco::PFJetRef& jet,
00020          const std::vector<RecoTauPiZero>& piZeros) const;
00021   private:
00022     RecoTauQualityCuts qcuts_;
00023     bool usePFLeptonsAsChargedHadrons_;
00024     double isolationConeSize_;
00025     struct decayModeInfo {
00026       uint32_t maxPiZeros_;
00027       uint32_t maxPFCHs_;
00028       uint32_t nCharged_;
00029       uint32_t nPiZeros_;
00030     };
00031     std::vector<decayModeInfo> decayModesToBuild_;
00032 };
00033 
00034 RecoTauBuilderCombinatoricPlugin::RecoTauBuilderCombinatoricPlugin(
00035     const edm::ParameterSet& pset): RecoTauBuilderPlugin(pset),
00036     qcuts_(pset.getParameter<edm::ParameterSet>("qualityCuts")),
00037     usePFLeptonsAsChargedHadrons_(pset.getParameter<bool>("usePFLeptons")),
00038     isolationConeSize_(pset.getParameter<double>("isolationConeSize")) {
00039   typedef std::vector<edm::ParameterSet> VPSet;
00040   const VPSet& decayModes = pset.getParameter<VPSet>("decayModes");
00041   for (VPSet::const_iterator dm = decayModes.begin();
00042        dm != decayModes.end(); ++dm) {
00043     decayModeInfo info;
00044     info.nCharged_ = dm->getParameter<uint32_t>("nCharged");
00045     info.nPiZeros_ = dm->getParameter<uint32_t>("nPiZeros");
00046     info.maxPFCHs_ = dm->getParameter<uint32_t>("maxTracks");
00047     info.maxPiZeros_ = dm->getParameter<uint32_t>("maxPiZeros");
00048     decayModesToBuild_.push_back(info);
00049   }
00050 }
00051 
00052 RecoTauBuilderCombinatoricPlugin::return_type
00053 RecoTauBuilderCombinatoricPlugin::operator()(
00054     const reco::PFJetRef& jet,
00055     const std::vector<RecoTauPiZero>& piZeros) const {
00056   typedef std::vector<PFCandidatePtr> PFCandPtrs;
00057   typedef std::vector<RecoTauPiZero> PiZeroList;
00058 
00059   output_type output;
00060 
00061   // Update the primary vertex used by the quality cuts.  The PV is supplied by
00062   // the base class.
00063   qcuts_.setPV(primaryVertex());
00064 
00065   // Get PFCHs from this jet.  They are already sorted by descending Pt
00066   PFCandPtrs pfchs;
00067   if (!usePFLeptonsAsChargedHadrons_) {
00068     pfchs = qcuts_.filterRefs(pfCandidates(*jet, reco::PFCandidate::h));
00069   } else {
00070     // Check if we want to include electrons in muons in "charged hadron"
00071     // collection.  This is the preferred behavior, as the PF lepton selections
00072     // are very loose.
00073     pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
00074   }
00075 
00076   PFCandPtrs pfnhs = qcuts_.filterRefs(
00077       pfCandidates(*jet, reco::PFCandidate::h0));
00078 
00079   // Loop over the decay modes we want to build
00080   for (std::vector<decayModeInfo>::const_iterator
00081        decayMode = decayModesToBuild_.begin();
00082        decayMode != decayModesToBuild_.end(); ++decayMode) {
00083     // Find how many piZeros are in this decay mode
00084     size_t piZerosToBuild = decayMode->nPiZeros_;
00085     // Find how many tracks are in this decay mode
00086     size_t tracksToBuild = decayMode->nCharged_;
00087 
00088     // Skip decay mode if jet doesn't have the multiplicity to support it
00089     if (pfchs.size() < tracksToBuild || piZeros.size() < piZerosToBuild)
00090       continue;
00091 
00092     // Find the start and end of potential signal tracks
00093     PFCandPtrs::iterator pfch_begin = pfchs.begin();
00094     PFCandPtrs::iterator pfch_end =  pfchs.end();
00095     pfch_end = takeNElements(pfch_begin, pfch_end, decayMode->maxPFCHs_);
00096 
00097     // Build our track combo generator
00098     typedef tau::CombinatoricGenerator<PFCandPtrs> PFCombo;
00099     PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
00100 
00101     // Find the start and end of potential signal tracks
00102     PiZeroList::const_iterator piZero_begin = piZeros.begin();
00103     PiZeroList::const_iterator piZero_end = piZeros.end();
00104     piZero_end = takeNElements(piZero_begin, piZero_end,
00105                                decayMode->maxPiZeros_);
00106 
00107     // Build our piZero combo generator
00108     typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
00109     PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
00110 
00111     /*
00112      * Begin combinatoric loop for this decay mode
00113      */
00114 
00115     // Loop over the different combinations of tracks
00116     for (PFCombo::iterator trackCombo = trackCombos.begin();
00117          trackCombo != trackCombos.end(); ++trackCombo) {
00118       // Loop over the different combinations of PiZeros
00119       for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
00120            piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
00121         // Output tau
00122         RecoTauConstructor tau(jet, getPFCands(), true);
00123         // Reserve space in our collections
00124         tau.reserve(RecoTauConstructor::kSignal,
00125                     RecoTauConstructor::kChargedHadron, tracksToBuild);
00126         tau.reserve(
00127             RecoTauConstructor::kSignal,
00128             RecoTauConstructor::kGamma, 2*piZerosToBuild);  // k-factor = 2
00129         tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
00130 
00131         // FIXME - are all these reserves okay?  will they get propagated to the
00132         // dataformat size if they are wrong?
00133         tau.reserve(
00134             RecoTauConstructor::kIsolation,
00135             RecoTauConstructor::kChargedHadron, pfchs.size() - tracksToBuild);
00136         tau.reserve(RecoTauConstructor::kIsolation,
00137                     RecoTauConstructor::kGamma,
00138                     (piZeros.size() - piZerosToBuild)*2);
00139         tau.reservePiZero(RecoTauConstructor::kIsolation,
00140                           (piZeros.size() - piZerosToBuild));
00141 
00142         // Set signal and isolation components for charged hadrons, after
00143         // converting them to a PFCandidateRefVector
00144         tau.addPFCands(
00145             RecoTauConstructor::kSignal, RecoTauConstructor::kChargedHadron,
00146             trackCombo->combo_begin(), trackCombo->combo_end()
00147             );
00148 
00149         // Get signal PiZero constituents and add them to the tau.
00150         // The sub-gammas are automatically added.
00151         tau.addPiZeros(
00152             RecoTauConstructor::kSignal,
00153             piZeroCombo->combo_begin(), piZeroCombo->combo_end()
00154             );
00155 
00156         // Now build isolation collections
00157         // Load our isolation tools
00158         using namespace reco::tau::cone;
00159         PFCandPtrDRFilter isolationConeFilter(tau.p4(), 0, isolationConeSize_);
00160 
00161         PiZeroDRFilter isolationConeFilterPiZero(
00162             tau.p4(), 0, isolationConeSize_);
00163 
00164 
00165         // Filter the isolation candidates in a DR cone
00166         tau.addPFCands(
00167             RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00168             boost::make_filter_iterator(
00169                 isolationConeFilter,
00170                 trackCombo->remainder_begin(), trackCombo->remainder_end()),
00171             boost::make_filter_iterator(
00172                 isolationConeFilter,
00173                 trackCombo->remainder_end(), trackCombo->remainder_end())
00174             );
00175 
00176         // Add all the candidates that weren't included in the combinatoric
00177         // generation
00178         tau.addPFCands(
00179             RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00180             boost::make_filter_iterator(
00181                 isolationConeFilter,
00182                 pfch_end, pfchs.end()),
00183             boost::make_filter_iterator(
00184                 isolationConeFilter,
00185                 pfchs.end(), pfchs.end())
00186             );
00187 
00188         // Add all the netural hadron candidates to the isolation collection
00189         tau.addPFCands(
00190             RecoTauConstructor::kIsolation, RecoTauConstructor::kNeutralHadron,
00191             boost::make_filter_iterator(
00192                 isolationConeFilter,
00193                 pfnhs.begin(), pfnhs.end()),
00194             boost::make_filter_iterator(
00195                 isolationConeFilter,
00196                 pfnhs.end(), pfnhs.end())
00197             );
00198 
00199         tau.addPiZeros(
00200             RecoTauConstructor::kIsolation,
00201             boost::make_filter_iterator(
00202                 isolationConeFilterPiZero,
00203                 piZeroCombo->remainder_begin(), piZeroCombo->remainder_end()),
00204             boost::make_filter_iterator(
00205                 isolationConeFilterPiZero,
00206                 piZeroCombo->remainder_end(), piZeroCombo->remainder_end())
00207             );
00208 
00209         tau.addPiZeros(
00210             RecoTauConstructor::kIsolation,
00211             boost::make_filter_iterator(
00212                 isolationConeFilterPiZero,
00213                 piZero_end, piZeros.end()),
00214             boost::make_filter_iterator(
00215                 isolationConeFilterPiZero,
00216                 piZeros.end(), piZeros.end())
00217             );
00218 
00219         output.push_back(tau.get(true));
00220       }
00221     }
00222   }
00223   return output.release();
00224 }
00225 }}  // end namespace reco::tau
00226 
00227 #include "FWCore/Framework/interface/MakerMacros.h"
00228 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory,
00229                   reco::tau::RecoTauBuilderCombinatoricPlugin,
00230                   "RecoTauBuilderCombinatoricPlugin");