CMS 3D CMS Logo

AlCaRecoTriggerBitsRcdUpdate.cc
Go to the documentation of this file.
1 
10 #include <string>
11 #include <map>
12 #include <vector>
13 #include <algorithm>
14 #include <set>
15 
16 // Framework
23 
24 // Database
26 
27 // What I want to write:
29 // Rcd for reading old one:
31 
33 public:
35  ~AlCaRecoTriggerBitsRcdUpdate() override = default;
36 
37  void analyze(const edm::Event &evt, const edm::EventSetup &evtSetup) override;
38  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
39 
40 private:
41  typedef std::map<std::string, std::string> TriggerMap;
42  bool removeKeysFromMap(const std::vector<std::string> &keys, TriggerMap &triggerMap) const;
43  bool replaceKeysFromMap(const std::vector<edm::ParameterSet> &alcarecoReplace, TriggerMap &triggerMap) const;
44  bool addTriggerLists(const std::vector<edm::ParameterSet> &triggerListsAdd, AlCaRecoTriggerBits &bits) const;
45  bool addPathsFromMap(const std::vector<edm::ParameterSet> &pathsToAdd, AlCaRecoTriggerBits &bits) const;
46  bool removePathsFromMap(const std::vector<edm::ParameterSet> &pathsToRemove, AlCaRecoTriggerBits &bits) const;
47  void writeBitsToDB(const AlCaRecoTriggerBits &bitsToWrite) const;
48 
50  unsigned int nEventCalls_;
51  const unsigned int firstRunIOV_;
52  const int lastRunIOV_;
53  const bool startEmpty_;
54  const std::vector<std::string> listNamesRemove_;
55  const std::vector<edm::ParameterSet> triggerListsAdd_;
56  const std::vector<edm::ParameterSet> alcarecoReplace_;
57  const std::vector<edm::ParameterSet> pathsToAdd_;
58  const std::vector<edm::ParameterSet> pathsToRemove_;
59 };
60 
64  desc.setComment("Plugin to write payloads of type AlCaRecoTriggerBits");
65  desc.add<unsigned int>("firstRunIOV", 1);
66  desc.add<int>("lastRunIOV", -1);
67  desc.add<bool>("startEmpty", true);
68  desc.add<std::vector<std::string>>("listNamesRemove", {});
69 
70  edm::ParameterSetDescription desc_triggeListsToAdd;
71  desc_triggeListsToAdd.add<std::string>("listName");
72  desc_triggeListsToAdd.add<std::vector<std::string>>("hltPaths");
73  std::vector<edm::ParameterSet> default_triggerListsToAdd;
74  desc.addVPSet("triggerListsAdd", desc_triggeListsToAdd, default_triggerListsToAdd);
75 
76  edm::ParameterSetDescription desc_alcarecoToReplace;
77  desc_alcarecoToReplace.add<std::string>("oldKey");
78  desc_alcarecoToReplace.add<std::string>("newKey");
79  std::vector<edm::ParameterSet> default_alcarecoToReplace;
80  desc.addVPSet("alcarecoToReplace", desc_alcarecoToReplace, default_alcarecoToReplace);
81 
82  edm::ParameterSetDescription desc_pathsToAdd;
83  desc_pathsToAdd.add<std::string>("listName");
84  desc_pathsToAdd.add<std::vector<std::string>>("hltPaths");
85  std::vector<edm::ParameterSet> default_pathsToAdd;
86  desc.addVPSet("pathsToAdd", desc_pathsToAdd, default_pathsToAdd);
87 
88  edm::ParameterSetDescription desc_pathsToRemove;
89  desc_pathsToRemove.add<std::string>("listName");
90  desc_pathsToRemove.add<std::vector<std::string>>("hltPaths");
91  std::vector<edm::ParameterSet> default_pathsToRemove;
92  desc.addVPSet("pathsToRemove", desc_pathsToRemove, default_pathsToRemove);
93 
94  descriptions.addWithDefaultLabel(desc);
95 }
96 
99  : triggerBitsToken_(esConsumes()),
100  nEventCalls_(0),
101  firstRunIOV_(cfg.getParameter<unsigned int>("firstRunIOV")),
102  lastRunIOV_(cfg.getParameter<int>("lastRunIOV")),
103  startEmpty_(cfg.getParameter<bool>("startEmpty")),
104  listNamesRemove_(cfg.getParameter<std::vector<std::string>>("listNamesRemove")),
105  triggerListsAdd_(cfg.getParameter<std::vector<edm::ParameterSet>>("triggerListsAdd")),
106  alcarecoReplace_(cfg.getParameter<std::vector<edm::ParameterSet>>("alcarecoToReplace")),
107  pathsToAdd_(cfg.getParameter<std::vector<edm::ParameterSet>>("pathsToAdd")),
108  pathsToRemove_(cfg.getParameter<std::vector<edm::ParameterSet>>("pathsToRemove")) {}
109 
112  if (nEventCalls_++ > 0) { // postfix increment!
113  edm::LogWarning("BadConfig") << "@SUB=analyze"
114  << "Writing to DB to be done only once, set\n"
115  << "'process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(1))'\n"
116  << " next time. But your writing is fine.)";
117  return;
118  }
119 
120  // create what to write - starting from empty or existing list
121  std::unique_ptr<AlCaRecoTriggerBits> bitsToWrite;
122  if (startEmpty_) {
123  bitsToWrite = std::make_unique<AlCaRecoTriggerBits>();
124  } else {
125  bitsToWrite = std::make_unique<AlCaRecoTriggerBits>(iSetup.getData(triggerBitsToken_));
126  }
127 
128  // remove some existing entries in map
129  this->removeKeysFromMap(listNamesRemove_, bitsToWrite->m_alcarecoToTrig);
130 
131  // now add new entries
132  this->addTriggerLists(triggerListsAdd_, *bitsToWrite);
133 
134  // now replace keys
135  this->replaceKeysFromMap(alcarecoReplace_, bitsToWrite->m_alcarecoToTrig);
136 
137  // add paths to the existing key
138  this->addPathsFromMap(pathsToAdd_, *bitsToWrite);
139 
140  // remove paths from the existing key
141  this->removePathsFromMap(pathsToRemove_, *bitsToWrite);
142 
143  // finally write to DB
144  this->writeBitsToDB(*bitsToWrite);
145 }
146 
148 bool AlCaRecoTriggerBitsRcdUpdate::removeKeysFromMap(const std::vector<std::string> &keys,
149  TriggerMap &triggerMap) const {
150  for (std::vector<std::string>::const_iterator iKey = keys.begin(), endKey = keys.end(); iKey != endKey; ++iKey) {
151  if (triggerMap.find(*iKey) != triggerMap.end()) {
152  triggerMap.erase(*iKey);
153  } else { // not in list ==> misconfiguartion!
154  throw cms::Exception("BadConfig") << "[AlCaRecoTriggerBitsRcdUpdate::removeKeysFromMap] "
155  << "Cannot remove key '" << *iKey << "' since not in "
156  << "list - typo in configuration?\n";
157  return false;
158  }
159  }
160  return true;
161 }
162 
164 bool AlCaRecoTriggerBitsRcdUpdate::replaceKeysFromMap(const std::vector<edm::ParameterSet> &alcarecoReplace,
165  TriggerMap &triggerMap) const {
166  std::vector<std::pair<std::string, std::string>> keyPairs;
167  keyPairs.reserve(alcarecoReplace.size());
168 
169  for (auto &iSet : alcarecoReplace) {
170  const std::string oldKey(iSet.getParameter<std::string>("oldKey"));
171  const std::string newKey(iSet.getParameter<std::string>("newKey"));
172  keyPairs.push_back(std::make_pair(oldKey, newKey));
173  }
174 
175  for (auto &iKey : keyPairs) {
176  if (triggerMap.find(iKey.first) != triggerMap.end()) {
177  std::string bitsToReplace = triggerMap[iKey.first];
178  triggerMap.erase(iKey.first);
179  triggerMap[iKey.second] = bitsToReplace;
180  } else { // not in list ==> misconfiguration!
181  edm::LogWarning("AlCaRecoTriggerBitsRcdUpdate")
182  << "[AlCaRecoTriggerBitsRcdUpdate::replaceKeysFromMap] "
183  << "Cannot replace key '" << iKey.first << "with " << iKey.second << " since not in "
184  << "list - typo in configuration?\n";
185  return false;
186  }
187  }
188  return true;
189 }
190 
192 bool AlCaRecoTriggerBitsRcdUpdate::addTriggerLists(const std::vector<edm::ParameterSet> &triggerListsAdd,
193  AlCaRecoTriggerBits &bits) const {
194  TriggerMap &triggerMap = bits.m_alcarecoToTrig;
195 
196  // loop on PSets, each containing the key (filter name) and a vstring with triggers
197  for (const auto &iSet : triggerListsAdd) {
198  const std::vector<std::string> paths(iSet.getParameter<std::vector<std::string>>("hltPaths"));
199  // We must avoid a map<string,vector<string> > in DB for performance reason,
200  // so we have to merge the paths into one string that will be decoded when needed:
201  const std::string mergedPaths = bits.compose(paths);
202 
203  const std::string filter(iSet.getParameter<std::string>("listName"));
204  if (triggerMap.find(filter) != triggerMap.end()) {
205  throw cms::Exception("BadConfig") << "List name '" << filter << "' already in map, either "
206  << "remove from 'triggerListsAdd' or "
207  << " add to 'listNamesRemove'.\n";
208  }
209  triggerMap[filter] = mergedPaths;
210  }
211 
212  return true;
213 }
214 
216 bool AlCaRecoTriggerBitsRcdUpdate::addPathsFromMap(const std::vector<edm::ParameterSet> &pathsToAdd,
217  AlCaRecoTriggerBits &bits) const {
218  TriggerMap &triggerMap = bits.m_alcarecoToTrig; //read from the condition tag
219 
220  // loop on PSets, each containing the key (filter name) and a vstring with triggers
221  for (const auto &iSet : pathsToAdd) {
222  const std::string filter(iSet.getParameter<std::string>("listName"));
223  std::string mergedPathsInKey;
224 
225  for (const auto &imap : triggerMap) {
226  if (imap.first == filter)
227  mergedPathsInKey = imap.second; //paths in the condition tag
228  }
229 
230  if (mergedPathsInKey.empty()) {
231  throw cms::Exception("BadConfig") << "List name '" << filter << "' not found in the map, "
232  << "if you want to add new key/paths, please use 'addTriggerLists'.\n";
233  }
234 
235  auto const &pathsInKey = bits.decompose(mergedPathsInKey);
236  auto const &paths = iSet.getParameter<std::vector<std::string>>("hltPaths"); //paths to add; from the configuration
237 
238  if (paths.empty()) { // nothing to add ==> misconfiguration!
239  throw cms::Exception("BadConfig") << "Didn't set any path to add!";
240  }
241 
242  std::set<std::string> pathsSet{pathsInKey.begin(), pathsInKey.end()};
243  std::copy(paths.begin(), paths.end(), std::inserter(pathsSet, pathsSet.end()));
244  std::vector<std::string> const newPathsInKey{pathsSet.begin(), pathsSet.end()};
245 
246  // We must avoid a map<string,vector<string> > in DB for performance reason,
247  // so we have to merge the paths into one string that will be decoded when needed:
248  triggerMap[filter] = bits.compose(newPathsInKey);
249  }
250 
251  return true;
252 }
253 
255 bool AlCaRecoTriggerBitsRcdUpdate::removePathsFromMap(const std::vector<edm::ParameterSet> &pathsToRemove,
256  AlCaRecoTriggerBits &bits) const {
257  TriggerMap &triggerMap = bits.m_alcarecoToTrig; //read from the condition tag
258 
259  // loop on PSets, each containing the key (filter name) and a vstring with triggers
260  for (const auto &iSet : pathsToRemove) {
261  const std::string filter(iSet.getParameter<std::string>("listName"));
262  std::string mergedPathsInKey;
263 
264  for (const auto &imap : triggerMap) {
265  if (imap.first == filter)
266  mergedPathsInKey = imap.second; //paths in the condition tag
267  }
268 
269  if (mergedPathsInKey.empty()) {
270  throw cms::Exception("BadConfig") << "List name '" << filter << "' not found in the map";
271  }
272 
273  auto PathsInKey = bits.decompose(mergedPathsInKey);
274  auto const paths(
275  iSet.getParameter<std::vector<std::string>>("hltPaths")); //paths to remove; from the configuration
276 
277  if (paths.empty()) { // nothing to remove ==> misconfiguration!
278  throw cms::Exception("BadConfig") << "Didn't set any path to remove!";
279  }
280 
281  for (auto const &path : paths) {
282  PathsInKey.erase(std::remove(PathsInKey.begin(), PathsInKey.end(), path), PathsInKey.end());
283  }
284 
285  // We must avoid a map<string,vector<string> > in DB for performance reason,
286  // so we have to merge the paths into one string that will be decoded when needed:
287  triggerMap[filter] = bits.compose(PathsInKey);
288  }
289 
290  return true;
291 }
292 
295  edm::LogInfo("AlCaRecoTriggerBitsRcdUpdate") << "Uploading to the database...";
296 
298  if (!poolDbService.isAvailable()) {
299  throw cms::Exception("NotAvailable") << "PoolDBOutputService not available.\n";
300  }
301 
302  const std::string recordName("AlCaRecoTriggerBitsRcd");
303 
304  // when updating existing tag, compare payload hashs and skip appending new hash if it's same with last iov's
305  poolDbService->startTransaction();
306  auto newHash = poolDbService->session().storePayload(bitsToWrite);
307  cond::TagInfo_t tag_info;
308 
309  if (poolDbService->tagInfo(recordName, tag_info)) {
310  if (newHash != tag_info.lastInterval.payloadId) {
311  edm::LogInfo("AlCaRecoTriggerBitsRcdUpdate") << "## Appending to existing tag...";
312  poolDbService->forceInit();
313  poolDbService->appendSinceTime(newHash, firstRunIOV_, recordName);
314  } else {
315  edm::LogInfo("AlCaRecoTriggerBitsRcdUpdate") << "## Skipping update since hash is the same...";
316  }
317 
318  } else {
319  edm::LogInfo("AlCaRecoTriggerBitsRcdUpdate") << "## Creating new tag...";
320  poolDbService->forceInit();
321  poolDbService->createNewIOV(newHash, firstRunIOV_, recordName);
322  }
323  poolDbService->commitTransaction();
324 
325  edm::LogInfo("AlCaRecoTriggerBitsRcdUpdate")
326  << "...done for runs " << firstRunIOV_ << " to " << lastRunIOV_ << " (< 0 meaning infinity)!";
327 }
328 
329 //define this as a plug-in
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const edm::ESGetToken< AlCaRecoTriggerBits, AlCaRecoTriggerBitsRcd > triggerBitsToken_
bool addTriggerLists(const std::vector< edm::ParameterSet > &triggerListsAdd, AlCaRecoTriggerBits &bits) const
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
Iov_t lastInterval
Definition: Types.h:73
bool addPathsFromMap(const std::vector< edm::ParameterSet > &pathsToAdd, AlCaRecoTriggerBits &bits) const
bool replaceKeysFromMap(const std::vector< edm::ParameterSet > &alcarecoReplace, TriggerMap &triggerMap) const
const std::vector< edm::ParameterSet > pathsToRemove_
std::map< std::string, std::string > TriggerMap
const std::vector< edm::ParameterSet > triggerListsAdd_
const std::vector< edm::ParameterSet > pathsToAdd_
bool removePathsFromMap(const std::vector< edm::ParameterSet > &pathsToRemove, AlCaRecoTriggerBits &bits) const
void analyze(const edm::Event &evt, const edm::EventSetup &evtSetup) override
const std::vector< edm::ParameterSet > alcarecoReplace_
bool removeKeysFromMap(const std::vector< std::string > &keys, TriggerMap &triggerMap) const
Hash payloadId
Definition: Types.h:55
void writeBitsToDB(const AlCaRecoTriggerBits &bitsToWrite) const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ParameterDescriptionBase * add(U const &iLabel, T const &value)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
~AlCaRecoTriggerBitsRcdUpdate() override=default
Log< level::Info, false > LogInfo
def remove(d, key, TELL=False)
Definition: MatrixUtil.py:223
bool appendSinceTime(const std::string &payloadId, cond::Time_t sinceTime, const std::string &recordName)
void createNewIOV(const std::string &firstPayloadId, cond::Time_t firstSinceTime, const std::string &recordName)
AlCaRecoTriggerBitsRcdUpdate(const edm::ParameterSet &cfg)
cond::Hash storePayload(const T &payload, const boost::posix_time::ptime &creationTime=boost::posix_time::microsec_clock::universal_time())
Definition: Session.h:186
HLT enums.
const std::vector< std::string > listNamesRemove_
bool isAvailable() const
Definition: Service.h:40
Log< level::Warning, false > LogWarning
bool tagInfo(const std::string &recordName, cond::TagInfo_t &result)
cond::persistency::Session session() const