41 enum class tauId_utag_idx : size_t {
dm = 0,
vsjet,
vse,
vsmu,
ptcorr,
qconf,
pdm0,
pdm1,
pdm2,
pdm10,
pdm11,
last };
47 addGenJetMatch_(
cfg.getParameter<
bool>(
"addGenJetMatch")),
48 dR2Max_(
std::
pow(
cfg.getParameter<double>(
"dRMax"), 2)),
49 jetPtMin_(
cfg.getParameter<double>(
"jetPtMin")),
50 jetEtaMax_(
cfg.getParameter<double>(
"jetEtaMax")),
53 UtagPtCorrName_(
cfg.getParameter<
std::
string>(
"UtagPtCorrName")),
54 tauScoreMin_(
cfg.getParameter<double>(
"tauScoreMin")),
55 vsJetMin_(
cfg.getParameter<double>(
"vsJetMin")),
56 chargeAssignmentProbMin_(
cfg.getParameter<double>(
"chargeAssignmentProbMin")),
57 checkTauScoreIsBest_(
cfg.getParameter<
bool>(
"checkTauScoreIsBest")),
58 usePFLeptonsAsChargedHadrons_(
cfg.getParameter<
bool>(
"usePFLeptonsAsChargedHadrons")),
59 tagToDM_({{
"1h0p", 0}, {
"1h1or2p", 1}, {
"1h1p", 1}, {
"1h2p", 2}, {
"3h0p", 10}, {
"3h1p", 11}}) {
61 std::vector<std::string> UTagScoreNames =
cfg.getParameter<std::vector<std::string>>(
"UTagScoreNames");
62 for (
const auto& scoreName : UTagScoreNames) {
64 if (scoreName.find(UTagLabel_) == std::string::npos)
66 size_t labelLength = scoreName.find(
':') == std::string::npos ? 0 : scoreName.find(
':') + 1;
68 if (
name.find(
"prob") == std::string::npos)
70 if (
name.find(
"probtau") != std::string::npos)
71 utagTauScoreNames_.push_back(
name);
72 else if (
name ==
"probele" ||
name ==
"probmu")
73 utagLepScoreNames_.push_back(
name);
74 else if (
name.find(
"data") == std::string::npos &&
name.find(
"mc") == std::string::npos)
75 utagJetScoreNames_.push_back(
name);
76 if (UtagPtCorrName_.find(
':') != std::string::npos)
77 UtagPtCorrName_ = UtagPtCorrName_.substr(UtagPtCorrName_.find(
':') + 1);
79 if (addGenJetMatch_) {
81 consumes<edm::Association<reco::GenJetCollection>>(
cfg.getParameter<
edm::InputTag>(
"genJetMatch"));
85 produces<std::vector<pat::Tau>>();
94 auto outputTaus = std::make_unique<std::vector<pat::Tau>>();
95 outputTaus->reserve(inputTaus->size());
127 std::set<unsigned int> matched_taus;
129 for (
const auto&
jet : *
jets) {
139 std::pair<std::string, float> bestUtagTauScore(
"probtauundef", -1);
140 float sumOfUtagTauScores = 0;
141 std::vector<float> tauPerDMScores(5);
142 float plusChargeProb = 0;
145 sumOfUtagTauScores +=
score;
146 if (scoreName.find(
"taup") != std::string::npos)
147 plusChargeProb +=
score;
148 if (
score > bestUtagTauScore.second) {
149 bestUtagTauScore.second =
score;
150 bestUtagTauScore.first = scoreName;
152 if (scoreName.find(
"1h0p") != std::string::npos)
153 tauPerDMScores[0] +=
score;
154 else if (scoreName.find(
"1h1") !=
157 tauPerDMScores[1] +=
score;
158 else if (scoreName.find(
"1h2p") != std::string::npos)
159 tauPerDMScores[2] +=
score;
160 else if (scoreName.find(
"3h0p") != std::string::npos)
161 tauPerDMScores[3] +=
score;
162 else if (scoreName.find(
"3h1p") != std::string::npos)
163 tauPerDMScores[4] +=
score;
165 if (sumOfUtagTauScores > 0)
166 plusChargeProb /= sumOfUtagTauScores;
168 float sumOfUtagEleScores = 0, sumOfUtagMuScores = 0;
169 bool isTauScoreBest = (sumOfUtagTauScores > 0);
172 if (scoreName.find(
"ele") != std::string::npos)
173 sumOfUtagEleScores +=
score;
174 else if (scoreName.find(
"mu") != std::string::npos)
175 sumOfUtagMuScores +=
score;
176 if (
score > bestUtagTauScore.second)
177 isTauScoreBest =
false;
181 if (
jet.bDiscriminator(
UTagLabel_ +
":" + scoreName) > bestUtagTauScore.second)
182 isTauScoreBest =
false;
188 (1. - sumOfUtagEleScores -
192 (sumOfUtagTauScores + sumOfUtagEleScores);
194 sumOfUtagTauScores / (sumOfUtagTauScores + sumOfUtagMuScores);
199 bestUtagTauScore.first.find(
"tau") + 3;
200 const char q = (
pos < bestUtagTauScore.first.size()) ? bestUtagTauScore.first[
pos] :
'u';
204 }
else if (
q ==
'p') {
208 auto UtagDM =
tagToDM_.find(bestUtagTauScore.first.substr(
pos));
228 for (
const auto& inputTau : *inputTaus) {
230 if (matched_taus.count(tau_idx - 1) > 0)
235 matched_taus.insert(tau_idx - 1);
237 const size_t nTauIds = inputTau.tauIDs().size();
238 std::vector<pat::Tau::IdPair> tauIds(nTauIds + tauIds_utag.size());
239 for (
size_t i = 0;
i < nTauIds; ++
i)
240 tauIds[
i] = inputTau.tauIDs()[
i];
241 for (
size_t i = 0;
i < tauIds_utag.size(); ++
i) {
242 if ((tauIds_utag[
i].
first.find(
"PtCorr") != std::string::npos) &&
243 (inputTau.tauID(
"decayModeFindingNewDMs") == -1)) {
249 tauIds[nTauIds +
i].first = tauIds_utag[
i].first;
250 tauIds[nTauIds +
i].second = tauIds_utag[
i].second *
jet.correctedP4(
"Uncorrected").pt() / inputTau.pt();
252 tauIds[nTauIds +
i] = tauIds_utag[
i];
257 outputTaus->push_back(outputTau);
273 reco::PFTau pfTauFromJet(bestCharge,
jet.correctedP4(
"Uncorrected"));
275 pfTauFromJet.
setPdgId(bestCharge < 0 ? 15 : -15);
277 pfTauFromJet.setDecayMode(
282 pfTauFromJet.setSignalConeSize(
283 std::clamp(3.6 /
jet.correctedP4(
"Uncorrected").pt(), 0.08, 0.12));
288 pat::Tau outputTauFromJet(pfTauFromJet);
290 std::vector<pat::Tau::IdPair> newtauIds(tauIds_minimal.size() + tauIds_utag.size());
291 for (
size_t i = 0;
i < tauIds_minimal.size(); ++
i)
292 newtauIds[
i] = tauIds_minimal[
i];
293 for (
size_t i = 0;
i < tauIds_utag.size(); ++
i)
294 newtauIds[tauIds_minimal.size() +
i] = tauIds_utag[
i];
303 outputTaus->push_back(outputTauFromJet);
308 if (matched_taus.size() < inputTaus->size()) {
309 for (
size_t iTau = 0; iTau < inputTaus->size(); ++iTau) {
310 if (matched_taus.count(iTau) > 0)
312 const pat::Tau& inputTau = inputTaus->at(iTau);
314 const size_t nTauIds = inputTau.
tauIDs().size();
315 std::vector<pat::Tau::IdPair> tauIds(nTauIds + tauIds_utag.size());
316 for (
size_t i = 0;
i < nTauIds; ++
i)
318 for (
size_t i = 0;
i < tauIds_utag.size(); ++
i) {
319 tauIds[nTauIds +
i] = tauIds_utag[
i];
320 tauIds[nTauIds +
i].second =
324 outputTaus->push_back(outputTau);
333 typedef std::vector<reco::CandidatePtr>
CandPtrs;
346 if (pfTau.
charge() == 0 || pfChs.size() == 1) {
349 pfChsSig.push_back(pfChs[0]);
350 pfChs.erase(pfChs.begin());
352 for (CandPtrs::iterator
it = pfChs.begin();
it != pfChs.end();) {
353 if ((*it)->charge() == pfTau.
charge()) {
356 pfChsSig.push_back(*
it);
357 it = pfChs.erase(
it);
367 pfChsSig.push_back(pfChs[0]);
368 pfChs.erase(pfChs.begin());
375 for (CandPtrs::iterator
it = pfChs.begin();
it != pfChs.end();) {
377 pfChsSig.push_back(*
it);
378 it = pfChs.erase(
it);
385 pfChs.erase(std::remove_if(pfChs.begin(),
411 std::clamp(0.2 *
std::pow((*it)->pt(), -0.66), 0.05, 0.15) &&
413 std::clamp(0.35 *
std::pow((*it)->pt(), -0.71), 0.05, 0.3)) {
414 pfGammasSig.push_back(*
it);
432 desc.add<
double>(
"dRMax", 0.4);
433 desc.add<
double>(
"jetPtMin", 20.0);
434 desc.add<
double>(
"jetEtaMax", 2.5);
436 desc.add<
std::string>(
"tagPrefix",
"byUTag")->setComment(
"Prefix to be set for PUPPI or CHS tagger");
437 desc.add<std::vector<std::string>>(
"UTagScoreNames", {})
438 ->setComment(
"Output nodes for Unified Tagger (different for PNet vs UParT)");
440 desc.add<
double>(
"tauScoreMin", -1)->setComment(
"Minimal value of the best tau score to built recovery tau");
441 desc.add<
double>(
"vsJetMin", -1)->setComment(
"Minimal value of UTag tau-vs-jet discriminant to built recovery tau");
442 desc.add<
bool>(
"checkTauScoreIsBest",
false)
443 ->setComment(
"If true, recovery tau is built only if one of tau scores is the highest");
444 desc.add<
double>(
"chargeAssignmentProbMin", 0.2)
445 ->setComment(
"Minimal value of charge assignment probability to built recovery tau (0,0.5)");
446 desc.add<
bool>(
"addGenJetMatch",
true)->setComment(
"add MC genTauJet matching");
448 desc.add<
bool>(
"usePFLeptonsAsChargedHadrons",
true)
449 ->setComment(
"If true, all charged particles are used as charged hadron candidates");
std::vector< CandidatePtr > pfCandidatesByPdgId(const Jet &jet, int pdgId, bool sort=true)
void setsignalChargedHadrCands(const std::vector< reco::CandidatePtr > &)
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
double signalConeSize() const
Size of signal cone.
const bool checkTauScoreIsBest_
std::vector< Jet > JetCollection
const CandidatePtr & leadChargedHadrCand() const
edm::EDGetTokenT< pat::JetCollection > jetsToken_
std::vector< std::string > utagTauScoreNames_
bool isNonnull() const
Checks for non-null.
std::vector< Tau > TauCollection
bool getByToken(EDGetToken token, Handle< PROD > &result) const
void setTauIDs(const std::vector< IdPair > &ids)
void setleadCand(const CandidatePtr &)
std::vector< CandidatePtr > pfChargedCands(const Jet &jet, bool sort=true)
Extract all non-neutral candidates from a PFJet.
void setisolationChargedHadrCands(const std::vector< reco::CandidatePtr > &)
PATTauHybridProducer(const edm::ParameterSet &)
const std::vector< IdPair > & tauIDs() const
void setleadChargedHadrCand(const CandidatePtr &)
U second(std::pair< T, U > const &p)
bool isNull() const
Checks for null.
ALPAKA_FN_ACC static ALPAKA_FN_INLINE float dR2(Position4 pos1, Position4 pos2)
std::vector< reco::CandidatePtr > CandPtrs
const float chargeAssignmentProbMin_
bool isNonnull() const
Checks for non-null.
Abs< T >::type abs(const T &t)
const std::map< std::string, int > tagToDM_
#define DEFINE_FWK_MODULE(type)
genJetMatch
switch on/off embedding of matched genJet's
std::vector< std::string > utagJetScoreNames_
Analysis-level tau class.
const std::string UTagLabel_
edm::EDGetTokenT< edm::Association< reco::GenJetCollection > > genJetMatchToken_
void produce(edm::Event &, const edm::EventSetup &) override
void fillTauFromJet(reco::PFTau &pfTau, const reco::JetBaseRef &jet)
void setGenJet(const reco::GenJetRef &ref)
set the matched GenJet
edm::EDGetTokenT< pat::TauCollection > tausToken_
const bool usePFLeptonsAsChargedHadrons_
hadronicDecayMode decayMode() const
std::string UtagPtCorrName_
void setisolationGammaCands(const std::vector< reco::CandidatePtr > &)
void setsignalGammaCands(const std::vector< reco::CandidatePtr > &)
const std::string tagPrefix_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
~PATTauHybridProducer() override
std::vector< std::string > utagLepScoreNames_
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
void setPdgId(int pdgId) final
Power< A, B >::type pow(const A &a, const B &b)
int charge() const final
electric charge
std::vector< CandidatePtr > pfGammas(const Jet &jet, bool sort=true)
Extract all pfGammas from a PFJet.