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
00067
00068 qcuts_.setPV(primaryVertex());
00069
00070
00071 PFCandPtrs pfchs;
00072 if (!usePFLeptonsAsChargedHadrons_) {
00073 pfchs = qcuts_.filterRefs(pfCandidates(*jet, reco::PFCandidate::h));
00074 } else {
00075
00076
00077
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
00089 for (std::vector<decayModeInfo>::const_iterator
00090 decayMode = decayModesToBuild_.begin();
00091 decayMode != decayModesToBuild_.end(); ++decayMode) {
00092
00093 size_t piZerosToBuild = decayMode->nPiZeros_;
00094
00095 size_t tracksToBuild = decayMode->nCharged_;
00096
00097
00098 if (pfchs.size() < tracksToBuild)
00099 continue;
00100
00101
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
00107 typedef tau::CombinatoricGenerator<PFCandPtrs> PFCombo;
00108 PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
00109
00110
00111
00112
00113
00114
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
00124
00125 if (cleanPiZeros.size() < piZerosToBuild)
00126 continue;
00127
00128
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
00136 typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
00137 PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
00138
00139
00140 for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
00141 piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
00142
00143
00144 RecoTauConstructor tau(jet, getPFCands(), true);
00145
00146 tau.reserve(RecoTauConstructor::kSignal,
00147 RecoTauConstructor::kChargedHadron, tracksToBuild);
00148 tau.reserve(
00149 RecoTauConstructor::kSignal,
00150 RecoTauConstructor::kGamma, 2*piZerosToBuild);
00151 tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
00152
00153
00154
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
00165
00166 tau.addPFCands(
00167 RecoTauConstructor::kSignal, RecoTauConstructor::kChargedHadron,
00168 trackCombo->combo_begin(), trackCombo->combo_end()
00169 );
00170
00171
00172
00173 tau.addPiZeros(
00174 RecoTauConstructor::kSignal,
00175 piZeroCombo->combo_begin(), piZeroCombo->combo_end()
00176 );
00177
00178
00179
00180 using namespace reco::tau::cone;
00181 PFCandPtrDRFilter isolationConeFilter(tau.p4(), 0, isolationConeSize_);
00182
00183
00184
00185
00186 xclean::CrossCleanPtrs pfCandXCleaner(cleanPiZeros);
00187
00188 xclean::PredicateAND<PFCandPtrDRFilter, xclean::CrossCleanPtrs>
00189 pfCandFilter(isolationConeFilter, pfCandXCleaner);
00190
00191 PiZeroDRFilter isolationConeFilterPiZero(
00192 tau.p4(), 0, isolationConeSize_);
00193
00194
00195
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,
00208 isolationConeFilter
00209 );
00210
00211 RegionalJunkConeAndIdFilter pfGammaJunk(
00212 pfgammaCandSelector,
00213 isolationConeFilter
00214 );
00215
00216 RegionalJunkConeAndIdFilter pfNeutralJunk(
00217 pfnhCandSelector,
00218 isolationConeFilter
00219 );
00220
00221
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
00233
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
00244
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
00254
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
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
00274
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 }}
00310
00311 #include "FWCore/Framework/interface/MakerMacros.h"
00312 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory,
00313 reco::tau::RecoTauBuilderCombinatoricPlugin,
00314 "RecoTauBuilderCombinatoricPlugin");