JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwEPICSEvent.cc
Go to the documentation of this file.
1/*!
2 * \file QwEPICSEvent.cc
3 * \brief EPICS data event handling and storage implementation
4 */
5
6#include "QwEPICSEvent.h"
7
8// System headers
9#include <iostream>
10#include <fstream>
11#include <cmath>
12
13// ROOT headers
14#include "TObject.h"
15#include "TList.h"
16#include "TString.h"
17#include "TObjString.h"
18#include "TFile.h"
19#include "TROOT.h"
20#include "TMath.h"
21#ifdef HAS_RNTUPLE_SUPPORT
22#include "ROOT/RNTupleModel.hxx"
23#include "ROOT/RField.hxx"
24#endif // HAS_RNTUPLE_SUPPORT
25
26// Qweak headers
27#include "QwLog.h"
28#include "QwParameterFile.h"
29#include "QwRootFile.h"
30#include "QwTypes.h"
31
32#ifdef __USE_DATABASE__
33#include "QwParitySchema.h"
34#include "QwParityDB.h"
35#endif //__USE_DATABASE__
36
37
38/*************************************
39 * Static definitions
40 *************************************/
41
42const int QwEPICSEvent::kDebug = 0; /* Debugging flag, set this to 1 to *
43 * enable debugging output, otherwise 0.*/
44const int QwEPICSEvent::kEPICS_Error = -1;
45const int QwEPICSEvent::kEPICS_OK = 1;
46
47const Double_t QwEPICSEvent::kInvalidEPICSData = -999999.0;
48
49
50// Default autogain list
51std::vector<std::string> QwEPICSEvent::fDefaultAutogainList;
52
53
54/*************************************
55 * Constructors/Destructors.
56 *************************************/
66
67
71
72
73/*************************************
74 * Member functions.
75 *************************************/
76
77/**
78 * Defines configuration options using QwOptions functionality.
79 * @param options Options object
80 */
82{
83#ifdef __USE_DATABASE__
84 // Option to disable EPICS database accesses
85 options.AddOptions("Default options")
86 ("disable-db-epics",
87 po::value<bool>()->default_bool_value(false),
88 "disable EPICS database access");
89#endif
90}
91
92
93/**
94 * Parse the configuration options and store in class fields
95 * @param options Options object
96 */
98{
99#ifdef __USE_DATABASE__
100 // Option to disable EPICS database accesses
101 fDisableDatabase = options.GetValue<bool>("disable-db-epics");
102#endif
103}
104
105Int_t QwEPICSEvent::LoadChannelMap(TString mapfile)
106{
107 Int_t lineread = 0;
108
110 fEPICSVariableList.clear();
111 fEPICSVariableType.clear();
112
115 fPrecessionReversal = kFALSE;
116
117 // Open the file
118 QwParameterFile mapstr(mapfile.Data());
119 std::string varname, varvalue;
120 while (mapstr.ReadNextLine()) {
121 lineread++;
122
123 mapstr.TrimComment(); // Remove everything after a '!' character.
124 mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces.
125 if (mapstr.LineIsEmpty()) continue;
126
127 if (mapstr.HasVariablePair("=",varname,varvalue)){
128 QwDebug << "QwEPICSEvent::LoadChannelMap: keyword,value pair:"
129 << varname << "," << varvalue << QwLog::endl;
130 if (varname == "NominalWienAngle"){
131 fNominalWienAngle = atof(varvalue.c_str());
132 } else if (varname == "BlinderReversalForRunTwo"){
136 }
137 } else if (varname == "PrecessionReversal"){
138 if (! fPrecessionReversal){
139 fPrecessionReversal = kTRUE;
141 }
142 } else {
143 QwError << "QwEPICSEvent::LoadChannelMap: "
144 << "Unknown keyword,variable pair: "
145 << varname << "," << varvalue << QwLog::endl;
146 exit(1);
147 }
148 continue;
149 }
150
151 varname = mapstr.GetTypedNextToken<std::string>();
152 std::string dbtable = mapstr.GetTypedNextToken<std::string>();
153 TString datatype = mapstr.GetTypedNextToken<TString>();
154 datatype.ToLower();
155
156 if (datatype == "") {
157 AddEPICSTag(varname,dbtable);
158 } else {
159 EQwEPICSDataType datatypeid = kEPICSString;
160 if (datatype == "string") datatypeid = kEPICSString;
161 if (datatype == "float") datatypeid = kEPICSFloat;
162 if (datatype == "int") datatypeid = kEPICSInt;
163 AddEPICSTag(varname,dbtable,datatypeid);
164 }
165 }
166 if (kDebug == 1) std::cout << "fNumberEPICSVariables = " << fNumberEPICSVariables << std::endl << std::endl;
167 if (kDebug == 1) std::cout << "line read in the parameter file =" << lineread << std::endl;
168
170 mapstr.Close(); // Close the file (ifstream)
171 return 0;
172}
173
174
175/// \brief Construct the branch and tree vector
176void QwEPICSEvent::ConstructBranchAndVector(TTree *tree, TString& prefix, QwRootTreeBranchVector &values)
177{
178 fTreeArrayIndex = values.size();
179 Int_t treeindex = fTreeArrayIndex;
180 for (size_t tagindex = 0; tagindex < fEPICSVariableType.size(); tagindex++) {
181 if (fEPICSVariableType[tagindex] == kEPICSString ||
182 fEPICSVariableType[tagindex] == kEPICSFloat ||
183 fEPICSVariableType[tagindex] == kEPICSInt) {
184
185 // Determine branch name
186 TString name = fEPICSVariableList[tagindex];
187 name.ReplaceAll(':','_'); // remove colons before creating branch
188
189 // Add element to vector
190 values.push_back(name.Data(), 'D');
191
192 // Create branch
193 tree->Branch(name, &(values[treeindex]), values.LeafList(treeindex).c_str());
194 treeindex++;
195
196 } else {
197
198 TString name = fEPICSVariableList[tagindex];
199 QwError << "Unrecognized type for EPICS variable " << name << QwLog::endl;
200
201 }
202 }
204}
205
206/// \brief Fill the tree vector
208{
209 Int_t treeindex = fTreeArrayIndex;
210 for (size_t tagindex = 0; tagindex < fEPICSVariableType.size(); tagindex++) {
211 switch (fEPICSVariableType[tagindex]) {
212 case kEPICSFloat:
213 case kEPICSInt: {
214 // Add value to vector
215 values.SetValue(treeindex, fEPICSDataEvent[tagindex].Value);
216 treeindex++;
217 break;
218 }
219 case kEPICSString: {
220 // Add value to vector
221 values.SetValue(treeindex, static_cast<Double_t>(fEPICSDataEvent[tagindex].StringValue.Hash()));
222 treeindex++;
223 break;
224 }
225 default: {
226 TString name = fEPICSVariableList[tagindex];
227 QwError << "Unrecognized type for EPICS variable " << name << QwLog::endl;
228 break;
229 }
230 }
231 }
232}
233
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)
236{
237 fTreeArrayIndex = values.size();
238 for (size_t tagindex = 0; tagindex < fEPICSVariableType.size(); tagindex++) {
239 if (fEPICSVariableType[tagindex] == kEPICSString ||
240 fEPICSVariableType[tagindex] == kEPICSFloat ||
241 fEPICSVariableType[tagindex] == kEPICSInt) {
242
243 // Add element to vector
244 values.push_back(0.0);
245
246 // Determine field name
247 TString name = fEPICSVariableList[tagindex];
248 name.ReplaceAll(':','_'); // remove colons before creating field
249 name.ReplaceAll('.','_'); // remove dots before creating field
250
251 // Create RNTuple field (handle duplicate field names gracefully)
252 // Note: Unlike TTrees which allow duplicate branch names, RNTuples require unique field names
253 try {
254 auto field = model->MakeField<Double_t>(name.Data());
255 fieldPtrs.push_back(field);
256 } catch (const std::exception& e) {
257 // Field already exists - this mimics TTree behavior where duplicate branches are allowed
258 // We still reserve space in the vector but use a nullptr for the field pointer
259 fieldPtrs.push_back(nullptr);
260 QwWarning << "EPICS field '" << name << "' already exists in RNTuple model, skipping duplicate creation" << QwLog::endl;
261 }
262 }
263 }
264 fTreeArrayNumEntries = values.size() - fTreeArrayIndex;
265}
266
267void QwEPICSEvent::FillNTupleVector(std::vector<Double_t>& values) const
268{
269 Int_t treeindex = fTreeArrayIndex;
270 for (size_t tagindex = 0; tagindex < fEPICSVariableType.size(); tagindex++) {
271 switch (fEPICSVariableType[tagindex]) {
272 case kEPICSFloat:
273 case kEPICSInt: {
274 // Add value to vector
275 values[treeindex] = fEPICSDataEvent[tagindex].Value;
276 treeindex++;
277 break;
278 }
279 case kEPICSString: {
280 // Add value to vector
281 values[treeindex] = static_cast<Double_t>(fEPICSDataEvent[tagindex].StringValue.Hash());
282 treeindex++;
283 break;
284 }
285 default: {
286 TString name = fEPICSVariableList[tagindex];
287 QwError << "Unrecognized type for EPICS variable " << name << QwLog::endl;
288 break;
289 }
290 }
291 }
292}
293#endif // HAS_RNTUPLE_SUPPORT
294
295
297 const string& tag,
298 const string& table,
299 EQwEPICSDataType datatype)
300{
301 fEPICSVariableList.push_back(tag);
302 fEPICSVariableMap[tag] = fEPICSVariableList.size() - 1;
303 fEPICSTableList.push_back(table);
304 fEPICSVariableType.push_back(datatype);
306 return 0;
307}
308
309
311{
312 if (kDebug == 1) std::cout <<"Here we are in 'CalculateRunningValues'!!"<<std::endl;
313 if (kDebug == 1) std::cout<<"fNumberEPICSVariables = "<<fNumberEPICSVariables<<std::endl<<std::endl;
314
315 Bool_t anyFilled = kFALSE;
316 for (size_t tagindex = 0; tagindex < fEPICSDataEvent.size(); tagindex++) {
317 anyFilled |= fEPICSDataEvent[tagindex].Filled;
318 }
319 if (! anyFilled) return;
320
321 for (size_t tagindex = 0; tagindex < fEPICSVariableType.size(); tagindex++) {
322 if (fEPICSVariableType[tagindex] == kEPICSFloat ||
323 fEPICSVariableType[tagindex] == kEPICSInt) {
324
325 if (fEPICSDataEvent[tagindex].Filled) {
326
327 if (! fEPICSCumulativeData[tagindex].Filled) {
328 fEPICSCumulativeData[tagindex].NumberRecords = 0;
329 fEPICSCumulativeData[tagindex].Sum = 0.0;
330 fEPICSCumulativeData[tagindex].SquaredSum = 0.0;
331 fEPICSCumulativeData[tagindex].Maximum =
332 fEPICSDataEvent[tagindex].Value;
333 fEPICSCumulativeData[tagindex].Minimum =
334 fEPICSDataEvent[tagindex].Value;
335 fEPICSCumulativeData[tagindex].Filled = kTRUE;
336 }
337 fEPICSCumulativeData[tagindex].NumberRecords++;
338 fEPICSCumulativeData[tagindex].Sum +=
339 fEPICSDataEvent[tagindex].Value;
340 fEPICSCumulativeData[tagindex].SquaredSum +=
341 (fEPICSDataEvent[tagindex].Value)*(fEPICSDataEvent[tagindex].Value);
342 if (fEPICSDataEvent[tagindex].Value
343 > fEPICSCumulativeData[tagindex].Maximum) {
344 fEPICSCumulativeData[tagindex].Maximum =
345 fEPICSDataEvent[tagindex].Value;
346 }
347 if (fEPICSDataEvent[tagindex].Value
348 < fEPICSCumulativeData[tagindex].Minimum) {
349 fEPICSCumulativeData[tagindex].Minimum =
350 fEPICSDataEvent[tagindex].Value;
351 }
352 if (kDebug == 1) std::cout << "This event has "<<fEPICSVariableList[tagindex]
353 << " equal to "<< fEPICSDataEvent[tagindex].Value
354 << " giving a running average of "
355 << fEPICSCumulativeData[tagindex].Sum /
356 fEPICSCumulativeData[tagindex].NumberRecords
357 << std::endl;
358 } else {
359 if (kDebug == 1) std::cout << fEPICSVariableList[tagindex]
360 << " seems to be not filled."<<std::endl;
361 }
362 }
363
364 ////////////////////////////////
365 else {
366 // This is a string value.
367 // Just check to see if the EPICS string has changed;
368 // if it is the same, increment the counter.
369
370 if (! fEPICSCumulativeData[tagindex].Filled) {
371 fEPICSCumulativeData[tagindex].NumberRecords = 0;
372 fEPICSCumulativeData[tagindex].SavedString =
373 fEPICSDataEvent[tagindex].StringValue;
374 fEPICSCumulativeData[tagindex].Filled = kTRUE;
375 }
376 if (fEPICSCumulativeData[tagindex].SavedString
377 == fEPICSDataEvent[tagindex].StringValue ) {
378 fEPICSCumulativeData[tagindex].NumberRecords++;
379 }
380 }
381 }
383 //////////////////////
384
385 if (kDebug == 1) std::cout << "fNumberEPICSEvents = " << fNumberEPICSEvents << std::endl;
386}
387
388
389void QwEPICSEvent::ExtractEPICSValues(const string& data, int event)
390{
391 /* This routine will decode the input string, which holds the *
392 * epics buffer and extract the EPICS values from it. */
393
394 if (kDebug == 1) std::cout <<"Here we are, entering 'ExtractEPICSValues'!!"<<std::endl;
395
396 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
397 fEPICSDataEvent[tagindex].Filled = kFALSE;
398 }
399
400 // Convert the input stream into a stringstream so we can
401 // do manipulation on it just like reading a file
402 std::stringstream ss(data, std::stringstream::in | std::stringstream::out);
403 QwParameterFile file(ss);
404 while (file.ReadNextLine()) {
405 file.TrimWhitespace();
406 string varname, varvalue;
407 if (file.HasVariablePair(" \t\n", varname, varvalue)) {
408 Int_t tagindex = FindIndex(varname);
409 if (tagindex != kEPICS_Error) {
410 SetDataValue(tagindex, varvalue, event);
411 SetDataLoaded(kTRUE);
412 }
413 }
414 }
415 if (fIsDataLoaded) {
416 // Determine the WienMode and save it.
417 SetDataValue("WienMode",WienModeName(DetermineWienMode()),event);
418 }
419}
420
421
422Int_t QwEPICSEvent::FindIndex(const string& tag) const
423{
424 // Find a match for the tag
425 std::map<std::string,Int_t>::const_iterator match = fEPICSVariableMap.find(tag);
426
427 if (match != fEPICSVariableMap.end())
428 // A match was found
429 return match->second;
430
431 else
432 // Otherwise return error
433 return kEPICS_Error;
434}
435
436
437Double_t QwEPICSEvent::GetDataValue(const string& tag) const
438{
439 Double_t data_value = kInvalidEPICSData;
440 Int_t tagindex = FindIndex(tag);
441 if (tagindex != kEPICS_Error) {
442 if (fEPICSDataEvent[tagindex].Filled) {
443 data_value = fEPICSDataEvent[tagindex].Value;
444 }
445 }
446 return data_value;
447}
448
449TString QwEPICSEvent::GetDataString(const string& tag) const
450{
451 Int_t tagindex = FindIndex(tag);
452 if (tagindex != kEPICS_Error) {
453 if (fEPICSVariableType[tagindex]==kEPICSString
454 && fEPICSDataEvent[tagindex].Filled) {
455 return(fEPICSDataEvent[tagindex].StringValue);
456 }
457 }
458 return TString("");
459}
460
462{
463 // Clear the vector first
464 fDefaultAutogainList.clear();
465
466 // Add default autogain channels
467 fDefaultAutogainList.push_back("IPM3C17.XIFG");
468 fDefaultAutogainList.push_back("IPM3C17.YIFG");
469 fDefaultAutogainList.push_back("IBC3C17.XIFG");
470 fDefaultAutogainList.push_back("IBC3C17.YIFG");
471 fDefaultAutogainList.push_back("IPM3C18.XIFG");
472 fDefaultAutogainList.push_back("IPM3C18.YIFG");
473 fDefaultAutogainList.push_back("IPM3C19.XIFG");
474 fDefaultAutogainList.push_back("IPM3C19.YIFG");
475 fDefaultAutogainList.push_back("IPM3C03.YIFG");
476 fDefaultAutogainList.push_back("IPM3P01.XIFG");
477 fDefaultAutogainList.push_back("IPM3P01.YIFG");
478 fDefaultAutogainList.push_back("IPM3P02A.XIFG");
479 fDefaultAutogainList.push_back("IPM3P02A.YIFG");
480 fDefaultAutogainList.push_back("IPM3P03A.XIFG");
481 fDefaultAutogainList.push_back("IPM3P03A.YIFG");
482 fDefaultAutogainList.push_back("IPM3P02B.XIFG");
483 fDefaultAutogainList.push_back("IPM3P02B.YIFG");
484 fDefaultAutogainList.push_back("IPM3C20.XIFG");
485 fDefaultAutogainList.push_back("IPM3C20.YIFG");
486 fDefaultAutogainList.push_back("IPM3C21.XIFG");
487 fDefaultAutogainList.push_back("IPM3C21.YIFG");
488 fDefaultAutogainList.push_back("IPM3H02.XIFG");
489 fDefaultAutogainList.push_back("IPM3H02.YIFG");
490 fDefaultAutogainList.push_back("IPM3H04.XIFG");
491 fDefaultAutogainList.push_back("IPM3H04.YIFG");
492 fDefaultAutogainList.push_back("IPM3H07A.XIFG");
493 fDefaultAutogainList.push_back("IPM3H07A.YIFG");
494 fDefaultAutogainList.push_back("IPM3H07B.XIFG");
495 fDefaultAutogainList.push_back("IPM3H07B.YIFG");
496 fDefaultAutogainList.push_back("IPM3H07C.XIFG");
497 fDefaultAutogainList.push_back("IPM3H07C.YIFG");
498 fDefaultAutogainList.push_back("IPM3H09.XIFG");
499 fDefaultAutogainList.push_back("IPM3H09.YIFG");
500 fDefaultAutogainList.push_back("IPM3H09B.XIFG");
501 fDefaultAutogainList.push_back("IPM3H09B.YIFG");
502}
503
504void QwEPICSEvent::SetDefaultAutogainList(std::vector<std::string>& input_list)
505{
506 fDefaultAutogainList.clear(); //clear the vector first
507 fDefaultAutogainList = input_list;
508}
509
510
511int QwEPICSEvent::SetDataValue(const string& tag, const double value, const int event)
512{
513 Int_t tagindex = FindIndex(tag);
514 return (SetDataValue(tagindex, value, event));
515}
516
517int QwEPICSEvent::SetDataValue(const string& tag, const string& value, const int event)
518{
519 Int_t tagindex = FindIndex(tag);
520 return (SetDataValue(tagindex, value, event));
521}
522
523int QwEPICSEvent::SetDataValue(int index, const double value, const int event)
524{
525 if (index == kEPICS_Error) return kEPICS_Error;
526 if (index < 0) return kEPICS_Error;
527
528 if (value != kInvalidEPICSData) {
529 fEPICSDataEvent[index].EventNumber = event;
530 fEPICSDataEvent[index].Value = value;
531 fEPICSDataEvent[index].StringValue = "";
532 fEPICSDataEvent[index].Filled = kTRUE;
533 return 0;
534 }
535 return kEPICS_Error;
536}
537
538int QwEPICSEvent::SetDataValue(int index, const string& value, const int event)
539{
540 if (index == kEPICS_Error) return kEPICS_Error;
541 if (index < 0) return kEPICS_Error;
542
543 Double_t tmpvalue = kInvalidEPICSData;
544 switch (fEPICSVariableType[index]) {
545 case kEPICSString:
546 fEPICSDataEvent[index].EventNumber = event;
547 fEPICSDataEvent[index].Value = 0.0;
548 fEPICSDataEvent[index].StringValue = value;
549 fEPICSDataEvent[index].Filled = kTRUE;
550 return 0;
551 break;
552
553 case kEPICSFloat:
554 if (IsNumber(value)) {
555 tmpvalue = Double_t(atof(value.c_str()));
556 }
557 return SetDataValue(index, tmpvalue, event);
558 break;
559
560 case kEPICSInt:
561 if(IsNumber(value)) {
562 tmpvalue = Double_t(atol(value.c_str()));
563 }
564 return SetDataValue(index, tmpvalue, event);
565 break;
566 }
567
568 return kEPICS_Error;
569}
570
572{
573 Double_t mean = 0.0;
574 Double_t average_of_squares = 0.0;
575 Double_t variance = 0.0;
576 Double_t sigma = 0.0;
577
578 std::cout <<"##### EPICS Event Summary from PrintAverages() #####\n"
579 <<"Total number of EPICS events in this run == "
580 <<fNumberEPICSEvents <<".\n\n"
581 << std::setw(20) << std::setiosflags(std::ios::left) <<"Name"
582 <<"\tMean Sigma "
583 <<"Minimum Maximum"<<std::endl;
584 std::cout << "*****Non-string EPICS Variables*****" << std::endl;
585 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
586 if (fEPICSVariableType[tagindex] == kEPICSFloat ||
587 fEPICSVariableType[tagindex] == kEPICSInt) {
588
589 mean = 0.0;
590 variance = 0.0;
591 sigma = 0.0;
592 if (fEPICSCumulativeData[tagindex].NumberRecords > 0){
593 mean = (fEPICSCumulativeData[tagindex].Sum)/
594 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
595 average_of_squares = (fEPICSCumulativeData[tagindex].SquaredSum)/
596 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
597 variance = average_of_squares - (mean * mean);
598 if (variance < 0.0){
599 sigma = sqrt(-1.0 * variance);
600 } else {
601 sigma = sqrt(variance);
602 }
603
604 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
605 <<fEPICSVariableList[tagindex]<<"\t"
606 << std::setprecision(5) << std::setw(10)
607 <<mean<<" " << std::setw(10)<<sigma<<" " << std::setw(10)
608 <<fEPICSCumulativeData[tagindex].Minimum<<" " << std::setw(10)
609 <<fEPICSCumulativeData[tagindex].Maximum<<std::endl;
610 } else {
611 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
612 <<fEPICSVariableList[tagindex]<<"\t"
613 << std::setprecision(5) << std::setw(10)
614 << "...No data..."
615 << std::endl;
616 }
617 }
618 }
619
620 std::cout << "*****String EPICS Variables are below, if any*****" << std::endl;
621 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
622 if (fEPICSVariableType[tagindex] == kEPICSString) {
623 if (fEPICSDataEvent[tagindex].Filled) {
624 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
625 <<"tagindex for variable "<< fEPICSVariableList[tagindex]<<"\t is "
626 <<tagindex<<"\tand status is\t\t"
627 <<fEPICSDataEvent[tagindex].StringValue;
628
629 if (fEPICSCumulativeData[tagindex].NumberRecords!= fNumberEPICSEvents){
630 std::cout << "\t*****\tThis variable changed during the run. Only "
631 << (Double_t(fEPICSCumulativeData[tagindex].NumberRecords)
632 *100.0 / Double_t(fNumberEPICSEvents))
633 << "% of the events has this value.";
634 }
635 std::cout <<std::endl;
636 } else {
637 std::cout << std::setw(20) << std::setiosflags(std::ios::left)
638 <<fEPICSVariableList[tagindex]<<"\t"
639 <<"No data..."<<std::endl;
640 }
641 }
642 }
643}
644
645
647{
648 // Prints all valid Epics variables on the terminal while creating a rootfile.
649 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
650 QwMessage << "fEPICSVariableList[" << tagindex << "] == "
651 << fEPICSVariableList[tagindex] << QwLog::endl;
652 }
653}
654
655
656std::vector<Double_t> QwEPICSEvent::ReportAutogains(std::vector<std::string> tag_list)
657{
658 std::vector<Double_t> autogain_values;
659 std::vector<std::string>::iterator ptr_tag;
660
661 autogain_values.clear(); //clear the vector first
662
663 /* Iterate through the input vector of the variable names *
664 * and fill the output vector with the values. */
665 ptr_tag = tag_list.begin();
666 while (ptr_tag < tag_list.end()) {
667 autogain_values.push_back(GetDataValue(*ptr_tag));
668 ptr_tag++;
669 }
670
671 return autogain_values;
672}
673
674
675
677{
678 Double_t mean = 0.0;
679 Double_t average_of_squares = 0.0;
680 Double_t variance = 0.0;
681 Double_t sigma = 0.0;
682
683
684 std::ofstream output;
685 TString theEPICSDataFile;
686 theEPICSDataFile = getenv("QW_TMP");
687 theEPICSDataFile += "/QwEPICSData.txt";// puts QwEPICSData.txt in QwAnalysis_DB_01.00.0000/scratch/tmp/ directory.
688 output.open(theEPICSDataFile,std::ofstream::out);
689
690 if (output.is_open()) {
691
692
693 output <<"##### EPICS Event Summary #####\n"
694 <<"Total number of EPICS events in this run == "
695 <<fNumberEPICSEvents <<".\n\n"
696 << std::setw(20) << std::setiosflags(std::ios::left) <<"Name"
697 <<"\tMean Sigma "
698 <<"Minimum Maximum"<<std::endl;
699 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
700 if (fEPICSVariableType[tagindex] == kEPICSFloat ||
701 fEPICSVariableType[tagindex] == kEPICSInt) {
702 mean = 0.0;
703 variance = 0.0;
704 sigma = 0.0;
705 if (fEPICSCumulativeData[tagindex].NumberRecords > 0){
706 mean = (fEPICSCumulativeData[tagindex].Sum)/
707 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
708 average_of_squares = (fEPICSCumulativeData[tagindex].SquaredSum)/
709 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
710 variance = average_of_squares - (mean * mean);
711 if (variance < 0.0){
712 sigma = sqrt(-1.0 * variance);
713 } else {
714 sigma = sqrt(variance);
715 }
716
717 output << std::setw(20) << std::setiosflags(std::ios::left)
718 <<fEPICSVariableList[tagindex]<<"\t"
719 << std::setprecision(5) << std::setw(10)
720 <<mean<<" " << std::setw(10)<<sigma<<" " << std::setw(10)
721 <<fEPICSCumulativeData[tagindex].Minimum<<" " << std::setw(10)
722 <<fEPICSCumulativeData[tagindex].Maximum<<std::endl;
723 } else {
724 output << std::setw(20) << std::setiosflags(std::ios::left)
725 <<fEPICSVariableList[tagindex]<<"\t"
726 << std::setprecision(5) << std::setw(10)
727 << "-No data-"
728 << std::endl;
729 }
730 }
731
732 }
733 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
734 if (fEPICSVariableType[tagindex] == kEPICSString) {
735 if (fEPICSDataEvent[tagindex].Filled) {
736 output << std::setw(20) << std::setiosflags(std::ios::left)
737 <<fEPICSVariableList[tagindex]<<"\t"
738 <<fEPICSDataEvent[tagindex].StringValue<<std::endl;
739 } else {
740 output << std::setw(20) << std::setiosflags(std::ios::left)
741 <<fEPICSVariableList[tagindex]<<"\t"
742 <<"No data..."<<std::endl;
743 }
744 }
745 }
746
747 } output.close();
748}
749
751{
752 fIsDataLoaded = kFALSE;
753 /* Verify that the variable list and variable type vectors
754 are the same size, and agree with fNumberEPICSVariables. */
755 Int_t listlength = fEPICSVariableList.size();
756 Int_t typelength = fEPICSVariableType.size();
757 if (typelength != fNumberEPICSVariables ||
758 listlength != fNumberEPICSVariables) {
759 std::cerr << "The EPICS variable label and type arrays are not the same size!\n"
760 << "EPICS readback may be corrupted!"<<std::endl;
761 }
762 /* Reset the sizes of the fEPICSDataEvent and
763 fEPICSCumulativeData vectors. */
766 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
767 fEPICSDataEvent[tagindex].Filled = kFALSE;
768 fEPICSDataEvent[tagindex].EventNumber = 0;
769 fEPICSDataEvent[tagindex].Value = 0.0;
770 fEPICSDataEvent[tagindex].StringValue = "";
771 fEPICSCumulativeData[tagindex].Filled = kFALSE;
772 fEPICSCumulativeData[tagindex].NumberRecords = 0;
773 fEPICSCumulativeData[tagindex].Sum = 0.0;
774 fEPICSCumulativeData[tagindex].SquaredSum = 0.0;
775 fEPICSCumulativeData[tagindex].Minimum = 0.0;
776 fEPICSCumulativeData[tagindex].Maximum = 0.0;
777 }
779}
780
781#ifdef __USE_DATABASE__
782void QwEPICSEvent::FillDB(QwParityDB *db)
783{
784 // Sunday, January 16 22:09:16 EST 2011, jhlee
785 // don't change disable database flag
786 // just disable FillSlowControlsSettings(db) when fDisableDatabase is off
787
788 bool hold_fDisableDatabase = fDisableDatabase;
789
790 try {
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())
797 );
798
799 if (recordsExist) {
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;
802
803 fDisableDatabase=true;
804 }
805 }
806 catch (const std::exception& er) {
807 QwError << er.what() << QwLog::endl;
808 QwError << "Unable to determine if there are other slow controls entries in the database for this run. THERE MAY BE DUPLICATES." << QwLog::endl;
809 }
810
811
812 if (! fDisableDatabase) {
816 }
817 fDisableDatabase=hold_fDisableDatabase;
818}
819
820
821void QwEPICSEvent::FillSlowControlsData(QwParityDB *db)
822{
823
824 QwDebug << " -------------------------------------------------------------------------- " << QwLog::endl;
825 QwDebug << " QwEPICSEvent::FillSlowControlsData(QwParityDB *db) " << QwLog::endl;
826 QwDebug << " -------------------------------------------------------------------------- " << QwLog::endl;
827
828 Double_t mean, average_of_squares, variance, sigma;
829 Int_t n_records;
830
831 mean = 0.0;
832 average_of_squares = 0.0;
833 variance = 0.0;
834 sigma = 0.0;
835 n_records = 0;
836 // Figure out if the target table has this runlet_id in it already,
837 // if not, create a new entry with the current runlet_id.
838
839 UInt_t runlet_id = db->GetRunletID();
840
841 QwParitySchema::slow_controls_data slow_controls_data;
842 std::vector<QwParitySchema::row<QwParitySchema::slow_controls_data>> entrylist;
843
844 UInt_t sc_detector_id;
845
846 string table = "slow_controls_data";
847
848 // QwError << "Step 1 Entering the loop " << QwLog::endl;
849 // Loop over EPICS variables
850 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
851
852 // Look for variables to write into this table
853 if (fEPICSTableList[tagindex] == table) {
854 QwParitySchema::row<QwParitySchema::slow_controls_data> tmp_row;
855
856 // Now get the current sc_detector_id for the above runlet_id.
857 sc_detector_id = db->GetSlowControlDetectorID(fEPICSVariableList[tagindex]);
858
859 tmp_row[slow_controls_data.runlet_id] = runlet_id;
860 tmp_row[slow_controls_data.sc_detector_id] = sc_detector_id;
861
862 if (!sc_detector_id) continue;
863
864
865 // Calculate average and error
866 if (fEPICSVariableType[tagindex] == kEPICSFloat
867 || fEPICSVariableType[tagindex] == kEPICSInt) {
868 if (fEPICSCumulativeData[tagindex].NumberRecords > 0){
869
870 mean = (fEPICSCumulativeData[tagindex].Sum)/
871 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
872 average_of_squares = (fEPICSCumulativeData[tagindex].SquaredSum)/
873 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
874 variance = average_of_squares - (mean * mean);
875 if (variance < 0.0){
876 sigma = sqrt(-1.0 * variance);
877 } else {
878 sigma = sqrt(variance);
879 }
880 n_records = fEPICSCumulativeData[tagindex].NumberRecords;
881
882 // Build the row and submit it to the list
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;
886 tmp_row[slow_controls_data.min_value] = fEPICSCumulativeData[tagindex].Minimum;
887 tmp_row[slow_controls_data.max_value] = fEPICSCumulativeData[tagindex].Maximum;
888
889 entrylist.push_back(tmp_row);
890 }
891 }
892 }
893 }
894
895 // Check the entrylist size, if it isn't zero, start to query..
896 if( entrylist.size() ) {
897 auto c = db->GetScopedConnection();
898 QwDebug << "QwEPICSEvent::FillSlowControlsData::Writing to database now" << QwLog::endl;
899
900 // Convert to sqlpp11 bulk insert
901 try {
902 for (const auto& entry : entrylist) {
903 c->QueryExecute(entry.insert_into());
904 }
905 QwDebug << "Done executing sqlpp11 bulk insert" << QwLog::endl;
906 } catch (const std::exception &er) {
907 QwError << "SQLite exception: " << er.what() << QwLog::endl;
908 }
909 } else {
910 QwDebug << "QwEPICSEvent::FillSlowControlsData :: This is the case when the entrylist contains nothing " << QwLog::endl;
911 }
912}
913
914
915void QwEPICSEvent::FillSlowControlsStrings(QwParityDB *db)
916{
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";
922
923 // QwError << "Step 1 Entering the loop " << QwLog::endl;
924 // Loop over EPICS variables
925 for (size_t tagindex = 0; tagindex < fEPICSVariableList.size(); tagindex++) {
926 // Look for variables to write into this table
927
928 if (fEPICSTableList[tagindex] == table) {
929 QwParitySchema::row<QwParitySchema::slow_controls_strings> tmp_row;
930
931 // Now get the current sc_detector_id for the above runlet_id.
932 sc_detector_id = db->GetSlowControlDetectorID(fEPICSVariableList[tagindex]);
933
934 tmp_row[slow_controls_strings.runlet_id] = runlet_id;
935 tmp_row[slow_controls_strings.sc_detector_id] = sc_detector_id;
936
937 if (!sc_detector_id) continue;
938
939 if (fEPICSVariableType[tagindex] == kEPICSString) {
940
941 if (fEPICSDataEvent[tagindex].Filled) {
942 if(fEPICSDataEvent[tagindex].StringValue.Contains("***") ){
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("");
945 }
946 else {
947 //std::cout<<" Just a test value: "<<fEPICSDataEvent[tagindex].StringValue.Data()<<QwLog::endl;
948 tmp_row[slow_controls_strings.value] = std::string(fEPICSDataEvent[tagindex].StringValue.Data());
949 }
950 // Only add rows for filled variables
951 entrylist.push_back(tmp_row);
952 }
953 }
954 }
955 }
956
957 // Check the entrylist size, if it isn't zero, start to query.
958 if( entrylist.size() ) {
959 auto c = db->GetScopedConnection();
960 QwDebug << "QwEPICSEvent::FillSlowControlsStrigs Writing to database now" << QwLog::endl;
961
962 // Convert to sqlpp11 bulk insert
963 try {
964 for (const auto& entry : entrylist) {
965 c->QueryExecute(entry.insert_into());
966 }
967 QwDebug << "Done executing sqlpp11 bulk insert for FillSlowControlsStrings"
968 << QwLog::endl;
969 } catch (const std::exception &er) {
970 QwError << "SQLite exception: " << er.what() << QwLog::endl;
971 }
972 } else {
973 QwDebug << "QwEPICSEvent::FillSlowControlsData :: This is the case when the entrylist contains nothing " << QwLog::endl;
974 }
975}
976
977
979{
980 // Get database connection
981 QwParitySchema::slow_controls_settings slow_controls_settings{};
982 QwParitySchema::row<QwParitySchema::slow_controls_settings> tmp_row;
983
984 // Initialize values
985 UInt_t runlet_id = db->GetRunletID();
986 tmp_row[slow_controls_settings.runlet_id] = runlet_id;
987
988 std::string precession_reversal;
989
990 // Set precession_reversal
991 if (fPrecessionReversal == 1) {
992 precession_reversal = "CCW";
993 } else {
994 precession_reversal = "CW";
995 }
996
997 Int_t tagindex;
998
999 // Add as many blocks as needed in the following for all slow_controls_settings.
1000
1001 ////////////////////////////////////////////////////////////
1002
1003 // For QTOR current
1004 tagindex = FindIndex("qw:qt_mps_i_dcct");
1005 if (tagindex != kEPICS_Error) {
1006 QwDebug << "tagindex for = qw:qt_mps_i_dcct" << tagindex << QwLog::endl;
1007 if (! fEPICSCumulativeData[tagindex].Filled) {
1008 // No data for this run.
1009 tmp_row[slow_controls_settings.qtor_current] = sqlpp::null;
1010 } else if (fEPICSCumulativeData[tagindex].NumberRecords <= 0) {
1011 // No events in this variable
1012 QwWarning << "The value of "
1013 << fEPICSVariableList[tagindex]
1014 << " had no events during this run. "
1015 << "Send NULL word to the database."
1016 << QwLog::endl;
1017 tmp_row[slow_controls_settings.qtor_current] = sqlpp::null;
1018 } else {
1019 Double_t qtorcurrent = (fEPICSCumulativeData[tagindex].Sum)/
1020 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
1021 QwDebug << "Send the value of "
1022 << fEPICSVariableList[tagindex]
1023 << ", "
1024 << qtorcurrent
1025 << ", to the database."
1026 << QwLog::endl;
1027 tmp_row[slow_controls_settings.qtor_current] = qtorcurrent;
1028 }
1029 }
1030
1031 ////////////////////////////////////////////////////////////
1032
1033 // For target position
1034 tagindex = FindIndex("QWtgt_name");
1035 if (tagindex != kEPICS_Error) {
1036 QwDebug << "tagindex for = QWtgt_name" << tagindex << QwLog::endl;
1037 if (! fEPICSCumulativeData[tagindex].Filled) {
1038 // No data for this run.
1039 tmp_row[slow_controls_settings.target_position] = sqlpp::null;
1040 } else if (fEPICSCumulativeData[tagindex].NumberRecords
1041 != fNumberEPICSEvents) {
1042 // Target position changed
1043 QwWarning << "The value of "
1044 << fEPICSVariableList[tagindex]
1045 << " changed during this run. "
1046 << "Send NULL word to the database."
1047 << QwLog::endl;
1048 tmp_row[slow_controls_settings.target_position] = sqlpp::null;
1049 }
1050 if(fEPICSDataEvent[tagindex].StringValue.Contains("***") ){
1051 QwWarning << "The value of "
1052 << fEPICSVariableList[tagindex]
1053 << " is not defined."
1054 << "Send NULL word to the database."
1055 << QwLog::endl;
1056 tmp_row[slow_controls_settings.target_position] = sqlpp::null;
1057 } else {
1058 // Target position did not change.
1059 // Store the position as a text string.
1060 QwDebug << "Send the value of "
1061 << fEPICSVariableList[tagindex]
1062 << ", "
1063 << fEPICSDataEvent[tagindex].StringValue.Data()
1064 << ", to the database."
1065 << QwLog::endl;
1066 tmp_row[slow_controls_settings.target_position] =
1067 std::string(fEPICSDataEvent[tagindex].StringValue.Data());
1068 }
1069 }
1070
1071 ////////////////////////////////////////////////////////////
1072
1073 // For insertable Half Wave Plate Setting
1074 tagindex = FindIndex("IGL1I00DI24_24M");
1075 if (tagindex != kEPICS_Error) {
1076 QwDebug << "tagindex for IGL1I00DI24_24M = " << tagindex << QwLog::endl;
1077
1078 if (! fEPICSCumulativeData[tagindex].Filled) {
1079 // No data for this run.
1080 tmp_row[slow_controls_settings.slow_helicity_plate] = sqlpp::null;
1081 } else if (fEPICSCumulativeData[tagindex].NumberRecords
1082 != fNumberEPICSEvents) {
1083 // Insertable Half Wave Plate Setting position changed
1084 QwWarning << "The value of "
1085 << fEPICSVariableList[tagindex]
1086 << " changed during the run."
1087 << "Send NULL word to the database."
1088 << QwLog::endl;
1089 tmp_row[slow_controls_settings.slow_helicity_plate] = sqlpp::null;
1090 }
1091 if(fEPICSDataEvent[tagindex].StringValue.Contains("***") ){
1092 QwWarning << "The value of "
1093 << fEPICSVariableList[tagindex]
1094 << " is not defined."
1095 << "Send NULL word to the database."
1096 << QwLog::endl;
1097 tmp_row[slow_controls_settings.slow_helicity_plate] = sqlpp::null;
1098 } else {
1099 // Insertable Half Wave Plate Setting position did not change
1100 // Insertable Half Wave Plate Setting setting is stored as a string with possible values
1101 // "OUT" and "IN".
1102 QwDebug << "Send the value of "
1103 << fEPICSVariableList[tagindex]
1104 << ", "
1105 << fEPICSDataEvent[tagindex].StringValue.Data()
1106 << ", to the database."
1107 << QwLog::endl;
1108 tmp_row[slow_controls_settings.slow_helicity_plate] = std::string(fEPICSDataEvent[tagindex].StringValue.Data());
1109 }
1110 }
1111
1112 // For IHWP2 Setting
1113 // IGL1I00DIOFLRD: Passive IHWP readback (13056=IN,8960=OUT)
1114 tagindex = FindIndex("IGL1I00DIOFLRD");
1115 if (tagindex != kEPICS_Error) {
1116 QwDebug << "tagindex for IGL1I00DIOFLRD = " << tagindex << QwLog::endl;
1117
1118 if (! fEPICSCumulativeData[tagindex].Filled) {
1119 // No data for this run.
1120 tmp_row[slow_controls_settings.passive_helicity_plate] = sqlpp::null;
1121 } else if (fEPICSCumulativeData[tagindex].NumberRecords
1122 != fNumberEPICSEvents) {
1123 // IHWP2 Setting position changed
1124 QwWarning << "The value of "
1125 << fEPICSVariableList[tagindex]
1126 << " changed during the run."
1127 << "Send NULL word to the database."
1128 << QwLog::endl;
1129 tmp_row[slow_controls_settings.passive_helicity_plate] = sqlpp::null;
1130 } else {
1131 Double_t ihwp2_readback = (fEPICSCumulativeData[tagindex].Sum)/
1132 ((Double_t) fEPICSCumulativeData[tagindex].NumberRecords);
1133 if (fabs(ihwp2_readback-13056)<1){
1134 // IHWP2 is IN
1135 QwDebug << "Send the value of "
1136 << fEPICSVariableList[tagindex]
1137 << ", "
1138 << fEPICSDataEvent[tagindex].StringValue.Data()
1139 << ", to the database."
1140 << QwLog::endl;
1141 tmp_row[slow_controls_settings.passive_helicity_plate] = std::string("in");
1142 } else if (fabs(ihwp2_readback-8960)<1){
1143 // IHWP2 is OUT
1144 QwDebug << "Send the value of "
1145 << fEPICSVariableList[tagindex]
1146 << ", "
1147 << fEPICSDataEvent[tagindex].StringValue.Data()
1148 << ", to the database."
1149 << QwLog::endl;
1150 tmp_row[slow_controls_settings.passive_helicity_plate] = std::string("out");
1151 } else {
1152 QwWarning << "The value of "
1153 << fEPICSVariableList[tagindex]
1154 << " is not defined."
1155 << "Send NULL word to the database."
1156 << QwLog::endl;
1157 tmp_row[slow_controls_settings.passive_helicity_plate] = sqlpp::null;
1158 }
1159 }
1160 }
1161
1162 // For Wien Setting
1163 tagindex = FindIndex("WienMode");
1164 if (tagindex != kEPICS_Error) {
1165 QwDebug << "tagindex for WienMode = " << tagindex << QwLog::endl;
1166
1167 if (! fEPICSCumulativeData[tagindex].Filled) {
1168 // No data for this run.
1169 tmp_row[slow_controls_settings.wien_reversal] = sqlpp::null;
1170 } else if (fEPICSCumulativeData[tagindex].NumberRecords
1171 != fNumberEPICSEvents) {
1172 // WienMode changed
1173 QwWarning << "The value of "
1174 << fEPICSVariableList[tagindex]
1175 << " changed during the run."
1176 << "Send NULL word to the database."
1177 << QwLog::endl;
1178 tmp_row[slow_controls_settings.wien_reversal] = sqlpp::null;
1179 }
1180 if(fEPICSDataEvent[tagindex].StringValue.Contains("***") ){
1181 QwWarning << "The value of "
1182 << fEPICSVariableList[tagindex]
1183 << " is not defined."
1184 << "Send NULL word to the database."
1185 << QwLog::endl;
1186 tmp_row[slow_controls_settings.wien_reversal] = sqlpp::null;
1187 } else {
1188 // WienMode is stored as an enum of the following labels:
1189 TString wien_enum[5] = {"indeterminate",
1190 "normal","reverse",
1191 "transverse_vertical",
1192 "transverse_horizontal"};
1193 QwDebug << "Send the value of "
1194 << fEPICSVariableList[tagindex]
1195 << ", "
1196 << fEPICSDataEvent[tagindex].StringValue.Data()
1197 << ", to the database."
1198 << QwLog::endl;
1199 tmp_row[slow_controls_settings.wien_reversal] =
1200 std::string(wien_enum[WienModeIndex(fEPICSDataEvent[tagindex].StringValue)].Data());
1201 }
1202 }
1203
1204 // For the precession reversal
1205 // This just uses the flag from the channel map to determine if the precession
1206 // is normal or reversed.
1208 tmp_row[slow_controls_settings.precession_reversal] = std::string("reverse");
1209 } else {
1210 tmp_row[slow_controls_settings.precession_reversal] = std::string("normal");
1211 }
1212
1213 // For charge feedback
1214
1215 tagindex = FindIndex("qw:ChargeFeedback");
1216 if (tagindex != kEPICS_Error) {
1217 //std::cout << "tagindex for qw:ChargeFeedback = " << tagindex << std::endl;
1218
1219 if (! fEPICSCumulativeData[tagindex].Filled) {
1220 // No data for this run.
1221 tmp_row[slow_controls_settings.charge_feedback] = sqlpp::null;
1222
1223 } else if (fEPICSCumulativeData[tagindex].NumberRecords
1224 != fNumberEPICSEvents) {
1225 // charge feedback status changed
1226 QwWarning << "The value of "
1227 << fEPICSVariableList[tagindex]
1228 << " changed during the run."
1229 << "Send NULL word to the database."
1230 << QwLog::endl;
1231 tmp_row[slow_controls_settings.charge_feedback] = sqlpp::null;
1232 }
1233
1234 if(fEPICSDataEvent[tagindex].StringValue.Contains("***") ){
1235 QwWarning << "The value of "
1236 << fEPICSVariableList[tagindex]
1237 << " is not defined."
1238 << "Send NULL word to the database."
1239 << QwLog::endl;
1240 tmp_row[slow_controls_settings.charge_feedback] = sqlpp::null;
1241 }
1242
1243 else {
1244 // charge feedback setting did not change
1245 // charge feedback setting is stored as a string with possible values
1246 // "on" and "off".
1247 QwDebug << "Send the value of "
1248 << fEPICSVariableList[tagindex]
1249 << ", "
1250 << fEPICSDataEvent[tagindex].StringValue.Data()
1251 << ", to the database."
1252 << QwLog::endl;
1253 TString tmpval = fEPICSDataEvent[tagindex].StringValue;
1254 tmpval.ToLower();
1255 tmp_row[slow_controls_settings.charge_feedback] = std::string(tmpval.Data());
1256 }
1257 }
1258
1259 ////////////////////////////////////////////////////////////
1260
1261 try {
1262 auto c = db->GetScopedConnection();
1263 QwDebug << "QwEPICSEvent::FillSlowControlsSettings Writing to database now" << QwLog::endl;
1264 c->QueryExecute(tmp_row.insert_into());
1265
1266 // Create the insert statement with required fields first
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
1270 );
1271 c->QueryExecute(insert_stmt);
1272 QwDebug << "QwEPICSEvent::FillSlowControlsSettings Successfully wrote to database" << QwLog::endl;
1273 } catch (const std::exception& er) {
1274 QwError << "Database exception: " << er.what() << QwLog::endl;
1275 }
1276 QwDebug << "Leaving QwEPICSEvent::FillSlowControlsSettings()" << QwLog::endl;
1277}
1278#endif //__USE_DATABASE__
1279
1281{
1282 Bool_t local_debug = false;
1283
1284 TList *string_list = new TList;
1285 string_list->SetOwner(true);
1286
1287 std::size_t tagindex = 0;
1288
1289 for (tagindex=0; tagindex<fEPICSVariableList.size(); tagindex++)
1290 {
1291 if (fEPICSVariableType[tagindex] == kEPICSString) {
1292
1293 TString epics_string = fEPICSVariableList[tagindex];
1294 epics_string += "---";
1295
1296 if (fEPICSDataEvent[tagindex].Filled) {
1297 epics_string += fEPICSDataEvent[tagindex].StringValue;
1298 }
1299 else {
1300 epics_string += "empty";
1301 }
1302 if(local_debug) {
1303 std::cout << "QwEPICSEvent::GetEPICSStringValues() "
1304 << epics_string
1305 << std::endl;
1306 }
1307 string_list -> Add(new TObjString(epics_string));
1308 }
1309 }
1310
1311 return string_list;
1312}
1313
1315{
1316 QwDebug << "Entering QwEPICSEvent::WriteEPICSStringValues()" << QwLog::endl;
1317
1318 Bool_t local_debug = false;
1319
1320 TSeqCollection *file_list = gROOT->GetListOfFiles();
1321
1322 if (file_list) {
1323
1324 Int_t size = file_list->GetSize();
1325 for (Int_t i=0; i<size; i++)
1326 {
1327 TFile *file = (TFile*) file_list->At(i);
1328
1329 if(local_debug) {
1330 std::cout << "QwEPICSEvent::WriteEPICSStringValue()"
1331 << file->GetName()
1332 << std::endl;
1333 }
1334
1335 TTree *slow_tree = (TTree*) file->Get("slow");
1336
1337 for (std::size_t tagindex=0; tagindex<fEPICSVariableList.size(); tagindex++)
1338 {
1339 // only String
1340 if (fEPICSVariableType[tagindex] == kEPICSString) {
1341
1342 TString name = fEPICSVariableList[tagindex];
1343 name.ReplaceAll(':','_'); // remove colons before creating branch
1344 TString name_type = name + "/C";\
1345
1346 Char_t epics_char[128];
1347 TString epics_string;
1348
1349 TBranch *new_branch = slow_tree->Branch(name, epics_char, name_type);
1350
1351 if (fEPICSDataEvent[tagindex].Filled) {
1352 epics_string = fEPICSDataEvent[tagindex].StringValue;
1353 }
1354 else {
1355 epics_string = "empty";
1356 }
1357
1358 if(local_debug) {
1359 std::cout << "QwEPICSEvent::WriteEPICSStringValue()\n";
1360 std::cout << name << " " << epics_string << std::endl;
1361 std::cout <<"\n";
1362 }
1363
1364 sprintf(epics_char, "%s", epics_string.Data());
1365 new_branch->Fill();
1366 }
1367
1368 }
1369
1370 file -> Write("", TObject::kOverwrite);
1371 }
1372 }
1373
1374 QwDebug << "Leaving QwEPICSEvent::WriteEPICSStringValues() normally" << QwLog::endl;
1375
1376 return;
1377
1378}
1379
1380
1382 Int_t ihwppolarity = 0;
1383 if (GetDataString("IGL1I00OD16_16")=="OUT"
1384 || GetDataString("IGL1I00OD16_16")=="0"){
1385 ihwppolarity = 1;
1386 } else if (GetDataString("IGL1I00OD16_16")=="IN"
1387 || GetDataString("IGL1I00OD16_16")=="1"){
1388 ihwppolarity = -1;
1389 } else {
1390 QwWarning << "IHWP state is not well defined: '"
1391 << GetDataString("IGL1I00OD16_16") << "'"
1392 << QwLog::endl;
1393 if (GetDataString("IGL1I00DI24_24M")=="OUT"
1394 || GetDataString("IGL1I00DI24_24M")=="1"){
1395 ihwppolarity = 1;
1396 } else if (GetDataString("IGL1I00DI24_24M")=="IN"
1397 || GetDataString("IGL1I00DI24_24M")=="0"){
1398 ihwppolarity = -1;
1399 } else {
1400 QwWarning << "IHWP state is not well defined: '"
1401 << GetDataString("IGL1I00DI24_24M") << "'"
1402 << QwLog::endl;
1403 }
1404 }
1405 QwDebug << "QwEPICSEvent::DetermineIHWPPolarity: "
1406 << "raw IHWP polarity is: "
1407 << ihwppolarity << QwLog::endl;
1408 ihwppolarity = fExtraHelicityReversal * ihwppolarity;
1409 QwDebug << "QwEPICSEvent::DetermineIHWPPolarity: "
1410 << "IHWP polarity after extra reversal is: "
1411 << ihwppolarity << QwLog::endl;
1412 return ihwppolarity;
1413}
1414
1417
1418 Double_t launchangle = 0.0;
1419
1420 Double_t vwienangle = GetDataValue("VWienAngle");
1421 Double_t phiangle = GetDataValue("Phi_FG");
1422 Double_t hwienangle = GetDataValue("HWienAngle");
1423 Double_t hoffset = 0.0;
1424 if (fabs(vwienangle)<10.0 && fabs(phiangle)<10.0){
1425 hoffset = 0.0;
1426 } else if (fabs(vwienangle)>80.0 && fabs(phiangle)>80.0
1427 && fabs(vwienangle+phiangle)<10. ){
1428 hoffset = -90.0;
1429 } else if (fabs(vwienangle)>80.0 && fabs(phiangle)>80.0
1430 && fabs(vwienangle+phiangle)>170. ){
1431 hoffset = +90.0;
1432 } else if (fabs(vwienangle)>80.0 && fabs(phiangle)<10.0) {
1433 wienmode = kWienVertTrans;
1434 }
1435 if (wienmode == kWienIndeterminate){
1436 launchangle = hoffset+hwienangle;
1437 Double_t long_proj =
1438 cos((launchangle-fNominalWienAngle)*TMath::DegToRad());
1439 if (long_proj > 0.5){
1440 wienmode = kWienForward;
1441 } else if (long_proj < -0.5){
1442 wienmode = kWienBackward;
1443 } else if (fabs(long_proj)<0.25){
1444 wienmode = kWienHorizTrans;
1445 }
1446 }
1447 return wienmode;
1448}
A logfile class, based on an identical class in the Hermes analyzer.
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
#define QwDebug
Predefined log drain for debugging output.
Definition QwLog.h:59
ROOT file and tree management wrapper classes.
Parameter file parsing and management.
EPICS data event handling and storage.
Basic data types and constants used throughout the Qweak analysis framework.
EQwWienMode WienModeIndex(TString name)
Definition QwTypes.cc:156
std::string WienModeName(EQwWienMode type)
Definition QwTypes.cc:150
EQwWienMode
Double Wien configuration.
Definition QwTypes.h:308
@ kWienIndeterminate
Definition QwTypes.h:309
@ kWienBackward
Definition QwTypes.h:311
@ kWienVertTrans
Definition QwTypes.h:312
@ kWienForward
Definition QwTypes.h:310
@ kWienHorizTrans
Definition QwTypes.h:313
Int_t AddEPICSTag(const string &tag, const string &table="", EQwEPICSDataType datatype=kEPICSFloat)
Bool_t fIsDataLoaded
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)
bool fDisableDatabase
virtual ~QwEPICSEvent()
Virtual destructor.
Double_t fNominalWienAngle
Bool_t IsNumber(const string &word)
static const int kDebug
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
size_t fTreeArrayIndex
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
Int_t fNumberEPICSEvents
void ResetCounters()
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.
Definition QwLog.cc:297
Command-line and configuration file options processor.
Definition QwOptions.h:141
T GetValue(const std::string &key)
Get a templated value.
Definition QwOptions.h:236
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
Definition QwOptions.h:170
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.
Definition QwRootFile.h:53
size_type size() const noexcept
Definition QwRootFile.h:81
std::string LeafList(size_type start_index=0) const
Definition QwRootFile.h:228
void push_back(const std::string &name, const char type='D')
Definition QwRootFile.h:195
void SetValue(size_type index, Double_t val)
Definition QwRootFile.h:108