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
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
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
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
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
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
0129
0130
0131 } else
0132 throw cms::Exception("Configuration") << "PFTauSelector: No suitable ID list found in provenace config!\n";
0133
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
0186 for (auto const& disc : discriminators_) {
0187
0188 if (!((*disc.handle)[tau] > disc.cut)) {
0189 passed = false;
0190 break;
0191 }
0192 }
0193 if (passed) {
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 }
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