Jpp master_rocky-44-g75b7c4f75
the software that should make you happy
Loading...
Searching...
No Matches
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"
32#include "JROOT/JManager.hh"
33#include "JSupport/JMeta.hh"
35
37
38#include "Jeep/JeepToolkit.hh"
39#include "Jeep/JComment.hh"
40#include "Jeep/JParser.hh"
41#include "Jeep/JMessage.hh"
42
43namespace {
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 */
127int 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
183 if (getFilenameExtension(outputFile) == ROOT_FILE_FORMAT) {
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
228 typedef map<int, data_type> map_type;
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
318 if (getFilenameExtension(outputFile) == ROOT_FILE_FORMAT) {
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
450 if (getFilenameExtension(outputFile) == ASCII_FILE_FORMAT) {
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}
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.
#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.
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
Implementation for ASCII output of objects with ROOT dictionary.
JRootWriter & put(const T &object)
Write object according equation format.
Range of values.
Definition JRange.hh:42
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Definition JFitK40.hh:103
Auxiliary data structure for data quality.
double value
setup identifier (see JRunsetups)
void put(const std::string &key, const std::string &value)
Put value at given key.
std::string name
setup name (see JRunsetups)
std::string GIT
GIT version used to write QA/QC data.
int detector
detector identifier
Auxiliary class for run setup evaluation.
Definition JRunsetups.hh:36
void put(const int run, const std::string setup)
Put run parameters.
bool has(const int run) const
Check if run setup is vailable.
float get(const int run) const
Get run setup value.
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