17#include "TObjString.h"
21#ifdef HAS_RNTUPLE_SUPPORT
22#include "ROOT/RNTupleModel.hxx"
23#include "ROOT/RField.hxx"
32#ifdef __USE_DATABASE__
33#include "QwParitySchema.h"
83#ifdef __USE_DATABASE__
87 po::value<bool>()->default_bool_value(
false),
88 "disable EPICS database access");
99#ifdef __USE_DATABASE__
119 std::string varname, varvalue;
128 QwDebug <<
"QwEPICSEvent::LoadChannelMap: keyword,value pair:"
130 if (varname ==
"NominalWienAngle"){
132 }
else if (varname ==
"BlinderReversalForRunTwo"){
137 }
else if (varname ==
"PrecessionReversal"){
143 QwError <<
"QwEPICSEvent::LoadChannelMap: "
144 <<
"Unknown keyword,variable pair: "
156 if (datatype ==
"") {
162 if (datatype ==
"int") datatypeid =
kEPICSInt;
167 if (
kDebug == 1) std::cout <<
"line read in the parameter file =" << lineread << std::endl;
187 name.ReplaceAll(
':',
'_');
193 tree->Branch(name, &(values[treeindex]), values.
LeafList(treeindex).c_str());
234#ifdef HAS_RNTUPLE_SUPPORT
235void QwEPICSEvent::ConstructNTupleAndVector(std::unique_ptr<ROOT::RNTupleModel>& model, TString& prefix, std::vector<Double_t>& values, std::vector<std::shared_ptr<Double_t>>& fieldPtrs)
244 values.push_back(0.0);
248 name.ReplaceAll(
':',
'_');
249 name.ReplaceAll(
'.',
'_');
254 auto field = model->MakeField<Double_t>(name.Data());
255 fieldPtrs.push_back(field);
256 }
catch (
const std::exception& e) {
259 fieldPtrs.push_back(
nullptr);
260 QwWarning <<
"EPICS field '" << name <<
"' already exists in RNTuple model, skipping duplicate creation" <<
QwLog::endl;
267void QwEPICSEvent::FillNTupleVector(std::vector<Double_t>& values)
const
281 values[treeindex] =
static_cast<Double_t
>(
fEPICSDataEvent[tagindex].StringValue.Hash());
312 if (
kDebug == 1) std::cout <<
"Here we are in 'CalculateRunningValues'!!"<<std::endl;
315 Bool_t anyFilled = kFALSE;
316 for (
size_t tagindex = 0; tagindex <
fEPICSDataEvent.size(); tagindex++) {
319 if (! anyFilled)
return;
354 <<
" giving a running average of "
360 <<
" seems to be not filled."<<std::endl;
394 if (
kDebug == 1) std::cout <<
"Here we are, entering 'ExtractEPICSValues'!!"<<std::endl;
402 std::stringstream ss(data, std::stringstream::in | std::stringstream::out);
406 string varname, varvalue;
429 return match->second;
555 tmpvalue = Double_t(atof(value.c_str()));
562 tmpvalue = Double_t(atol(value.c_str()));
574 Double_t average_of_squares = 0.0;
575 Double_t variance = 0.0;
576 Double_t sigma = 0.0;
578 std::cout <<
"##### EPICS Event Summary from PrintAverages() #####\n"
579 <<
"Total number of EPICS events in this run == "
581 << std::setw(20) << std::setiosflags(std::ios::left) <<
"Name"
583 <<
"Minimum Maximum"<<std::endl;
584 std::cout <<
"*****Non-string EPICS Variables*****" << std::endl;
597 variance = average_of_squares - (mean * mean);
599 sigma = sqrt(-1.0 * variance);
601 sigma = sqrt(variance);
604 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
606 << std::setprecision(5) << std::setw(10)
607 <<mean<<
" " << std::setw(10)<<sigma<<
" " << std::setw(10)
611 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
613 << std::setprecision(5) << std::setw(10)
620 std::cout <<
"*****String EPICS Variables are below, if any*****" << std::endl;
624 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
626 <<tagindex<<
"\tand status is\t\t"
630 std::cout <<
"\t*****\tThis variable changed during the run. Only "
633 <<
"% of the events has this value.";
635 std::cout <<std::endl;
637 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
639 <<
"No data..."<<std::endl;
650 QwMessage <<
"fEPICSVariableList[" << tagindex <<
"] == "
658 std::vector<Double_t> autogain_values;
659 std::vector<std::string>::iterator ptr_tag;
661 autogain_values.clear();
665 ptr_tag = tag_list.begin();
666 while (ptr_tag < tag_list.end()) {
671 return autogain_values;
679 Double_t average_of_squares = 0.0;
680 Double_t variance = 0.0;
681 Double_t sigma = 0.0;
684 std::ofstream output;
685 TString theEPICSDataFile;
686 theEPICSDataFile = getenv(
"QW_TMP");
687 theEPICSDataFile +=
"/QwEPICSData.txt";
688 output.open(theEPICSDataFile,std::ofstream::out);
690 if (output.is_open()) {
693 output <<
"##### EPICS Event Summary #####\n"
694 <<
"Total number of EPICS events in this run == "
696 << std::setw(20) << std::setiosflags(std::ios::left) <<
"Name"
698 <<
"Minimum Maximum"<<std::endl;
710 variance = average_of_squares - (mean * mean);
712 sigma = sqrt(-1.0 * variance);
714 sigma = sqrt(variance);
717 output << std::setw(20) << std::setiosflags(std::ios::left)
719 << std::setprecision(5) << std::setw(10)
720 <<mean<<
" " << std::setw(10)<<sigma<<
" " << std::setw(10)
724 output << std::setw(20) << std::setiosflags(std::ios::left)
726 << std::setprecision(5) << std::setw(10)
736 output << std::setw(20) << std::setiosflags(std::ios::left)
740 output << std::setw(20) << std::setiosflags(std::ios::left)
742 <<
"No data..."<<std::endl;
759 std::cerr <<
"The EPICS variable label and type arrays are not the same size!\n"
760 <<
"EPICS readback may be corrupted!"<<std::endl;
781#ifdef __USE_DATABASE__
791 auto c = db->GetScopedConnection();
792 QwParitySchema::slow_controls_settings slow_controls_settings;
793 bool recordsExist = c->QueryExists(
794 sqlpp::select(slow_controls_settings.slow_controls_settings_id)
795 .from(slow_controls_settings)
796 .where(slow_controls_settings.runlet_id == db->GetRunletID())
800 QwError <<
"This runlet already has slow controls entries in the database!" <<
QwLog::endl;
801 QwError <<
"Slow controls values from this replay will NOT be stored in the database." <<
QwLog::endl;
806 catch (
const std::exception& er) {
808 QwError <<
"Unable to determine if there are other slow controls entries in the database for this run. THERE MAY BE DUPLICATES." <<
QwLog::endl;
824 QwDebug <<
" -------------------------------------------------------------------------- " <<
QwLog::endl;
826 QwDebug <<
" -------------------------------------------------------------------------- " <<
QwLog::endl;
828 Double_t mean, average_of_squares, variance, sigma;
832 average_of_squares = 0.0;
839 UInt_t runlet_id = db->GetRunletID();
841 QwParitySchema::slow_controls_data slow_controls_data;
842 std::vector<QwParitySchema::row<QwParitySchema::slow_controls_data>> entrylist;
844 UInt_t sc_detector_id;
846 string table =
"slow_controls_data";
854 QwParitySchema::row<QwParitySchema::slow_controls_data> tmp_row;
859 tmp_row[slow_controls_data.runlet_id] = runlet_id;
860 tmp_row[slow_controls_data.sc_detector_id] = sc_detector_id;
862 if (!sc_detector_id)
continue;
874 variance = average_of_squares - (mean * mean);
876 sigma = sqrt(-1.0 * variance);
878 sigma = sqrt(variance);
883 tmp_row[slow_controls_data.n] =
static_cast<UInt_t
>(n_records);
884 tmp_row[slow_controls_data.value] = mean;
885 tmp_row[slow_controls_data.error] = sigma;
889 entrylist.push_back(tmp_row);
896 if( entrylist.size() ) {
897 auto c = db->GetScopedConnection();
898 QwDebug <<
"QwEPICSEvent::FillSlowControlsData::Writing to database now" <<
QwLog::endl;
902 for (
const auto& entry : entrylist) {
903 c->QueryExecute(entry.insert_into());
906 }
catch (
const std::exception &er) {
910 QwDebug <<
"QwEPICSEvent::FillSlowControlsData :: This is the case when the entrylist contains nothing " <<
QwLog::endl;
917 QwParitySchema::slow_controls_strings slow_controls_strings{};
918 std::vector<QwParitySchema::row<QwParitySchema::slow_controls_strings>> entrylist;
919 UInt_t sc_detector_id;
920 UInt_t runlet_id = db->GetRunletID();
921 string table =
"polarized_source";
929 QwParitySchema::row<QwParitySchema::slow_controls_strings> tmp_row;
934 tmp_row[slow_controls_strings.runlet_id] = runlet_id;
935 tmp_row[slow_controls_strings.sc_detector_id] = sc_detector_id;
937 if (!sc_detector_id)
continue;
943 QwWarning<<
"fEPICSDataEvent[tagindex].StringValue.Data() is not defined, tmp_row.value is set to an empty string."<<
QwLog::endl;
944 tmp_row[slow_controls_strings.value] = std::string(
"");
948 tmp_row[slow_controls_strings.value] = std::string(
fEPICSDataEvent[tagindex].StringValue.Data());
951 entrylist.push_back(tmp_row);
958 if( entrylist.size() ) {
959 auto c = db->GetScopedConnection();
960 QwDebug <<
"QwEPICSEvent::FillSlowControlsStrigs Writing to database now" <<
QwLog::endl;
964 for (
const auto& entry : entrylist) {
965 c->QueryExecute(entry.insert_into());
967 QwDebug <<
"Done executing sqlpp11 bulk insert for FillSlowControlsStrings"
969 }
catch (
const std::exception &er) {
973 QwDebug <<
"QwEPICSEvent::FillSlowControlsData :: This is the case when the entrylist contains nothing " <<
QwLog::endl;
981 QwParitySchema::slow_controls_settings slow_controls_settings{};
982 QwParitySchema::row<QwParitySchema::slow_controls_settings> tmp_row;
985 UInt_t runlet_id = db->GetRunletID();
986 tmp_row[slow_controls_settings.runlet_id] = runlet_id;
988 std::string precession_reversal;
992 precession_reversal =
"CCW";
994 precession_reversal =
"CW";
1004 tagindex =
FindIndex(
"qw:qt_mps_i_dcct");
1009 tmp_row[slow_controls_settings.qtor_current] = sqlpp::null;
1014 <<
" had no events during this run. "
1015 <<
"Send NULL word to the database."
1017 tmp_row[slow_controls_settings.qtor_current] = sqlpp::null;
1021 QwDebug <<
"Send the value of "
1025 <<
", to the database."
1027 tmp_row[slow_controls_settings.qtor_current] = qtorcurrent;
1039 tmp_row[slow_controls_settings.target_position] = sqlpp::null;
1045 <<
" changed during this run. "
1046 <<
"Send NULL word to the database."
1048 tmp_row[slow_controls_settings.target_position] = sqlpp::null;
1053 <<
" is not defined."
1054 <<
"Send NULL word to the database."
1056 tmp_row[slow_controls_settings.target_position] = sqlpp::null;
1060 QwDebug <<
"Send the value of "
1064 <<
", to the database."
1066 tmp_row[slow_controls_settings.target_position] =
1074 tagindex =
FindIndex(
"IGL1I00DI24_24M");
1080 tmp_row[slow_controls_settings.slow_helicity_plate] = sqlpp::null;
1086 <<
" changed during the run."
1087 <<
"Send NULL word to the database."
1089 tmp_row[slow_controls_settings.slow_helicity_plate] = sqlpp::null;
1094 <<
" is not defined."
1095 <<
"Send NULL word to the database."
1097 tmp_row[slow_controls_settings.slow_helicity_plate] = sqlpp::null;
1102 QwDebug <<
"Send the value of "
1106 <<
", to the database."
1108 tmp_row[slow_controls_settings.slow_helicity_plate] = std::string(
fEPICSDataEvent[tagindex].StringValue.Data());
1120 tmp_row[slow_controls_settings.passive_helicity_plate] = sqlpp::null;
1126 <<
" changed during the run."
1127 <<
"Send NULL word to the database."
1129 tmp_row[slow_controls_settings.passive_helicity_plate] = sqlpp::null;
1133 if (fabs(ihwp2_readback-13056)<1){
1135 QwDebug <<
"Send the value of "
1139 <<
", to the database."
1141 tmp_row[slow_controls_settings.passive_helicity_plate] = std::string(
"in");
1142 }
else if (fabs(ihwp2_readback-8960)<1){
1144 QwDebug <<
"Send the value of "
1148 <<
", to the database."
1150 tmp_row[slow_controls_settings.passive_helicity_plate] = std::string(
"out");
1154 <<
" is not defined."
1155 <<
"Send NULL word to the database."
1157 tmp_row[slow_controls_settings.passive_helicity_plate] = sqlpp::null;
1169 tmp_row[slow_controls_settings.wien_reversal] = sqlpp::null;
1175 <<
" changed during the run."
1176 <<
"Send NULL word to the database."
1178 tmp_row[slow_controls_settings.wien_reversal] = sqlpp::null;
1183 <<
" is not defined."
1184 <<
"Send NULL word to the database."
1186 tmp_row[slow_controls_settings.wien_reversal] = sqlpp::null;
1189 TString wien_enum[5] = {
"indeterminate",
1191 "transverse_vertical",
1192 "transverse_horizontal"};
1193 QwDebug <<
"Send the value of "
1197 <<
", to the database."
1199 tmp_row[slow_controls_settings.wien_reversal] =
1208 tmp_row[slow_controls_settings.precession_reversal] = std::string(
"reverse");
1210 tmp_row[slow_controls_settings.precession_reversal] = std::string(
"normal");
1215 tagindex =
FindIndex(
"qw:ChargeFeedback");
1221 tmp_row[slow_controls_settings.charge_feedback] = sqlpp::null;
1228 <<
" changed during the run."
1229 <<
"Send NULL word to the database."
1231 tmp_row[slow_controls_settings.charge_feedback] = sqlpp::null;
1237 <<
" is not defined."
1238 <<
"Send NULL word to the database."
1240 tmp_row[slow_controls_settings.charge_feedback] = sqlpp::null;
1247 QwDebug <<
"Send the value of "
1251 <<
", to the database."
1255 tmp_row[slow_controls_settings.charge_feedback] = std::string(tmpval.Data());
1262 auto c = db->GetScopedConnection();
1263 QwDebug <<
"QwEPICSEvent::FillSlowControlsSettings Writing to database now" <<
QwLog::endl;
1264 c->QueryExecute(tmp_row.insert_into());
1267 auto insert_stmt = sqlpp::insert_into(slow_controls_settings).set(
1268 slow_controls_settings.runlet_id = runlet_id,
1269 slow_controls_settings.precession_reversal = precession_reversal
1271 c->QueryExecute(insert_stmt);
1272 QwDebug <<
"QwEPICSEvent::FillSlowControlsSettings Successfully wrote to database" <<
QwLog::endl;
1273 }
catch (
const std::exception& er) {
1282 Bool_t local_debug =
false;
1284 TList *string_list =
new TList;
1285 string_list->SetOwner(
true);
1287 std::size_t tagindex = 0;
1294 epics_string +=
"---";
1300 epics_string +=
"empty";
1303 std::cout <<
"QwEPICSEvent::GetEPICSStringValues() "
1307 string_list -> Add(
new TObjString(epics_string));
1318 Bool_t local_debug =
false;
1320 TSeqCollection *file_list = gROOT->GetListOfFiles();
1324 Int_t size = file_list->GetSize();
1325 for (Int_t i=0; i<size; i++)
1327 TFile *file = (TFile*) file_list->At(i);
1330 std::cout <<
"QwEPICSEvent::WriteEPICSStringValue()"
1335 TTree *slow_tree = (TTree*) file->Get(
"slow");
1343 name.ReplaceAll(
':',
'_');
1344 TString name_type = name +
"/C";\
1346 Char_t epics_char[128];
1347 TString epics_string;
1349 TBranch *new_branch = slow_tree->Branch(name, epics_char, name_type);
1355 epics_string =
"empty";
1359 std::cout <<
"QwEPICSEvent::WriteEPICSStringValue()\n";
1360 std::cout << name <<
" " << epics_string << std::endl;
1364 sprintf(epics_char,
"%s", epics_string.Data());
1370 file -> Write(
"", TObject::kOverwrite);
1382 Int_t ihwppolarity = 0;
1390 QwWarning <<
"IHWP state is not well defined: '"
1400 QwWarning <<
"IHWP state is not well defined: '"
1405 QwDebug <<
"QwEPICSEvent::DetermineIHWPPolarity: "
1406 <<
"raw IHWP polarity is: "
1409 QwDebug <<
"QwEPICSEvent::DetermineIHWPPolarity: "
1410 <<
"IHWP polarity after extra reversal is: "
1412 return ihwppolarity;
1418 Double_t launchangle = 0.0;
1423 Double_t hoffset = 0.0;
1424 if (fabs(vwienangle)<10.0 && fabs(phiangle)<10.0){
1426 }
else if (fabs(vwienangle)>80.0 && fabs(phiangle)>80.0
1427 && fabs(vwienangle+phiangle)<10. ){
1429 }
else if (fabs(vwienangle)>80.0 && fabs(phiangle)>80.0
1430 && fabs(vwienangle+phiangle)>170. ){
1432 }
else if (fabs(vwienangle)>80.0 && fabs(phiangle)<10.0) {
1436 launchangle = hoffset+hwienangle;
1437 Double_t long_proj =
1439 if (long_proj > 0.5){
1441 }
else if (long_proj < -0.5){
1443 }
else if (fabs(long_proj)<0.25){
ROOT file and tree management wrapper classes.
Parameter file parsing and management.
EPICS data event handling and storage.
A logfile class, based on an identical class in the Hermes analyzer.
#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.
Basic data types and constants used throughout the Qweak analysis framework.
EQwWienMode WienModeIndex(TString name)
std::string WienModeName(EQwWienMode type)
EQwWienMode
Double Wien configuration.
Int_t AddEPICSTag(const string &tag, const string &table="", EQwEPICSDataType datatype=kEPICSFloat)
static void DefineOptions(QwOptions &options)
Define the configuration options.
Int_t DetermineIHWPPolarity() const
void ProcessOptions(QwOptions &options)
Process the configuration options.
std::vector< std::string > fEPICSVariableList
void WriteEPICSStringValues()
std::vector< EPICSVariableRecord > fEPICSDataEvent
void ExtractEPICSValues(const string &data, int event)
void FillSlowControlsSettings(QwParityDB *db)
Int_t LoadChannelMap(TString mapfile)
virtual ~QwEPICSEvent()
Virtual destructor.
Double_t fNominalWienAngle
Bool_t IsNumber(const string &word)
void FillSlowControlsStrings(QwParityDB *db)
int SetDataValue(const string &tag, const double value, const int event)
void PrintAverages() const
void CalculateRunningValues()
void ReportEPICSData() const
Int_t fExtraHelicityReversal
static void SetDefaultAutogainList(std::vector< std::string > &input_list)
static std::vector< std::string > fDefaultAutogainList
Default autogain list.
void FillDB(QwParityDB *db)
std::vector< EQwEPICSDataType > fEPICSVariableType
void SetDataLoaded(Bool_t flag)
EQwWienMode DetermineWienMode() const
void FillSlowControlsData(QwParityDB *db)
std::map< std::string, Int_t > fEPICSVariableMap
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values)
Construct the branch and tree vector.
std::vector< EPICSCumulativeRecord > fEPICSCumulativeData
static void InitDefaultAutogainList()
Initialize the default autogain list.
Int_t FindIndex(const string &tag) const
Find the index of an EPICS variable, or return error.
void FillTreeVector(QwRootTreeBranchVector &values) const
Fill the tree vector.
std::vector< Double_t > ReportAutogains(std::vector< std::string > tag_list=fDefaultAutogainList)
static const int kEPICS_OK
Double_t GetDataValue(const string &tag) const
static const Double_t kInvalidEPICSData
Int_t fNumberEPICSVariables
TString GetDataString(const string &tag) const
Bool_t fPrecessionReversal
std::vector< std::string > fEPICSTableList
EQwEPICSDataType
EPICS data types.
size_t fTreeArrayNumEntries
TList * GetEPICSStringValues()
void PrintVariableList() const
QwEPICSEvent()
Default constructor.
Bool_t fBlinderReversalForRunTwo
static const int kEPICS_Error
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.
Configuration file parser with flexible tokenization and search capabilities.
T GetTypedNextToken()
Get next token into specific type.
void TrimWhitespace(TString::EStripType head_tail=TString::kBoth)
Bool_t HasVariablePair(const std::string &separatorchars, std::string &varname, std::string &varvalue)
void TrimComment(const char commentchar)
A helper class to manage a vector of branch entries for ROOT trees.
size_type size() const noexcept
std::string LeafList(size_type start_index=0) const
void push_back(const std::string &name, const char type='D')
void SetValue(size_type index, Double_t val)