Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-04-28 04:48:37

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/Framework/interface/EventSetup.h"
0004 #include "FWCore/Utilities/interface/InputTag.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "DataFormats/PatCandidates/interface/Tau.h"
0007 #include "DataFormats/PatCandidates/interface/Jet.h"
0008 #include "FWCore/Utilities/interface/transform.h"
0009 #include "DataFormats/JetReco/interface/GenJetCollection.h"
0010 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0012 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0013 
0014 class PATTauHybridProducer : public edm::stream::EDProducer<> {
0015 public:
0016   explicit PATTauHybridProducer(const edm::ParameterSet&);
0017   ~PATTauHybridProducer() override{};
0018 
0019   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0020   void produce(edm::Event&, const edm::EventSetup&) override;
0021 
0022 private:
0023   void fillTauFromJet(reco::PFTau& pfTau, const reco::JetBaseRef& jet);
0024   //--- configuration parameters
0025   edm::EDGetTokenT<pat::TauCollection> tausToken_;
0026   edm::EDGetTokenT<pat::JetCollection> jetsToken_;
0027   bool addGenJetMatch_;
0028   edm::EDGetTokenT<edm::Association<reco::GenJetCollection>> genJetMatchToken_;
0029   const float dR2Max_, jetPtMin_, jetEtaMax_;
0030   const std::string pnetLabel_;
0031   std::vector<std::string> pnetTauScoreNames_;
0032   std::vector<std::string> pnetJetScoreNames_;
0033   std::vector<std::string> pnetLepScoreNames_;
0034   std::string pnetPtCorrName_;
0035   const float tauScoreMin_, vsJetMin_, chargeAssignmentProbMin_;
0036   const bool checkTauScoreIsBest_;
0037   const bool usePFLeptonsAsChargedHadrons_;
0038 
0039   const std::map<std::string, int> tagToDM_;
0040   enum class tauId_pnet_idx : size_t { dm = 0, vsjet, vse, vsmu, ptcorr, qconf, pdm0, pdm1, pdm2, pdm10, pdm11, last };
0041   enum class tauId_min_idx : size_t { hpsnew = 0, last };
0042 };
0043 
0044 PATTauHybridProducer::PATTauHybridProducer(const edm::ParameterSet& cfg)
0045     : tausToken_(consumes<pat::TauCollection>(cfg.getParameter<edm::InputTag>("src"))),
0046       jetsToken_(consumes<pat::JetCollection>(cfg.getParameter<edm::InputTag>("jetSource"))),
0047       addGenJetMatch_(cfg.getParameter<bool>("addGenJetMatch")),
0048       dR2Max_(std::pow(cfg.getParameter<double>("dRMax"), 2)),
0049       jetPtMin_(cfg.getParameter<double>("jetPtMin")),
0050       jetEtaMax_(cfg.getParameter<double>("jetEtaMax")),
0051       pnetLabel_(cfg.getParameter<std::string>("pnetLabel")),
0052       pnetPtCorrName_(cfg.getParameter<std::string>("pnetPtCorrName")),
0053       tauScoreMin_(cfg.getParameter<double>("tauScoreMin")),
0054       vsJetMin_(cfg.getParameter<double>("vsJetMin")),
0055       chargeAssignmentProbMin_(cfg.getParameter<double>("chargeAssignmentProbMin")),
0056       checkTauScoreIsBest_(cfg.getParameter<bool>("checkTauScoreIsBest")),
0057       usePFLeptonsAsChargedHadrons_(cfg.getParameter<bool>("usePFLeptonsAsChargedHadrons")),
0058       tagToDM_({{"1h0p", 0}, {"1h1or2p", 1}, {"1h1p", 1}, {"1h2p", 2}, {"3h0p", 10}, {"3h1p", 11}}) {
0059   // Read the different PNet score names
0060   std::vector<std::string> pnetScoreNames = cfg.getParameter<std::vector<std::string>>("pnetScoreNames");
0061   for (const auto& scoreName : pnetScoreNames) {
0062     size_t labelLenght = scoreName.find(':') == std::string::npos ? 0 : scoreName.find(':') + 1;
0063     std::string name = scoreName.substr(labelLenght);
0064     if (name.find("prob") == std::string::npos)
0065       continue;
0066     if (name.find("tau") != std::string::npos)
0067       pnetTauScoreNames_.push_back(name);
0068     else if (name.find("ele") != std::string::npos || name.find("mu") != std::string::npos)
0069       pnetLepScoreNames_.push_back(name);
0070     else
0071       pnetJetScoreNames_.push_back(name);
0072     if (pnetPtCorrName_.find(':') != std::string::npos)
0073       pnetPtCorrName_ = pnetPtCorrName_.substr(pnetPtCorrName_.find(':') + 1);
0074     // GenJet matching
0075     if (addGenJetMatch_) {
0076       genJetMatchToken_ =
0077           consumes<edm::Association<reco::GenJetCollection>>(cfg.getParameter<edm::InputTag>("genJetMatch"));
0078     }
0079   }
0080 
0081   produces<std::vector<pat::Tau>>();
0082   //FIXME: produce a separate collection for PNet-recovered taus?
0083 }
0084 
0085 void PATTauHybridProducer::produce(edm::Event& evt, const edm::EventSetup& es) {
0086   // Get the vector of taus
0087   edm::Handle<pat::TauCollection> inputTaus;
0088   evt.getByToken(tausToken_, inputTaus);
0089 
0090   auto outputTaus = std::make_unique<std::vector<pat::Tau>>();
0091   outputTaus->reserve(inputTaus->size());
0092 
0093   // Get the vector of jets
0094   edm::Handle<pat::JetCollection> jets;
0095   evt.getByToken(jetsToken_, jets);
0096 
0097   // Switch off gen-matching for real data
0098   if (evt.isRealData()) {
0099     addGenJetMatch_ = false;
0100   }
0101   edm::Handle<edm::Association<reco::GenJetCollection>> genJetMatch;
0102   if (addGenJetMatch_)
0103     evt.getByToken(genJetMatchToken_, genJetMatch);
0104 
0105   // Minimal HPS-like tauID list
0106   std::vector<pat::Tau::IdPair> tauIds_minimal((size_t)tauId_min_idx::last);
0107   tauIds_minimal[(size_t)tauId_min_idx::hpsnew] = std::make_pair("decayModeFindingNewDMs", -1);
0108 
0109   // PNet tauID list
0110   std::vector<pat::Tau::IdPair> tauIds_pnet((size_t)tauId_pnet_idx::last);
0111   tauIds_pnet[(size_t)tauId_pnet_idx::dm] = std::make_pair("byPNetDecayMode", reco::PFTau::kNull);
0112   tauIds_pnet[(size_t)tauId_pnet_idx::vsjet] = std::make_pair("byPNetVSjetraw", -1);
0113   tauIds_pnet[(size_t)tauId_pnet_idx::vse] = std::make_pair("byPNetVSeraw", -1);
0114   tauIds_pnet[(size_t)tauId_pnet_idx::vsmu] = std::make_pair("byPNetVSmuraw", -1);
0115   tauIds_pnet[(size_t)tauId_pnet_idx::ptcorr] = std::make_pair("byPNetPtCorr", 1);
0116   tauIds_pnet[(size_t)tauId_pnet_idx::qconf] = std::make_pair("byPNetQConf", 0);
0117   tauIds_pnet[(size_t)tauId_pnet_idx::pdm0] = std::make_pair("byPNetProb1h0pi0", -1);
0118   tauIds_pnet[(size_t)tauId_pnet_idx::pdm1] = std::make_pair("byPNetProb1h1pi0", -1);
0119   tauIds_pnet[(size_t)tauId_pnet_idx::pdm2] = std::make_pair("byPNetProb1h2pi0", -1);
0120   tauIds_pnet[(size_t)tauId_pnet_idx::pdm10] = std::make_pair("byPNetProb3h0pi0", -1);
0121   tauIds_pnet[(size_t)tauId_pnet_idx::pdm11] = std::make_pair("byPNetProb3h1pi0", -1);
0122 
0123   std::set<unsigned int> matched_taus;
0124   size_t jet_idx = 0;
0125   for (const auto& jet : *jets) {
0126     jet_idx++;
0127     if (jet.pt() < jetPtMin_)
0128       continue;
0129     if (std::abs(jet.eta()) > jetEtaMax_)
0130       continue;
0131     size_t tau_idx = 0;
0132     bool matched = false;
0133 
0134     // Analyse PNet scores
0135     std::pair<std::string, float> bestPnetTauScore("probtauundef", -1);
0136     float sumOfPnetTauScores = 0;
0137     std::vector<float> tauPerDMScores(5);
0138     float plusChargeProb = 0;
0139     for (const auto& scoreName : pnetTauScoreNames_) {
0140       float score = jet.bDiscriminator(pnetLabel_ + ":" + scoreName);
0141       sumOfPnetTauScores += score;
0142       if (scoreName.find("taup") != std::string::npos)
0143         plusChargeProb += score;
0144       if (score > bestPnetTauScore.second) {
0145         bestPnetTauScore.second = score;
0146         bestPnetTauScore.first = scoreName;
0147       }
0148       if (scoreName.find("1h0p") != std::string::npos)
0149         tauPerDMScores[0] += score;
0150       else if (scoreName.find("1h1") !=
0151                std::string::
0152                    npos)  //Note: final "p" in "1p" ommited to enble matching also with "1h1or2p" from early trainings
0153         tauPerDMScores[1] += score;
0154       else if (scoreName.find("1h2p") != std::string::npos)
0155         tauPerDMScores[2] += score;
0156       else if (scoreName.find("3h0p") != std::string::npos)
0157         tauPerDMScores[3] += score;
0158       else if (scoreName.find("3h1p") != std::string::npos)
0159         tauPerDMScores[4] += score;
0160     }
0161     if (sumOfPnetTauScores > 0)
0162       plusChargeProb /= sumOfPnetTauScores;
0163 
0164     float sumOfPnetEleScores = 0, sumOfPnetMuScores = 0;
0165     bool isTauScoreBest = (sumOfPnetTauScores > 0);
0166     for (const auto& scoreName : pnetLepScoreNames_) {
0167       float score = jet.bDiscriminator(pnetLabel_ + ":" + scoreName);
0168       if (scoreName.find("ele") != std::string::npos)
0169         sumOfPnetEleScores += score;
0170       else if (scoreName.find("mu") != std::string::npos)
0171         sumOfPnetMuScores += score;
0172       if (score > bestPnetTauScore.second)
0173         isTauScoreBest = false;
0174     }
0175     if (checkTauScoreIsBest_ && isTauScoreBest) {  //if needed iterate over jet scores
0176       for (const auto& scoreName : pnetJetScoreNames_)
0177         if (jet.bDiscriminator(pnetLabel_ + ":" + scoreName) > bestPnetTauScore.second)
0178           isTauScoreBest = false;
0179     }
0180 
0181     // PNet discriminants vs jets, electrons and muons
0182     tauIds_pnet[(size_t)tauId_pnet_idx::vsjet].second =
0183         sumOfPnetTauScores /
0184         (1. - sumOfPnetEleScores -
0185          sumOfPnetMuScores);  //vsJet: tau scores by sum of tau and jet scores or equally by  1 - sum of lepton scores
0186     tauIds_pnet[(size_t)tauId_pnet_idx::vse].second =
0187         sumOfPnetTauScores /
0188         (sumOfPnetTauScores + sumOfPnetEleScores);  //vsEle: tau scores by sum of tau and ele scores
0189     tauIds_pnet[(size_t)tauId_pnet_idx::vsmu].second =
0190         sumOfPnetTauScores / (sumOfPnetTauScores + sumOfPnetMuScores);  //vsMu: tau scores by sum of tau and mu scores
0191 
0192     // Decay mode and charge of the highest tau score
0193     int bestCharge = 0;
0194     size_t pos =
0195         bestPnetTauScore.first.find("tau") + 3;  //this is well defined by constraction as name is "probtauXXXX"
0196     const char q = (pos < bestPnetTauScore.first.size()) ? bestPnetTauScore.first[pos] : 'u';
0197     if (q == 'm') {  //minus
0198       pos++;
0199       bestCharge = -1;
0200     } else if (q == 'p') {  //plus
0201       pos++;
0202       bestCharge = 1;
0203     }
0204     auto pNetDM = tagToDM_.find(bestPnetTauScore.first.substr(pos));
0205     if (pNetDM != tagToDM_.end())
0206       tauIds_pnet[(size_t)tauId_pnet_idx::dm].second = pNetDM->second;
0207 
0208     // PNet Pt correction
0209     float ptcorr = jet.bDiscriminator(pnetLabel_ + ":" + pnetPtCorrName_);
0210     if (ptcorr > -1000.)  // -1000. is default for not found discriminantor
0211       tauIds_pnet[(size_t)tauId_pnet_idx::ptcorr].second = ptcorr;
0212 
0213     // PNet charge confidence
0214     tauIds_pnet[(size_t)tauId_pnet_idx::qconf].second = (plusChargeProb - 0.5);
0215 
0216     // PNet per decay mode normalised score
0217     tauIds_pnet[(size_t)tauId_pnet_idx::pdm0].second = tauPerDMScores[0] / sumOfPnetTauScores;
0218     tauIds_pnet[(size_t)tauId_pnet_idx::pdm1].second = tauPerDMScores[1] / sumOfPnetTauScores;
0219     tauIds_pnet[(size_t)tauId_pnet_idx::pdm2].second = tauPerDMScores[2] / sumOfPnetTauScores;
0220     tauIds_pnet[(size_t)tauId_pnet_idx::pdm10].second = tauPerDMScores[3] / sumOfPnetTauScores;
0221     tauIds_pnet[(size_t)tauId_pnet_idx::pdm11].second = tauPerDMScores[4] / sumOfPnetTauScores;
0222 
0223     // Search for matching tau
0224     for (const auto& inputTau : *inputTaus) {
0225       tau_idx++;
0226       if (matched_taus.count(tau_idx - 1) > 0)
0227         continue;
0228       float dR2 = deltaR2(jet, inputTau);
0229       // select 1st found match rather than best match (both should be equivalent for reasonable dRMax)
0230       if (dR2 < dR2Max_) {
0231         matched_taus.insert(tau_idx - 1);
0232         pat::Tau outputTau(inputTau);
0233         const size_t nTauIds = inputTau.tauIDs().size();
0234         std::vector<pat::Tau::IdPair> tauIds(nTauIds + tauIds_pnet.size());
0235         for (size_t i = 0; i < nTauIds; ++i)
0236           tauIds[i] = inputTau.tauIDs()[i];
0237         for (size_t i = 0; i < tauIds_pnet.size(); ++i)
0238           tauIds[nTauIds + i] = tauIds_pnet[i];
0239         outputTau.setTauIDs(tauIds);
0240         matched = true;
0241         outputTaus->push_back(outputTau);
0242 
0243         break;
0244       }
0245     }  // end of tau loop
0246     if (matched)
0247       continue;
0248 
0249     // Accept only jets passing minimal tau-like selection, i.e. with one of the tau score being globally the best and above some threshold, and with good quality of charge assignment
0250     if ((checkTauScoreIsBest_ && !isTauScoreBest) || bestPnetTauScore.second < tauScoreMin_ ||
0251         tauIds_pnet[(size_t)tauId_pnet_idx::vsjet].second < vsJetMin_ ||
0252         std::abs(0.5 - plusChargeProb) < chargeAssignmentProbMin_)
0253       continue;
0254 
0255     // Build taus from non-matched jets
0256     // "Null" pftau with raw (uncorrected) jet kinematics
0257     reco::PFTau pfTauFromJet(bestCharge, jet.correctedP4("Uncorrected"));
0258     // Set PDGid
0259     pfTauFromJet.setPdgId(bestCharge < 0 ? 15 : -15);
0260     // and decay mode predicted by PNet
0261     pfTauFromJet.setDecayMode(
0262         static_cast<const reco::PFTau::hadronicDecayMode>(int(tauIds_pnet[(size_t)tauId_pnet_idx::dm].second)));
0263     // Fill tau content using only jet consistunets within cone around leading
0264     // charged particle
0265     // FIXME: more sophisticated finding of tau constituents will be considered later
0266     pfTauFromJet.setSignalConeSize(
0267         std::clamp(3.6 / jet.correctedP4("Uncorrected").pt(), 0.08, 0.12));  // shrinking cone in function of jet-Pt
0268     const edm::Ref<pat::JetCollection> jetRef(jets, jet_idx - 1);
0269     fillTauFromJet(pfTauFromJet, reco::JetBaseRef(jetRef));
0270 
0271     // PATTau
0272     pat::Tau outputTauFromJet(pfTauFromJet);
0273     // Add tauIDs
0274     std::vector<pat::Tau::IdPair> newtauIds(tauIds_minimal.size() + tauIds_pnet.size());
0275     for (size_t i = 0; i < tauIds_minimal.size(); ++i)
0276       newtauIds[i] = tauIds_minimal[i];
0277     for (size_t i = 0; i < tauIds_pnet.size(); ++i)
0278       newtauIds[tauIds_minimal.size() + i] = tauIds_pnet[i];
0279     outputTauFromJet.setTauIDs(newtauIds);
0280     // Add genTauJet match
0281     if (addGenJetMatch_) {
0282       reco::GenJetRef genJetTau = (*genJetMatch)[jetRef];
0283       if (genJetTau.isNonnull() && genJetTau.isAvailable()) {
0284         outputTauFromJet.setGenJet(genJetTau);
0285       }
0286     }
0287     outputTaus->push_back(outputTauFromJet);
0288 
0289   }  // end of jet loop
0290 
0291   // Taus non-matched to jets (usually at pt-threshold or/and eta boundaries)
0292   if (matched_taus.size() < inputTaus->size()) {
0293     for (size_t iTau = 0; iTau < inputTaus->size(); ++iTau) {
0294       if (matched_taus.count(iTau) > 0)
0295         continue;
0296       const pat::Tau& inputTau = inputTaus->at(iTau);
0297       pat::Tau outputTau(inputTau);
0298       const size_t nTauIds = inputTau.tauIDs().size();
0299       std::vector<pat::Tau::IdPair> tauIds(nTauIds + tauIds_pnet.size());
0300       for (size_t i = 0; i < nTauIds; ++i)
0301         tauIds[i] = inputTau.tauIDs()[i];
0302       for (size_t i = 0; i < tauIds_pnet.size(); ++i) {
0303         tauIds[nTauIds + i] = tauIds_pnet[i];
0304         tauIds[nTauIds + i].second =
0305             (i != (size_t)tauId_pnet_idx::ptcorr ? (i != (size_t)tauId_pnet_idx::qconf ? -1 : 0) : 1);
0306       }
0307       outputTau.setTauIDs(tauIds);
0308       outputTaus->push_back(outputTau);
0309     }
0310   }  //non-matched taus
0311 
0312   evt.put(std::move(outputTaus));
0313 }
0314 
0315 void PATTauHybridProducer::fillTauFromJet(reco::PFTau& pfTau, const reco::JetBaseRef& jet) {
0316   // Use tools as in PFTau builders to select tau decay products and isolation candidates
0317   typedef std::vector<reco::CandidatePtr> CandPtrs;
0318 
0319   // Get the charged hadron candidates
0320   CandPtrs pfChs, pfChsSig;
0321   // Check if we want to include electrons and muons in "charged hadron"
0322   // collection. This is the preferred behavior, as the PF lepton selections
0323   // are very loose.
0324   if (!usePFLeptonsAsChargedHadrons_) {
0325     pfChs = reco::tau::pfCandidatesByPdgId(*jet, 211);
0326   } else {
0327     pfChs = reco::tau::pfChargedCands(*jet);
0328   }
0329   // take 1st charged candidate with charge as of tau (collection is pt-sorted)
0330   if (pfTau.charge() == 0 || pfChs.size() == 1) {
0331     pfTau.setleadChargedHadrCand(pfChs[0]);
0332     pfTau.setleadCand(pfChs[0]);
0333     pfChsSig.push_back(pfChs[0]);
0334     pfChs.erase(pfChs.begin());
0335   } else {
0336     for (CandPtrs::iterator it = pfChs.begin(); it != pfChs.end();) {
0337       if ((*it)->charge() == pfTau.charge()) {
0338         pfTau.setleadChargedHadrCand(*it);
0339         pfTau.setleadCand(*it);
0340         pfChsSig.push_back(*it);
0341         it = pfChs.erase(it);
0342         break;
0343       } else {
0344         ++it;
0345       }
0346     }
0347     // In case of lack of candidate with charge same as of tau use leading charged candidate
0348     if (pfTau.leadChargedHadrCand().isNull() && !pfChs.empty()) {
0349       pfTau.setleadChargedHadrCand(pfChs[0]);
0350       pfTau.setleadCand(pfChs[0]);
0351       pfChsSig.push_back(pfChs[0]);
0352       pfChs.erase(pfChs.begin());
0353     }
0354   }
0355   // if more than one charged decay product is expected add all inside signal
0356   // cone around the leading track
0357   const double dR2Max = std::pow(pfTau.signalConeSize(), 2);
0358   if (pfTau.decayMode() >= reco::PFTau::kThreeProng0PiZero && pfTau.leadChargedHadrCand().isNonnull()) {
0359     for (CandPtrs::iterator it = pfChs.begin(); it != pfChs.end();) {
0360       if (deltaR2((*it)->p4(), pfTau.leadChargedHadrCand()->p4()) < dR2Max) {
0361         pfChsSig.push_back(*it);
0362         it = pfChs.erase(it);
0363       } else {
0364         ++it;
0365       }
0366     }
0367   }
0368   // Clean isolation candidates from low-pt and leptonic ones
0369   for (CandPtrs::iterator it = pfChs.begin(); it != pfChs.end();) {
0370     if ((*it)->pt() < 0.5 || std::abs((*it)->pdgId()) != 211) {
0371       it = pfChs.erase(it);
0372     } else {
0373       ++it;
0374     }
0375   }
0376   // Set charged candidates
0377   pfTau.setsignalChargedHadrCands(pfChsSig);
0378   pfTau.setisolationChargedHadrCands(pfChs);
0379 
0380   // Get the gamma candidates (pi0 decay products)
0381   CandPtrs pfGammas, pfGammasSig;
0382   pfGammas = reco::tau::pfCandidatesByPdgId(*jet, 22);
0383   // In case of lack of leading charged candidate substiute it with leading gamma candidate
0384   if (pfTau.leadChargedHadrCand().isNull() && !pfGammas.empty()) {
0385     pfTau.setleadChargedHadrCand(pfGammas[0]);
0386     pfTau.setleadCand(pfGammas[0]);
0387     pfGammasSig.push_back(pfGammas[0]);
0388     pfChs.erase(pfGammas.begin());
0389   }
0390   // Clean gamma candidates from low-pt ones
0391   for (CandPtrs::iterator it = pfGammas.begin(); it != pfGammas.end();) {
0392     if ((*it)->pt() < 0.5) {
0393       it = pfGammas.erase(it);
0394     } else {
0395       ++it;
0396     }
0397   }
0398   // if decay mode with pi0s is expected look for signal gamma candidates
0399   // within eta-phi strips around leading track
0400   if (pfTau.decayMode() % 5 != 0 && pfTau.leadChargedHadrCand().isNonnull()) {
0401     for (CandPtrs::iterator it = pfGammas.begin(); it != pfGammas.end();) {
0402       if (std::abs((*it)->eta() - pfTau.leadChargedHadrCand()->eta()) <
0403               std::clamp(0.2 * std::pow((*it)->pt(), -0.66), 0.05, 0.15) &&
0404           deltaPhi((*it)->phi(), pfTau.leadChargedHadrCand()->phi()) <
0405               std::clamp(0.35 * std::pow((*it)->pt(), -0.71), 0.05, 0.3)) {
0406         pfGammasSig.push_back(*it);
0407         it = pfGammas.erase(it);
0408       } else {
0409         ++it;
0410       }
0411     }
0412   }
0413   // Set gamma candidates
0414   pfTau.setsignalGammaCands(pfGammasSig);
0415   pfTau.setisolationGammaCands(pfGammas);
0416 }
0417 
0418 void PATTauHybridProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0419   // patTauHybridProducer
0420   edm::ParameterSetDescription desc;
0421 
0422   desc.add<edm::InputTag>("src", edm::InputTag("slimmedTaus"));
0423   desc.add<edm::InputTag>("jetSource", edm::InputTag("slimmedJetsUpadted"));
0424   desc.add<double>("dRMax", 0.4);
0425   desc.add<double>("jetPtMin", 20.0);
0426   desc.add<double>("jetEtaMax", 2.5);
0427   desc.add<std::string>("pnetLabel", "pfParticleNetAK4JetTags");
0428   desc.add<std::vector<std::string>>(
0429       "pnetScoreNames",
0430       {"probmu",       "probele",      "probtaup1h0p", "probtaup1h1p", "probtaup1h2p", "probtaup3h0p", "probtaup3h1p",
0431        "probtaum1h0p", "probtaum1h1p", "probtaum1h2p", "probtaum3h0p", "probtaum3h1p", "probb",        "probc",
0432        "probuds",      "probg",        "ptcorr",       "ptreshigh",    "ptreslow",     "ptnu"});
0433   desc.add<std::string>("pnetPtCorrName", "ptcorr");
0434   desc.add<double>("tauScoreMin", -1)->setComment("Minimal value of the best tau score to built recovery tau");
0435   desc.add<double>("vsJetMin", -1)->setComment("Minimal value of PNet tau-vs-jet discriminant to built recovery tau");
0436   desc.add<bool>("checkTauScoreIsBest", false)
0437       ->setComment("If true, recovery tau is built only if one of tau scores is the highest");
0438   desc.add<double>("chargeAssignmentProbMin", 0.2)
0439       ->setComment("Minimal value of charge assignment probability to built recovery tau (0,0.5)");
0440   desc.add<bool>("addGenJetMatch", true)->setComment("add MC genTauJet matching");
0441   desc.add<edm::InputTag>("genJetMatch", edm::InputTag("tauGenJetMatch"));
0442   desc.add<bool>("usePFLeptonsAsChargedHadrons", true)
0443       ->setComment("If true, all charged particles are used as charged hadron candidates");
0444 
0445   descriptions.addWithDefaultLabel(desc);
0446 }
0447 
0448 #include "FWCore/Framework/interface/MakerMacros.h"
0449 
0450 DEFINE_FWK_MODULE(PATTauHybridProducer);