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}
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.
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
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:55
size_type size() const noexcept
Definition QwRootFile.h:83
std::string LeafList(size_type start_index=0) const
Definition QwRootFile.h:230
void push_back(const std::string &name, const char type='D')
Definition QwRootFile.h:197
void SetValue(size_type index, Double_t val)
Definition QwRootFile.h:110