Line data Source code
1 : /** \file logMeta.hpp
2 : * \brief Declares and defines the logMeta class and related classes.
3 : * \author Jared R. Males (jaredmales@gmail.com)
4 : *
5 : * \ingroup logger_files
6 : *
7 : * History:
8 : * - 2020-01-02 created by JRM
9 : */
10 :
11 : #ifndef logger_logMeta_hpp
12 : #define logger_logMeta_hpp
13 :
14 : #include <mx/ioutils/fits/fitsHeaderCard.hpp>
15 : // #define HARD_EXIT
16 : #include "logMap.hpp"
17 :
18 : namespace MagAOX
19 : {
20 : namespace logger
21 : {
22 :
23 : // This is how the user specifies an item of log meta data (i.e. via a config file)
24 : struct logMetaSpec
25 : {
26 : std::string device;
27 : flatlogs::eventCodeT eventCode;
28 : std::string member;
29 : std::string keyword; // overrides the default
30 : std::string format; // overrides the default
31 : std::string comment; // overrides the default
32 :
33 0 : logMetaSpec()
34 0 : {
35 0 : }
36 :
37 : logMetaSpec( const std::string &dev,
38 : const flatlogs::eventCodeT ec,
39 : const std::string &memb,
40 : const std::string &k,
41 : const std::string &f,
42 : const std::string &c )
43 : : device( dev ), eventCode( ec ), member( memb ), keyword( k ), format( f ), comment( c )
44 : {
45 : }
46 :
47 0 : logMetaSpec( const std::string &dev, const flatlogs::eventCodeT ec, const std::string &memb )
48 0 : : device( dev ), eventCode( ec ), member( memb )
49 : {
50 0 : }
51 : };
52 :
53 : // This is the data returned by the member accessor.
54 : struct logMetaDetail
55 : {
56 : std::string keyword;
57 : std::string comment;
58 : std::string format;
59 : int valType{ -1 };
60 : int metaType{ -1 };
61 : void *accessor{ nullptr };
62 : bool hierarch{ true }; // if false the device name is not included.
63 :
64 55 : logMetaDetail()
65 55 : {
66 55 : }
67 :
68 : logMetaDetail( const std::string &k, const std::string &c, const std::string &f, int vt, int mt, void *acc )
69 : : keyword( k ), comment( c ), format( f ), valType( vt ), metaType( mt ), accessor( acc )
70 : {
71 : }
72 :
73 0 : logMetaDetail( const std::string &k, const std::string &c, const std::string &f, int vt, int mt, void *acc, bool h )
74 0 : : keyword( k ), comment( c ), format( f ), valType( vt ), metaType( mt ), accessor( acc ), hierarch( h )
75 : {
76 0 : }
77 :
78 0 : logMetaDetail( const std::string &k, const std::string &c, int vt, int mt, void *acc, bool h )
79 0 : : keyword( k ), comment( c ), valType( vt ), metaType( mt ), accessor( acc ), hierarch( h )
80 : {
81 0 : }
82 :
83 0 : logMetaDetail( const std::string &k, int vt, int mt, void *acc )
84 0 : : keyword( k ), valType( vt ), metaType( mt ), accessor( acc )
85 : {
86 0 : }
87 :
88 0 : logMetaDetail( const std::string &k, int vt, int mt, void *acc, bool h )
89 0 : : keyword( k ), valType( vt ), metaType( mt ), accessor( acc ), hierarch( h )
90 : {
91 0 : }
92 : };
93 :
94 :
95 : /*logMetaDetail logMemberAccessor( flatlogs::eventCodeT ec,
96 : const std::string & memberName
97 : );
98 : */
99 :
100 : template <typename valT, class verboseT = XWC_DEFAULT_VERBOSITY>
101 0 : int getLogStateVal( valT &val,
102 : logMap<verboseT> &lm,
103 : const std::string &appName,
104 : flatlogs::eventCodeT ev,
105 : const flatlogs::timespecX &stime,
106 : const flatlogs::timespecX &atime,
107 : valT ( *getter )( void * ),
108 : char **hint = 0 )
109 : {
110 0 : char *atprior = nullptr;
111 0 : char *stprior = nullptr;
112 :
113 0 : char *_hint = nullptr;
114 :
115 0 : if( hint )
116 0 : _hint = *hint;
117 : else
118 0 : _hint = 0;
119 :
120 : #ifdef DEBUG
121 : std::cerr << __FILE__ << " " << __LINE__ << "\n";
122 : #endif
123 :
124 0 : if( lm.getPriorLog( stprior, appName, ev, stime, _hint ) != 0 )
125 : {
126 0 : std::cerr << __FILE__ << " " << __LINE__ << " getPriorLog returned error for " << appName << ":" << ev << "\n";
127 0 : return -1;
128 : }
129 0 : valT stprV = getter( flatlogs::logHeader::messageBuffer( stprior ) );
130 :
131 0 : valT atprV;
132 :
133 : #ifdef DEBUG
134 : std::cerr << __FILE__ << " " << __LINE__ << "\n";
135 : #endif
136 :
137 0 : if( lm.getNextLog( atprior, stprior, appName ) != 0 )
138 : {
139 0 : std::cerr << __FILE__ << " " << __LINE__ << " getNextLog returned error for " << appName << ":" << ev << "\n";
140 0 : return -1;
141 : }
142 :
143 : #ifdef DEBUG
144 : std::cerr << __FILE__ << " " << __LINE__ << "\n";
145 : #endif
146 :
147 0 : while( flatlogs::logHeader::timespec( atprior ) < atime )
148 : {
149 0 : atprV = getter( flatlogs::logHeader::messageBuffer( atprior ) );
150 0 : if( atprV != stprV )
151 : {
152 0 : val = atprV;
153 0 : if( hint )
154 0 : *hint = stprior;
155 0 : return 0;
156 : }
157 0 : stprior = atprior;
158 0 : if( lm.getNextLog( atprior, stprior, appName ) != 0 )
159 : {
160 0 : std::cerr << __FILE__ << " " << __LINE__ << " getNextLog returned error for " << appName << ":" << ev
161 0 : << "\n";
162 0 : return -1;
163 : }
164 : }
165 :
166 0 : val = stprV;
167 :
168 0 : if( hint )
169 0 : *hint = stprior;
170 0 : return 0;
171 0 : }
172 :
173 : template <typename valT, class verboseT = XWC_DEFAULT_VERBOSITY>
174 0 : int getLogContVal( valT &val,
175 : logMap<verboseT> &lm,
176 : const std::string &appName,
177 : flatlogs::eventCodeT ev,
178 : const flatlogs::timespecX &stime,
179 : const flatlogs::timespecX &atime,
180 : valT ( *getter )( void * ),
181 : char **hint = 0 )
182 : {
183 : char *atafter;
184 : char *stprior;
185 :
186 : char *_hint;
187 0 : if( hint )
188 0 : _hint = *hint;
189 : else
190 0 : _hint = 0;
191 :
192 0 : flatlogs::timespecX midexp = meanTimespecX( atime, stime );
193 :
194 : // Get log entry before midexp
195 0 : if( lm.getPriorLog( stprior, appName, ev, midexp, _hint ) != 0 )
196 : {
197 0 : std::cerr << __FILE__ << " " << __LINE__ << " getPriorLog returned error for " << appName << ":" << ev << "\n";
198 0 : return 1;
199 : }
200 0 : valT stprV = getter( flatlogs::logHeader::messageBuffer( stprior ) );
201 :
202 : // Get log entry after.
203 0 : if( lm.getNextLog( atafter, stprior, appName ) != 0 )
204 : {
205 0 : std::cerr << __FILE__ << " " << __LINE__ << " getNextLog returned error for " << appName << ":" << ev << "\n";
206 : #ifdef HARD_EXIT
207 : exit( -1 );
208 : #endif
209 0 : return 1;
210 : }
211 0 : valT atprV = getter( flatlogs::logHeader::messageBuffer( atafter ) );
212 :
213 0 : double st = flatlogs::logHeader::timespec( stprior ).asDouble();
214 0 : double it = midexp.asDouble();
215 0 : double et = flatlogs::logHeader::timespec( atafter ).asDouble();
216 :
217 0 : val = stprV + ( atprV - stprV ) / ( et - st ) * ( it - st );
218 :
219 0 : if( hint )
220 0 : *hint = stprior;
221 :
222 0 : return 0;
223 : }
224 :
225 : /// Manage meta data for a log entry
226 : /** Handles cases where log is a state, i.e. has one of a finite number of values, or is a
227 : * continuous variable, e.g. a temperature.
228 : *
229 : * Contains the information to construct a FITS header card.
230 : */
231 : struct logMeta
232 : {
233 : typedef XWC_DEFAULT_VERBOSITY verboseT;
234 :
235 : public:
236 : enum valTypes
237 : {
238 : String = mx::fits::fitsType<std::string>(),
239 : Bool = mx::fits::fitsType<bool>(),
240 : Char = mx::fits::fitsType<char>(),
241 : UChar = mx::fits::fitsType<unsigned char>(),
242 : Short = mx::fits::fitsType<short>(),
243 : UShort = mx::fits::fitsType<unsigned short>(),
244 : Int = mx::fits::fitsType<int>(),
245 : UInt = mx::fits::fitsType<unsigned int>(),
246 : Long = mx::fits::fitsType<long>(),
247 : ULong = mx::fits::fitsType<unsigned long>(),
248 : LongLong = mx::fits::fitsType<long long>(),
249 : ULongLong = mx::fits::fitsType<unsigned long long>(),
250 : Float = mx::fits::fitsType<float>(),
251 : Double = mx::fits::fitsType<double>(),
252 : Vector_String = 10000,
253 : Vector_Bool = 10002,
254 : Vector_Char = 10004,
255 : Vector_UChar = 10006,
256 : Vector_Short = 10008,
257 : Vector_UShort = 10010,
258 : Vector_Int = 10012,
259 : Vector_UInt = 10014,
260 : Vector_Long = 10016,
261 : Vector_ULong = 10018,
262 : Vector_LongLong = 10020,
263 : Vector_ULongLong = 10022,
264 : Vector_Float = 10024,
265 : Vector_Double = 10026
266 : };
267 :
268 : enum metaTypes
269 : {
270 : State,
271 : Continuous
272 : };
273 :
274 : protected:
275 : logMetaSpec m_spec;
276 : logMetaDetail m_detail;
277 :
278 : bool m_isValid{ false };
279 : std::string m_invalidValue{ "invalid" };
280 :
281 : char *m_hint{ nullptr };
282 :
283 : public:
284 : logMeta( const logMetaSpec &lms /**< [in] the specification of this meta data entry */ );
285 :
286 : const std::string &device();
287 : const std::string &keyword();
288 :
289 : const std::string &comment();
290 :
291 : int setLog( const logMetaSpec & );
292 :
293 : std::string value( logMap<verboseT> &lm, const flatlogs::timespecX &stime, const flatlogs::timespecX &atime );
294 :
295 : std::string valueNumber( logMap<verboseT> &lm, const flatlogs::timespecX &stime, const flatlogs::timespecX &atime );
296 :
297 : std::string valueString( logMap<verboseT> &lm, const flatlogs::timespecX &stime, const flatlogs::timespecX &atime );
298 :
299 : mx::fits::fitsHeaderCard<verboseT>
300 : card( logMap<verboseT> &lm, const flatlogs::timespecX &stime, const flatlogs::timespecX &atime );
301 : };
302 :
303 : } // namespace logger
304 : } // namespace MagAOX
305 :
306 : #endif // logger_logMeta_hpp
|