Jpp  18.3.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
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
Selection of GIT tags.
#define WARNING(A)
Definition: JMessage.hh:65
Q(UTCMax_s-UTCMin_s)-livetime_s
debug
Definition: JMessage.hh:29
int main(int argc, char *argv[])
Definition: Main.cc:15
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.
Print objects in ASCII format using ROOT dictionary.
*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
Dynamic ROOT object management.
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.
Auxiliary methods for handling file names, type names and environment.
ROOT I/O of application specific meta data.
#define NOTICE(A)
Definition: JMessage.hh:64
then awk string
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
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
bool is_integer(const std::string &buffer)
Check if string is an integer.
Definition: JLangToolkit.hh:58
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:67
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
void reset(T &value)
Reset value.
const double xmin
Definition: JQuadrature.cc:23
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition: JHead.hh:1829
Auxiliary class to define a range between two values.
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
Utility class to parse command line options.
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
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
static const char *const ROOT_FILE_FORMAT
file name extension ROOT format
Specifications of file name extensions.
const double epsilon
Definition: JQuadrature.cc:21
int debug
debug level
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62