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 namespace
00058 {
00059 class SortPi0sDescendingPt {
00060 public:
00061 bool operator()(const RecoTauPiZero& a, const RecoTauPiZero& b) const {
00062 return a.pt() > b.pt();
00063 }
00064 };
00065 }
00066
00067 RecoTauBuilderCombinatoricPlugin::return_type
00068 RecoTauBuilderCombinatoricPlugin::operator()(
00069 const reco::PFJetRef& jet,
00070 const std::vector<RecoTauPiZero>& piZeros,
00071 const std::vector<PFCandidatePtr>& regionalExtras) const
00072 {
00073
00074
00075 typedef std::vector<PFCandidatePtr> PFCandPtrs;
00076 typedef std::vector<RecoTauPiZero> PiZeroList;
00077
00078 output_type output;
00079 reco::VertexRef primaryVertexRef = primaryVertex(jet);
00080
00081
00082
00083 qcuts_.setPV(primaryVertexRef);
00084
00085
00086 PFCandPtrs pfchs;
00087 if (!usePFLeptonsAsChargedHadrons_) {
00088 pfchs = qcuts_.filterRefs(pfCandidates(*jet, reco::PFCandidate::h));
00089 } else {
00090
00091
00092
00093 pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 PFCandPtrs pfnhs = qcuts_.filterRefs(
00111 pfCandidates(*jet, reco::PFCandidate::h0));
00112
00115 PFCandPtrs regionalJunk = qcuts_.filterRefs(regionalExtras);
00116
00117
00118 for (std::vector<decayModeInfo>::const_iterator
00119 decayMode = decayModesToBuild_.begin();
00120 decayMode != decayModesToBuild_.end(); ++decayMode) {
00121
00122 size_t piZerosToBuild = decayMode->nPiZeros_;
00123
00124
00125 size_t tracksToBuild = decayMode->nCharged_;
00126
00127
00128
00129 if (pfchs.size() < tracksToBuild)
00130 continue;
00131
00132
00133 PFCandPtrs::iterator pfch_begin = pfchs.begin();
00134 PFCandPtrs::iterator pfch_end = pfchs.end();
00135 pfch_end = takeNElements(pfch_begin, pfch_end, decayMode->maxPFCHs_);
00136
00137
00138 typedef tau::CombinatoricGenerator<PFCandPtrs> PFCombo;
00139 PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
00140
00141
00142
00143
00144
00145 for (PFCombo::iterator trackCombo = trackCombos.begin();
00146 trackCombo != trackCombos.end(); ++trackCombo) {
00147 xclean::CrossCleanPiZeros<PFCombo::combo_iterator>
00148 xCleaner(trackCombo->combo_begin(), trackCombo->combo_end());
00149
00150 PiZeroList cleanPiZeros = xCleaner(piZeros);
00151
00152
00153 std::sort(cleanPiZeros.begin(), cleanPiZeros.end(), SortPi0sDescendingPt());
00154
00155
00156
00157 if (cleanPiZeros.size() < piZerosToBuild)
00158 continue;
00159
00160
00161 PiZeroList::iterator piZero_begin = cleanPiZeros.begin();
00162 PiZeroList::iterator piZero_end = cleanPiZeros.end();
00163
00164 piZero_end = takeNElements(piZero_begin, piZero_end,
00165 decayMode->maxPiZeros_);
00166
00167
00168 typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
00169 PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
00170
00171 for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
00172 piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
00173
00174 RecoTauConstructor tau(jet, getPFCands(), true);
00175
00176 tau.reserve(RecoTauConstructor::kSignal,
00177 RecoTauConstructor::kChargedHadron, tracksToBuild);
00178 tau.reserve(
00179 RecoTauConstructor::kSignal,
00180 RecoTauConstructor::kGamma, 2*piZerosToBuild);
00181 tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
00182
00183
00184
00185 tau.reserve(
00186 RecoTauConstructor::kIsolation,
00187 RecoTauConstructor::kChargedHadron, pfchs.size() - tracksToBuild);
00188 tau.reserve(RecoTauConstructor::kIsolation,
00189 RecoTauConstructor::kGamma,
00190 (cleanPiZeros.size() - piZerosToBuild)*2);
00191 tau.reservePiZero(RecoTauConstructor::kIsolation,
00192 (cleanPiZeros.size() - piZerosToBuild));
00193
00194
00195
00196 tau.addPFCands(
00197 RecoTauConstructor::kSignal, RecoTauConstructor::kChargedHadron,
00198 trackCombo->combo_begin(), trackCombo->combo_end()
00199 );
00200
00201
00202
00203 tau.addPiZeros(
00204 RecoTauConstructor::kSignal,
00205 piZeroCombo->combo_begin(), piZeroCombo->combo_end()
00206 );
00207
00208
00209
00210 using namespace reco::tau::cone;
00211 PFCandPtrDRFilter isolationConeFilter(tau.p4(), 0, isolationConeSize_);
00212
00213
00214
00215
00216 xclean::CrossCleanPtrs pfCandXCleaner(cleanPiZeros);
00217
00218 xclean::PredicateAND<PFCandPtrDRFilter, xclean::CrossCleanPtrs>
00219 pfCandFilter(isolationConeFilter, pfCandXCleaner);
00220
00221 PiZeroDRFilter isolationConeFilterPiZero(
00222 tau.p4(), 0, isolationConeSize_);
00223
00224
00225
00226 typedef xclean::PredicateAND<xclean::FilterPFCandByParticleId,
00227 PFCandPtrDRFilter> RegionalJunkConeAndIdFilter;
00228
00229 xclean::FilterPFCandByParticleId
00230 pfchCandSelector(reco::PFCandidate::h);
00231 xclean::FilterPFCandByParticleId
00232 pfgammaCandSelector(reco::PFCandidate::gamma);
00233 xclean::FilterPFCandByParticleId
00234 pfnhCandSelector(reco::PFCandidate::h0);
00235
00236 RegionalJunkConeAndIdFilter pfChargedJunk(
00237 pfchCandSelector,
00238 isolationConeFilter
00239 );
00240
00241 RegionalJunkConeAndIdFilter pfGammaJunk(
00242 pfgammaCandSelector,
00243 isolationConeFilter
00244 );
00245
00246 RegionalJunkConeAndIdFilter pfNeutralJunk(
00247 pfnhCandSelector,
00248 isolationConeFilter
00249 );
00250
00251
00252 tau.addPFCands(
00253 RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00254 boost::make_filter_iterator(
00255 pfCandFilter,
00256 trackCombo->remainder_begin(), trackCombo->remainder_end()),
00257 boost::make_filter_iterator(
00258 pfCandFilter,
00259 trackCombo->remainder_end(), trackCombo->remainder_end())
00260 );
00261
00262
00263
00264 tau.addPFCands(
00265 RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00266 boost::make_filter_iterator(
00267 pfCandFilter,
00268 pfch_end, pfchs.end()),
00269 boost::make_filter_iterator(
00270 pfCandFilter,
00271 pfchs.end(), pfchs.end())
00272 );
00273
00274
00275 tau.addPFCands(
00276 RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron,
00277 boost::make_filter_iterator(
00278 pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
00279 boost::make_filter_iterator(
00280 pfChargedJunk, regionalJunk.end(), regionalJunk.end())
00281 );
00282
00283
00284
00285 tau.addPFCands(
00286 RecoTauConstructor::kIsolation, RecoTauConstructor::kGamma,
00287 boost::make_filter_iterator(
00288 pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
00289 boost::make_filter_iterator(
00290 pfGammaJunk, regionalJunk.end(), regionalJunk.end())
00291 );
00292
00293
00294 tau.addPFCands(
00295 RecoTauConstructor::kIsolation, RecoTauConstructor::kNeutralHadron,
00296 boost::make_filter_iterator(
00297 pfCandFilter,
00298 pfnhs.begin(), pfnhs.end()),
00299 boost::make_filter_iterator(
00300 pfCandFilter,
00301 pfnhs.end(), pfnhs.end())
00302 );
00303
00304
00305 tau.addPFCands(
00306 RecoTauConstructor::kIsolation, RecoTauConstructor::kNeutralHadron,
00307 boost::make_filter_iterator(
00308 pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
00309 boost::make_filter_iterator(
00310 pfNeutralJunk, regionalJunk.end(), regionalJunk.end())
00311 );
00312
00313 tau.addPiZeros(
00314 RecoTauConstructor::kIsolation,
00315 boost::make_filter_iterator(
00316 isolationConeFilterPiZero,
00317 piZeroCombo->remainder_begin(), piZeroCombo->remainder_end()),
00318 boost::make_filter_iterator(
00319 isolationConeFilterPiZero,
00320 piZeroCombo->remainder_end(), piZeroCombo->remainder_end())
00321 );
00322
00323 tau.addPiZeros(
00324 RecoTauConstructor::kIsolation,
00325 boost::make_filter_iterator(
00326 isolationConeFilterPiZero,
00327 piZero_end, cleanPiZeros.end()),
00328 boost::make_filter_iterator(
00329 isolationConeFilterPiZero,
00330 cleanPiZeros.end(), cleanPiZeros.end())
00331 );
00332
00333 std::auto_ptr<reco::PFTau> tauPtr = tau.get(true);
00334
00335 if ( primaryVertexRef.isNonnull() )
00336 tauPtr->setVertex(primaryVertexRef->position());
00337
00338 output.push_back(tauPtr);
00339 }
00340 }
00341 }
00342 return output.release();
00343 }
00344 }}
00345
00346 #include "FWCore/Framework/interface/MakerMacros.h"
00347 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory,
00348 reco::tau::RecoTauBuilderCombinatoricPlugin,
00349 "RecoTauBuilderCombinatoricPlugin");