File indexing completed on 2025-01-31 02:19:25
0001 #include <algorithm>
0002 #include <iterator>
0003 #include <ostream>
0004 #include <cctype>
0005
0006 #include "boost/algorithm/string.hpp"
0007
0008 #include "DataFormats/Provenance/interface/ProductDescription.h"
0009 #include "FWCore/Framework/interface/ProductSelectorRules.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0012 #include "FWCore/Utilities/interface/EDMException.h"
0013
0014 namespace edm {
0015
0016
0017 typedef std::vector<edm::ProductDescription const*> VCBDP;
0018
0019 namespace {
0020
0021
0022
0023
0024 inline bool partial_match(const std::regex& regularExpression, const std::string& branchstring) {
0025 return std::regex_match(branchstring, regularExpression);
0026 }
0027 }
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 ProductSelectorRules::Rule::Rule(std::string const& s, std::string const& parameterName, std::string const& owner)
0058 : selectflag_(), productType_(), moduleLabel_(), instanceName_(), processName_() {
0059 if (s.size() < 6)
0060 throw edm::Exception(edm::errors::Configuration)
0061 << "Invalid statement in configuration file\n"
0062 << "In " << owner << " parameter named '" << parameterName << "'\n"
0063 << "Rule must have at least 6 characters because it must\n"
0064 << "specify 'keep ' or 'drop ' and also supply a pattern.\n"
0065 << "This is the invalid output configuration rule:\n"
0066 << " " << s << "\n"
0067 << "Exception thrown from ProductSelectorRules::Rule\n";
0068
0069 if (s.substr(0, 4) == "keep")
0070 selectflag_ = true;
0071 else if (s.substr(0, 4) == "drop")
0072 selectflag_ = false;
0073 else
0074 throw edm::Exception(edm::errors::Configuration)
0075 << "Invalid statement in configuration file\n"
0076 << "In " << owner << " parameter named '" << parameterName << "'\n"
0077 << "Rule must specify 'keep ' or 'drop ' and also supply a pattern.\n"
0078 << "This is the invalid output configuration rule:\n"
0079 << " " << s << "\n"
0080 << "Exception thrown from ProductSelectorRules::Rule\n";
0081
0082 if (!std::isspace(s[4])) {
0083 throw edm::Exception(edm::errors::Configuration)
0084 << "Invalid statement in configuration file\n"
0085 << "In " << owner << " parameter named '" << parameterName << "'\n"
0086 << "In each rule, 'keep' or 'drop' must be followed by a space\n"
0087 << "This is the invalid output configuration rule:\n"
0088 << " " << s << "\n"
0089 << "Exception thrown from ProductSelectorRules::Rule\n";
0090 }
0091
0092
0093
0094
0095
0096
0097 std::string spec(s.begin() + 5, s.end());
0098
0099
0100 boost::trim(spec);
0101
0102 if (spec == "*")
0103 {
0104 productType_ = ".*";
0105 moduleLabel_ = ".*";
0106 instanceName_ = ".*";
0107 processName_ = ".*";
0108 return;
0109 } else {
0110 std::vector<std::string> parts;
0111 boost::split(parts, spec, boost::is_any_of("_"));
0112
0113
0114
0115 bool good = (parts.size() == 4);
0116
0117
0118
0119 if (good) {
0120 for (int i = 0; i < 4; ++i) {
0121 std::string& field = parts[i];
0122 int size = field.size();
0123 for (int j = 0; j < size; ++j) {
0124 if (!(isalnum(field[j]) || field[j] == '*' || field[j] == '?')) {
0125 good = false;
0126 }
0127 }
0128
0129
0130
0131
0132
0133 boost::replace_all(parts[i], "*", ".*");
0134 boost::replace_all(parts[i], "?", ".");
0135 }
0136 }
0137
0138 if (!good) {
0139 throw edm::Exception(edm::errors::Configuration)
0140 << "Invalid statement in configuration file\n"
0141 << "In " << owner << " parameter named '" << parameterName << "'\n"
0142 << "In each rule, after 'keep ' or 'drop ' there must\n"
0143 << "be a branch specification of the form 'type_label_instance_process'\n"
0144 << "There must be 4 fields separated by underscores\n"
0145 << "The fields can only contain alphanumeric characters and the wildcards * or ?\n"
0146 << "Alternately, a single * is also allowed for the branch specification\n"
0147 << "This is the invalid output configuration rule:\n"
0148 << " " << s << "\n"
0149 << "Exception thrown from ProductSelectorRules::Rule\n";
0150 }
0151
0152 productType_ = parts[0];
0153 moduleLabel_ = parts[1];
0154 instanceName_ = parts[2];
0155 processName_ = parts[3];
0156 }
0157 }
0158
0159 void ProductSelectorRules::Rule::applyToAll(std::vector<BranchSelectState>& branchstates) const {
0160 std::vector<BranchSelectState>::iterator it = branchstates.begin();
0161 std::vector<BranchSelectState>::iterator end = branchstates.end();
0162 for (; it != end; ++it)
0163 applyToOne(it->desc, it->selectMe);
0164 }
0165
0166 void ProductSelectorRules::applyToAll(std::vector<BranchSelectState>& branchstates) const {
0167 std::vector<Rule>::const_iterator it = rules_.begin();
0168 std::vector<Rule>::const_iterator end = rules_.end();
0169 for (; it != end; ++it)
0170 it->applyToAll(branchstates);
0171 }
0172
0173 bool ProductSelectorRules::select(edm::ProductDescription const& bd) const {
0174 bool selected = false;
0175 for (auto const& rule : rules_) {
0176 rule.applyToOne(&bd, selected);
0177 if (selected) {
0178 return true;
0179 }
0180 }
0181 return false;
0182 }
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 void ProductSelectorRules::Rule::applyToOne(edm::ProductDescription const* branch, bool& result) const {
0197 if (this->appliesTo(branch))
0198 result = selectflag_;
0199 }
0200
0201 bool ProductSelectorRules::Rule::appliesTo(edm::ProductDescription const* branch) const {
0202 return partial_match(productType_, branch->friendlyClassName()) &&
0203 partial_match(moduleLabel_, branch->moduleLabel()) &&
0204 partial_match(instanceName_, branch->productInstanceName()) &&
0205 partial_match(processName_, branch->processName());
0206 }
0207
0208 const std::vector<std::string>& ProductSelectorRules::defaultSelectionStrings() {
0209 static const std::vector<std::string> s_defaultStrings(1U, std::string("keep *"));
0210 return s_defaultStrings;
0211 }
0212
0213 void ProductSelectorRules::fillDescription(ParameterSetDescription& desc,
0214 char const* parameterName,
0215 std::vector<std::string> const& defaultStrings) {
0216 ;
0217 desc.addUntracked<std::vector<std::string> >(parameterName, defaultStrings)
0218 ->setComment("Specifies which branches are kept or dropped.");
0219 }
0220
0221 ProductSelectorRules::ProductSelectorRules(ParameterSet const& pset,
0222 std::string const& parameterName,
0223 std::string const& parameterOwnerName)
0224 : rules_(), parameterName_(parameterName), parameterOwnerName_(parameterOwnerName) {
0225
0226
0227
0228 std::vector<std::string> defaultCommands(1U, std::string("keep *"));
0229
0230 std::vector<std::string> commands =
0231 pset.getUntrackedParameter<std::vector<std::string> >(parameterName, defaultCommands);
0232 if (commands.empty()) {
0233 commands.push_back(defaultCommands[0]);
0234 }
0235 rules_.reserve(commands.size());
0236 for (std::vector<std::string>::const_iterator it = commands.begin(), end = commands.end(); it != end; ++it) {
0237 rules_.push_back(Rule(*it, parameterName, parameterOwnerName));
0238 }
0239 keepAll_ = commands.size() == 1 && commands[0] == defaultCommands[0];
0240 }
0241
0242 }