Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaEpics.cxx
Go to the documentation of this file.
1
2//
3// THaEpics
4// Hall A EPICS data.
5//
6// EPICS data come in two forms
7// (tag, value) e.g. (IPM1H04B.XPOS, 0.204)
8// and
9// (tag, value, units) e.g. (HELG0TSETTLEs, 500, usec)
10//
11// All data are received as characters and are parsed.
12// 'tags' remain characters, 'values' are either character
13// or double, and 'units' are characters.
14// Data are stored in an STL map and retrievable by
15// 'tag' (e.g. IPM1H04B.XPOS) and by proximity to
16// a physics event number (closest one is picked).
17//
18// Replaces THaEpicsStack (obsolete)
19//
20// author Robert Michaels (rom@jlab.org)
21//
23
24#include "THaEpics.h"
25#include <iostream>
26#include <string>
27#include <sstream>
28#ifdef __GLIBC__
29#include "Textvars.h" // for Podd::Tokenize
30#endif
31
32using namespace std;
33
34static int DEBUGL = 0; // FIXME: -> fDebug member variable
35
36namespace Decoder {
37
38//_____________________________________________________________________________
40{
41 // Convert dtime string (formatted as "%a %b %e %H:%M:%S %Z %Y", see
42 // strftime(3)) to Unix time.
43
44 struct tm ts{};
45 string dt{dtime};
46 timestamp = -1;
47#ifdef __GLIBC__
48 // Simple workaround for lack of time zone support in Linux's strptime.
49 // This assumes that the current machine's local time zone is the same as
50 // that of the time stamp. Doing better than this is complicated since the
51 // time stamp encodes the time zone as a letter abbreviation (e.g. "EDT"),
52 // not a numerical offset (e.g. -0400), and there seems to be no library
53 // support under Linux for looking up the latter from the former.
54 vector<string> tok;
55 Podd::Tokenize(dtime, " ", tok);
56 if( tok.size() != 6 )
57 return;
58 dt = tok[0]+" "+tok[1]+" "+tok[2]+" "+tok[3]+" "+tok[5];
59 const char* r = strptime(dt.c_str(), "%a %b %e %H:%M:%S %Y", &ts);
60 ts.tm_isdst = -1;
61#else
62 const char* r = strptime(dt.c_str(), "%a %b %e %H:%M:%S %Z %Y", &ts);
63#endif
64 if( !r || r-dt.c_str()-dt.length() != 0 )
65 return;
66 timestamp = mktime(&ts);
67}
68
69//_____________________________________________________________________________
71{
72 cout << "\n\n====================== \n";
73 cout << "Print of Epics Data : "<<endl;
74 Int_t j = 0;
75 for( auto& pm : epicsData ) {
76 const vector<EpicsChan>& vepics = pm.second;
77 const string& tag = pm.first;
78 j++;
79 cout << "\n\nEpics Var #" << j;
80 cout << " Var Name = \""<<tag<<"\""<<endl;
81 cout << "Size of epics vector "<<vepics.size();
82 for( const auto& chan : vepics ) {
83 cout << "\n Tag = " << chan.GetTag();
84 cout << " Evnum = " << chan.GetEvNum();
85 cout << " Date = " << chan.GetDate();
86 cout << " Timestamp = " << chan.GetTimeStamp();
87 cout << " Data = " << chan.GetData();
88 cout << " String = " << chan.GetString();
89 cout << " Units = " << chan.GetUnits();
90 }
91 cout << endl;
92 }
93}
94
95//_____________________________________________________________________________
96Bool_t THaEpics::IsLoaded(const char* tag) const
97{
98 const vector<EpicsChan> ep = GetChan(tag);
99 return !ep.empty();
100}
101
102//_____________________________________________________________________________
103Double_t THaEpics::GetData ( const char* tag, UInt_t event) const
104{
105 const vector<EpicsChan> ep = GetChan(tag);
106 UInt_t k = FindEvent(ep, event);
107 if( k == kMaxUInt ) return 0;
108 return ep[k].GetData();
109}
110
111//_____________________________________________________________________________
112string THaEpics::GetString ( const char* tag, UInt_t event) const
113{
114 const vector<EpicsChan> ep = GetChan(tag);
115 UInt_t k = FindEvent(ep, event);
116 if( k == kMaxUInt ) return "";
117 return ep[k].GetString();
118}
119
120//_____________________________________________________________________________
121time_t THaEpics::GetTimeStamp( const char* tag, UInt_t event) const
122{
123 const vector<EpicsChan> ep = GetChan(tag);
124 UInt_t k = FindEvent(ep, event);
125 if( k == kMaxUInt ) return 0;
126 return ep[k].GetTimeStamp();
127}
128
129//_____________________________________________________________________________
130vector<EpicsChan> THaEpics::GetChan(const char *tag) const
131{
132 // Return the vector of Epics data for 'tag'
133 // where 'tag' is the name of the Epics variable.
134 auto pm = epicsData.find(string(tag));
135 if (pm != epicsData.end())
136 return pm->second;
137 else
138 return {};
139}
140
141//_____________________________________________________________________________
142UInt_t THaEpics::FindEvent( const vector<EpicsChan>& ep, UInt_t event )
143{
144 // Return the index in the vector of Epics data
145 // nearest in event number to event 'event'.
146 if (ep.empty())
147 return kMaxUInt;
148 UInt_t myidx = ep.size()-1;
149 if (event == 0) return myidx; // return last event
150 Long64_t min = 9999999;
151 for( size_t k = 0; k < ep.size(); k++ ) {
152 Long64_t diff = event - ep[k].GetEvNum();
153 if( diff < 0 ) diff = -diff;
154 if( diff < min ) {
155 min = diff;
156 myidx = k;
157 }
158 }
159 return myidx;
160}
161
162//_____________________________________________________________________________
163int THaEpics::LoadData( const UInt_t* evbuffer, UInt_t event)
164{
165 // load data from the event buffer 'evbuffer'
166 // for event nearest 'evnum'.
167
168 const string::size_type MAX_VAL_LEN = 32;
169
170 const char* cbuff = (const char*)evbuffer;
171 size_t len = sizeof(UInt_t)*(evbuffer[0]+1);
172 if (DEBUGL>1) cout << "Enter loadData, len = "<<len<<endl;
173 if( len<16 ) return 0;
174 // The first 16 bytes of the buffer are the event header
175 len -= 16;
176 cbuff += 16;
177
178 // Copy data to internal string buffer
179 string buf( cbuff, len );
180
181 // The first line is the time stamp
182 string date;
183 istringstream ib(buf);
184 if( !getline(ib,date) || date.size() < 16 ) {
185 cerr << "Invalid time stamp for EPICS event at evnum = " << event << endl;
186 return 0;
187 }
188 if(DEBUGL>1) cout << "Timestamp: " << date <<endl;
189
190 string line;
191 istringstream il, iv;
192 while( getline(ib,line) ) {
193 // Here we parse each line
194 if(DEBUGL>2) cout << "epics line : "<<line<<endl;
195 il.clear(); il.str(line);
196 string wtag, wval, wunits;
197 il >> wtag;
198 if( wtag.empty() || wtag[0] == 0 ) continue;
199 istringstream::pos_type spos = il.tellg();
200 il >> wval;
201 Double_t dval = 0;
202 bool got_val = false;
203 if( !wval.empty() && wval.length() <= MAX_VAL_LEN ) {
204 iv.clear(); iv.str(wval);
205 if( iv >> dval )
206 got_val = true;
207 }
208 if( got_val ) {
209 il >> wunits; // Assumes that wunits contains no whitespace
210 } else {
211 // Mimic the old behavior: if the string doesn't convert to a number,
212 // then wval = rest of string after tag, dval = 0, sunit = empty
213 string::size_type lpos = line.find_first_not_of(" \t",spos);
214 wval = ( lpos != string::npos ) ? line.substr(lpos) : "";
215 dval = 0;
216 }
217 if(DEBUGL>2) cout << "wtag = "<<wtag<<" wval = "<<wval
218 << " dval = "<<dval<<" wunits = "<<wunits<<endl;
219
220 // Add tag/value/units to the EPICS data.
221 epicsData[wtag].push_back( EpicsChan(wtag, date, event, wval, wunits, dval) );
222 }
223 if(DEBUGL) Print();
224 return 1;
225}
226
227}
228
int Int_t
unsigned int UInt_t
uint32_t chan
ROOT::R::TRInterface & r
bool Bool_t
const UInt_t kMaxUInt
double Double_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
static int DEBUGL
Definition THaEpics.cxx:34
std::string dtime
Definition THaEpics.h:47
static UInt_t FindEvent(const std::vector< EpicsChan > &ep, UInt_t event)
Definition THaEpics.cxx:142
Double_t GetData(const char *tag, UInt_t event=0) const
Definition THaEpics.cxx:103
std::map< std::string, std::vector< EpicsChan > > epicsData
Definition THaEpics.h:74
std::string GetString(const char *tag, UInt_t event=0) const
Definition THaEpics.cxx:112
Int_t LoadData(const UInt_t *evbuffer, UInt_t event=0)
Definition THaEpics.cxx:163
time_t GetTimeStamp(const char *tag, UInt_t event=0) const
Definition THaEpics.cxx:121
std::vector< EpicsChan > GetChan(const char *tag) const
Definition THaEpics.cxx:130
Bool_t IsLoaded(const char *tag) const
Definition THaEpics.cxx:96
long long Long64_t
TLine * line
double min(double x, double y)
STL namespace.
ClassImp(TPyArg)