Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:50

0001 #ifndef RecoTauTag_RecoTau_PFTauSelectorDefinition
0002 #define RecoTauTag_RecoTau_PFTauSelectorDefinition
0003 
0004 #include "FWCore/Common/interface/Provenance.h"
0005 #include "FWCore/Framework/interface/ConsumesCollector.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "FWCore/Framework/interface/Event.h"
0008 
0009 #include "DataFormats/Provenance/interface/ProcessHistoryID.h"
0010 #include "DataFormats/Provenance/interface/ProductProvenance.h"
0011 #include "DataFormats/TauReco/interface/PFTau.h"
0012 #include "DataFormats/TauReco/interface/PFTauDiscriminator.h"
0013 #include "DataFormats/TauReco/interface/TauDiscriminatorContainer.h"
0014 
0015 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0016 
0017 #include <memory>
0018 #include <iostream>
0019 
0020 struct PFTauSelectorDefinition {
0021   typedef reco::PFTauCollection collection;
0022   typedef edm::Handle<collection> HandleToCollection;
0023   typedef std::vector<const reco::PFTau*> container;
0024   typedef container::const_iterator const_iterator;
0025 
0026   struct DiscCutPair {
0027     edm::Handle<reco::PFTauDiscriminator> handle;
0028     edm::EDGetTokenT<reco::PFTauDiscriminator> inputToken;
0029     double cut;
0030   };
0031   struct DiscContainerCutPair {
0032     edm::Handle<reco::TauDiscriminatorContainer> handle;
0033     edm::EDGetTokenT<reco::TauDiscriminatorContainer> inputToken;
0034     std::vector<std::string> rawLabels;
0035     std::vector<std::pair<int, double>> rawCuts;
0036     std::vector<std::string> wpLabels;
0037     std::vector<int> wpCuts;
0038   };
0039   typedef std::vector<DiscCutPair> DiscCutPairVec;
0040   typedef std::vector<DiscContainerCutPair> DiscContainerCutPairVec;
0041 
0042   PFTauSelectorDefinition(const edm::ParameterSet& cfg, edm::ConsumesCollector&& iC) {
0043     auto const& discriminators = cfg.getParameter<std::vector<edm::ParameterSet>>("discriminators");
0044     auto const& discriminatorContainers = cfg.getParameter<std::vector<edm::ParameterSet>>("discriminatorContainers");
0045     // Build each of our cuts
0046     for (auto const& pset : discriminators) {
0047       DiscCutPair newCut;
0048       newCut.inputToken = iC.consumes<reco::PFTauDiscriminator>(pset.getParameter<edm::InputTag>("discriminator"));
0049       newCut.cut = pset.getParameter<double>("selectionCut");
0050       discriminators_.push_back(newCut);
0051     }
0052     for (auto const& pset : discriminatorContainers) {
0053       DiscContainerCutPair newCut;
0054       newCut.inputToken =
0055           iC.consumes<reco::TauDiscriminatorContainer>(pset.getParameter<edm::InputTag>("discriminator"));
0056       auto const& rawLabels = pset.getParameter<std::vector<std::string>>("rawValues");
0057       auto const& rawCutValues = pset.getParameter<std::vector<double>>("selectionCuts");
0058       if (rawLabels.size() != rawCutValues.size()) {
0059         throw cms::Exception("PFTauSelectorBadHandle")
0060             << "unequal number of TauIDContainer raw value indices and cut values given to PFTauSelector.";
0061       }
0062       for (size_t i = 0; i < rawLabels.size(); i++) {
0063         newCut.rawCuts.push_back(std::pair<int, double>(-99, rawCutValues[i]));
0064         newCut.rawLabels.push_back(rawLabels[i]);
0065       }
0066       newCut.wpLabels = pset.getParameter<std::vector<std::string>>("workingPoints");
0067       newCut.wpCuts.resize(newCut.wpLabels.size());
0068       discriminatorContainers_.push_back(newCut);
0069     }
0070 
0071     // Build a string cut if desired
0072     cut_ = std::make_unique<StringCutObjectSelector<reco::PFTau>>(cfg.getParameter<std::string>("cut"));
0073   }
0074 
0075   const_iterator begin() const { return selected_.begin(); }
0076   const_iterator end() const { return selected_.end(); }
0077 
0078   void select(const HandleToCollection& hc, const edm::Event& e, const edm::EventSetup& s) {
0079     selected_.clear();
0080 
0081     if (!hc.isValid()) {
0082       throw cms::Exception("PFTauSelectorBadHandle")
0083           << "an invalid PFTau handle with ProductID" << hc.id() << " passed to PFTauSelector.";
0084     }
0085 
0086     // Load each discriminator
0087     for (auto& disc : discriminators_) {
0088       e.getByToken(disc.inputToken, disc.handle);
0089     }
0090     for (auto& disc : discriminatorContainers_) {
0091       e.getByToken(disc.inputToken, disc.handle);
0092     }
0093     // Retrieve ID container indices if config history changes, in particular for the first event.
0094     if (phID_ != e.processHistoryID()) {
0095       phID_ = e.processHistoryID();
0096       for (auto& disc : discriminatorContainers_) {
0097         auto const& psetsFromProvenance = edm::parameterSet(disc.handle.provenance()->stable(), e.processHistory());
0098         // find raw value indices
0099         if (psetsFromProvenance.exists("rawValues")) {
0100           auto const idlist = psetsFromProvenance.getParameter<std::vector<std::string>>("rawValues");
0101           for (size_t i = 0; i < disc.rawLabels.size(); ++i) {
0102             bool found = false;
0103             for (size_t j = 0; j < idlist.size(); ++j) {
0104               if (disc.rawLabels[i] == idlist[j]) {
0105                 found = true;
0106                 disc.rawCuts[i].first = j;
0107               }
0108             }
0109             if (!found)
0110               throw cms::Exception("Configuration")
0111                   << "PFTauSelector: Requested working point '" << disc.rawLabels[i] << "' not found!\n";
0112           }
0113         } else if (psetsFromProvenance.exists("IDdefinitions")) {
0114           auto const idlist = psetsFromProvenance.getParameter<std::vector<edm::ParameterSet>>("IDdefinitions");
0115           for (size_t i = 0; i < disc.rawLabels.size(); ++i) {
0116             bool found = false;
0117             for (size_t j = 0; j < idlist.size(); ++j) {
0118               if (disc.rawLabels[i] == idlist[j].getParameter<std::string>("IDname")) {
0119                 found = true;
0120                 disc.rawCuts[i].first = j;
0121               }
0122             }
0123             if (!found)
0124               throw cms::Exception("Configuration")
0125                   << "PFTauSelector: Requested working point '" << disc.rawLabels[i] << "' not found!\n";
0126           }
0127         } else if (psetsFromProvenance.exists("VSjetWP")) {
0128           // This else statement was added in the update of the HLT paths to use DeepTauId instead of charged isolation. Because the DeepTauId module is shared
0129           // with offline and its psetsFromProvenance do not contain any of the above but only VSxWP, this selector would automatically go to the else statement
0130           // that follows this one and fail. It is left empty because at HLT the raw values are not used and no action is needed here.
0131         } else
0132           throw cms::Exception("Configuration") << "PFTauSelector: No suitable ID list found in provenace config!\n";
0133         // find working point indices
0134         if (psetsFromProvenance.exists("workingPoints")) {
0135           auto const idlist = psetsFromProvenance.getParameter<std::vector<std::string>>("workingPoints");
0136           for (size_t i = 0; i < disc.wpLabels.size(); ++i) {
0137             bool found = false;
0138             for (size_t j = 0; j < idlist.size(); ++j) {
0139               if (disc.wpLabels[i] == idlist[j]) {
0140                 found = true;
0141                 disc.wpCuts[i] = j;
0142               }
0143             }
0144             if (!found)
0145               throw cms::Exception("Configuration")
0146                   << "PFTauSelector: Requested working point '" << disc.wpLabels[i] << "' not found!\n";
0147           }
0148         } else if (psetsFromProvenance.exists("IDWPdefinitions")) {
0149           auto const idlist = psetsFromProvenance.getParameter<std::vector<edm::ParameterSet>>("IDWPdefinitions");
0150           for (size_t i = 0; i < disc.wpLabels.size(); ++i) {
0151             bool found = false;
0152             for (size_t j = 0; j < idlist.size(); ++j) {
0153               if (disc.wpLabels[i] == idlist[j].getParameter<std::string>("IDname")) {
0154                 found = true;
0155                 disc.wpCuts[i] = j;
0156               }
0157             }
0158             if (!found)
0159               throw cms::Exception("Configuration")
0160                   << "PFTauSelector: Requested working point '" << disc.wpLabels[i] << "' not found!\n";
0161           }
0162         } else if (psetsFromProvenance.exists("VSjetWP")) {
0163           auto const idlist = psetsFromProvenance.getParameter<std::vector<std::string>>("VSjetWP");
0164           for (size_t i = 0; i < disc.wpLabels.size(); ++i) {
0165             bool found = false;
0166             for (size_t j = 0; j < idlist.size(); ++j) {
0167               if (disc.wpLabels[i] == idlist[j]) {
0168                 found = true;
0169                 disc.wpCuts[i] = j;
0170               }
0171             }
0172             if (!found)
0173               throw cms::Exception("Configuration")
0174                   << "PFTauSelector: Requested working point '" << disc.wpLabels[i] << "' not found!\n";
0175           }
0176         } else
0177           throw cms::Exception("Configuration") << "PFTauSelector: No suitable ID WP list found in provenace config!\n";
0178       }
0179     }
0180 
0181     const size_t nTaus = hc->size();
0182     for (size_t iTau = 0; iTau < nTaus; ++iTau) {
0183       bool passed = true;
0184       reco::PFTauRef tau(hc, iTau);
0185       // Check if it passed all the discrimiantors
0186       for (auto const& disc : discriminators_) {
0187         // Check this discriminator passes
0188         if (!((*disc.handle)[tau] > disc.cut)) {
0189           passed = false;
0190           break;
0191         }
0192       }
0193       if (passed) {  // if passed so far, check other discriminators
0194         for (auto const& disc : discriminatorContainers_) {
0195           for (auto const& rawCut : disc.rawCuts) {
0196             if (!((*disc.handle)[tau].rawValues.at(rawCut.first) > rawCut.second)) {
0197               passed = false;
0198               break;
0199             }
0200           }
0201           if (!passed)
0202             break;
0203           for (auto const& wpCut : disc.wpCuts) {
0204             if (!((*disc.handle)[tau].workingPoints.at(wpCut))) {
0205               passed = false;
0206               break;
0207             }
0208           }
0209           if (!passed)
0210             break;
0211         }
0212       }
0213 
0214       if (passed && cut_.get()) {
0215         passed = (*cut_)(*tau);
0216       }
0217 
0218       if (passed)
0219         selected_.push_back(tau.get());
0220     }
0221   }  // end select()
0222 
0223   size_t size() const { return selected_.size(); }
0224 
0225 private:
0226   container selected_;
0227   DiscCutPairVec discriminators_;
0228   DiscContainerCutPairVec discriminatorContainers_;
0229   edm::ProcessHistoryID phID_;
0230 
0231   std::unique_ptr<StringCutObjectSelector<reco::PFTau>> cut_;
0232 };
0233 
0234 #endif