File indexing completed on 2024-09-07 04:37:25
0001 #ifndef Selections_H
0002 #define Selections_H
0003
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "CommonTools/UtilAlgos/interface/EventSelector.h"
0006 #include <cstdlib>
0007 #include <iomanip>
0008 #include <iostream>
0009 #include <sstream>
0010 #include "TFormula.h"
0011
0012 class Filter {
0013 public:
0014 Filter() = default;
0015 Filter(const edm::ParameterSet& iConfig, edm::ConsumesCollector& iC);
0016 Filter(std::string name, edm::ParameterSet& iConfig, edm::ConsumesCollector& iC)
0017 : name_(name), cached_decision_(false), eventCacheID_(0) {
0018 dump_ = iConfig.dump();
0019 if (!iConfig.empty()) {
0020 const std::string d("name");
0021 iConfig.addUntrackedParameter<std::string>(d, name);
0022 std::string componentName = iConfig.getParameter<std::string>("selector");
0023 selector_ = EventSelectorFactoryFromHelper::get()->create(componentName, iConfig, iC);
0024 if (iConfig.exists("description"))
0025 description_ = iConfig.getParameter<std::vector<std::string> >("description");
0026 else
0027 description_ = selector_->description();
0028 }
0029 }
0030 virtual ~Filter() {}
0031
0032 Filter(const Filter&) = delete;
0033 Filter& operator=(const Filter&) = delete;
0034 Filter(Filter&&) = default;
0035 Filter& operator=(Filter&&) = default;
0036
0037 const std::string& name() { return name_; }
0038 const std::string& dump() { return dump_; }
0039 const std::vector<std::string> description() { return description_; }
0040 const std::string descriptionText() {
0041 std::string text;
0042 for (unsigned int i = 0; i != description_.size(); ++i)
0043 text += description_[i] + "\n";
0044 text += dump() + "\n";
0045 return text;
0046 }
0047
0048 virtual bool accept(edm::Event& iEvent) {
0049 bool decision = false;
0050 if (std::numeric_limits<edm::Event::CacheIdentifier_t>::max() != eventCacheID_ and
0051 eventCacheID_ != iEvent.cacheIdentifier()) {
0052 eventCacheID_ = iEvent.cacheIdentifier();
0053
0054 if (selector_)
0055 decision = selector_->select(iEvent);
0056 else
0057 decision = true;
0058 cached_decision_ = decision;
0059 } else {
0060 decision = cached_decision_;
0061 }
0062 return decision;
0063 }
0064
0065 protected:
0066 std::string name_;
0067 std::vector<std::string> description_;
0068 std::unique_ptr<EventSelector> selector_;
0069 mutable bool cached_decision_;
0070 mutable edm::Event::CacheIdentifier_t eventCacheID_ = 0;
0071 std::string dump_;
0072 };
0073
0074
0075 class SFilter {
0076 public:
0077 SFilter(Filter* f, bool i) : filter_(f), inverted_(i) {}
0078 ~SFilter() {}
0079
0080 Filter& operator*() { return *filter_; }
0081 Filter* operator->() { return filter_; }
0082 bool inverted() { return inverted_; }
0083
0084 private:
0085 Filter* filter_;
0086 bool inverted_;
0087 };
0088
0089 class FilterOR : public Filter {
0090 public:
0091 ~FilterOR() override {}
0092 FilterOR(const std::string& filterORlist, const std::map<std::string, Filter*>& filters) {
0093 std::string filterORlistCopy = filterORlist;
0094 name_ = filterORlist;
0095 std::stringstream ss;
0096 ss << "Filter doing an OR of: ";
0097
0098 unsigned int size = 0;
0099 bool OK = true;
0100 while (OK) {
0101 size_t orPos = filterORlistCopy.find("_OR_");
0102 if (orPos == std::string::npos && !filterORlistCopy.empty()) {
0103 size = filterORlistCopy.size();
0104 OK = false;
0105 } else
0106 size = orPos;
0107
0108 std::string filter = filterORlistCopy.substr(0, size);
0109
0110 if (OK)
0111 filterORlistCopy = filterORlistCopy.substr(0 + size + 4);
0112
0113 std::map<std::string, Filter*>::const_iterator it = filters.find(filter);
0114 if (it == filters.end()) {
0115 edm::LogError("FilterOR") << "cannot do an OR of: " << filter << " OR expression is: " << filterORlist;
0116 break;
0117 }
0118 filters_.push_back(std::make_pair(it->first, it->second));
0119 ss << it->first << " ";
0120 }
0121 description_.push_back(ss.str());
0122 }
0123 bool accept(edm::Event& iEvent) override {
0124 for (unsigned int i = 0; i != filters_.size(); ++i)
0125 if (filters_[i].second->accept(iEvent))
0126 return true;
0127 return false;
0128 }
0129
0130 private:
0131 std::vector<std::pair<std::string, Filter*> > filters_;
0132 };
0133
0134
0135 class FilterSelections;
0136
0137 class FilterSelection : public Filter {
0138 public:
0139 typedef std::vector<SFilter>::iterator iterator;
0140 friend class FilterSelections;
0141
0142 FilterSelection(std::string name, const edm::ParameterSet& iConfig)
0143 : name_(name),
0144 ntuplize_(iConfig.getParameter<bool>("ntuplize")),
0145 makeContentPlots_(iConfig.getParameter<bool>("makeContentPlots")),
0146 makeFinalPlots_(iConfig.getParameter<bool>("makeFinalPlots")),
0147 makeCumulativePlots_(iConfig.getParameter<bool>("makeCumulativePlots")),
0148 makeAllButOnePlots_(iConfig.getParameter<bool>("makeAllButOnePlots")),
0149 nSeen_(0),
0150 makeSummaryTable_(iConfig.getParameter<bool>("makeSummaryTable")),
0151 makeDetailledPrintout_(iConfig.exists("detailledPrintoutCategory")) {
0152 Filter::name_ = name_;
0153 Filter::description_.push_back(std::string("See definition of the corresponding selection"));
0154 if (iConfig.exists("nMonitor"))
0155 nMonitor_ = iConfig.getParameter<unsigned int>("nMonitor");
0156 else
0157 nMonitor_ = 0;
0158
0159 if (makeDetailledPrintout_)
0160 detailledPrintoutCategory_ = iConfig.getParameter<std::string>("detailledPrintoutCategory");
0161 }
0162
0163 FilterSelection(const FilterSelection&) = delete;
0164 FilterSelection& operator=(const FilterSelection&) = delete;
0165 FilterSelection(FilterSelection&&) = default;
0166 FilterSelection& operator=(FilterSelection&&) = default;
0167
0168 const std::string& name() { return name_; }
0169 iterator begin() { return filters_.begin(); }
0170 iterator end() { return filters_.end(); }
0171
0172 bool accept(edm::Event& iEvent) override {
0173 if (std::numeric_limits<edm::Event::CacheIdentifier_t>::max() != eventCacheID_ and
0174 eventCacheID_ != iEvent.cacheIdentifier()) {
0175 this->acceptMap(iEvent);
0176 }
0177 return cached_decision_;
0178 }
0179
0180 std::map<std::string, bool> acceptMap(edm::Event& iEvent) {
0181 nSeen_++;
0182 if (nMonitor_ != 0 && nSeen_ % nMonitor_ == 0) {
0183 if (nSeen_ == nMonitor_)
0184 print();
0185 else
0186 print(false);
0187 }
0188 std::map<std::string, bool> ret;
0189 bool global = true;
0190 for (iterator filter = begin(); filter != end(); ++filter) {
0191 const std::string& fName = (*filter)->name();
0192 Count& count = counts_[fName];
0193 count.nSeen_++;
0194 bool decision = (*filter)->accept(iEvent);
0195 bool inverted = (*filter).inverted();
0196 if (inverted)
0197 decision = !decision;
0198 ret[fName] = decision;
0199 if (decision)
0200 count.nPass_++;
0201 global = global && decision;
0202 if (global)
0203 count.nCumulative_++;
0204 }
0205
0206 if (makeDetailledPrintout_) {
0207 std::stringstream summary;
0208 summary << std::setw(20) << name().substr(0, 19) << " : " << std::setw(10) << iEvent.id().run() << " : "
0209 << std::setw(10) << iEvent.id().event();
0210 for (iterator filter = begin(); filter != end(); ++filter) {
0211 const std::string& fName = (*filter)->name();
0212 summary << " : " << std::setw(10) << (ret[fName] ? "pass" : "reject");
0213 }
0214 edm::LogVerbatim(detailledPrintoutCategory_) << summary.str();
0215 }
0216
0217 cached_decision_ = global;
0218 eventCacheID_ = iEvent.cacheIdentifier();
0219 return ret;
0220 }
0221
0222 void printDetailledPrintoutHeader() {
0223 if (makeDetailledPrintout_) {
0224 std::stringstream summary;
0225 summary << std::setw(20) << " selection name "
0226 << " : " << std::setw(10) << " run "
0227 << " : " << std::setw(10) << " event ";
0228 for (iterator filter = begin(); filter != end(); ++filter) {
0229 summary << " : " << std::setw(10) << (*filter)->name().substr(0, 9);
0230 }
0231 edm::LogVerbatim(detailledPrintoutCategory_) << summary.str();
0232 }
0233 }
0234
0235 void print(bool description = true) {
0236 if (!makeSummaryTable_)
0237 return;
0238
0239 unsigned int maxFnameSize = 20;
0240 for (iterator filter = begin(); filter != end(); ++filter) {
0241 if ((*filter)->name().size() > maxFnameSize)
0242 maxFnameSize = (*filter)->name().size() + 1;
0243 }
0244
0245
0246 const std::string category = "Selections";
0247 std::stringstream summary;
0248 summary << " Summary table for selection: " << name() << " with: " << nSeen_ << " events run." << std::endl;
0249 if (nSeen_ == 0)
0250 return;
0251 if (description) {
0252 for (iterator filter = begin(); filter != end(); ++filter) {
0253 const std::string& fName = (*filter)->name();
0254 summary << "filter: " << std::right << std::setw(10) << fName << "\n" << (*filter)->descriptionText() << "\n";
0255 }
0256 }
0257 summary << " filter stand-alone pass: " << std::endl;
0258 summary << std::right << std::setw(maxFnameSize) << "total read"
0259 << ": " << std::right << std::setw(10) << nSeen_ << std::endl;
0260 for (iterator filter = begin(); filter != end(); ++filter) {
0261 std::string fName = (*filter)->name();
0262 const Count& count = counts_[fName];
0263 if ((*filter).inverted())
0264 fName = '!' + fName;
0265 summary << std::right << std::setw(maxFnameSize) << fName << ": " << std::right << std::setw(10) << count.nPass_
0266 << " passed events. " << std::right << std::setw(10) << std::setprecision(5)
0267 << (count.nPass_ / (float)count.nSeen_) * 100. << " [%]" << std::endl;
0268 }
0269 summary << " filter cumulative pass:" << std::endl;
0270 summary << std::right << std::setw(maxFnameSize) << "total read"
0271 << ": " << std::right << std::setw(10) << nSeen_ << std::endl;
0272 unsigned int lastCount = nSeen_;
0273 for (iterator filter = begin(); filter != end(); ++filter) {
0274 std::string fName = (*filter)->name();
0275 const Count& count = counts_[fName];
0276 if ((*filter).inverted())
0277 fName = '!' + fName;
0278 summary << std::right << std::setw(maxFnameSize) << fName << ": " << std::right << std::setw(10)
0279 << count.nCumulative_ << " passed events. " << std::right << std::setw(10) << std::setprecision(5)
0280 << (count.nCumulative_ / (float)count.nSeen_) * 100. << " [%]";
0281 if (lastCount != 0)
0282 summary << " (to previous count) " << std::right << std::setw(10) << std::setprecision(5)
0283 << (count.nCumulative_ / (float)lastCount) * 100. << " [%]";
0284 summary << std::endl;
0285
0286 lastCount = count.nCumulative_;
0287 }
0288 summary << "-------------------------------------\n";
0289 edm::LogVerbatim(category) << summary.str();
0290 std::cout << summary.str();
0291 };
0292
0293 bool ntuplize() { return ntuplize_; }
0294 bool makeContentPlots() { return makeContentPlots_; }
0295 bool makeFinalPlots() { return makeFinalPlots_; }
0296 bool makeCumulativePlots() { return makeCumulativePlots_; }
0297 bool makeAllButOnePlots() { return makeAllButOnePlots_; }
0298 bool makeSummaryTable() { return makeSummaryTable_; }
0299
0300 private:
0301 std::string name_;
0302 std::vector<SFilter> filters_;
0303
0304
0305 bool ntuplize_;
0306 bool makeContentPlots_;
0307 bool makeFinalPlots_;
0308 bool makeCumulativePlots_;
0309 bool makeAllButOnePlots_;
0310
0311 unsigned int nSeen_;
0312 unsigned int nMonitor_;
0313
0314 struct Count {
0315 unsigned int nPass_;
0316 unsigned int nSeen_;
0317 unsigned int nCumulative_;
0318 };
0319 std::map<std::string, Count> counts_;
0320 bool makeSummaryTable_;
0321 bool makeDetailledPrintout_;
0322 std::string detailledPrintoutCategory_;
0323 };
0324
0325 class FilterSelections {
0326 public:
0327 typedef std::vector<FilterSelection>::iterator iterator;
0328
0329 FilterSelections(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC)
0330 : filtersPSet_(iConfig.getParameter<edm::ParameterSet>("filters")),
0331 selectionPSet_(iConfig.getParameter<edm::ParameterSet>("selections")) {
0332
0333
0334
0335 std::vector<std::string> filterNames;
0336 unsigned int nF = filtersPSet_.getParameterSetNames(filterNames);
0337 for (unsigned int iF = 0; iF != nF; iF++) {
0338 edm::ParameterSet pset = filtersPSet_.getParameter<edm::ParameterSet>(filterNames[iF]);
0339 filters_.insert(std::make_pair(filterNames[iF],
0340 new Filter(filterNames[iF], pset, iC)));
0341 }
0342
0343
0344 std::vector<std::string> selectionNames;
0345 std::map<std::string, std::vector<std::string> > selectionFilters;
0346 unsigned int nS = selectionPSet_.getParameterSetNames(selectionNames);
0347 for (unsigned int iS = 0; iS != nS; iS++) {
0348 edm::ParameterSet pset = selectionPSet_.getParameter<edm::ParameterSet>(selectionNames[iS]);
0349
0350 selections_.push_back(FilterSelection(selectionNames[iS], pset));
0351
0352
0353 selectionFilters[selectionNames[iS]] = pset.getParameter<std::vector<std::string> >("filterOrder");
0354 }
0355
0356
0357
0358
0359
0360 for (std::map<std::string, std::vector<std::string> >::iterator sIt = selectionFilters.begin();
0361 sIt != selectionFilters.end();
0362 ++sIt) {
0363
0364 for (std::vector<std::string>::iterator fOrS = sIt->second.begin(); fOrS != sIt->second.end(); ++fOrS) {
0365 if (filters_.find(*fOrS) == filters_.end()) {
0366
0367 if (fOrS->find("_OR_") != std::string::npos) {
0368 filters_.insert(std::make_pair((*fOrS), new FilterOR((*fOrS), filters_)));
0369 }
0370 else {
0371
0372 std::map<std::string, std::vector<std::string> >::iterator s = selectionFilters.find(*fOrS);
0373 if (s == selectionFilters.end()) {
0374
0375 if ((*fOrS)[0] != '!') {
0376 edm::LogError("SelectionHelper") << "unresolved filter/selection name: " << *fOrS;
0377 }
0378 }
0379 else {
0380
0381
0382 std::vector<std::string>::iterator newLoc = sIt->second.erase(fOrS);
0383
0384 sIt->second.insert(newLoc, s->second.begin(), s->second.end());
0385
0386 sIt--;
0387 break;
0388 }
0389 }
0390 }
0391
0392 }
0393 }
0394
0395
0396
0397
0398
0399
0400 for (std::vector<FilterSelection>::iterator sIt = selections_.begin(); sIt != selections_.end(); ++sIt) {
0401 const std::string& sName = sIt->name();
0402 FilterSelection& selection = *sIt;
0403
0404
0405 std::vector<std::string>& listOfFilters = selectionFilters[sName];
0406 for (std::vector<std::string>::iterator fIt = listOfFilters.begin(); fIt != listOfFilters.end(); ++fIt) {
0407 std::string fOsName = *fIt;
0408 bool inverted = false;
0409 if (fOsName[0] == '!') {
0410 inverted = true;
0411 fOsName = fOsName.substr(1);
0412 }
0413 std::map<std::string, Filter*>::iterator filterInstance = filters_.find(fOsName);
0414 if (filterInstance == filters_.end()) {
0415
0416 bool replaceBySelection = false;
0417
0418 for (std::vector<FilterSelection>::iterator sit = selections_.begin(); sit != selections_.end(); ++sit) {
0419 if (fOsName == sit->name_) {
0420 selection.filters_.push_back(SFilter(&(*sit), inverted));
0421 replaceBySelection = true;
0422 }
0423 }
0424 if (!replaceBySelection) {
0425
0426 edm::LogError("Selections") << "cannot resolve: " << fOsName;
0427 }
0428 } else {
0429
0430 selection.filters_.push_back(SFilter(filterInstance->second, inverted));
0431 }
0432 }
0433 }
0434
0435 for (iterator sIt = begin(); sIt != end(); ++sIt)
0436 sIt->printDetailledPrintoutHeader();
0437 }
0438
0439 iterator begin() { return selections_.begin(); }
0440 iterator end() { return selections_.end(); }
0441
0442
0443 void print() {
0444 for (std::vector<FilterSelection>::iterator sIt = selections_.begin(); sIt != selections_.end(); ++sIt)
0445 sIt->print();
0446 }
0447
0448 private:
0449 edm::ParameterSet filtersPSet_;
0450 std::map<std::string, Filter*> filters_;
0451
0452 edm::ParameterSet selectionPSet_;
0453 std::vector<FilterSelection> selections_;
0454 };
0455
0456 #endif