11#include "QwParitySchema.h"
18using namespace QwParitySchema;
21std::map<string, unsigned int> QwParityDB::fMonitorIDs;
22std::map<string, unsigned int> QwParityDB::fMainDetectorIDs;
23std::map<string, unsigned int> QwParityDB::fLumiDetectorIDs;
24std::vector<string> QwParityDB::fMeasurementIDs;
25std::map<string, unsigned int> QwParityDB::fSlowControlDetectorIDs;
26std::map<string, unsigned char> QwParityDB::fErrorCodeIDs;
37QwParityDB::QwParityDB() :
QwDatabase(
"01",
"04",
"0000")
47 fDisableAnalysisCheck =
false;
65 fDisableAnalysisCheck =
false;
67 ProcessAdditionalOptions(options);
73QwParityDB::~QwParityDB()
75 QwDebug <<
"QwParityDB::~QwParityDB() : Good-bye World from QwParityDB destructor!" <<
QwLog::endl;
76 if( Connected() ) Disconnect();
85 if (this->AllowsReadAccess()) {
86 UInt_t run_id = this->GetRunID(qwevt);
87 UInt_t runlet_id = this->GetRunletID(qwevt);
88 UInt_t analysis_id = this->GetAnalysisID(qwevt);
105bool QwParityDB::SetRunNumber(
const UInt_t runnum)
112 auto c = GetScopedConnection();
114 const auto& run = QwParitySchema::run{};
115 auto query = sqlpp::select(sqlpp::all_of(run))
117 .where(run.run_number == runnum);
119 auto results = QuerySelect(query);
120 size_t result_count = CountResults(results);
123 if (result_count != 1) {
124 QwError <<
"Unable to find unique run number " << runnum <<
" in database." <<
QwLog::endl;
126 QwError <<
"Please make sure that the database contains one unique entry for this run." <<
QwLog::endl;
131 UInt_t found_run_id = 0;
132 ForFirstResult(results, [&](
const auto& row) {
133 found_run_id = row.run_id;
138 fRunID = found_run_id;
140 catch (
const std::exception& er) {
157 auto c = GetScopedConnection();
159 const auto& run = QwParitySchema::run{};
160 auto query = sqlpp::select(sqlpp::all_of(run))
163 auto results = QuerySelect(query);
165 size_t result_count = CountResults(results);
166 UInt_t first_run_id = 0;
167 UInt_t first_run_number = 0;
168 ForFirstResult(results, [&](
const auto& row) {
169 first_run_id = row.run_id;
170 first_run_number = row.run_number;
173 QwDebug <<
"QwParityDB::SetRunID => Number of rows returned: " << result_count <<
QwLog::endl;
176 if (result_count > 1) {
179 QwError <<
"Please make sure that the database contains one unique entry for this run." <<
QwLog::endl;
184 if (result_count == 1) {
188 fRunID = first_run_id;
194 QwParitySchema::row<QwParitySchema::run> run_row;
196 run_row[run.run_type] =
"good";
199 run_row[run.start_time] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::from_time_t(qwevt.
GetStartUnixTime()));
200 run_row[run.end_time] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::from_time_t(qwevt.
GetEndUnixTime()));
201 run_row[run.n_mps] = 0;
202 run_row[run.n_qrt] = 0;
204 run_row[run.slug] = 9999;
205 run_row[run.wien_slug] = 9999;
206 run_row[run.injector_slug] = 9999;
207 run_row[run.comment] =
"";
210 auto insert_id = QueryInsertAndGetId(run_row.insert_into());
212 if (insert_id != 0) {
218 catch (
const std::exception& er) {
236 if (fRunID == 0 || fRunNumber != (UInt_t) qwevt.
GetRunNumber() ) {
259 auto c = GetScopedConnection();
261 QwParitySchema::runlet runlet{};
266 auto query = sqlpp::select(sqlpp::all_of(runlet))
268 .where(runlet.run_id == fRunID
269 and runlet.full_run ==
"false"
270 and runlet.segment_number == fSegmentNumber);
271 auto results = QuerySelect(query);
274 size_t result_count = CountResults(results);
275 UInt_t found_runlet_id = 0;
276 ForFirstResult(results, [&](
const auto& row) {
277 found_runlet_id = row.runlet_id;
280 QwDebug <<
"QwParityDB::SetRunletID => Number of rows returned: " << result_count <<
QwLog::endl;
283 if (result_count > 1) {
286 QwError <<
"Please make sure that the database contains one unique entry for this run." <<
QwLog::endl;
291 if (result_count == 1) {
292 QwDebug <<
"QwParityDB::SetRunletID => Runlet ID = " << found_runlet_id <<
QwLog::endl;
293 fRunletID = found_runlet_id;
298 auto query = sqlpp::select(sqlpp::all_of(runlet))
300 .where(runlet.run_id == fRunID
301 and runlet.full_run ==
"true");
302 auto results = QuerySelect(query);
305 size_t result_count = CountResults(results);
306 UInt_t found_runlet_id = 0;
307 ForFirstResult(results, [&](
const auto& row) {
308 found_runlet_id = row.runlet_id;
311 QwDebug <<
"QwParityDB::SetRunletID => Number of rows returned: " << result_count <<
QwLog::endl;
314 if (result_count > 1) {
317 QwError <<
"Please make sure that the database contains one unique entry for this run." <<
QwLog::endl;
322 if (result_count == 1) {
323 QwDebug <<
"QwParityDB::SetRunletID => Runlet ID = " << found_runlet_id <<
QwLog::endl;
324 fRunletID = found_runlet_id;
331 QwParitySchema::runlet runlet_table{};
332 QwParitySchema::row<QwParitySchema::runlet> row;
333 row[runlet_table.run_id] = fRunID;
338 row[runlet_table.first_mps] = 0;
339 row[runlet_table.last_mps] = 0;
343 row[runlet_table.segment_number] = fSegmentNumber;
344 row[runlet_table.full_run] =
"false";
345 QwDebug <<
"QwParityDB::SetRunletID() => Executing sqlpp11 runlet insert (with segment)" <<
QwLog::endl;
350 row[runlet_table.full_run] =
"true";
351 QwDebug <<
"QwParityDB::SetRunletID() => Executing sqlpp11 runlet insert (no segment)" <<
QwLog::endl;
354 auto insert_id = QueryInsertAndGetId(row.insert_into());
355 if (insert_id != 0) {
356 fRunletID = insert_id;
360 catch (
const std::exception& er) {
376 QwDebug <<
"QwParityDB::GetRunletID() set fRunletID to " << SetRunletID(qwevt) <<
QwLog::endl;
392 auto c = GetScopedConnection();
394 const auto& analysis = QwParitySchema::analysis{};
395 auto query = sqlpp::select(analysis.analysis_id)
397 .where(analysis.beam_mode ==
"nbm"
398 and analysis.slope_calculation ==
"off"
399 and analysis.slope_correction ==
"off"
400 and analysis.runlet_id == this->GetRunletID(qwevt));
401 auto results = QuerySelect(query);
402 size_t result_count = CountResults(results);
403 if (result_count > 0) {
405 QwError <<
"The following analysis_id values already exist in the database: ";
406 ForEachResult(results, [&](
const auto& row) {
407 QwError << row.analysis_id <<
" ";
411 if (fDisableAnalysisCheck==
false) {
415 QwWarning <<
"Analysis will continue. A duplicate entry with new analysis_id will be added to the analysis table." <<
QwLog::endl;
419 catch (
const std::exception& er) {
421 QwError <<
"Unable to determine if there are other database entries for this run. Exiting." <<
QwLog::endl;
428 QwParitySchema::analysis analysis;
429 QwParitySchema::row<QwParitySchema::analysis> analysis_row;
431 analysis_row[analysis.runlet_id] = GetRunletID(qwevt);
432 analysis_row[analysis.seed_id] = 1;
434 std::pair<UInt_t, UInt_t> event_range;
437 analysis_row[analysis.time] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now());
438 analysis_row[analysis.bf_checksum] =
"empty";
439 analysis_row[analysis.beam_mode] =
"nbm";
440 analysis_row[analysis.n_mps] = 0;
441 analysis_row[analysis.n_qrt] = 4;
442 analysis_row[analysis.first_event] = event_range.first;
443 analysis_row[analysis.last_event] = event_range.second;
444 analysis_row[analysis.segment] = 0;
445 analysis_row[analysis.slope_calculation] =
"off";
446 analysis_row[analysis.slope_correction] =
"off";
455 run_condition.Get()->Print();
457 TIter next(run_condition.Get());
459 TString str_val, str_var;
463 while ((obj_str = (TObjString *) next())) {
467 str_var = str_val = obj_str->GetString();
468 location = str_val.First(
":");
469 location = location + 2;
470 str_val.Remove(0,location);
473 if (str_var.BeginsWith(
"ROOT Version")) {
474 analysis_row[analysis.root_version] = str_val;
475 }
else if (str_var.BeginsWith(
"ROOT file creating time")) {
476 analysis_row[analysis.root_file_time] = str_val;
477 }
else if (str_var.BeginsWith(
"ROOT file created on Hostname")) {
478 analysis_row[analysis.root_file_host] = str_val;
479 }
else if (str_var.BeginsWith(
"ROOT file created by the user")) {
480 analysis_row[analysis.root_file_user] = str_val;
481 }
else if (str_var.BeginsWith(
"QwAnalyzer Name")) {
482 analysis_row[analysis.analyzer_name] = str_val;
483 }
else if (str_var.BeginsWith(
"QwAnalyzer Options")) {
484 analysis_row[analysis.analyzer_argv] = str_val;
485 }
else if (str_var.BeginsWith(
"QwAnalyzer SVN Revision")) {
486 analysis_row[analysis.analyzer_svn_rev] = str_val;
487 }
else if (str_var.BeginsWith(
"QwAnalyzer SVN Last Changed Revision")) {
488 analysis_row[analysis.analyzer_svn_lc_rev] = str_val;
489 }
else if (str_var.BeginsWith(
"QwAnalyzer SVN URL")) {
490 analysis_row[analysis.analyzer_svn_url] = str_val;
491 }
else if (str_var.BeginsWith(
"DAQ ROC flags when QwAnalyzer runs")) {
492 analysis_row[analysis.roc_flags] = str_val;
496 auto c = GetScopedConnection();
498 auto insert_id = QueryInsertAndGetId(analysis_row.insert_into());
502 fAnalysisID = insert_id;
506 catch (
const std::exception& er) {
517 auto c = GetScopedConnection();
519 QwParitySchema::parameter_files parameter_files;
520 QwParitySchema::row<QwParitySchema::parameter_files> parameter_file_row;
521 parameter_file_row[parameter_files.analysis_id] = GetAnalysisID();
523 param_file_list->Print();
524 TIter next(param_file_list);
526 while ((pfl_elem = (TList *) next())) {
527 parameter_file_row[parameter_files.filename] = pfl_elem->GetName();
528 QueryExecute(parameter_file_row.insert_into());
530 delete param_file_list;
532 catch (
const std::exception& er) {
534 delete param_file_list;
544 if (fRunletID == 0) {
545 QwDebug <<
"QwParityDB::GetAnalysisID() : fRunletID must be set before proceeding. Check to make sure run exists in database." <<
QwLog::endl;
549 if (fAnalysisID == 0 || fRunNumber != (UInt_t) qwevt.
GetRunNumber()
551 QwDebug <<
"QwParityDB::GetAnalysisID() set fAnalysisID to " << SetAnalysisID(qwevt) <<
QwLog::endl;
552 if (fAnalysisID==0) {
553 QwError <<
"QwParityDB::SetAnalysisID() unable to set valid fAnalysisID for this run. Exiting." <<
QwLog::endl;
565UInt_t QwParityDB::GetMonitorID(
const string& name, Bool_t zero_id_is_error)
567 if (fMonitorIDs.size() == 0) {
571 UInt_t monitor_id = fMonitorIDs[name];
573 if (zero_id_is_error && monitor_id==0) {
575 QwError <<
"QwParityDB::GetMonitorID() => Unable to determine valid ID for beam monitor " << name <<
QwLog::endl;
585void QwParityDB::StoreMonitorIDs()
588 auto c = GetScopedConnection();
590 QwParitySchema::monitor monitor{};
591 auto query = sqlpp::select(sqlpp::all_of(monitor)).from(monitor).where(sqlpp::value(
true));
592 QuerySelectForEachResult(query, [&](
const auto& row) {
593 QwDebug <<
"StoreMonitorID: monitor_id = " << row.monitor_id <<
" quantity = " << row.quantity <<
QwLog::endl;
594 QwParityDB::fMonitorIDs.insert(std::make_pair(row.quantity, row.monitor_id));
597 catch (
const std::exception& er) {
607UInt_t QwParityDB::GetMainDetectorID(
const string& name, Bool_t zero_id_is_error)
609 if (fMainDetectorIDs.size() == 0) {
610 StoreMainDetectorIDs();
613 UInt_t main_detector_id = fMainDetectorIDs[name];
615 if (zero_id_is_error && main_detector_id==0) {
617 if (fDBInsertMissingKeys) {
618 QwWarning <<
"Inserting missing variable " << name <<
" into main_detector table." <<
QwLog::endl;
620 auto c = GetScopedConnection();
622 QwParitySchema::main_detector main_detector;
623 QwParitySchema::row<QwParitySchema::main_detector> main_detector_row;
624 main_detector_row[main_detector.quantity] = name;
625 main_detector_row[main_detector.title] =
"unknown";
627 auto insert_id = QueryInsertAndGetId(main_detector_row.insert_into());
629 if (insert_id != 0) {
630 fMainDetectorIDs[name] = insert_id;
631 main_detector_id = insert_id;
632 QwWarning <<
"Successfully inserted variable " << name <<
" into main_detector table with ID " << insert_id <<
QwLog::endl;
634 QwError <<
"Failed to insert variable " << name <<
" into main_detector table." <<
QwLog::endl;
637 catch (
const std::exception& er) {
641 QwError <<
"To enable automatic insertion of missing variables, set the option '--QwDatabase.insert-missing-keys'" <<
QwLog::endl;
645 return main_detector_id;
652void QwParityDB::StoreMainDetectorIDs()
655 auto c = GetScopedConnection();
657 QwParitySchema::main_detector main_detector{};
658 auto query = sqlpp::select(sqlpp::all_of(main_detector)).from(main_detector).where(sqlpp::value(
true));
659 QuerySelectForEachResult(query, [&](
const auto& row) {
660 QwDebug <<
"StoreMainDetectorID: main_detector_id = " << row.main_detector_id <<
" quantity = " << row.quantity <<
QwLog::endl;
661 QwParityDB::fMainDetectorIDs.insert(std::make_pair(row.quantity, row.main_detector_id));
664 catch (
const std::exception& er) {
675UInt_t QwParityDB::GetSlowControlDetectorID(
const string& name)
677 if (fSlowControlDetectorIDs.size() == 0) {
678 StoreSlowControlDetectorIDs();
681 UInt_t sc_detector_id = fSlowControlDetectorIDs[name];
683 if (sc_detector_id==0) {
684 QwError <<
"QwParityDB::GetSlowControlDetectorID() => Unable to determine valid ID for the epics variable " << name <<
QwLog::endl;
686 if (fDBInsertMissingKeys) {
687 QwWarning <<
"Inserting missing variable " << name <<
" into sc_detector table." <<
QwLog::endl;
689 auto c = GetScopedConnection();
691 QwParitySchema::sc_detector sc_detector;
692 QwParitySchema::row<QwParitySchema::sc_detector> sc_detector_row;
693 sc_detector_row[sc_detector.name] = name;
694 sc_detector_row[sc_detector.units] =
"unknown";
695 sc_detector_row[sc_detector.comment] =
"unknown";
697 auto insert_id = QueryInsertAndGetId(sc_detector_row.insert_into());
699 if (insert_id != 0) {
700 fSlowControlDetectorIDs[name] = insert_id;
701 sc_detector_id = insert_id;
702 QwWarning <<
"Successfully inserted variable " << name <<
" into sc_detector table with ID " << insert_id <<
QwLog::endl;
704 QwError <<
"Failed to insert variable " << name <<
" into sc_detector table." <<
QwLog::endl;
707 catch (
const std::exception& er) {
711 QwError <<
"To enable automatic insertion of missing variables, set the option '--QwDatabase.insert-missing-keys'" <<
QwLog::endl;
715 return sc_detector_id;
722UInt_t QwParityDB::GetErrorCodeID(
const string& name)
724 if (fErrorCodeIDs.size() == 0) {
728 UInt_t error_code_id = fErrorCodeIDs[name];
730 if (error_code_id==0) {
731 QwError <<
"QwParityDB::GetErrorCodeID() => Unable to determine valid ID for the error code " << name <<
QwLog::endl;
734 return error_code_id;
741void QwParityDB::StoreSlowControlDetectorIDs()
744 auto c = GetScopedConnection();
746 QwParitySchema::sc_detector sc_detector{};
747 auto query = sqlpp::select(sqlpp::all_of(sc_detector)).from(sc_detector).where(sqlpp::value(
true));
748 QuerySelectForEachResult(query, [&](
const auto& row) {
749 QwDebug <<
"StoreSlowControlDetectorID: sc_detector_id = " << row.sc_detector_id <<
" name = " << row.name <<
QwLog::endl;
750 QwParityDB::fSlowControlDetectorIDs.insert(std::make_pair(row.name, row.sc_detector_id));
753 catch (
const std::exception& er) {
763void QwParityDB::StoreErrorCodeIDs()
766 auto c = GetScopedConnection();
768 QwParitySchema::error_code error_code{};
769 auto query = sqlpp::select(sqlpp::all_of(error_code)).from(error_code).where(sqlpp::value(
true));
770 QuerySelectForEachResult(query, [&](
const auto& row) {
771 QwDebug <<
"StoreErrorCodeID: error_code_id = " << row.error_code_id <<
" quantity = " << row.quantity <<
QwLog::endl;
772 QwParityDB::fErrorCodeIDs.insert(std::make_pair(row.quantity, row.error_code_id));
775 catch (
const std::exception& er) {
785UInt_t QwParityDB::GetLumiDetectorID(
const string& name, Bool_t zero_id_is_error)
787 if (fLumiDetectorIDs.size() == 0) {
788 StoreLumiDetectorIDs();
791 UInt_t lumi_detector_id = fLumiDetectorIDs[name];
793 if (zero_id_is_error && lumi_detector_id==0) {
794 QwError <<
"QwParityDB::GetLumiDetectorID() => Unable to determine valid ID for beam lumi_detector " << name <<
QwLog::endl;
797 return lumi_detector_id;
803void QwParityDB::StoreLumiDetectorIDs()
806 auto c = GetScopedConnection();
808 QwParitySchema::lumi_detector lumi_detector{};
809 auto query = sqlpp::select(sqlpp::all_of(lumi_detector)).from(lumi_detector).where(sqlpp::value(
true));
810 QuerySelectForEachResult(query, [&](
const auto& row) {
811 QwDebug <<
"StoreLumiDetectorID: lumi_detector_id = " << row.lumi_detector_id <<
" quantity = " << row.quantity <<
QwLog::endl;
812 QwParityDB::fLumiDetectorIDs.insert(std::make_pair(row.quantity, row.lumi_detector_id));
815 catch (
const std::exception& er) {
825const string QwParityDB::GetMeasurementID(
const Int_t index)
827 if (fMeasurementIDs.size() == 0) {
828 StoreMeasurementIDs();
831 string measurement_type = fMeasurementIDs[index];
833 if (measurement_type.empty()) {
834 QwError <<
"QwParityDB::GetMeasurementID() => Unable to determine valid ID for measurement type with " << index <<
QwLog::endl;
837 return measurement_type;
840void QwParityDB::StoreMeasurementIDs()
843 auto c = GetScopedConnection();
845 QwParitySchema::measurement_type measurement_type{};
846 auto query = sqlpp::select(sqlpp::all_of(measurement_type)).from(measurement_type).where(sqlpp::value(
true));
847 QuerySelectForEachResult(query, [&](
const auto& row) {
848 QwDebug <<
"StoreMeasurementID: measurement_type = " << row.measurement_type_id <<
QwLog::endl;
849 QwParityDB::fMeasurementIDs.push_back((std::string) row.measurement_type_id);
852 catch (
const std::exception& er) {
866void QwParityDB::DefineAdditionalOptions(
QwOptions& options)
869 options.
AddOptions(
"Parity Analyzer Database options")
870 (
"QwParityDB.disable-analysis-check",
871 po::value<bool>()->default_bool_value(
false),
872 "disable check of pre-existing analysis_id");
880void QwParityDB::ProcessAdditionalOptions(
QwOptions &options)
882 if (options.
GetValue<
bool>(
"QwParityDB.disable-analysis-check"))
883 fDisableAnalysisCheck=
true;
#define QwError
Predefined log drain for errors.
#define QwWarning
Predefined log drain for warnings.
#define QwMessage
Predefined log drain for regular messages.
#define QwDebug
Predefined log drain for debugging output.
Run condition management and metadata.
Event buffer management for reading and processing CODA data.
A color changing class for the output stream.
A database interface class.
Event buffer management for reading and processing CODA data.
time_t GetStartUnixTime()
std::pair< UInt_t, UInt_t > GetEventRange() const
Int_t GetSegmentNumber() const
Return CODA file segment number.
Int_t GetRunNumber() const
Return CODA file run number.
Bool_t AreRunletsSplit() const
Return true if file segments are being separated for.
static std::ostream & endl(std::ostream &)
End of the line.
Command-line and configuration file options processor.
T GetValue(const std::string &key)
Get a templated value.
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
Run condition and quality management.
TList * GetParamFileNameList(TString name) const
Get list of parameter files.
Subsystem array container specialized for parity analysis with asymmetry calculations.