44 #include <boost/ptr_container/ptr_vector.hpp>
45 #include <boost/ptr_container/ptr_list.hpp>
66 void print(
const T& chargedHadrons);
93 std::unique_ptr<StringCutObjectSelector<reco::PFRecoTauChargedHadron>>
outputSelector_;
100 : moduleLabel_(
cfg.getParameter<
std::
string>(
"@module_label")) {
109 for (edm::VParameterSet::const_iterator
pset = psets_builders.begin();
pset != psets_builders.end(); ++
pset) {
119 for (edm::VParameterSet::const_iterator
pset = psets_rankers.begin();
pset != psets_rankers.end(); ++
pset) {
135 produces<reco::PFJetChargedHadronAssociation>();
140 edm::LogPrint(
"PFRecoTauChHProducer") <<
"<PFRecoTauChargedHadronProducer::produce>:";
146 builder.setup(evt, es);
155 size_t nElements =
jets->size();
156 for (
size_t i = 0;
i < nElements; ++
i) {
161 std::unique_ptr<reco::PFJetChargedHadronAssociation> pfJetChargedHadronAssociations;
166 pfJetChargedHadronAssociations = std::make_unique<reco::PFJetChargedHadronAssociation>();
170 for (
const auto& pfJet :
pfJets) {
184 edm::LogPrint(
"PFRecoTauChHProducer") <<
"result of builder = " << builder.name() <<
":";
187 uncleanedChargedHadrons.transfer(uncleanedChargedHadrons.end(),
result);
190 <<
"Exception caught in builder plugin " << builder.name() <<
", rethrowing" << std::endl;
199 std::vector<reco::PFRecoTauChargedHadron> cleanedChargedHadrons;
202 typedef std::pair<double, double> etaPhiPair;
203 std::list<etaPhiPair> tracksInCleanCollection;
204 std::set<reco::CandidatePtr> neutralPFCandsInCleanCollection;
206 while (!uncleanedChargedHadrons.empty()) {
208 std::unique_ptr<reco::PFRecoTauChargedHadron> nextChargedHadron(uncleanedChargedHadrons.pop_front().release());
210 edm::LogPrint(
"PFRecoTauChHProducer") <<
"processing nextChargedHadron:";
211 edm::LogPrint(
"PFRecoTauChHProducer") << (*nextChargedHadron);
219 if (nextChargedHadron->getChargedPFCandidate().isNonnull()) {
221 dynamic_cast<const reco::PFCandidate*>(&*nextChargedHadron->getChargedPFCandidate());
235 if (nextChargedHadron->getTrack().isNonnull() && !
track) {
236 track = nextChargedHadron->getTrack().get();
240 bool isTrack_overlap =
false;
242 double track_eta =
track->eta();
243 double track_phi =
track->phi();
244 for (std::list<etaPhiPair>::const_iterator trackInCleanCollection = tracksInCleanCollection.begin();
245 trackInCleanCollection != tracksInCleanCollection.end();
246 ++trackInCleanCollection) {
247 double dR =
deltaR(track_eta, track_phi, trackInCleanCollection->first, trackInCleanCollection->second);
249 isTrack_overlap =
true;
253 edm::LogPrint(
"PFRecoTauChHProducer") <<
"isTrack_overlap = " << isTrack_overlap;
259 bool isNeutralPFCand_overlap =
false;
261 for (std::set<reco::CandidatePtr>::const_iterator neutralPFCandInCleanCollection =
262 neutralPFCandsInCleanCollection.begin();
263 neutralPFCandInCleanCollection != neutralPFCandsInCleanCollection.end();
264 ++neutralPFCandInCleanCollection) {
265 if ((*neutralPFCandInCleanCollection) == nextChargedHadron->getChargedPFCandidate())
266 isNeutralPFCand_overlap =
true;
270 edm::LogPrint(
"PFRecoTauChHProducer") <<
"isNeutralPFCand_overlap = " << isNeutralPFCand_overlap;
272 if (isNeutralPFCand_overlap)
276 std::vector<reco::CandidatePtr> uniqueNeutralPFCands;
277 std::set_difference(nextChargedHadron->getNeutralPFCandidates().begin(),
278 nextChargedHadron->getNeutralPFCandidates().end(),
279 neutralPFCandsInCleanCollection.begin(),
280 neutralPFCandsInCleanCollection.end(),
281 std::back_inserter(uniqueNeutralPFCands));
283 if (uniqueNeutralPFCands.size() ==
284 nextChargedHadron->getNeutralPFCandidates()
287 tracksInCleanCollection.push_back(std::make_pair(
track->eta(),
track->phi()));
288 neutralPFCandsInCleanCollection.insert(nextChargedHadron->getNeutralPFCandidates().begin(),
289 nextChargedHadron->getNeutralPFCandidates().end());
291 edm::LogPrint(
"PFRecoTauChHProducer") <<
"--> adding nextChargedHadron to output collection.";
293 cleanedChargedHadrons.push_back(*nextChargedHadron);
295 nextChargedHadron->neutralPFCandidates_.clear();
296 for (
auto const& neutralPFCand : uniqueNeutralPFCands) {
297 nextChargedHadron->neutralPFCandidates_.push_back(neutralPFCand);
304 uncleanedChargedHadrons.begin(), uncleanedChargedHadrons.end(), *nextChargedHadron, *
predicate_);
306 edm::LogPrint(
"PFRecoTauChHProducer") <<
"--> removing non-unique neutral PFCandidates and reinserting "
307 "nextChargedHadron in uncleaned collection.";
309 uncleanedChargedHadrons.insert(insertionPoint,
std::move(nextChargedHadron));
314 print(cleanedChargedHadrons);
318 pfJetChargedHadronAssociations->setValue(pfJet.key(), cleanedChargedHadrons);
324 template <
typename T>
330 for (rankerList::const_iterator ranker =
rankers_.begin(); ranker !=
rankers_.end(); ++ranker) {
331 const unsigned width = 25;
333 <<
" " << std::setiosflags(std::ios::left) << std::setw(
width) << ranker->name() <<
" "
334 << std::resetiosflags(std::ios::left) << std::setprecision(3) << (*ranker)(*chargedHadron) << std::endl;
345 desc_ranking.
add<
double>(
"selectionFailValue", 1000.0);
346 desc_ranking.
add<
std::string>(
"selection",
"algoIs(\"kChargedPFCandidate\")");
348 desc_ranking.
add<
std::string>(
"plugin",
"PFRecoTauChargedHadronStringQuality");
352 pset_ranking.addParameter<
double>(
"selectionFailValue", 1000.0);
353 pset_ranking.addParameter<
std::string>(
"selection",
"algoIs(\"kChargedPFCandidate\")");
354 pset_ranking.addParameter<
std::string>(
"name",
"ChargedPFCandidate");
355 pset_ranking.addParameter<
std::string>(
"plugin",
"PFRecoTauChargedHadronStringQuality");
356 std::vector<edm::ParameterSet> vpsd_ranking;
357 vpsd_ranking.push_back(pset_ranking);
359 desc.addVPSet(
"ranking", desc_ranking, vpsd_ranking);
362 desc.add<
int>(
"verbosity", 0);
363 desc.add<
double>(
"maxJetAbsEta", 2.5);
365 desc.add<
double>(
"minJetPt", 14.0);
370 desc_builders.
add<
double>(
"minMergeChargedHadronPt");
374 desc_builders.
addOptional<
bool>(
"dRconeLimitedToJetArea");
375 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadron");
376 desc_builders.
addOptional<
double>(
"dRmergePhoton");
383 desc_builders.
add<
double>(
"minMergeGammaEt");
384 desc_builders.
add<
int>(
"verbosity", 0);
385 desc_builders.
add<
double>(
"minMergeNeutralHadronEt");
387 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtChargedHadron");
388 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtNeutralHadron");
389 desc_builders.
addOptional<
int>(
"maxUnmatchedBlockElementsNeutralHadron");
390 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtElectron");
391 desc_builders.
addOptional<std::vector<int>>(
"chargedHadronCandidatesParticleIds");
392 desc_builders.
addOptional<
int>(
"minBlockElementMatchesPhoton");
393 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtNeutralHadron");
394 desc_builders.
addOptional<
int>(
"maxUnmatchedBlockElementsPhoton");
395 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtOther");
396 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtElectron");
397 desc_builders.
addOptional<
int>(
"minBlockElementMatchesNeutralHadron");
398 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtOther");
399 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtChargedHadron");
403 pset_builders.addParameter<
std::string>(
"plugin",
"");
407 std::vector<edm::ParameterSet> vpsd_builders;
408 vpsd_builders.push_back(pset_builders);
410 desc.addVPSet(
"builders", desc_builders, vpsd_builders);
413 descriptions.
add(
"pfRecoTauChargedHadronProducer",
desc);