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 "DataFormats/VertexReco/interface/Vertex.h"
00013 #include "RecoTauTag/RecoTau/interface/RecoTauConstructor.h"
00014 #include "RecoTauTag/RecoTau/interface/RecoTauQualityCuts.h"
00015
00016 namespace reco { namespace tau {
00017
00018 class RecoTauBuilderCombinatoricPlugin : public RecoTauBuilderPlugin {
00019 public:
00020 explicit RecoTauBuilderCombinatoricPlugin(const edm::ParameterSet& pset);
00021 virtual ~RecoTauBuilderCombinatoricPlugin() {}
00022 virtual return_type operator() (const reco::PFJetRef& jet,
00023 const std::vector<RecoTauPiZero>& piZeros,
00024 const std::vector<PFCandidatePtr>& regionalExtras) const;
00025 private:
00026 RecoTauQualityCuts qcuts_;
00027 bool usePFLeptonsAsChargedHadrons_;
00028 double isolationConeSize_;
00029 struct decayModeInfo {
00030 uint32_t maxPiZeros_;
00031 uint32_t maxPFCHs_;
00032 uint32_t nCharged_;
00033 uint32_t nPiZeros_;
00034 };
00035 std::vector<decayModeInfo> decayModesToBuild_;
00036 };
00037
00038 RecoTauBuilderCombinatoricPlugin::RecoTauBuilderCombinatoricPlugin(
00039 const edm::ParameterSet& pset): RecoTauBuilderPlugin(pset),
00040 qcuts_(pset.getParameterSet(
00041 "qualityCuts").getParameterSet("signalQualityCuts")),
00042 usePFLeptonsAsChargedHadrons_(pset.getParameter<bool>("usePFLeptons")),
00043 isolationConeSize_(pset.getParameter<double>("isolationConeSize")) {
00044 typedef std::vector<edm::ParameterSet> VPSet;
00045 const VPSet& decayModes = pset.getParameter<VPSet>("decayModes");
00046 for (VPSet::const_iterator dm = decayModes.begin();
00047 dm != decayModes.end(); ++dm) {
00048 decayModeInfo info;
00049 info.nCharged_ = dm->getParameter<uint32_t>("nCharged");
00050 info.nPiZeros_ = dm->getParameter<uint32_t>("nPiZeros");
00051 info.maxPFCHs_ = dm->getParameter<uint32_t>("maxTracks");
00052 info.maxPiZeros_ = dm->getParameter<uint32_t>("maxPiZeros");
00053 decayModesToBuild_.push_back(info);
00054 }
00055 }
00056
00057 reco::VertexRef primaryVertexRef;
00058 RecoTauBuilderCombinatoricPlugin::return_type
00059 RecoTauBuilderCombinatoricPlugin::operator()(
00060 const reco::PFJetRef& jet,
00061 const std::vector<RecoTauPiZero>& piZeros,
00062 const std::vector<PFCandidatePtr>& regionalExtras) const {
00063
00064 typedef std::vector<PFCandidatePtr> PFCandPtrs;
00065 typedef std::vector<RecoTauPiZero> PiZeroList;
00066
00067 output_type output;
00068 primaryVertexRef = primaryVertex(jet);
00069
00070
00071
00072 qcuts_.setPV(primaryVertexRef);
00073
00074
00075 PFCandPtrs pfchs;
00076 if (!usePFLeptonsAsChargedHadrons_) {
00077 pfchs = qcuts_.filterRefs(pfCandidates(*jet, reco::PFCandidate::h));
00078 } else {
00079
00080
00081
00082 pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
00083 }
00084
00085 PFCandPtrs pfnhs = qcuts_.filterRefs(
00086 pfCandidates(*jet, reco::PFCandidate::h0));
00087
00090 PFCandPtrs regionalJunk = qcuts_.filterRefs(regionalExtras);
00091
00092
00093 for (std::vector<decayModeInfo>::const_iterator
00094 decayMode = decayModesToBuild_.begin();
00095 decayMode != decayModesToBuild_.end(); ++decayMode) {
00096
00097 size_t piZerosToBuild = decayMode->nPiZeros_;
00098
00099 size_t tracksToBuild = decayMode->nCharged_;
00100
00101 if (pfchs.size() < tracksToBuild)
00102 continue;
00103
00104
00105 PFCandPtrs::iterator pfch_begin = pfchs.begin();
00106 PFCandPtrs::iterator pfch_end = pfchs.end();
00107 pfch_end = takeNElements(pfch_begin, pfch_end, decayMode->maxPFCHs_);
00108
00109
00110 typedef tau::CombinatoricGenerator<PFCandPtrs> PFCombo;
00111 PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
00112
00113
00114
00115
00116
00117 for (PFCombo::iterator trackCombo = trackCombos.begin();
00118 trackCombo != trackCombos.end(); ++trackCombo) {
00119 xclean::CrossCleanPiZeros<PFCombo::combo_iterator>
00120 xCleaner(trackCombo->combo_begin(), trackCombo->combo_end());
00121
00122 PiZeroList cleanPiZeros = xCleaner(piZeros);
00123
00124
00125
00126 if (cleanPiZeros.size() < piZerosToBuild)
00127 continue;
00128
00129
00130 PiZeroList::iterator piZero_begin = cleanPiZeros.begin();
00131 PiZeroList::iterator piZero_end = cleanPiZeros.end();
00132
00133 piZero_end = takeNElements(piZero_begin, piZero_end,
00134 decayMode->maxPiZeros_);
00135
00136
00137 typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
00138 PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
00139
00140 for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
00141 piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
00142
00143 RecoTauConstructor tau(jet, getPFCands(), true);
00144
00145 tau.reserve(RecoTauConstructor::kSignal,
00146 RecoTauConstructor::kChargedHadron, tracksToBuild);
00147 tau.reserve(
00148 RecoTauConstructor::kSignal,
00149 RecoTauConstructor::kGamma, 2*piZerosToBuild);
00150 tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
00151
00152
00153
00154 tau.reserve(
00155 RecoTauConstructor::kIsolation,
00156 RecoTauConstructor::kChargedHadron, pfchs.size() - tracksToBuild);
00157 tau.reserve(RecoTauConstructor::kIsolation,
00158 RecoTauConstructor::kGamma,
00159 (cleanPiZeros.size() - piZerosToBuild)*2);
00160 tau.reservePiZero(RecoTauConstructor::kIsolation,
00161 (cleanPiZeros.size() - piZerosToBuild));
00162
00163
00164
00165 tau.addPFCands(
00166 RecoTauConstructor::kSignal, RecoTauConstructor::kChargedHadron,
00167 trackCombo->combo_begin(), trackCombo->combo_end()
00168 );
00169
00170
00171
00172 tau.addPiZeros(
00173 RecoTauConstructor::kSignal,
00174 piZeroCombo->combo_begin(), piZeroCombo->combo_end()
00175 );
00176
00177
00178
00179 using namespace reco::tau::cone;
00180 PFCandPtrDRFilter isolationConeFilter(tau.p4(), 0, isolationConeSize_);
00181
00182
00183
00184
00185 xclean::CrossCleanPtrs pfCandXCleaner(cleanPiZeros);
00186
00187 xclean::PredicateAND<PFCandPtrDRFilter, xclean::CrossCleanPtrs>
00188 pfCandFilter(isolationConeFilter, pfCandXCleaner);
00189
00190 PiZeroDRFilter isolationConeFilterPiZero(
00191 tau.p4(), 0, isolationConeSize_);
00192
00193
00194
00195 typedef xclean::PredicateAND<xclean::FilterPFCandByParticleId,
00196 PFCandPtrDRFilter> RegionalJunkConeAndIdFilter;
00197
00198 xclean::FilterPFCandByParticleId
00199 pfchCandSelector(reco::PFCandidate::h);
00200 xclean::FilterPFCandByParticleId
00201 pfgammaCandSelector(reco::PFCandidate::gamma);
00202 xclean::FilterPFCandByParticleId
00203 pfnhCandSelector(reco::PFCandidate::h0);
00204
00205 RegionalJunkConeAndIdFilter pfChargedJunk(
00206 pfchCandSelector,
00207 isolationConeFilter
00208 );
00209
00210 RegionalJunkConeAndIdFilter pfGammaJunk(
00211 pfgammaCandSelector,
00212 isolationConeFilter
00213 );
00214
00215 RegionalJunkConeAndIdFilter pfNeutralJunk(
00216 pfnhCandSelector,
00217 isolationConeFilter
00218 );
00219
00220
00221 tau.addPFCands(
00222 RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00223 boost::make_filter_iterator(
00224 pfCandFilter,
00225 trackCombo->remainder_begin(), trackCombo->remainder_end()),
00226 boost::make_filter_iterator(
00227 pfCandFilter,
00228 trackCombo->remainder_end(), trackCombo->remainder_end())
00229 );
00230
00231
00232
00233 tau.addPFCands(
00234 RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00235 boost::make_filter_iterator(
00236 pfCandFilter,
00237 pfch_end, pfchs.end()),
00238 boost::make_filter_iterator(
00239 pfCandFilter,
00240 pfchs.end(), pfchs.end())
00241 );
00242
00243
00244 tau.addPFCands(
00245 RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00246 boost::make_filter_iterator(
00247 pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
00248 boost::make_filter_iterator(
00249 pfChargedJunk, regionalJunk.end(), regionalJunk.end())
00250 );
00251
00252
00253
00254 tau.addPFCands(
00255 RecoTauConstructor::kIsolation, RecoTauConstructor::kGamma,
00256 boost::make_filter_iterator(
00257 pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
00258 boost::make_filter_iterator(
00259 pfGammaJunk, regionalJunk.end(), regionalJunk.end())
00260 );
00261
00262
00263 tau.addPFCands(
00264 RecoTauConstructor::kIsolation, RecoTauConstructor::kNeutralHadron,
00265 boost::make_filter_iterator(
00266 pfCandFilter,
00267 pfnhs.begin(), pfnhs.end()),
00268 boost::make_filter_iterator(
00269 pfCandFilter,
00270 pfnhs.end(), pfnhs.end())
00271 );
00272
00273
00274 tau.addPFCands(
00275 RecoTauConstructor::kIsolation, RecoTauConstructor::kNeutralHadron,
00276 boost::make_filter_iterator(
00277 pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
00278 boost::make_filter_iterator(
00279 pfNeutralJunk, regionalJunk.end(), regionalJunk.end())
00280 );
00281
00282 tau.addPiZeros(
00283 RecoTauConstructor::kIsolation,
00284 boost::make_filter_iterator(
00285 isolationConeFilterPiZero,
00286 piZeroCombo->remainder_begin(), piZeroCombo->remainder_end()),
00287 boost::make_filter_iterator(
00288 isolationConeFilterPiZero,
00289 piZeroCombo->remainder_end(), piZeroCombo->remainder_end())
00290 );
00291
00292 tau.addPiZeros(
00293 RecoTauConstructor::kIsolation,
00294 boost::make_filter_iterator(
00295 isolationConeFilterPiZero,
00296 piZero_end, cleanPiZeros.end()),
00297 boost::make_filter_iterator(
00298 isolationConeFilterPiZero,
00299 cleanPiZeros.end(), cleanPiZeros.end())
00300 );
00301
00302 std::auto_ptr<reco::PFTau> tauPtr = tau.get(true);
00303
00304 if ( primaryVertexRef.isNonnull() )
00305 tauPtr->setVertex(primaryVertexRef->position());
00306
00307 output.push_back(tauPtr);
00308 }
00309 }
00310 }
00311 return output.release();
00312 }
00313 }}
00314
00315 #include "FWCore/Framework/interface/MakerMacros.h"
00316 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory,
00317 reco::tau::RecoTauBuilderCombinatoricPlugin,
00318 "RecoTauBuilderCombinatoricPlugin");