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
00062
00063 qcuts_.setPV(primaryVertex());
00064
00065
00066 PFCandPtrs pfchs;
00067 if (!usePFLeptonsAsChargedHadrons_) {
00068 pfchs = qcuts_.filterRefs(pfCandidates(*jet, reco::PFCandidate::h));
00069 } else {
00070
00071
00072
00073 pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
00074 }
00075
00076 PFCandPtrs pfnhs = qcuts_.filterRefs(
00077 pfCandidates(*jet, reco::PFCandidate::h0));
00078
00079
00080 for (std::vector<decayModeInfo>::const_iterator
00081 decayMode = decayModesToBuild_.begin();
00082 decayMode != decayModesToBuild_.end(); ++decayMode) {
00083
00084 size_t piZerosToBuild = decayMode->nPiZeros_;
00085
00086 size_t tracksToBuild = decayMode->nCharged_;
00087
00088
00089 if (pfchs.size() < tracksToBuild || piZeros.size() < piZerosToBuild)
00090 continue;
00091
00092
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
00098 typedef tau::CombinatoricGenerator<PFCandPtrs> PFCombo;
00099 PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
00100
00101
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
00108 typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
00109 PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
00110
00111
00112
00113
00114
00115
00116 for (PFCombo::iterator trackCombo = trackCombos.begin();
00117 trackCombo != trackCombos.end(); ++trackCombo) {
00118
00119 for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
00120 piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
00121
00122 RecoTauConstructor tau(jet, getPFCands(), true);
00123
00124 tau.reserve(RecoTauConstructor::kSignal,
00125 RecoTauConstructor::kChargedHadron, tracksToBuild);
00126 tau.reserve(
00127 RecoTauConstructor::kSignal,
00128 RecoTauConstructor::kGamma, 2*piZerosToBuild);
00129 tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
00130
00131
00132
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
00143
00144 tau.addPFCands(
00145 RecoTauConstructor::kSignal, RecoTauConstructor::kChargedHadron,
00146 trackCombo->combo_begin(), trackCombo->combo_end()
00147 );
00148
00149
00150
00151 tau.addPiZeros(
00152 RecoTauConstructor::kSignal,
00153 piZeroCombo->combo_begin(), piZeroCombo->combo_end()
00154 );
00155
00156
00157
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
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
00177
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
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 }}
00226
00227 #include "FWCore/Framework/interface/MakerMacros.h"
00228 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory,
00229 reco::tau::RecoTauBuilderCombinatoricPlugin,
00230 "RecoTauBuilderCombinatoricPlugin");