CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
HLTriggerJSONMonitoring.cc
Go to the documentation of this file.
1 
7 #include <atomic>
8 #include <fstream>
9 
10 #include <fmt/printf.h>
11 
30 
32  // variables accumulated event by event in each stream
33  struct stream {
34  unsigned int processed; // number of events processed
35  std::vector<unsigned int> hltWasRun; // number of events where each path was run
36  std::vector<unsigned int> hltL1s; // number of events where each path passed the L1 seed
37  std::vector<unsigned int> hltPre; // number of events where each path passed the prescale
38  std::vector<unsigned int> hltAccept; // number of events accepted by each path
39  std::vector<unsigned int> hltReject; // number of events rejected by each path
40  std::vector<unsigned int> hltErrors; // number of events with errors in each path
41  std::vector<unsigned int> datasets; // number of events accepted by each dataset
42  };
43 
44  // variables initialised for each run
45  struct run {
48  std::string baseRunDir; // base directory from EvFDaqDirector
49  std::string jsdFileName; // definition file name for JSON with rates
50 
51  HLTConfigProvider hltConfig; // HLT configuration for the current run
52  std::vector<int> posL1s; // position of last L1T HLT seed filter in each path, or -1 if not present
53  std::vector<int> posPre; // position of last HLT prescale filter in each path, or -1 if not present
54  std::vector<std::vector<unsigned int>> datasets; // list of paths in each dataset
55  };
56 
57  // variables accumulated over the whole lumisection
58  struct lumisection {
59  jsoncollector::HistoJ<unsigned int> processed; // number of events processed
60  jsoncollector::HistoJ<unsigned int> hltWasRun; // number of events where each path was run
61  jsoncollector::HistoJ<unsigned int> hltL1s; // number of events where each path passed the L1 seed
62  jsoncollector::HistoJ<unsigned int> hltPre; // number of events where each path passed the prescale
63  jsoncollector::HistoJ<unsigned int> hltAccept; // number of events accepted by each path
64  jsoncollector::HistoJ<unsigned int> hltReject; // number of events rejected by each path
65  jsoncollector::HistoJ<unsigned int> hltErrors; // number of events with errors in each path
66  jsoncollector::HistoJ<unsigned int> datasets; // number of events accepted by each dataset
67  };
68 };
69 
71  // per-stream information
72  edm::StreamCache<HLTriggerJSONMonitoringData::stream>,
73  // per-run accounting
74  edm::RunCache<HLTriggerJSONMonitoringData::run>,
75  // accumulate per-lumisection statistics
76  edm::LuminosityBlockSummaryCache<HLTriggerJSONMonitoringData::lumisection>> {
77 public:
78  // constructor
80 
81  // destructor
82  ~HLTriggerJSONMonitoring() override = default;
83 
84  // validate the configuration and optionally fill the default values
85  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
86 
87  // called for each Event
88  void analyze(edm::StreamID, edm::Event const&, edm::EventSetup const&) const override;
89 
90  // -- inherited from edm::StreamCache<HLTriggerJSONMonitoringData::stream>
91 
92  // called once for each Stream being used in the job to create the cache object that will be used for that particular Stream
93  std::unique_ptr<HLTriggerJSONMonitoringData::stream> beginStream(edm::StreamID) const override;
94 
95  // called when the Stream is switching from one LuminosityBlock to a new LuminosityBlock.
97 
98  // -- inherited from edm::RunCache<HLTriggerJSONMonitoringData::run>
99 
100  // called each time the Source sees a new Run, and guaranteed to finish before any Stream calls streamBeginRun for that same Run
101  std::shared_ptr<HLTriggerJSONMonitoringData::run> globalBeginRun(edm::Run const&,
102  edm::EventSetup const&) const override;
103 
104  // called after all Streams have finished processing a given Run (i.e. streamEndRun for all Streams have completed)
105  void globalEndRun(edm::Run const&, edm::EventSetup const&) const override;
106 
107  // -- inherited from edm::LuminosityBlockSummaryCache<HLTriggerJSONMonitoringData::lumisection>
108 
109  // called each time the Source sees a new LuminosityBlock
110  std::shared_ptr<HLTriggerJSONMonitoringData::lumisection> globalBeginLuminosityBlockSummary(
111  edm::LuminosityBlock const&, edm::EventSetup const&) const override;
112 
113  // called when a Stream has finished processing a LuminosityBlock, after streamEndLuminosityBlock
115  edm::LuminosityBlock const&,
116  edm::EventSetup const&,
118 
119  // called after the streamEndLuminosityBlockSummary method for all Streams have finished processing a given LuminosityBlock
121  edm::EventSetup const&,
123 
124 private:
125  static constexpr const char* streamName_ = "streamHLTRates";
126 
128  static void writeIniFile(HLTriggerJSONMonitoringData::run const&, unsigned int);
129 
130  // configuration
131  const edm::InputTag triggerResults_; // InputTag for TriggerResults
133 };
134 
135 // constructor
137  : triggerResults_(config.getParameter<edm::InputTag>("triggerResults")),
138  triggerResultsToken_(consumes<edm::TriggerResults>(triggerResults_)) {}
139 
140 // validate the configuration and optionally fill the default values
143  desc.add<edm::InputTag>("triggerResults", edm::InputTag("TriggerResults", "", "HLT"));
144  descriptions.add("HLTriggerJSONMonitoring", desc);
145 }
146 
147 // called once for each Stream being used in the job to create the cache object that will be used for that particular Stream
148 std::unique_ptr<HLTriggerJSONMonitoringData::stream> HLTriggerJSONMonitoring::beginStream(edm::StreamID) const {
149  return std::make_unique<HLTriggerJSONMonitoringData::stream>();
150 }
151 
152 // called each time the Source sees a new Run, and guaranteed to finish before any Stream calls streamBeginRun for that same Run
153 std::shared_ptr<HLTriggerJSONMonitoringData::run> HLTriggerJSONMonitoring::globalBeginRun(
154  edm::Run const& run, edm::EventSetup const& setup) const {
155  auto rundata = std::make_shared<HLTriggerJSONMonitoringData::run>();
156 
157  // set the DAQ parameters
159  rundata->streamDestination = edm::Service<evf::EvFDaqDirector>()->getStreamDestinations(streamName_);
160  rundata->streamMergeType =
162  rundata->baseRunDir = edm::Service<evf::EvFDaqDirector>()->baseRunDir();
163  } else {
164  rundata->streamDestination = "";
165  rundata->streamMergeType = "";
166  rundata->baseRunDir = ".";
167  }
168 
169  // initialize HLTConfigProvider
170  bool changed = true;
171  if (not rundata->hltConfig.init(run, setup, triggerResults_.process(), changed)) {
172  edm::LogError("HLTriggerJSONMonitoring") << "HLTConfigProvider initialization failed!" << std::endl;
173  } else if (changed) {
174  // update the trigger and dataset names
175  auto const& triggerNames = rundata->hltConfig.triggerNames();
176  auto const& datasetNames = rundata->hltConfig.datasetNames();
177  auto const& datasets = rundata->hltConfig.datasetContents();
178 
179  const unsigned int triggersSize = triggerNames.size();
180  const unsigned int datasetsSize = datasetNames.size();
181 
182  // extract the definition of the datasets
183  rundata->datasets.resize(datasetsSize);
184  for (unsigned int ds = 0; ds < datasetsSize; ++ds) {
185  auto& dataset = rundata->datasets[ds];
186  unsigned int paths = datasets[ds].size();
187  dataset.reserve(paths);
188  for (unsigned int p = 0; p < paths; p++) {
189  unsigned int index = rundata->hltConfig.triggerIndex(datasets[ds][p]);
190  if (index < triggersSize)
191  dataset.push_back(index);
192  }
193  }
194 
195  // find the positions of the L1 seed and prescale filters
196  rundata->posL1s.resize(triggersSize);
197  rundata->posPre.resize(triggersSize);
198  for (unsigned int i = 0; i < triggersSize; ++i) {
199  rundata->posL1s[i] = -1;
200  rundata->posPre[i] = -1;
201  std::vector<std::string> const& moduleLabels = rundata->hltConfig.moduleLabels(i);
202  for (unsigned int j = 0; j < moduleLabels.size(); ++j) {
203  std::string const& label = rundata->hltConfig.moduleType(moduleLabels[j]);
204  if (label == "HLTL1TSeed")
205  rundata->posL1s[i] = j;
206  else if (label == "HLTPrescaler")
207  rundata->posPre[i] = j;
208  }
209  }
210  }
211 
212  // write the per-run .jsd file
213  rundata->jsdFileName = fmt::sprintf("run%06d_ls0000_streamHLTRates_pid%05d.jsd", run.run(), getpid());
214  writeJsdFile(*rundata);
215 
216  // write the per-run .ini file
217  //iniFileName = fmt::sprintf("run%06d_ls0000_streamHLTRates_pid%05d.ini", run.run(), getpid());
218  writeIniFile(*rundata, run.run());
219 
220  return rundata;
221 }
222 
223 // called after all Streams have finished processing a given Run (i.e. streamEndRun for all Streams have completed)
225 
226 // called for each Event
228  auto& stream = *streamCache(sid);
229  auto const& rundata = *runCache(event.getRun().index());
230 
231  ++stream.processed;
232 
233  // check that the HLTConfigProvider for the current run has been successfully initialised
234  if (not rundata.hltConfig.inited())
235  return;
236 
237  // get hold of TriggerResults
239  if (not event.getByToken(triggerResultsToken_, handle) or not handle.isValid()) {
240  edm::LogError("HLTriggerJSONMonitoring")
241  << "TriggerResults with label [" + triggerResults_.encode() + "] not present or invalid";
242  return;
243  }
245  assert(results.size() == stream.hltWasRun.size());
246 
247  // check the results for each HLT path
248  for (unsigned int i = 0; i < results.size(); ++i) {
249  auto const& status = results.at(i);
250  if (status.wasrun()) {
251  ++stream.hltWasRun[i];
252  if (status.accept()) {
253  ++stream.hltL1s[i];
254  ++stream.hltPre[i];
255  ++stream.hltAccept[i];
256  } else {
257  int index = (int)status.index();
258  if (index > rundata.posL1s[i])
259  ++stream.hltL1s[i];
260  if (index > rundata.posPre[i])
261  ++stream.hltPre[i];
262  if (status.error())
263  ++stream.hltErrors[i];
264  else
265  ++stream.hltReject[i];
266  }
267  }
268  }
269 
270  // check the decision for each dataset
271  // FIXME this ignores the prescales, "smart" prescales, and event selection applied in the OutputModule itself
272  for (unsigned int i = 0; i < rundata.datasets.size(); ++i)
273  if (std::any_of(rundata.datasets[i].begin(), rundata.datasets[i].end(), [&](unsigned int path) {
274  return results.accept(path);
275  }))
276  ++stream.datasets[i];
277 }
278 
279 // called each time the Source sees a new LuminosityBlock
280 std::shared_ptr<HLTriggerJSONMonitoringData::lumisection> HLTriggerJSONMonitoring::globalBeginLuminosityBlockSummary(
281  edm::LuminosityBlock const& lumi, edm::EventSetup const&) const {
282  unsigned int triggers = 0;
283  unsigned int datasets = 0;
284  auto const& rundata = *runCache(lumi.getRun().index());
285  if (rundata.hltConfig.inited()) {
286  triggers = rundata.hltConfig.triggerNames().size();
287  datasets = rundata.hltConfig.datasetNames().size();
288  };
289 
290  // the API of jsoncollector::HistoJ does not really match our use case,
291  // but it is the only vector-like object available in JsonMonitorable.h
292  auto lumidata = std::make_shared<HLTriggerJSONMonitoringData::lumisection>(HLTriggerJSONMonitoringData::lumisection{
293  jsoncollector::HistoJ<unsigned int>(1), // processed
294  jsoncollector::HistoJ<unsigned int>(triggers), // hltWasRun
295  jsoncollector::HistoJ<unsigned int>(triggers), // hltL1s
296  jsoncollector::HistoJ<unsigned int>(triggers), // hltPre
297  jsoncollector::HistoJ<unsigned int>(triggers), // hltAccept
298  jsoncollector::HistoJ<unsigned int>(triggers), // hltReject
299  jsoncollector::HistoJ<unsigned int>(triggers), // hltErrors
300  jsoncollector::HistoJ<unsigned int>(datasets) // datasets
301  });
302  // repeated calls to `update` necessary to set the internal element counter
303  lumidata->processed.update(0);
304  for (unsigned int i = 0; i < triggers; ++i)
305  lumidata->hltWasRun.update(0);
306  for (unsigned int i = 0; i < triggers; ++i)
307  lumidata->hltL1s.update(0);
308  for (unsigned int i = 0; i < triggers; ++i)
309  lumidata->hltPre.update(0);
310  for (unsigned int i = 0; i < triggers; ++i)
311  lumidata->hltAccept.update(0);
312  for (unsigned int i = 0; i < triggers; ++i)
313  lumidata->hltReject.update(0);
314  for (unsigned int i = 0; i < triggers; ++i)
315  lumidata->hltErrors.update(0);
316  for (unsigned int i = 0; i < datasets; ++i)
317  lumidata->datasets.update(0);
318 
319  return lumidata;
320 }
321 
322 // called when the Stream is switching from one LuminosityBlock to a new LuminosityBlock.
324  edm::LuminosityBlock const& lumi,
325  edm::EventSetup const&) const {
326  auto& stream = *streamCache(sid);
327 
328  unsigned int triggers = 0;
329  unsigned int datasets = 0;
330  auto const& rundata = *runCache(lumi.getRun().index());
331  if (rundata.hltConfig.inited()) {
332  triggers = rundata.hltConfig.triggerNames().size();
333  datasets = rundata.hltConfig.datasetNames().size();
334  };
335 
336  // reset the stream counters
337  stream.processed = 0;
338  stream.hltWasRun.assign(triggers, 0);
339  stream.hltL1s.assign(triggers, 0);
340  stream.hltPre.assign(triggers, 0);
341  stream.hltAccept.assign(triggers, 0);
342  stream.hltReject.assign(triggers, 0);
343  stream.hltErrors.assign(triggers, 0);
344  stream.datasets.assign(datasets, 0);
345 }
346 
347 // called when a Stream has finished processing a LuminosityBlock, after streamEndLuminosityBlock
349  edm::LuminosityBlock const& lumi,
350  edm::EventSetup const&,
352  auto const& stream = *streamCache(sid);
353  auto const& rundata = *runCache(lumi.getRun().index());
354  lumidata->processed.value()[0] += stream.processed;
355 
356  // check that the HLTConfigProvider for the current run has been successfully initialised
357  if (not rundata.hltConfig.inited())
358  return;
359 
360  unsigned int triggers = rundata.hltConfig.triggerNames().size();
361  for (unsigned int i = 0; i < triggers; ++i) {
362  lumidata->hltWasRun.value()[i] += stream.hltWasRun[i];
363  lumidata->hltL1s.value()[i] += stream.hltL1s[i];
364  lumidata->hltPre.value()[i] += stream.hltPre[i];
365  lumidata->hltAccept.value()[i] += stream.hltAccept[i];
366  lumidata->hltReject.value()[i] += stream.hltReject[i];
367  lumidata->hltErrors.value()[i] += stream.hltErrors[i];
368  }
369  unsigned int datasets = rundata.hltConfig.datasetNames().size();
370  for (unsigned int i = 0; i < datasets; ++i)
371  lumidata->datasets.value()[i] += stream.datasets[i];
372 }
373 
374 // called after the streamEndLuminosityBlockSummary method for all Streams have finished processing a given LuminosityBlock
376  edm::EventSetup const&,
378  unsigned int ls = lumi.luminosityBlock();
379  unsigned int run = lumi.run();
380 
381  bool writeFiles = true;
382  if (edm::Service<evf::MicroStateService>().isAvailable()) {
385  if (fms)
386  writeFiles = fms->shouldWriteFiles(ls);
387  }
388  if (not writeFiles)
389  return;
390 
391  unsigned int processed = lumidata->processed.value().at(0);
392  auto const& rundata = *runCache(lumi.getRun().index());
393  Json::StyledWriter writer;
394 
395  // [SIC]
396  char hostname[33];
397  gethostname(hostname, 32);
398  std::string sourceHost(hostname);
399 
400  // [SIC]
401  std::stringstream sOutDef;
402  sOutDef << rundata.baseRunDir << "/"
403  << "output_" << getpid() << ".jsd";
404 
405  std::string jsndataFileList = "";
406  unsigned int jsndataSize = 0;
407  unsigned int jsndataAdler32 = 1; // adler32 checksum for an empty file
408 
409  if (processed) {
410  // write the .jsndata files which contain the actual rates
411  Json::Value jsndata;
412  jsndata[jsoncollector::DataPoint::SOURCE] = sourceHost;
413  jsndata[jsoncollector::DataPoint::DEFINITION] = rundata.jsdFileName;
422 
423  auto jsndataFileName = fmt::sprintf("run%06d_ls%04d_streamHLTRates_pid%05d.jsndata", run, ls, getpid());
424 
425  std::string result = writer.write(jsndata);
426  std::ofstream jsndataFile(rundata.baseRunDir + "/" + jsndataFileName);
427  jsndataFile << result;
428  jsndataFile.close();
429 
430  jsndataFileList = jsndataFileName;
431  jsndataSize = result.size();
432  jsndataAdler32 = cms::Adler32(result.c_str(), result.size());
433  }
434 
435  // create a metadata json file for the "HLT rates" pseudo-stream
436  unsigned int jsnProcessed = processed;
437  unsigned int jsnAccepted = processed;
438  unsigned int jsnErrorEvents = 0;
439  unsigned int jsnRetCodeMask = 0;
440  std::string jsnInputFiles = "";
441  unsigned int jsnHLTErrorEvents = 0;
442 
443  Json::Value jsn;
444  jsn[jsoncollector::DataPoint::SOURCE] = sourceHost;
445  jsn[jsoncollector::DataPoint::DEFINITION] = sOutDef.str();
446  jsn[jsoncollector::DataPoint::DATA].append(jsnProcessed);
447  jsn[jsoncollector::DataPoint::DATA].append(jsnAccepted);
448  jsn[jsoncollector::DataPoint::DATA].append(jsnErrorEvents);
449  jsn[jsoncollector::DataPoint::DATA].append(jsnRetCodeMask);
450  jsn[jsoncollector::DataPoint::DATA].append(jsndataFileList);
451  jsn[jsoncollector::DataPoint::DATA].append(jsndataSize);
452  jsn[jsoncollector::DataPoint::DATA].append(jsnInputFiles);
453  jsn[jsoncollector::DataPoint::DATA].append(jsndataAdler32);
454  jsn[jsoncollector::DataPoint::DATA].append(rundata.streamDestination);
455  jsn[jsoncollector::DataPoint::DATA].append(rundata.streamMergeType);
456  jsn[jsoncollector::DataPoint::DATA].append(jsnHLTErrorEvents);
457 
458  auto jsnFileName = fmt::sprintf("run%06d_ls%04d_streamHLTRates_pid%05d.jsn", run, ls, getpid());
459  std::ofstream jsnFile(rundata.baseRunDir + "/" + jsnFileName);
460  jsnFile << writer.write(jsn);
461  jsnFile.close();
462 }
463 
465  std::ofstream file(rundata.baseRunDir + "/" + rundata.jsdFileName);
466  file << R"""({ "data" : [ { "name" : "Processed", "type" : "integer", "operation" : "histo"}, { "name" : "Path-WasRun", "type" : "integer", "operation" : "histo"}, { "name" : "Path-AfterL1Seed", "type" : "integer", "operation" : "histo"}, { "name" : "Path-AfterPrescale", "type" : "integer", "operation" : "histo"}, { "name" : "Path-Accepted", "type" : "integer", "operation" : "histo"}, { "name" : "Path-Rejected", "type" : "integer", "operation" : "histo"}, { "name" : "Path-Errors", "type" : "integer", "operation" : "histo"}, { "name" : "Dataset-Accepted", "type" : "integer", "operation" : "histo"} ] } )""";
467  file.close();
468 }
469 
472 
474  for (auto const& name : rundata.hltConfig.triggerNames())
475  triggerNames.append(name);
476  content["Path-Names"] = triggerNames;
477 
479  for (auto const& name : rundata.hltConfig.datasetNames())
480  datasetNames.append(name);
481  content["Dataset-Names"] = datasetNames;
483  std::string iniFileName = fmt::sprintf("run%06d_ls0000_streamHLTRates_pid%05d.ini", run, getpid());
484  std::ofstream file(rundata.baseRunDir + "/" + iniFileName);
485  Json::StyledWriter writer;
486  file << writer.write(content);
487  file.close();
488 }
489 
490 // declare as a framework plugin
494 
static constexpr const char * streamName_
void globalEndRun(edm::Run const &, edm::EventSetup const &) const override
RunNumber_t run() const
Definition: RunBase.h:40
static const std::string SOURCE
Definition: DataPoint.h:116
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
~HLTriggerJSONMonitoring() override=default
std::vector< std::vector< unsigned int > > datasets
dictionary results
HLTriggerJSONMonitoring(const edm::ParameterSet &)
bool accept() const
Has at least one path accepted the event?
const std::vector< std::string > & triggerNames() const
names of trigger paths
void streamBeginLuminosityBlock(edm::StreamID, edm::LuminosityBlock const &, edm::EventSetup const &) const override
def ls
Definition: eostools.py:349
list status
Definition: mps_update.py:107
static void writeIniFile(HLTriggerJSONMonitoringData::run const &, unsigned int)
Value & append(const Value &value)
Append value to array at the end.
Run const & getRun() const
Definition: Event.cc:112
jsoncollector::HistoJ< unsigned int > hltReject
Represents a JSON value.
Definition: value.h:99
Log< level::Error, false > LogError
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
assert(be >=bs)
virtual Json::Value toJsonValue() const
std::string encode() const
Definition: InputTag.cc:159
const edm::EDGetTokenT< edm::TriggerResults > triggerResultsToken_
jsoncollector::HistoJ< unsigned int > hltErrors
std::vector< T > & value()
tuple result
Definition: mps_fire.py:311
static const std::string DATA
Definition: DataPoint.h:118
LuminosityBlockNumber_t luminosityBlock() const
char const * label
void analyze(edm::StreamID, edm::Event const &, edm::EventSetup const &) const override
unsigned int size() const
Get number of paths stored.
jsoncollector::HistoJ< unsigned int > hltPre
std::unique_ptr< HLTriggerJSONMonitoringData::stream > beginStream(edm::StreamID) const override
std::shared_ptr< HLTriggerJSONMonitoringData::lumisection > globalBeginLuminosityBlockSummary(edm::LuminosityBlock const &, edm::EventSetup const &) const override
bool isAvailable() const
Definition: Service.h:40
tuple handle
Definition: patZpeak.py:25
RunIndex index() const
Definition: Run.cc:26
RunNumber_t run() const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isValid() const
Definition: HandleBase.h:70
list lumi
Definition: dqmdumpme.py:53
const HLTPathStatus & at(const unsigned int i) const
void Adler32(char const *data, size_t len, uint32_t &a, uint32_t &b)
static void writeJsdFile(HLTriggerJSONMonitoringData::run const &)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
jsoncollector::HistoJ< unsigned int > hltWasRun
std::string write(const Value &root) override
Serialize a Value in JSON format.
std::string const & process() const
Definition: InputTag.h:40
tuple config
parse the configuration file
void streamEndLuminosityBlockSummary(edm::StreamID, edm::LuminosityBlock const &, edm::EventSetup const &, HLTriggerJSONMonitoringData::lumisection *) const override
jsoncollector::HistoJ< unsigned int > hltL1s
const edm::InputTag triggerResults_
void globalEndLuminosityBlockSummary(edm::LuminosityBlock const &, edm::EventSetup const &, HLTriggerJSONMonitoringData::lumisection *) const override
jsoncollector::HistoJ< unsigned int > processed
Writes a Value in JSON format in a human friendly way.
Definition: writer.h:63
bool shouldWriteFiles(unsigned int lumi, unsigned int *proc=nullptr)
static const std::string DEFINITION
Definition: DataPoint.h:117
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
jsoncollector::HistoJ< unsigned int > datasets
std::shared_ptr< HLTriggerJSONMonitoringData::run > globalBeginRun(edm::Run const &, edm::EventSetup const &) const override
Definition: Run.h:45
const std::vector< std::string > & datasetNames() const
jsoncollector::HistoJ< unsigned int > hltAccept
array value (ordered list)
Definition: value.h:30
Run const & getRun() const