Jpp  18.4.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
JDataQuality.cc File Reference

Main program to evaluate quality data from data base. More...

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include "TROOT.h"
#include "TFile.h"
#include "TH1D.h"
#include "TF1.h"
#include "TString.h"
#include "TNtuple.h"
#include "TRegexp.h"
#include "JDB/JDB.hh"
#include "JDB/JSelector.hh"
#include "JDB/JSelectorSupportkit.hh"
#include "JDB/JRunQuality.hh"
#include "JDB/JRunsetups.hh"
#include "JDB/JDBToolkit.hh"
#include "JLang/JLangToolkit.hh"
#include "JTools/JRange.hh"
#include "JROOT/JRootClass.hh"
#include "JROOT/JRootPrinter.hh"
#include "JROOT/JRootToolkit.hh"
#include "JROOT/JRootStreamObjectOutput.hh"
#include "JROOT/JRootDictionary.hh"
#include "JROOT/JASCIIFileStreamer.hh"
#include "JROOT/JManager.hh"
#include "JSupport/JMeta.hh"
#include "JSupport/JFilenameSupportkit.hh"
#include "JDataQuality/JGITTags.hh"
#include "Jeep/JeepToolkit.hh"
#include "Jeep/JComment.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Main program to evaluate quality data from data base.

The evaluation of the data quality is based on the following procedure.
For each data taking run, the script JQAQC.sh is executed which produces a set of values. The values are subsequently uploaded into the database in table "runsummarynumbers". This table is a general purpose table for any value related to some data taking run. With this application, the QA/QC data are consistently downloaded from the database; evaluated according some formula and tested against a validity range. The underlying data structure is JDATABASE::JRunQuality.

The formula and validity range are referred to as a condition and can be specified with option -Q. Each condition has an optional weight (default is 1). The normalised total weight is used to define an overall quality, ranging from 0 = worst to 1 = best. There is also the possibility to specify a veto (option -V), which is similar to a condition but only the number of vetoes is counted. The overall quality and the number of vetoes can be used to accept or reject a data taking run.

By default, a list of the run numbers, the overall weight and the number of vetoes is printed. If a ROOT file is specified for the output (i.e. filename extension is JSUPPORT::ROOT_FILE_FORMAT), a file is written which contains a histogram for each condition and each veto; some summary histograms and a ROOT n-tuple. If an ASCII file is specified for the output (i.e. filename extension is JSUPPORT::ASCII_FILE_FORMAT), a text file is written which can subsequently be used as input file.

Author
mdejong

Definition in file JDataQuality.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 127 of file JDataQuality.cc.

128 {
129  using namespace std;
130  using namespace JPP;
131 
132  typedef JRange<int> JRange_t;
133  typedef vector<JCondition> JCondition_t;
134 
135  JServer server;
136  string usr;
137  string pwd;
138  string cookie;
139  string inputFile;
140  string outputFile;
141  string detid;
142  JRange_t runs;
143  vector<string> source;
144  JCondition_t condition;
145  JCondition_t veto;
146  TRegexp regexp(".");
147  JSelector selection;
148  int debug;
149 
150  try {
151 
152  JParser<> zap("Main program to evaluate quality data from data base."\
153  "\nThe condition and veto can be any TFormula compatible expression involving QA/QC parameters (see e.g. JQAQC.sh -h).");
154 
155  zap['s'] = make_field(server) = getServernames();
156  zap['u'] = make_field(usr) = "";
157  zap['!'] = make_field(pwd) = "";
158  zap['C'] = make_field(cookie) = "";
159  zap['f'] = make_field(inputFile, "Optional input file instead of database.") = "";
160  zap['o'] = make_field(outputFile, "ROOT file with histograms and n-tuple or ASCII file with QA/QC data.") = "quality.root";
161  zap['D'] = make_field(detid) = "";
162  zap['R'] = make_field(runs, "Run range") = JRange_t(1, JRange_t::getMaximum());
163  zap['S'] = make_field(source, "GIT versions") = getGITTags(TRegexp("v[0-9]*\\.[0-9]*\\.[0-9]*$"), JGITTags_t::key_type("2019-04-12"));
164  zap['Q'] = make_field(condition, "User defined conditions") = JPARSER::initialised();
165  zap['V'] = make_field(veto, "User defined vetos.") = JPARSER::initialised();
166  zap['r'] = make_field(regexp, "TRegexp for selection of run setup names.") = JPARSER::initialised();
167  zap['@'] = make_field(selection) = JPARSER::initialised();
168  zap['d'] = make_field(debug, "Debug level") = 1;
169 
170  zap(argc, argv);
171  }
172  catch(const exception &error) {
173  FATAL(error.what() << endl);
174  }
175 
176 
177  double W = 0.0;
178 
179  for (JCondition_t::const_iterator i = condition.begin(); i != condition.end(); ++i) {
180  W += i->weight;
181  }
182 
184  if (W <= 0.0) {
185  FATAL("Invalid total weight: " << W << endl);
186  }
187  }
188 
189 
190  JRunsetups setups; // run -> value
191  set<JRunQuality> buffer; // storage
192 
193 
194  if (inputFile == "") { // read data from database
195 
196  ASSERT(detid != "");
197 
198  try {
199 
200  JDB::reset(usr, pwd, cookie);
201 
202  const int ID = getDetector<int> (detid);
203  detid = getDetector<string>(detid);
204 
205  // run setups
206 
207  selection += getSelector<JRuns>(ID);
208 
209  NOTICE("Extracting run information from database... " << flush);
210 
211  ResultSet& rs = getResultSet(getTable<JRuns>(), selection);
212 
213  for (JRuns parameters; rs >> parameters; ) {
214  if (TString(parameters.RUNSETUPNAME.c_str()).Contains(regexp)) {
215  setups.put(parameters);
216  }
217  }
218 
219  rs.Close();
220 
221  NOTICE("OK" << endl);
222 
223  // run summary data
224 
225  for (vector<string>::const_iterator git = source.begin(); git != source.end(); ++git) {
226 
229 
230  map_type zmap;
231 
232  JSelector selector = getSelector<JRunSummaryNumbers>(detid, runs.getLowerLimit(), runs.getUpperLimit());
233 
234  selector.add(&JRunSummaryNumbers::SOURCE_NAME, *git);
235 
236  try {
237 
238  NOTICE("Extracting run summmary information with source " << *git << " from database... " << flush);
239 
240  ResultSet& rs = getResultSet(getTable<JRunSummaryNumbers>(), selector);
241 
242  for (JRunSummaryNumbers parameters; rs >> parameters; ) {
243  if (setups.has(parameters.RUN)) {
244  zmap[parameters.RUN].insert(make_pair(parameters.PARAMETER_NAME, parameters.DATA_VALUE));
245  }
246  }
247 
248  rs.Close();
249 
250  NOTICE("OK" << endl);
251  }
252  catch(const exception& error) { NOTICE(endl); }
253 
254  for (map_type::const_iterator run = zmap.begin(); run != zmap.end(); ++run) {
255 
256  JRunQuality quality;
257 
258  quality.GIT = *git;
259  quality.detector = ID;
260  quality.run = run->first;
261  quality.name = setups[run->first].name;
262  quality.value = setups[run->first].value;
263 
264  for (data_type::const_iterator i = run->second.begin(); i != run->second.end(); ++i) {
265  quality.put(i->first, i->second);
266  }
267 
268  quality.name = replace(quality.name, ' ', '_');
269 
270  buffer.insert(quality); // only insert if absent
271  }
272  }
273  }
274  catch(const exception& error) {
275  FATAL(error.what() << endl);
276  }
277 
278  } else { // read data from file
279 
280  if (detid != "" && !is_integer(detid)) {
281  WARNING("Detector identifier \"" << detid << "\" discarded." << endl);
282  }
283 
284  const int ID = (is_integer(detid) ? to_value<int>(detid) : -1);
285 
286  JASCIIFileReader<JRunQuality> in(inputFile.c_str(), JDBDictionary::getInstance());
287 
288  JComment comment;
289 
290  in >> comment;
291 
292  for (JRunQuality quality; in >> quality; ) {
293  if (ID == -1 || ID == quality.detector) {
294  if (runs(quality.run)) {
295  buffer.insert(quality);
296  }
297  }
298  }
299 
300  in.close();
301  }
302 
303 
304  if (buffer.empty()) {
305  FATAL("No data." << endl);
306  }
307 
308  if (debug >= debug_t) {
309 
310  JRootWriter writer(cout, JEquationParameters(), JDBDictionary::getInstance());
311 
312  for (set<JRunQuality>::const_iterator quality = buffer.begin(); quality != buffer.end(); ++quality) {
313  writer.put(*quality);
314  }
315  }
316 
317 
319 
320  runs = JRange_t(buffer.begin()->run, buffer.rbegin()->run);
321 
322  TH1D h0("h0", NULL, 1000, 0.0, 1.01);
323  TH1D h1("h1", NULL, condition.size(), -0.5, condition.size() - 0.5);
324 
325  for (size_t i = 0; i != condition.size(); ++i) {
326  h1.GetXaxis()->SetBinLabel(i+1, condition[i].formula.c_str());
327  }
328 
329  h0.SetMinimum(0.0);
330  h0.SetMaximum(1.1 * (runs.getUpperLimit() - runs.getLowerLimit() + 1));
331 
332  h1.SetMinimum(0.0);
333  h1.SetMaximum(1.1 * (runs.getUpperLimit() - runs.getLowerLimit() + 1));
334 
335  const Double_t xmin = runs.getLowerLimit() - 0.5;
336  const Double_t xmax = runs.getUpperLimit() + 0.5;
337 
338  JManager<TString, TH1D> H1(new TH1D("%", NULL, runs.getLength() + 1, xmin, xmax));
339 
340  // show validity range
341 
342  for (JCondition_t::const_iterator i = condition.begin(); i != condition.end();++i) {
343  H1[i->formula]->GetListOfFunctions()->Add(new TF1(MAKE_CSTRING("C " << i->formula << ":upper"), MAKE_CSTRING(i->range.getUpperLimit()), xmin, xmax));
344  H1[i->formula]->GetListOfFunctions()->Add(new TF1(MAKE_CSTRING("C " << i->formula << ":lower"), MAKE_CSTRING(i->range.getLowerLimit()), xmin, xmax));
345  }
346 
347  for (JCondition_t::const_iterator i = veto.begin(); i != veto.end();++i) {
348  H1[i->formula]->GetListOfFunctions()->Add(new TF1(MAKE_CSTRING("V " << i->formula << ":upper"), MAKE_CSTRING(i->range.getUpperLimit()), xmin, xmax));
349  H1[i->formula]->GetListOfFunctions()->Add(new TF1(MAKE_CSTRING("V " << i->formula << ":lower"), MAKE_CSTRING(i->range.getLowerLimit()), xmin, xmax));
350  }
351 
352  ostringstream os; // N-tuple format
353 
354  os << "run";
355 
356  for (size_t i = 0; i != condition.size(); ++i) {
357  os << ":" << (char) ('a' + i);
358  }
359 
360  os << ":Q:V:R";
361 
362  TNtuple n1("n1", "quality", os.str().c_str());
363 
364 
365  // process data
366 
367  for (set<JRunQuality>::const_iterator quality = buffer.begin(); quality != buffer.end(); ++quality) {
368 
369  vector<Float_t> tuple(1, (Float_t) quality->run);
370 
371  double w = 0.0;
372 
373  for (size_t i = 0; i != condition.size(); ++i) {
374 
375  const JCondition& ps = condition[i];
376  const double y = getResult(ps.formula, *quality);
377 
378  DEBUG(ps.formula << ' ' << y << endl);
379 
380  tuple.push_back((Float_t) y);
381 
382  TH1D* p = H1[ps.formula];
383 
384  p->SetBinContent(p->FindBin((double) quality->run), y);
385  p->SetBinError (p->FindBin((double) quality->run), numeric_limits<double>::epsilon());
386 
387  if (ps.range(y)) {
388  w += ps.weight;
389  }
390 
391  h1.AddBinContent(i + 1, ps.range(y) ? 1.0 : 0.0);
392  }
393 
394  const double Q = w/W;
395 
396  tuple.push_back((Float_t) Q);
397 
398  int V = 0;
399 
400  for (size_t i = 0; i != veto.size(); ++i) {
401 
402  const JCondition& ps = veto[i];
403  const double y = getResult(ps.formula, *quality);
404 
405  DEBUG(ps.formula << ' ' << y << endl);
406 
407  TH1D* p = NULL;
408 
409  p = H1[ps.formula];
410 
411  p->SetBinContent(p->FindBin((double) quality->run), y);
412  p->SetBinError (p->FindBin((double) quality->run), numeric_limits<double>::epsilon());
413 
414  p = H1[MAKE_STRING("VETO[" << ps.formula << "]")];
415 
416  p->SetBinContent(p->FindBin((double) quality->run), ps.range(y) ? 0.0 : 1.0);
417  p->SetBinError (p->FindBin((double) quality->run), numeric_limits<double>::epsilon());
418 
419  if (!ps.range(y)) {
420  ++V;
421  }
422  }
423 
424  tuple.push_back((Float_t) V);
425  tuple.push_back((Float_t) setups.get(quality->run));
426 
427  h0.Fill(Q);
428  n1.Fill(tuple.data());
429 
430  cout << setw(8) << quality->run << ' ' << FIXED(5,3) << Q << ' ' << setw(2) << V << endl;
431  }
432 
433  double w = 0.0;
434 
435  for (Int_t i = 0; i <= h0.GetXaxis()->GetNbins(); ++i) {
436  h0.SetBinContent(i, (w += h0.GetBinContent(i)));
437  }
438 
439  // store results
440 
441  TFile out(outputFile.c_str(), "recreate");
442 
443  out << h0 << h1 << n1 << H1;
444 
445  out.Write();
446  out.Close();
447  }
448 
449 
451 
452  // store data
453 
454  JASCIIFileWriter<JRunQuality> out(outputFile.c_str(), JDBDictionary::getInstance());
455 
456  out.setf(ios::fixed);
457 
458  JComment comment;
459 
460  comment.add(JMeta(argc, argv));
461 
462  out << comment;
463 
464  for (set<JRunQuality>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
465  out << *i << endl;
466  }
467 
468  out.close();
469  }
470 }
const double xmax
Definition: JQuadrature.cc:24
Utility class to parse command line options.
Definition: JParser.hh:1514
data_type w[N+1][M+1]
Definition: JPolint.hh:867
#define WARNING(A)
Definition: JMessage.hh:65
Q(UTCMax_s-UTCMin_s)-livetime_s
debug
Definition: JMessage.hh:29
std::vector< event_type > data_type
Definition: JPerth.cc:78
TString replace(const TString &target, const TRegexp &regexp, const T &replacement)
Replace regular expression in input by given replacement.
Definition: JPrintResult.cc:63
std::map< int, buffer_type > map_type
string -&gt; hits
Definition: JPerth.cc:68
std::vector< std::string > getGITTags(const TRegexp &regexp, const JGITTags_t::key_type &date)
Get selection of GIT tags.
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:136
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:83
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
static const char *const ASCII_FILE_FORMAT
file name extension ASCII format
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
string outputFile
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:127
#define ASSERT(A,...)
Assert macro.
Definition: JMessage.hh:90
T & getInstance(const T &object)
Get static instance from temporary object.
Definition: JObject.hh:75
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1989
Double_t getResult(const TString &text, TObject *object=NULL)
Get result of given textual formula.
#define NOTICE(A)
Definition: JMessage.hh:64
then echo Variable JPP_DIR undefined exit fi source $JPP_DIR setenv sh $JPP_DIR &dev null set_variable DETECTOR $JPP_DATA km3net_reference detx set_variable NUMBER_OF_STRINGS set_variable ID if do_usage *then usage $script[detector file[identifier]] fi case set_variable ID
Definition: JDetector.sh:24
bool is_integer(const std::string &buffer)
Check if string is an integer.
Definition: JLangToolkit.hh:58
#define FATAL(A)
Definition: JMessage.hh:67
void reset(T &value)
Reset value.
const double xmin
Definition: JQuadrature.cc:23
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:48
std::string getFilenameExtension(const std::string &file_name)
Get file name extension, i.e. part after last JEEP::FILENAME_SEPARATOR if any.
Definition: JeepToolkit.hh:109
ResultSet & getResultSet(const std::string &query)
Get result set.
Definition: JDB.hh:436
std::vector< JServer > getServernames()
Get list of names of available database servers.
Definition: JDB.hh:106
static const char *const ROOT_FILE_FORMAT
file name extension ROOT format
const double epsilon
Definition: JQuadrature.cc:21
int debug
debug level
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62