Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:23:53

0001 /**
0002   \class    pat::PATTauProducer PATTauProducer.h "PhysicsTools/PatAlgos/interface/PATTauProducer.h"
0003   \brief    Produces pat::Tau's
0004 
0005    The PATTauProducer produces analysis-level pat::Tau's starting from
0006    a collection of objects of TauType.
0007 
0008   \author   Steven Lowette, Christophe Delaere
0009 */
0010 
0011 #include "CommonTools/Utils/interface/PtComparator.h"
0012 #include "DataFormats/Common/interface/Association.h"
0013 #include "DataFormats/Common/interface/Handle.h"
0014 #include "DataFormats/Common/interface/Ref.h"
0015 #include "DataFormats/Common/interface/View.h"
0016 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0017 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
0018 #include "DataFormats/JetReco/interface/GenJetCollection.h"
0019 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0020 #include "DataFormats/PatCandidates/interface/Tau.h"
0021 #include "DataFormats/PatCandidates/interface/TauJetCorrFactors.h"
0022 #include "DataFormats/PatCandidates/interface/TauPFSpecific.h"
0023 #include "DataFormats/PatCandidates/interface/UserData.h"
0024 #include "DataFormats/Provenance/interface/ProcessHistoryID.h"
0025 #include "DataFormats/Provenance/interface/ProductProvenance.h"
0026 #include "DataFormats/TauReco/interface/PFTau.h"
0027 #include "DataFormats/TauReco/interface/PFTauDiscriminator.h"
0028 #include "DataFormats/TauReco/interface/PFTauTransverseImpactParameter.h"
0029 #include "DataFormats/TauReco/interface/PFTauTransverseImpactParameterAssociation.h"
0030 #include "DataFormats/TauReco/interface/PFTauTransverseImpactParameterFwd.h"
0031 #include "DataFormats/TauReco/interface/TauDiscriminatorContainer.h"
0032 #include "FWCore/Common/interface/Provenance.h"
0033 #include "FWCore/Framework/interface/Event.h"
0034 #include "FWCore/Framework/interface/stream/EDProducer.h"
0035 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0036 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0037 #include "FWCore/ParameterSet/interface/FileInPath.h"
0038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0039 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0040 #include "FWCore/Utilities/interface/InputTag.h"
0041 #include "PhysicsTools/PatAlgos/interface/EfficiencyLoader.h"
0042 #include "PhysicsTools/PatAlgos/interface/KinResolutionsLoader.h"
0043 #include "PhysicsTools/PatAlgos/interface/MultiIsolator.h"
0044 #include "PhysicsTools/PatAlgos/interface/PATUserDataHelper.h"
0045 #include "PhysicsTools/PatAlgos/interface/PATUserDataMerger.h"
0046 #include "RecoTauTag/RecoTau/interface/PositionAtECalEntranceComputer.h"
0047 
0048 #include <memory>
0049 #include <string>
0050 #include <vector>
0051 
0052 typedef edm::AssociationVector<reco::PFTauRefProd, std::vector<reco::PFTauTransverseImpactParameterRef>>
0053     PFTauTIPAssociationByRef;
0054 namespace pat {
0055 
0056   class PATTauProducer : public edm::stream::EDProducer<> {
0057   public:
0058     explicit PATTauProducer(const edm::ParameterSet& iConfig);
0059     ~PATTauProducer() override;
0060 
0061     void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0062 
0063     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0064 
0065   private:
0066     bool firstOccurence_;  // used to print LogWarnings only at first occurnece in the event loop
0067 
0068     // configurables
0069     edm::EDGetTokenT<edm::View<reco::BaseTau>> baseTauToken_;
0070     edm::EDGetTokenT<PFTauTIPAssociationByRef> tauTransverseImpactParameterToken_;
0071     edm::EDGetTokenT<reco::PFTauCollection> pfTauToken_;
0072     edm::InputTag tauTransverseImpactParameterSrc_;
0073     bool embedIsolationTracks_;
0074     bool embedLeadTrack_;
0075     bool embedSignalTracks_;
0076     bool embedLeadPFCand_;
0077     bool embedLeadPFChargedHadrCand_;
0078     bool embedLeadPFNeutralCand_;
0079     bool embedSignalPFCands_;
0080     bool embedSignalPFChargedHadrCands_;
0081     bool embedSignalPFNeutralHadrCands_;
0082     bool embedSignalPFGammaCands_;
0083     bool embedIsolationPFCands_;
0084     bool embedIsolationPFChargedHadrCands_;
0085     bool embedIsolationPFNeutralHadrCands_;
0086     bool embedIsolationPFGammaCands_;
0087 
0088     bool addGenMatch_;
0089     bool embedGenMatch_;
0090     std::vector<edm::EDGetTokenT<edm::Association<reco::GenParticleCollection>>> genMatchTokens_;
0091 
0092     bool addGenJetMatch_;
0093     bool embedGenJetMatch_;
0094     edm::EDGetTokenT<edm::Association<reco::GenJetCollection>> genJetMatchToken_;
0095 
0096     bool addTauJetCorrFactors_;
0097     std::vector<edm::EDGetTokenT<edm::ValueMap<TauJetCorrFactors>>> tauJetCorrFactorsTokens_;
0098 
0099     bool addTauID_;
0100     typedef std::pair<std::string, edm::InputTag> NameTag;
0101     typedef std::pair<std::string, std::string> WPCfg;
0102     typedef std::pair<WPCfg, int> WPIdx;
0103     typedef std::pair<std::string, WPIdx> NameWPIdx;
0104     typedef std::pair<edm::InputTag, std::vector<NameWPIdx>>
0105         IDContainerData;  //to save input module tag and corresponding pairs <working point name for the output tree, WP index in the input ID container>
0106     std::vector<NameTag> tauIDSrcs_;
0107     std::vector<std::vector<NameWPIdx>> tauIDSrcContainers_;
0108     std::vector<edm::EDGetTokenT<reco::PFTauDiscriminator>> pfTauIDTokens_;
0109     std::vector<edm::EDGetTokenT<reco::TauDiscriminatorContainer>> pfTauIDContainerTokens_;
0110     bool skipMissingTauID_;
0111     edm::ProcessHistoryID phID_;
0112     // tools
0113     GreaterByPt<Tau> pTTauComparator_;
0114 
0115     pat::helper::MultiIsolator isolator_;
0116     pat::helper::MultiIsolator::IsolationValuePairs isolatorTmpStorage_;  // better here than recreate at each event
0117     std::vector<std::pair<pat::IsolationKeys, edm::InputTag>> isoDepositLabels_;
0118     std::vector<edm::EDGetTokenT<edm::ValueMap<IsoDeposit>>> isoDepositTokens_;
0119 
0120     bool addEfficiencies_;
0121     pat::helper::EfficiencyLoader efficiencyLoader_;
0122 
0123     bool addResolutions_;
0124     pat::helper::KinResolutionsLoader resolutionLoader_;
0125 
0126     bool useUserData_;
0127     pat::PATUserDataHelper<pat::Tau> userDataHelper_;
0128 
0129     template <typename TauCollectionType, typename TauDiscrType>
0130     float getTauIdDiscriminator(const edm::Handle<TauCollectionType>&, size_t, const edm::Handle<TauDiscrType>&);
0131     float getTauIdDiscriminatorFromContainer(const edm::Handle<reco::PFTauCollection>&,
0132                                              size_t,
0133                                              const edm::Handle<reco::TauDiscriminatorContainer>&,
0134                                              int);
0135 
0136     PositionAtECalEntranceComputer posAtECalEntranceComputer_;
0137   };
0138 
0139 }  // namespace pat
0140 
0141 using namespace pat;
0142 
0143 PATTauProducer::PATTauProducer(const edm::ParameterSet& iConfig)
0144     : isolator_(iConfig.getParameter<edm::ParameterSet>("userIsolation"), consumesCollector(), false),
0145       useUserData_(iConfig.exists("userData")),
0146       posAtECalEntranceComputer_(consumesCollector()) {
0147   firstOccurence_ = true;
0148   // initialize the configurables
0149   baseTauToken_ = consumes<edm::View<reco::BaseTau>>(iConfig.getParameter<edm::InputTag>("tauSource"));
0150   tauTransverseImpactParameterSrc_ = iConfig.getParameter<edm::InputTag>("tauTransverseImpactParameterSource");
0151   tauTransverseImpactParameterToken_ = consumes<PFTauTIPAssociationByRef>(tauTransverseImpactParameterSrc_);
0152   pfTauToken_ = consumes<reco::PFTauCollection>(iConfig.getParameter<edm::InputTag>("tauSource"));
0153   embedIsolationTracks_ = iConfig.getParameter<bool>("embedIsolationTracks");
0154   embedLeadTrack_ = iConfig.getParameter<bool>("embedLeadTrack");
0155   embedSignalTracks_ = iConfig.getParameter<bool>("embedSignalTracks");
0156   embedLeadPFCand_ = iConfig.getParameter<bool>("embedLeadPFCand");
0157   embedLeadPFChargedHadrCand_ = iConfig.getParameter<bool>("embedLeadPFChargedHadrCand");
0158   embedLeadPFNeutralCand_ = iConfig.getParameter<bool>("embedLeadPFNeutralCand");
0159   embedSignalPFCands_ = iConfig.getParameter<bool>("embedSignalPFCands");
0160   embedSignalPFChargedHadrCands_ = iConfig.getParameter<bool>("embedSignalPFChargedHadrCands");
0161   embedSignalPFNeutralHadrCands_ = iConfig.getParameter<bool>("embedSignalPFNeutralHadrCands");
0162   embedSignalPFGammaCands_ = iConfig.getParameter<bool>("embedSignalPFGammaCands");
0163   embedIsolationPFCands_ = iConfig.getParameter<bool>("embedIsolationPFCands");
0164   embedIsolationPFChargedHadrCands_ = iConfig.getParameter<bool>("embedIsolationPFChargedHadrCands");
0165   embedIsolationPFNeutralHadrCands_ = iConfig.getParameter<bool>("embedIsolationPFNeutralHadrCands");
0166   embedIsolationPFGammaCands_ = iConfig.getParameter<bool>("embedIsolationPFGammaCands");
0167   addGenMatch_ = iConfig.getParameter<bool>("addGenMatch");
0168   if (addGenMatch_) {
0169     embedGenMatch_ = iConfig.getParameter<bool>("embedGenMatch");
0170     genMatchTokens_.push_back(consumes<edm::Association<reco::GenParticleCollection>>(
0171         iConfig.getParameter<edm::InputTag>("genParticleMatch")));
0172   }
0173   addGenJetMatch_ = iConfig.getParameter<bool>("addGenJetMatch");
0174   if (addGenJetMatch_) {
0175     embedGenJetMatch_ = iConfig.getParameter<bool>("embedGenJetMatch");
0176     genJetMatchToken_ =
0177         consumes<edm::Association<reco::GenJetCollection>>(iConfig.getParameter<edm::InputTag>("genJetMatch"));
0178   }
0179   addTauJetCorrFactors_ = iConfig.getParameter<bool>("addTauJetCorrFactors");
0180   tauJetCorrFactorsTokens_ = edm::vector_transform(
0181       iConfig.getParameter<std::vector<edm::InputTag>>("tauJetCorrFactorsSource"),
0182       [this](edm::InputTag const& tag) { return mayConsume<edm::ValueMap<TauJetCorrFactors>>(tag); });
0183   // tau ID configurables
0184   addTauID_ = iConfig.getParameter<bool>("addTauID");
0185   if (addTauID_) {
0186     // read the different tau ID names
0187     edm::ParameterSet idps = iConfig.getParameter<edm::ParameterSet>("tauIDSources");
0188     std::vector<std::string> names = idps.getParameterNamesForType<edm::ParameterSet>();
0189     std::map<std::string, IDContainerData> idContainerMap;
0190     for (auto const& name : names) {
0191       auto const& idp = idps.getParameter<edm::ParameterSet>(name);
0192       std::string prov_cfg_label = idp.getParameter<std::string>("provenanceConfigLabel");
0193       std::string prov_ID_label = idp.getParameter<std::string>("idLabel");
0194       edm::InputTag tag = idp.getParameter<edm::InputTag>("inputTag");
0195       if (prov_cfg_label.empty()) {
0196         tauIDSrcs_.push_back(NameTag(name, tag));
0197       } else {
0198         if (prov_cfg_label != "rawValues" && prov_cfg_label != "workingPoints" && prov_cfg_label != "IDdefinitions" &&
0199             prov_cfg_label != "IDWPdefinitions" && prov_cfg_label != "direct_rawValues" &&
0200             prov_cfg_label != "direct_workingPoints")
0201           throw cms::Exception("Configuration")
0202               << "PATTauProducer: Parameter 'provenanceConfigLabel' does only accept 'rawValues', 'workingPoints', "
0203                  "'IDdefinitions', 'IDWPdefinitions', 'direct_rawValues', 'direct_workingPoints'\n";
0204         std::map<std::string, IDContainerData>::iterator it;
0205         it = idContainerMap.insert({tag.label() + tag.instance(), {tag, std::vector<NameWPIdx>()}}).first;
0206         it->second.second.push_back(NameWPIdx(name, WPIdx(WPCfg(prov_cfg_label, prov_ID_label), -99)));
0207       }
0208     }
0209     // but in any case at least once
0210     if (tauIDSrcs_.empty() && idContainerMap.empty())
0211       throw cms::Exception("Configuration") << "PATTauProducer: id addTauID is true, you must specify either:\n"
0212                                             << "\tPSet tauIDSources = { \n"
0213                                             << "\t\tInputTag <someName> = <someTag>   // as many as you want \n "
0214                                             << "\t}\n";
0215 
0216     for (auto const& mapEntry : idContainerMap) {
0217       tauIDSrcContainers_.push_back(mapEntry.second.second);
0218       pfTauIDContainerTokens_.push_back(mayConsume<reco::TauDiscriminatorContainer>(mapEntry.second.first));
0219     }
0220   }
0221   pfTauIDTokens_ = edm::vector_transform(
0222       tauIDSrcs_, [this](NameTag const& tag) { return mayConsume<reco::PFTauDiscriminator>(tag.second); });
0223   skipMissingTauID_ = iConfig.getParameter<bool>("skipMissingTauID");
0224   // IsoDeposit configurables
0225   if (iConfig.exists("isoDeposits")) {
0226     edm::ParameterSet depconf = iConfig.getParameter<edm::ParameterSet>("isoDeposits");
0227     if (depconf.exists("tracker"))
0228       isoDepositLabels_.push_back(std::make_pair(pat::TrackIso, depconf.getParameter<edm::InputTag>("tracker")));
0229     if (depconf.exists("ecal"))
0230       isoDepositLabels_.push_back(std::make_pair(pat::EcalIso, depconf.getParameter<edm::InputTag>("ecal")));
0231     if (depconf.exists("hcal"))
0232       isoDepositLabels_.push_back(std::make_pair(pat::HcalIso, depconf.getParameter<edm::InputTag>("hcal")));
0233     if (depconf.exists("pfAllParticles"))
0234       isoDepositLabels_.push_back(
0235           std::make_pair(pat::PfAllParticleIso, depconf.getParameter<edm::InputTag>("pfAllParticles")));
0236     if (depconf.exists("pfChargedHadron"))
0237       isoDepositLabels_.push_back(
0238           std::make_pair(pat::PfChargedHadronIso, depconf.getParameter<edm::InputTag>("pfChargedHadron")));
0239     if (depconf.exists("pfNeutralHadron"))
0240       isoDepositLabels_.push_back(
0241           std::make_pair(pat::PfNeutralHadronIso, depconf.getParameter<edm::InputTag>("pfNeutralHadron")));
0242     if (depconf.exists("pfGamma"))
0243       isoDepositLabels_.push_back(std::make_pair(pat::PfGammaIso, depconf.getParameter<edm::InputTag>("pfGamma")));
0244 
0245     if (depconf.exists("user")) {
0246       std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag>>("user");
0247       std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
0248       int key = UserBaseIso;
0249       for (; it != ed; ++it, ++key) {
0250         isoDepositLabels_.push_back(std::make_pair(IsolationKeys(key), *it));
0251       }
0252     }
0253   }
0254   isoDepositTokens_ =
0255       edm::vector_transform(isoDepositLabels_, [this](std::pair<IsolationKeys, edm::InputTag> const& label) {
0256         return consumes<edm::ValueMap<IsoDeposit>>(label.second);
0257       });
0258   // Efficiency configurables
0259   addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
0260   if (addEfficiencies_) {
0261     efficiencyLoader_ =
0262         pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"), consumesCollector());
0263   }
0264   // Resolution configurables
0265   addResolutions_ = iConfig.getParameter<bool>("addResolutions");
0266   if (addResolutions_) {
0267     resolutionLoader_ =
0268         pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"), consumesCollector());
0269   }
0270   // Check to see if the user wants to add user data
0271   if (useUserData_) {
0272     userDataHelper_ = PATUserDataHelper<Tau>(iConfig.getParameter<edm::ParameterSet>("userData"), consumesCollector());
0273   }
0274   // produces vector of taus
0275   produces<std::vector<Tau>>();
0276 }
0277 
0278 PATTauProducer::~PATTauProducer() {}
0279 
0280 void PATTauProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0281   // switch off embedding (in unschedules mode)
0282   if (iEvent.isRealData()) {
0283     addGenMatch_ = false;
0284     embedGenMatch_ = false;
0285     addGenJetMatch_ = false;
0286   }
0287 
0288   // Get the collection of taus from the event
0289   edm::Handle<edm::View<reco::BaseTau>> anyTaus;
0290   try {
0291     iEvent.getByToken(baseTauToken_, anyTaus);
0292   } catch (const edm::Exception& e) {
0293     edm::LogWarning("DataSource") << "WARNING! No Tau collection found. This missing input will not block the job. "
0294                                      "Instead, an empty tau collection is being be produced.";
0295     auto patTaus = std::make_unique<std::vector<Tau>>();
0296     iEvent.put(std::move(patTaus));
0297     return;
0298   }
0299 
0300   posAtECalEntranceComputer_.beginEvent(iSetup);
0301 
0302   if (isolator_.enabled())
0303     isolator_.beginEvent(iEvent, iSetup);
0304 
0305   if (efficiencyLoader_.enabled())
0306     efficiencyLoader_.newEvent(iEvent);
0307   if (resolutionLoader_.enabled())
0308     resolutionLoader_.newEvent(iEvent, iSetup);
0309 
0310   std::vector<edm::Handle<edm::ValueMap<IsoDeposit>>> deposits(isoDepositTokens_.size());
0311   for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
0312     iEvent.getByToken(isoDepositTokens_[j], deposits[j]);
0313   }
0314 
0315   // prepare the MC matching
0316   std::vector<edm::Handle<edm::Association<reco::GenParticleCollection>>> genMatches(genMatchTokens_.size());
0317   if (addGenMatch_) {
0318     for (size_t j = 0, nd = genMatchTokens_.size(); j < nd; ++j) {
0319       iEvent.getByToken(genMatchTokens_[j], genMatches[j]);
0320     }
0321   }
0322 
0323   edm::Handle<edm::Association<reco::GenJetCollection>> genJetMatch;
0324   if (addGenJetMatch_)
0325     iEvent.getByToken(genJetMatchToken_, genJetMatch);
0326 
0327   // read in the jet correction factors ValueMap
0328   std::vector<edm::ValueMap<TauJetCorrFactors>> tauJetCorrs;
0329   if (addTauJetCorrFactors_) {
0330     for (size_t i = 0; i < tauJetCorrFactorsTokens_.size(); ++i) {
0331       edm::Handle<edm::ValueMap<TauJetCorrFactors>> tauJetCorr;
0332       iEvent.getByToken(tauJetCorrFactorsTokens_[i], tauJetCorr);
0333       tauJetCorrs.push_back(*tauJetCorr);
0334     }
0335   }
0336 
0337   auto patTaus = std::make_unique<std::vector<Tau>>();
0338 
0339   bool first = true;  // this is introduced to issue warnings only for the first tau-jet
0340   for (size_t idx = 0, ntaus = anyTaus->size(); idx < ntaus; ++idx) {
0341     edm::RefToBase<reco::BaseTau> tausRef = anyTaus->refAt(idx);
0342     edm::Ptr<reco::BaseTau> tausPtr = anyTaus->ptrAt(idx);
0343 
0344     Tau aTau(tausRef);
0345     if (embedLeadTrack_)
0346       aTau.embedLeadTrack();
0347     if (embedSignalTracks_)
0348       aTau.embedSignalTracks();
0349     if (embedIsolationTracks_)
0350       aTau.embedIsolationTracks();
0351     if (embedLeadPFCand_) {
0352       if (aTau.isPFTau())
0353         aTau.embedLeadPFCand();
0354       else
0355         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0356                                          "from a reco::PFTau is impossible.\n";
0357     }
0358     if (embedLeadPFChargedHadrCand_) {
0359       if (aTau.isPFTau())
0360         aTau.embedLeadPFChargedHadrCand();
0361       else
0362         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0363                                          "from a reco::PFTau is impossible.\n";
0364     }
0365     if (embedLeadPFNeutralCand_) {
0366       if (aTau.isPFTau())
0367         aTau.embedLeadPFNeutralCand();
0368       else
0369         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0370                                          "from a reco::PFTau is impossible.\n";
0371     }
0372     if (embedSignalPFCands_) {
0373       if (aTau.isPFTau())
0374         aTau.embedSignalPFCands();
0375       else
0376         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0377                                          "from a reco::PFTau is impossible.\n";
0378     }
0379     if (embedSignalPFChargedHadrCands_) {
0380       if (aTau.isPFTau())
0381         aTau.embedSignalPFChargedHadrCands();
0382       else
0383         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0384                                          "from a reco::PFTau is impossible.\n";
0385     }
0386     if (embedSignalPFNeutralHadrCands_) {
0387       if (aTau.isPFTau())
0388         aTau.embedSignalPFNeutralHadrCands();
0389       else
0390         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0391                                          "from a reco::PFTau is impossible.\n";
0392     }
0393     if (embedSignalPFGammaCands_) {
0394       if (aTau.isPFTau())
0395         aTau.embedSignalPFGammaCands();
0396       else
0397         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0398                                          "from a reco::PFTau is impossible.\n";
0399     }
0400     if (embedIsolationPFCands_) {
0401       if (aTau.isPFTau())
0402         aTau.embedIsolationPFCands();
0403       else
0404         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0405                                          "from a reco::PFTau is impossible.\n";
0406     }
0407     if (embedIsolationPFChargedHadrCands_) {
0408       if (aTau.isPFTau())
0409         aTau.embedIsolationPFChargedHadrCands();
0410       else
0411         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0412                                          "from a reco::PFTau is impossible.\n";
0413     }
0414     if (embedIsolationPFNeutralHadrCands_) {
0415       if (aTau.isPFTau())
0416         aTau.embedIsolationPFNeutralHadrCands();
0417       else
0418         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0419                                          "from a reco::PFTau is impossible.\n";
0420     }
0421     if (embedIsolationPFGammaCands_) {
0422       if (aTau.isPFTau())
0423         aTau.embedIsolationPFGammaCands();
0424       else
0425         edm::LogWarning("Type Error") << "Embedding a PFTau-specific information into a pat::Tau which wasn't made "
0426                                          "from a reco::PFTau is impossible.\n";
0427     }
0428 
0429     if (addTauJetCorrFactors_) {
0430       // add additional JetCorrs to the jet
0431       for (unsigned int i = 0; i < tauJetCorrs.size(); ++i) {
0432         const TauJetCorrFactors& tauJetCorr = tauJetCorrs[i][tausRef];
0433         // uncomment for debugging
0434         // tauJetCorr.print();
0435         aTau.addJECFactors(tauJetCorr);
0436       }
0437       std::vector<std::string> levels = tauJetCorrs[0][tausRef].correctionLabels();
0438       if (std::find(levels.begin(), levels.end(), "L2L3Residual") != levels.end()) {
0439         aTau.initializeJEC(tauJetCorrs[0][tausRef].jecLevel("L2L3Residual"));
0440       } else if (std::find(levels.begin(), levels.end(), "L3Absolute") != levels.end()) {
0441         aTau.initializeJEC(tauJetCorrs[0][tausRef].jecLevel("L3Absolute"));
0442       } else {
0443         aTau.initializeJEC(tauJetCorrs[0][tausRef].jecLevel("Uncorrected"));
0444         if (first) {
0445           edm::LogWarning("L3Absolute not found")
0446               << "L2L3Residual and L3Absolute are not part of the correction applied jetCorrFactors \n"
0447               << "of module " << tauJetCorrs[0][tausRef].jecSet() << " jets will remain"
0448               << " uncorrected.";
0449           first = false;
0450         }
0451       }
0452     }
0453 
0454     // store the match to the generated final state muons
0455     if (addGenMatch_) {
0456       for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
0457         reco::GenParticleRef genTau = (*genMatches[i])[tausRef];
0458         aTau.addGenParticleRef(genTau);
0459       }
0460       if (embedGenMatch_)
0461         aTau.embedGenParticle();
0462     }
0463 
0464     // store the match to the visible part of the generated tau
0465     if (addGenJetMatch_) {
0466       reco::GenJetRef genJetTau = (*genJetMatch)[tausRef];
0467       if (genJetTau.isNonnull() && genJetTau.isAvailable()) {
0468         aTau.setGenJet(genJetTau);
0469       }  // leave empty if no match found
0470     }
0471 
0472     // prepare ID extraction
0473     if (addTauID_) {
0474       size_t numberPlainTauIds = tauIDSrcs_.size();
0475       size_t numberTauIds = numberPlainTauIds;
0476       for (auto const& it : tauIDSrcContainers_) {
0477         numberTauIds += it.size();
0478       }
0479       // if ID containers exist, product incices need to be retrieved from provenanceConfigLabel.
0480       // This is done if config history changes, in particular for the first event.
0481       if (numberPlainTauIds != numberTauIds && phID_ != iEvent.processHistoryID()) {
0482         phID_ = iEvent.processHistoryID();
0483         for (size_t idx = 0; idx < tauIDSrcContainers_.size(); ++idx) {
0484           auto pfTauIdDiscr = iEvent.getHandle(pfTauIDContainerTokens_[idx]);
0485           if (!pfTauIdDiscr.isValid())
0486             continue;  // missing IDs will be skipped lateron or crash there depending on skipMissingTauID_
0487           const edm::Provenance* prov = pfTauIdDiscr.provenance();
0488           for (NameWPIdx& idcfg : tauIDSrcContainers_[idx]) {
0489             std::string prov_cfg_label = idcfg.second.first.first;
0490             std::string prov_ID_label = idcfg.second.first.second;
0491             bool found = false;
0492             if (prov_cfg_label == "rawValues" || prov_cfg_label == "workingPoints") {
0493               const std::vector<std::string> psetsFromProvenance =
0494                   edm::parameterSet(prov->stable(), iEvent.processHistory())
0495                       .getParameter<std::vector<std::string>>(prov_cfg_label);
0496               for (size_t i = 0; i < psetsFromProvenance.size(); ++i) {
0497                 if (psetsFromProvenance[i] == prov_ID_label) {
0498                   // using negative indices for raw values
0499                   if (prov_cfg_label == "rawValues")
0500                     idcfg.second.second = -1 - i;
0501                   else
0502                     idcfg.second.second = i;
0503                   found = true;
0504                 }
0505               }
0506             } else if (prov_cfg_label == "IDdefinitions" || prov_cfg_label == "IDWPdefinitions") {
0507               const std::vector<edm::ParameterSet> psetsFromProvenance =
0508                   edm::parameterSet(prov->stable(), iEvent.processHistory())
0509                       .getParameter<std::vector<edm::ParameterSet>>(prov_cfg_label);
0510               for (size_t i = 0; i < psetsFromProvenance.size(); ++i) {
0511                 if (psetsFromProvenance[i].getParameter<std::string>("IDname") == prov_ID_label) {
0512                   // using negative indices for raw values
0513                   if (prov_cfg_label == "IDdefinitions")
0514                     idcfg.second.second = -1 - i;
0515                   else
0516                     idcfg.second.second = i;
0517                   found = true;
0518                 }
0519               }
0520             } else {
0521               // checked prov_cfg_label before, so it must be a direct access via indices
0522               try {
0523                 int i = std::stoi(prov_ID_label);
0524                 if (prov_cfg_label == "direct_rawValues")
0525                   idcfg.second.second = -1 - i;
0526                 else
0527                   idcfg.second.second = i;
0528                 found = true;
0529               } catch (std::invalid_argument const& e) {
0530                 throw cms::Exception("Configuration") << "PATTauProducer: Direct access to ID container requested, so "
0531                                                          "argument of 'idLabel' must be convertable to int!\n";
0532               }
0533             }
0534             if (!found) {
0535               throw cms::Exception("Configuration") << "PATTauProducer: Requested working point '" << prov_ID_label
0536                                                     << "' for ID '" << idcfg.first << "' not found!\n";
0537             }
0538           }
0539         }
0540       }
0541       std::string missingDiscriminators;
0542       std::vector<pat::Tau::IdPair> ids(numberTauIds);
0543       auto const& tausDeref = *tausRef;
0544       if (typeid(tausDeref) == typeid(reco::PFTau)) {
0545         edm::Handle<reco::PFTauCollection> pfTauCollection;
0546         iEvent.getByToken(pfTauToken_, pfTauCollection);
0547         for (size_t i = 0; i < numberPlainTauIds; ++i) {
0548           //std::cout << "filling PFTauDiscriminator '" << tauIDSrcs_[i].first << "' into pat::Tau object..." << std::endl;
0549 
0550           auto pfTauIdDiscr = iEvent.getHandle(pfTauIDTokens_[i]);
0551 
0552           if (skipMissingTauID_ && !pfTauIdDiscr.isValid()) {
0553             if (!missingDiscriminators.empty()) {
0554               missingDiscriminators += ", ";
0555             }
0556             missingDiscriminators += tauIDSrcs_[i].first;
0557             continue;
0558           }
0559           ids[i].first = tauIDSrcs_[i].first;
0560           ids[i].second = getTauIdDiscriminator(pfTauCollection, idx, pfTauIdDiscr);
0561         }
0562         for (size_t i = 0; i < tauIDSrcContainers_.size(); ++i) {
0563           auto pfTauIdDiscr = iEvent.getHandle(pfTauIDContainerTokens_[i]);
0564           if (skipMissingTauID_ && !pfTauIdDiscr.isValid()) {
0565             for (auto const& it : tauIDSrcContainers_[i]) {
0566               if (!missingDiscriminators.empty()) {
0567                 missingDiscriminators += ", ";
0568               }
0569               missingDiscriminators += it.first;
0570             }
0571             continue;
0572           }
0573           for (size_t j = 0; j < tauIDSrcContainers_[i].size(); ++j) {
0574             ids[numberPlainTauIds + j].first = tauIDSrcContainers_[i][j].first;
0575             ids[numberPlainTauIds + j].second = getTauIdDiscriminatorFromContainer(
0576                 pfTauCollection, idx, pfTauIdDiscr, tauIDSrcContainers_[i][j].second.second);
0577           }
0578           numberPlainTauIds += tauIDSrcContainers_[i].size();
0579         }
0580       } else {
0581         throw cms::Exception("Type Mismatch")
0582             << "PATTauProducer: unsupported datatype '" << typeid(tausDeref).name() << "' for tauSource\n";
0583       }
0584       if (!missingDiscriminators.empty() && firstOccurence_) {
0585         edm::LogWarning("DataSource") << "The following tau discriminators have not been found in the event:\n"
0586                                       << missingDiscriminators << "\n"
0587                                       << "They will not be embedded into the pat::Tau object.\n"
0588                                       << "Note: this message will be printed only at first occurence.";
0589         firstOccurence_ = false;
0590       }
0591       aTau.setTauIDs(ids);
0592     }
0593 
0594     // extraction of reconstructed tau decay mode
0595     // (only available for PFTaus)
0596     if (aTau.isPFTau()) {
0597       edm::Handle<reco::PFTauCollection> pfTaus;
0598       iEvent.getByToken(pfTauToken_, pfTaus);
0599       reco::PFTauRef pfTauRef(pfTaus, idx);
0600 
0601       aTau.setDecayMode(pfTauRef->decayMode());
0602     }
0603 
0604     // extraction of variables needed to rerun MVA isolation and anti-electron discriminator on MiniAOD
0605     if (!aTau.pfEssential_.empty()) {
0606       edm::Handle<reco::PFTauCollection> pfTaus;
0607       iEvent.getByToken(pfTauToken_, pfTaus);
0608       reco::PFTauRef pfTauRef(pfTaus, idx);
0609       pat::tau::TauPFEssential& aTauPFEssential = aTau.pfEssential_[0];
0610       float ecalEnergy = 0;
0611       float hcalEnergy = 0;
0612       float sumPhiTimesEnergy = 0.;
0613       float sumEtaTimesEnergy = 0.;
0614       float sumEnergy = 0.;
0615       float leadChargedCandPt = -99;
0616       float leadChargedCandEtaAtEcalEntrance = -99;
0617       const std::vector<reco::CandidatePtr>& signalCands = pfTauRef->signalCands();
0618       for (const auto& it : signalCands) {
0619         const reco::PFCandidate* ipfcand = dynamic_cast<const reco::PFCandidate*>(it.get());
0620         if (ipfcand != nullptr) {
0621           ecalEnergy += ipfcand->ecalEnergy();
0622           hcalEnergy += ipfcand->hcalEnergy();
0623           sumPhiTimesEnergy += ipfcand->positionAtECALEntrance().phi() * ipfcand->energy();
0624           sumEtaTimesEnergy += ipfcand->positionAtECALEntrance().eta() * ipfcand->energy();
0625           sumEnergy += ipfcand->energy();
0626           const reco::Track* track = nullptr;
0627           if (ipfcand->trackRef().isNonnull())
0628             track = ipfcand->trackRef().get();
0629           else if (ipfcand->muonRef().isNonnull() && ipfcand->muonRef()->innerTrack().isNonnull())
0630             track = ipfcand->muonRef()->innerTrack().get();
0631           else if (ipfcand->muonRef().isNonnull() && ipfcand->muonRef()->globalTrack().isNonnull())
0632             track = ipfcand->muonRef()->globalTrack().get();
0633           else if (ipfcand->muonRef().isNonnull() && ipfcand->muonRef()->outerTrack().isNonnull())
0634             track = ipfcand->muonRef()->outerTrack().get();
0635           else if (ipfcand->gsfTrackRef().isNonnull())
0636             track = ipfcand->gsfTrackRef().get();
0637           if (track) {
0638             if (track->pt() > leadChargedCandPt) {
0639               leadChargedCandEtaAtEcalEntrance = ipfcand->positionAtECALEntrance().eta();
0640               leadChargedCandPt = track->pt();
0641             }
0642           }
0643         } else {
0644           // TauReco@MiniAOD: individual ECAL and HCAL energies recovered from fractions,
0645           // and position at ECAL entrance computed on-the-fly
0646           const pat::PackedCandidate* ipatcand = dynamic_cast<const pat::PackedCandidate*>(it.get());
0647           if (ipatcand != nullptr) {
0648             ecalEnergy += ipatcand->caloFraction() * ipatcand->energy() * (1. - ipatcand->hcalFraction());
0649             hcalEnergy += ipatcand->caloFraction() * ipatcand->energy() * ipatcand->hcalFraction();
0650             double posAtECal_phi = ipatcand->phi();
0651             double posAtECal_eta = ipatcand->eta();
0652             bool success = false;
0653             reco::Candidate::Point posAtECalEntrance = posAtECalEntranceComputer_(ipatcand, success);
0654             if (success) {
0655               posAtECal_phi = posAtECalEntrance.phi();
0656               posAtECal_eta = posAtECalEntrance.eta();
0657             }
0658             sumPhiTimesEnergy += posAtECal_phi * ipatcand->energy();
0659             sumEtaTimesEnergy += posAtECal_eta * ipatcand->energy();
0660             sumEnergy += ipatcand->energy();
0661             const reco::Track* track = ipatcand->bestTrack();
0662             if (track != nullptr) {
0663               if (track->pt() > leadChargedCandPt) {
0664                 leadChargedCandEtaAtEcalEntrance = posAtECal_eta;
0665                 leadChargedCandPt = track->pt();
0666               }
0667             }
0668           }
0669         }
0670       }
0671       aTauPFEssential.ecalEnergy_ = ecalEnergy;
0672       aTauPFEssential.hcalEnergy_ = hcalEnergy;
0673       aTauPFEssential.ptLeadChargedCand_ = leadChargedCandPt;
0674       aTauPFEssential.etaAtEcalEntranceLeadChargedCand_ = leadChargedCandEtaAtEcalEntrance;
0675       if (sumEnergy != 0.) {
0676         aTauPFEssential.phiAtEcalEntrance_ = sumPhiTimesEnergy / sumEnergy;
0677         aTauPFEssential.etaAtEcalEntrance_ = sumEtaTimesEnergy / sumEnergy;
0678       } else {
0679         aTauPFEssential.phiAtEcalEntrance_ = -99.;
0680         aTauPFEssential.etaAtEcalEntrance_ = -99.;
0681       }
0682       float leadingTrackNormChi2 = 0;
0683       float ecalEnergyLeadChargedHadrCand = -99.;
0684       float hcalEnergyLeadChargedHadrCand = -99.;
0685       float emFraction = -1.;
0686       float myHCALenergy = 0.;
0687       float myECALenergy = 0.;
0688       const reco::CandidatePtr& leadingPFCharged = pfTauRef->leadChargedHadrCand();
0689       if (leadingPFCharged.isNonnull()) {
0690         const reco::PFCandidate* pfCandPtr = dynamic_cast<const reco::PFCandidate*>(leadingPFCharged.get());
0691         if (pfCandPtr != nullptr) {  // PFTau made from PFCandidates
0692           ecalEnergyLeadChargedHadrCand = pfCandPtr->ecalEnergy();
0693           hcalEnergyLeadChargedHadrCand = pfCandPtr->hcalEnergy();
0694           reco::TrackRef trackRef = pfCandPtr->trackRef();
0695           if (trackRef.isNonnull()) {
0696             leadingTrackNormChi2 = trackRef->normalizedChi2();
0697             for (const auto& isoPFCand : pfTauRef->isolationPFCands()) {
0698               myHCALenergy += isoPFCand->hcalEnergy();
0699               myECALenergy += isoPFCand->ecalEnergy();
0700             }
0701             for (const auto& signalPFCand : pfTauRef->signalPFCands()) {
0702               myHCALenergy += signalPFCand->hcalEnergy();
0703               myECALenergy += signalPFCand->ecalEnergy();
0704             }
0705             if (myHCALenergy + myECALenergy != 0.) {
0706               emFraction = myECALenergy / (myHCALenergy + myECALenergy);
0707             }
0708           }
0709         } else {
0710           const pat::PackedCandidate* packedCandPtr = dynamic_cast<const pat::PackedCandidate*>(leadingPFCharged.get());
0711           if (packedCandPtr != nullptr) {
0712             // TauReco@MiniAOD: individual ECAL and HCAL energies recovered from fractions,
0713             // and position at ECAL entrance computed on-the-fly
0714             ecalEnergyLeadChargedHadrCand =
0715                 packedCandPtr->caloFraction() * packedCandPtr->energy() * (1. - packedCandPtr->hcalFraction());
0716             hcalEnergyLeadChargedHadrCand =
0717                 packedCandPtr->caloFraction() * packedCandPtr->energy() * packedCandPtr->hcalFraction();
0718             const reco::Track* track = packedCandPtr->bestTrack();
0719             if (track != nullptr) {
0720               leadingTrackNormChi2 = track->normalizedChi2();
0721               for (const auto& isoCand : pfTauRef->isolationCands()) {
0722                 //can safely use static_cast as it is ensured that this PFTau is
0723                 //built with packedCands as its leadingCanidate
0724                 const pat::PackedCandidate* isoPackedCand = static_cast<const pat::PackedCandidate*>(isoCand.get());
0725                 myHCALenergy += isoPackedCand->caloFraction() * isoPackedCand->energy() * isoPackedCand->hcalFraction();
0726                 myECALenergy +=
0727                     isoPackedCand->caloFraction() * isoPackedCand->energy() * (1. - isoPackedCand->hcalFraction());
0728               }
0729               for (const auto& signalCand : pfTauRef->signalCands()) {
0730                 //can safely use static_cast as it is ensured that this PFTau is
0731                 //built with packedCands as its leadingCanidate
0732                 const pat::PackedCandidate* sigPackedCand = static_cast<const pat::PackedCandidate*>(signalCand.get());
0733                 myHCALenergy += sigPackedCand->caloFraction() * sigPackedCand->energy() * sigPackedCand->hcalFraction();
0734                 myECALenergy +=
0735                     sigPackedCand->caloFraction() * sigPackedCand->energy() * (1. - sigPackedCand->hcalFraction());
0736               }
0737               if (myHCALenergy + myECALenergy != 0.) {
0738                 emFraction = myECALenergy / (myHCALenergy + myECALenergy);
0739               }
0740             }
0741           }
0742         }
0743       }
0744 
0745       aTauPFEssential.emFraction_ = emFraction;
0746       aTauPFEssential.leadingTrackNormChi2_ = leadingTrackNormChi2;
0747       aTauPFEssential.ecalEnergyLeadChargedHadrCand_ = ecalEnergyLeadChargedHadrCand;
0748       aTauPFEssential.hcalEnergyLeadChargedHadrCand_ = hcalEnergyLeadChargedHadrCand;
0749       // extraction of tau lifetime information
0750       if (!tauTransverseImpactParameterSrc_.label().empty()) {
0751         edm::Handle<PFTauTIPAssociationByRef> tauLifetimeInfos;
0752         iEvent.getByToken(tauTransverseImpactParameterToken_, tauLifetimeInfos);
0753         const reco::PFTauTransverseImpactParameter& tauLifetimeInfo = *(*tauLifetimeInfos)[pfTauRef];
0754         pat::tau::TauPFEssential& aTauPFEssential = aTau.pfEssential_[0];
0755         aTauPFEssential.dxy_PCA_ = tauLifetimeInfo.dxy_PCA();
0756         aTauPFEssential.dxy_ = tauLifetimeInfo.dxy();
0757         aTauPFEssential.dxy_error_ = tauLifetimeInfo.dxy_error();
0758         aTauPFEssential.hasSV_ = tauLifetimeInfo.hasSecondaryVertex();
0759         aTauPFEssential.flightLength_ = tauLifetimeInfo.flightLength();
0760         aTauPFEssential.flightLengthSig_ = tauLifetimeInfo.flightLengthSig();
0761         aTauPFEssential.ip3d_ = tauLifetimeInfo.ip3d();
0762         aTauPFEssential.ip3d_error_ = tauLifetimeInfo.ip3d_error();
0763       }
0764     }
0765 
0766     // Isolation
0767     if (isolator_.enabled()) {
0768       isolator_.fill(*anyTaus, idx, isolatorTmpStorage_);
0769       typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
0770       // better to loop backwards, so the vector is resized less times
0771       for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(),
0772                                                        ed = isolatorTmpStorage_.rend();
0773            it != ed;
0774            ++it) {
0775         aTau.setIsolation(it->first, it->second);
0776       }
0777     }
0778 
0779     for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
0780       aTau.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[tausRef]);
0781     }
0782 
0783     if (efficiencyLoader_.enabled()) {
0784       efficiencyLoader_.setEfficiencies(aTau, tausRef);
0785     }
0786 
0787     if (resolutionLoader_.enabled()) {
0788       resolutionLoader_.setResolutions(aTau);
0789     }
0790 
0791     if (useUserData_) {
0792       userDataHelper_.add(aTau, iEvent, iSetup);
0793     }
0794 
0795     patTaus->push_back(aTau);
0796   }
0797 
0798   // sort taus in pT
0799   std::sort(patTaus->begin(), patTaus->end(), pTTauComparator_);
0800 
0801   // put genEvt object in Event
0802   iEvent.put(std::move(patTaus));
0803 
0804   // clean up
0805   if (isolator_.enabled())
0806     isolator_.endEvent();
0807 }
0808 
0809 template <typename TauCollectionType, typename TauDiscrType>
0810 float PATTauProducer::getTauIdDiscriminator(const edm::Handle<TauCollectionType>& tauCollection,
0811                                             size_t tauIdx,
0812                                             const edm::Handle<TauDiscrType>& tauIdDiscr) {
0813   edm::Ref<TauCollectionType> tauRef(tauCollection, tauIdx);
0814   return (*tauIdDiscr)[tauRef];
0815 }
0816 float PATTauProducer::getTauIdDiscriminatorFromContainer(const edm::Handle<reco::PFTauCollection>& tauCollection,
0817                                                          size_t tauIdx,
0818                                                          const edm::Handle<reco::TauDiscriminatorContainer>& tauIdDiscr,
0819                                                          int wpIdx) {
0820   edm::Ref<reco::PFTauCollection> tauRef(tauCollection, tauIdx);
0821   if (wpIdx < 0) {
0822     //Only 0th component filled with default value if prediscriminor in RecoTauDiscriminator failed.
0823     if ((*tauIdDiscr)[tauRef].rawValues.size() == 1)
0824       return (*tauIdDiscr)[tauRef].rawValues.at(0);
0825     //uses negative indices to access rawValues. In most cases only one rawValue at wpIdx=-1 exists.
0826     return (*tauIdDiscr)[tauRef].rawValues.at(-1 - wpIdx);
0827   } else {
0828     //WP vector not filled if prediscriminor in RecoTauDiscriminator failed. Set PAT output to false in this case
0829     if ((*tauIdDiscr)[tauRef].workingPoints.empty())
0830       return 0.0;
0831     return (*tauIdDiscr)[tauRef].workingPoints.at(wpIdx);
0832   }
0833 }
0834 
0835 // ParameterSet description for module
0836 void PATTauProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0837   edm::ParameterSetDescription iDesc;
0838   iDesc.setComment("PAT tau producer module");
0839 
0840   // input source
0841   iDesc.add<edm::InputTag>("tauSource", edm::InputTag())->setComment("input collection");
0842 
0843   // embedding
0844   iDesc.add<bool>("embedIsolationTracks", false)->setComment("embed external isolation tracks");
0845   iDesc.add<bool>("embedLeadTrack", false)->setComment("embed external leading track");
0846   iDesc.add<bool>("embedLeadTracks", false)->setComment("embed external signal tracks");
0847 
0848   // MC matching configurables
0849   iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
0850   iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
0851   std::vector<edm::InputTag> emptySourceVector;
0852   iDesc
0853       .addNode(edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
0854                edm::ParameterDescription<std::vector<edm::InputTag>>("genParticleMatch", emptySourceVector, true))
0855       ->setComment("input with MC match information");
0856 
0857   // MC jet matching variables
0858   iDesc.add<bool>("addGenJetMatch", true)->setComment("add MC jet matching");
0859   iDesc.add<bool>("embedGenJetMatch", false)->setComment("embed MC jet matched jet information");
0860   iDesc.add<edm::InputTag>("genJetMatch", edm::InputTag("tauGenJetMatch"));
0861 
0862   pat::helper::KinResolutionsLoader::fillDescription(iDesc);
0863 
0864   // tau ID configurables
0865   iDesc.add<bool>("addTauID", true)->setComment("add tau ID variables");
0866   edm::ParameterSetDescription tauIDSourcesPSet;
0867   tauIDSourcesPSet.setAllowAnything();
0868   iDesc
0869       .addNode(edm::ParameterDescription<edm::InputTag>("tauIDSource", edm::InputTag(), true) xor
0870                edm::ParameterDescription<edm::ParameterSetDescription>("tauIDSources", tauIDSourcesPSet, true))
0871       ->setComment("input with tau ID variables");
0872   // (Dis)allow to skip missing tauId sources
0873   iDesc.add<bool>("skipMissingTauID", false)
0874       ->setComment("allow to skip a tau ID variable when not present in the event");
0875 
0876   // IsoDeposit configurables
0877   edm::ParameterSetDescription isoDepositsPSet;
0878   isoDepositsPSet.addOptional<edm::InputTag>("tracker");
0879   isoDepositsPSet.addOptional<edm::InputTag>("ecal");
0880   isoDepositsPSet.addOptional<edm::InputTag>("hcal");
0881   isoDepositsPSet.addOptional<edm::InputTag>("pfAllParticles");
0882   isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadron");
0883   isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadron");
0884   isoDepositsPSet.addOptional<edm::InputTag>("pfGamma");
0885   isoDepositsPSet.addOptional<std::vector<edm::InputTag>>("user");
0886   iDesc.addOptional("isoDeposits", isoDepositsPSet);
0887 
0888   // Efficiency configurables
0889   edm::ParameterSetDescription efficienciesPSet;
0890   efficienciesPSet.setAllowAnything();  // TODO: the pat helper needs to implement a description.
0891   iDesc.add("efficiencies", efficienciesPSet);
0892   iDesc.add<bool>("addEfficiencies", false);
0893 
0894   // Check to see if the user wants to add user data
0895   edm::ParameterSetDescription userDataPSet;
0896   PATUserDataHelper<Tau>::fillDescription(userDataPSet);
0897   iDesc.addOptional("userData", userDataPSet);
0898 
0899   edm::ParameterSetDescription isolationPSet;
0900   isolationPSet.setAllowAnything();  // TODO: the pat helper needs to implement a description.
0901   iDesc.add("userIsolation", isolationPSet);
0902 }
0903 
0904 #include "FWCore/Framework/interface/MakerMacros.h"
0905 
0906 DEFINE_FWK_MODULE(PATTauProducer);