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());
234 track = nextChargedHadron->getChargedPFCandidate()->bestTrack();
237 if (
track ==
nullptr) {
238 if (nextChargedHadron->getTrack().isNonnull()) {
239 track = nextChargedHadron->getTrack().get();
240 }
else if (nextChargedHadron->getLostTrackCandidate().isNonnull()) {
241 track = nextChargedHadron->getLostTrackCandidate()->bestTrack();
246 bool isTrack_overlap =
false;
248 double track_eta =
track->eta();
249 double track_phi =
track->phi();
250 for (std::list<etaPhiPair>::const_iterator trackInCleanCollection = tracksInCleanCollection.begin();
251 trackInCleanCollection != tracksInCleanCollection.end();
252 ++trackInCleanCollection) {
253 double dR =
deltaR(track_eta, track_phi, trackInCleanCollection->first, trackInCleanCollection->second);
255 isTrack_overlap =
true;
259 edm::LogPrint(
"PFRecoTauChHProducer") <<
"isTrack_overlap = " << isTrack_overlap;
265 bool isNeutralPFCand_overlap =
false;
267 for (std::set<reco::CandidatePtr>::const_iterator neutralPFCandInCleanCollection =
268 neutralPFCandsInCleanCollection.begin();
269 neutralPFCandInCleanCollection != neutralPFCandsInCleanCollection.end();
270 ++neutralPFCandInCleanCollection) {
271 if ((*neutralPFCandInCleanCollection) == nextChargedHadron->getChargedPFCandidate())
272 isNeutralPFCand_overlap =
true;
276 edm::LogPrint(
"PFRecoTauChHProducer") <<
"isNeutralPFCand_overlap = " << isNeutralPFCand_overlap;
278 if (isNeutralPFCand_overlap)
282 std::vector<reco::CandidatePtr> uniqueNeutralPFCands;
283 std::set_difference(nextChargedHadron->getNeutralPFCandidates().begin(),
284 nextChargedHadron->getNeutralPFCandidates().end(),
285 neutralPFCandsInCleanCollection.begin(),
286 neutralPFCandsInCleanCollection.end(),
287 std::back_inserter(uniqueNeutralPFCands));
289 if (uniqueNeutralPFCands.size() ==
290 nextChargedHadron->getNeutralPFCandidates()
293 tracksInCleanCollection.push_back(std::make_pair(
track->eta(),
track->phi()));
294 neutralPFCandsInCleanCollection.insert(nextChargedHadron->getNeutralPFCandidates().begin(),
295 nextChargedHadron->getNeutralPFCandidates().end());
297 edm::LogPrint(
"PFRecoTauChHProducer") <<
"--> adding nextChargedHadron to output collection.";
299 cleanedChargedHadrons.push_back(*nextChargedHadron);
301 nextChargedHadron->neutralPFCandidates_.clear();
302 for (
auto const& neutralPFCand : uniqueNeutralPFCands) {
303 nextChargedHadron->neutralPFCandidates_.push_back(neutralPFCand);
310 uncleanedChargedHadrons.begin(), uncleanedChargedHadrons.end(), *nextChargedHadron, *
predicate_);
312 edm::LogPrint(
"PFRecoTauChHProducer") <<
"--> removing non-unique neutral PFCandidates and reinserting "
313 "nextChargedHadron in uncleaned collection.";
315 uncleanedChargedHadrons.insert(insertionPoint,
std::move(nextChargedHadron));
320 print(cleanedChargedHadrons);
324 pfJetChargedHadronAssociations->setValue(pfJet.key(), cleanedChargedHadrons);
330 template <
typename T>
336 for (rankerList::const_iterator ranker =
rankers_.begin(); ranker !=
rankers_.end(); ++ranker) {
337 const unsigned width = 25;
339 <<
" " << std::setiosflags(std::ios::left) << std::setw(
width) << ranker->name() <<
" "
340 << std::resetiosflags(std::ios::left) << std::setprecision(3) << (*ranker)(*chargedHadron) << std::endl;
351 desc_ranking.
add<
double>(
"selectionFailValue", 1000.0);
352 desc_ranking.
add<
std::string>(
"selection",
"algoIs(\"kChargedPFCandidate\")");
354 desc_ranking.
add<
std::string>(
"plugin",
"PFRecoTauChargedHadronStringQuality");
358 pset_ranking.addParameter<
double>(
"selectionFailValue", 1000.0);
359 pset_ranking.addParameter<
std::string>(
"selection",
"algoIs(\"kChargedPFCandidate\")");
360 pset_ranking.addParameter<
std::string>(
"name",
"ChargedPFCandidate");
361 pset_ranking.addParameter<
std::string>(
"plugin",
"PFRecoTauChargedHadronStringQuality");
362 std::vector<edm::ParameterSet> vpsd_ranking;
363 vpsd_ranking.push_back(pset_ranking);
365 desc.addVPSet(
"ranking", desc_ranking, vpsd_ranking);
368 desc.add<
int>(
"verbosity", 0);
369 desc.add<
double>(
"maxJetAbsEta", 2.5);
371 desc.add<
double>(
"minJetPt", 14.0);
376 desc_builders.
add<
double>(
"minMergeChargedHadronPt");
380 desc_builders.
addOptional<
bool>(
"dRconeLimitedToJetArea");
381 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadron");
382 desc_builders.
addOptional<
double>(
"dRmergePhoton");
389 desc_builders.
add<
double>(
"minMergeGammaEt");
390 desc_builders.
add<
int>(
"verbosity", 0);
391 desc_builders.
add<
double>(
"minMergeNeutralHadronEt");
393 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtChargedHadron");
394 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtNeutralHadron");
395 desc_builders.
addOptional<
int>(
"maxUnmatchedBlockElementsNeutralHadron");
396 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtElectron");
397 desc_builders.
addOptional<std::vector<int>>(
"chargedHadronCandidatesParticleIds");
398 desc_builders.
addOptional<
int>(
"minBlockElementMatchesPhoton");
399 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtNeutralHadron");
400 desc_builders.
addOptional<
int>(
"maxUnmatchedBlockElementsPhoton");
401 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtOther");
402 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtElectron");
403 desc_builders.
addOptional<
int>(
"minBlockElementMatchesNeutralHadron");
404 desc_builders.
addOptional<
double>(
"dRmergePhotonWrtOther");
405 desc_builders.
addOptional<
double>(
"dRmergeNeutralHadronWrtChargedHadron");
409 pset_builders.addParameter<
std::string>(
"plugin",
"");
413 std::vector<edm::ParameterSet> vpsd_builders;
414 vpsd_builders.push_back(pset_builders);
416 desc.addVPSet(
"builders", desc_builders, vpsd_builders);
419 descriptions.
add(
"pfRecoTauChargedHadronProducer",
desc);