Jpp  master_rocky-37-gf0c5bc59d
the software that should make you happy
JDataQuality.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <sstream>
3 #include <fstream>
4 #include <iomanip>
5 #include <vector>
6 #include <set>
7 #include <map>
8 
9 #include "TROOT.h"
10 #include "TFile.h"
11 #include "TH1D.h"
12 #include "TF1.h"
13 #include "TString.h"
14 #include "TNtuple.h"
15 #include "TRegexp.h"
16 
17 #include "JDB/JDB.hh"
18 #include "JDB/JSelector.hh"
20 #include "JDB/JRunQuality.hh"
21 #include "JDB/JRunsetups.hh"
22 #include "JDB/JDBToolkit.hh"
23 
24 #include "JLang/JLangToolkit.hh"
25 #include "JTools/JRange.hh"
26 #include "JROOT/JRootClass.hh"
27 #include "JROOT/JRootPrinter.hh"
28 #include "JROOT/JRootToolkit.hh"
30 #include "JROOT/JRootDictionary.hh"
32 #include "JROOT/JManager.hh"
33 #include "JSupport/JMeta.hh"
35 
36 #include "JDataQuality/JGITTags.hh"
37 
38 #include "Jeep/JeepToolkit.hh"
39 #include "Jeep/JComment.hh"
40 #include "Jeep/JParser.hh"
41 #include "Jeep/JMessage.hh"
42 
43 namespace {
44 
45  /**
46  * Auxiliary data structure for run quality evaluation.
47  *
48  * A condition is composed of a ROOT TFormula compatible expression and a validity range for the result.
49  */
50  struct JCondition {
51 
52  static const char SEPARATOR = ';';
53 
54  /**
55  * Read selection from input stream.
56  *
57  * \param in input stream
58  * \param object selection
59  * \return input stream
60  */
61  friend inline std::istream& operator>>(std::istream& in, JCondition& object)
62  {
63  std::getline(in, object.formula, SEPARATOR);
64 
65  object.range = JTOOLS::JRange<double>();
66  object.weight = 1.0;
67 
68  if ((in >> object.range) && ! (in >> object.weight)) {
69  in.clear();
70  }
71 
72  return in;
73  }
74 
75 
76  /**
77  * Write selection to output stream.
78  *
79  * \param out output stream
80  * \param object selection
81  * \return output stream
82  */
83  friend inline std::ostream& operator<<(std::ostream& out, const JCondition& object)
84  {
85  out << object.formula << SEPARATOR << object.range << ' ' << object.weight << std::endl;
86 
87  return out;
88  }
89 
90  std::string formula;
92  double weight;
93  };
94 }
95 
96 
97 /**
98  * \file
99  *
100  * Main program to evaluate quality data from data base.
101  *
102  * The evaluation of the data quality is based on the following procedure.\n
103  * For each data taking run, the script JQAQC.sh is executed which produces a set of values.
104  * The values are subsequently uploaded into the database in table "runsummarynumbers".
105  * This table is a general purpose table for any value related to some data taking run.
106  * With this application,
107  * the QA/QC data are consistently downloaded from the database;
108  * evaluated according some formula and
109  * tested against a validity range.
110  * The underlying data structure is JDATABASE::JRunQuality.
111  *
112  * The formula and validity range are referred to as a condition and can be specified with option -Q.
113  * Each condition has an optional weight (default is 1).
114  * The normalised total weight is used to define an overall quality, ranging from 0 = worst to 1 = best.
115  * There is also the possibility to specify a veto (option -V),
116  * which is similar to a condition but only the number of vetoes is counted.
117  * The overall quality and the number of vetoes can be used to accept or reject a data taking run.
118  *
119  * By default, a list of the run numbers, the overall weight and the number of vetoes is printed.
120  * If a ROOT file is specified for the output (i.e.\ filename extension is JSUPPORT::ROOT_FILE_FORMAT),
121  * a file is written which contains a histogram for each condition and each veto; some summary histograms and a ROOT n-tuple.
122  * If an ASCII file is specified for the output (i.e.\ filename extension is JSUPPORT::ASCII_FILE_FORMAT),
123  * a text file is written which can subsequently be used as input file.
124  *
125  * \author mdejong
126  */
127 int main(int argc, char **argv)
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 
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 
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 
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 }
string outputFile
Selection of GIT tags.
int main(int argc, char **argv)
Specifications of file name extensions.
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition: JHead.hh:1832
Dynamic ROOT object management.
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
#define ASSERT(A,...)
Assert macro.
Definition: JMessage.hh:90
#define NOTICE(A)
Definition: JMessage.hh:64
#define FATAL(A)
Definition: JMessage.hh:67
int debug
debug level
Definition: JSirene.cc:69
#define WARNING(A)
Definition: JMessage.hh:65
ROOT I/O of application specific meta data.
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2142
TString replace(const TString &target, const TRegexp &regexp, const T &replacement)
Replace regular expression in input by given replacement.
Definition: JPrintResult.cc:63
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:72
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:63
Auxiliary class to define a range between two values.
Print objects in ASCII format using ROOT dictionary.
Auxiliary methods for handling file names, type names and environment.
Auxiliary class for specifying selection of database data.
JSelector & add(const JSelector &selection)
Add selection.
Object reading from ASCII file.
Object(s) writing to ASCII file.
virtual void close()
Close file.
virtual void close()
Close file.
Simple data structure to support I/O of equations (see class JLANG::JEquation).
Utility class to parse command line options.
Definition: JParser.hh:1698
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys.
Definition: JManager.hh:47
void Write(TDirectory &out, const bool wm=false)
Write objects to file.
Definition: JManager.hh:304
Implementation for ASCII output of objects with ROOT dictionary.
JRootWriter & put(const T &object)
Write object according equation format.
T getLength() const
Get length (difference between upper and lower limit).
Definition: JRange.hh:289
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:213
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
const double xmax
Definition: JQuadrature.cc:24
const double xmin
Definition: JQuadrature.cc:23
const double epsilon
Definition: JQuadrature.cc:21
ResultSet & getResultSet(const std::string &query)
Get result set.
Definition: JDB.hh:437
std::vector< JServer > getServernames()
Get list of names of available database servers.
Definition: JDB.hh:107
std::vector< std::string > getGITTags(const TRegexp &regexp, const JGITTags_t::key_type &date)
Get selection of GIT tags.
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
@ debug_t
debug
Definition: JMessage.hh:29
Double_t getResult(const TString &text, TObject *object=NULL)
Get result of given textual formula.
bool is_integer(const std::string &buffer)
Check if string is an integer.
Definition: JLangToolkit.hh:58
T & getInstance(const T &object)
Get static instance from temporary object.
Definition: JObject.hh:75
T getMaximum(const array_type< T > &buffer, const T value)
Get maximum of values.
Definition: JVectorize.hh:218
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
std::vector< event_type > data_type
Definition: JPerth.cc:82
static const char *const ASCII_FILE_FORMAT
file name extension ASCII format
static const char *const ROOT_FILE_FORMAT
file name extension ROOT format
data_type w[N+1][M+1]
Definition: JPolint.hh:867
void reset(T &value)
Reset value.
std::map< int, range_type > map_type
Definition: JSTDTypes.hh:14
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:448
Type definition of range.
Definition: JHead.hh:43
Auxiliary data structure for data quality.
Definition: JRunQuality.hh:36
double value
setup identifier (see JRunsetups)
Definition: JRunQuality.hh:183
void put(const std::string &key, const std::string &value)
Put value at given key.
Definition: JRunQuality.cc:25
std::string name
setup name (see JRunsetups)
Definition: JRunQuality.hh:182
std::string GIT
GIT version used to write QA/QC data.
Definition: JRunQuality.hh:139
int detector
detector identifier
Definition: JRunQuality.hh:143
Auxiliary class for run setup evaluation.
Definition: JRunsetups.hh:36
void put(const int run, const std::string setup)
Put run parameters.
Definition: JRunsetups.hh:105
bool has(const int run) const
Check if run setup is vailable.
Definition: JRunsetups.hh:153
float get(const int run) const
Get run setup value.
Definition: JRunsetups.hh:165
Wrapper class for server name.
Definition: JDB.hh:53
Template definition for getting table specific selector.
Auxiliary class for comment.
Definition: JComment.hh:43
JComment & add(const std::string &comment)
Add comment.
Definition: JComment.hh:100
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:68
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:72