CMS 3D CMS Logo

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