7 #ifndef indiTSAccumulator_hpp
8 #define indiTSAccumulator_hpp
12 #include "../../libMagAOX/libMagAOX.hpp"
13 #include "../../magaox_git_version.h"
131 config.add(
"elements",
"",
"elements", argType::Required,
"",
"elements",
false,
"vector<string>",
"Comma separated List of elements specified as device.property.element.");
136 std::vector<std::string> elements;
137 _config(elements,
"elements");
139 if(elements.size() < 1)
146 for(
size_t n = 0; n < elements.size(); ++n)
148 size_t p1 = elements[n].find(
'.');
149 if(p1 == std::string::npos)
155 size_t p2 = elements[n].find(
'.', p1+1);
156 if(p2 == std::string::npos)
165 std::string devName = elements[n].substr(0,p1);
166 std::string propName = elements[n].substr(p1+1, p2-p1-1);
167 std::string elName = elements[n].substr(p2+1);
168 std::string key = devName +
"." + propName;
174 catch(
const std::exception& e)
176 log<software_critical>({__FILE__, __LINE__, std::string(
"Exception caught: ") + e.what() +
" [on element " + std::to_string(n) +
"]"});
195 std::string devName =
it->second.m_property.getDevice();
196 std::string propName =
it->second.m_property.getName();
199 log<software_critical>({__FILE__, __LINE__,
"Error inserting property: " + devName +
"." + propName});
203 for(
size_t n=0; n <
it->second.m_elements.size(); ++n)
205 it->second.m_elements[n].m_imageStream = (IMAGE *) malloc(
sizeof(IMAGE));
207 uint32_t imsize[3] = {0,0,0};
211 std::string shmimName = devName +
"." + propName +
"." +
it->second.m_elements[n].m_name;
213 std::cerr <<
"Creating: " << shmimName <<
" " << imsize[0] <<
" " << imsize[1] <<
" " << imsize[2] <<
"\n";
215 ImageStreamIO_createIm_gpu(
it->second.m_elements[n].m_imageStream, shmimName.c_str(), 3, imsize,
IMAGESTRUCT_FLOAT, -1, 1, IMAGE_NB_SEMAPHORE, 0, CIRCULAR_BUFFER | ZAXIS_TEMPORAL, 0);
217 it->second.m_elements[n].m_imageStream->md->cnt1 =
it->second.m_elements[n].m_imageStream->md->size[2] - 1;
219 it->second.m_elements[n].m_imageStream->md->atime = {0,0};
220 it->second.m_elements[n].m_imageStream->md->writetime = {0,0};
222 for(
size_t m = 0; m <
it->second.m_elements[n].m_imageStream->md->size[2]; ++m )
224 it->second.m_elements[n].m_imageStream->cntarray[m] = std::numeric_limits<uint64_t>::max();
225 it->second.m_elements[n].m_imageStream->atimearray[m] = {0,0};
226 it->second.m_elements[n].m_imageStream->writetimearray[m] = {0,0};
246 std::string key =
ipRecv.createUniqueKey();
249 if(
ipRecv.getType() != pcf::IndiProperty::Number)
251 log<text_log>(key +
" is not a Number property. Can't time-series this.",
logPrio::LOG_WARNING);
256 for(
size_t n=0; n <
m_properties[key].m_elements.size(); ++n)
260 IMAGE * image =
m_properties[key].m_elements[n].m_imageStream;
264 log<software_error>({__FILE__, __LINE__,
"Image for " + key +
"." +
m_properties[key].m_elements[n].m_name +
" is nullptr"});
269 ts.tv_sec =
ipRecv.getTimeStamp().getTimeValSecs();
270 ts.tv_nsec =
ipRecv.getTimeStamp().getTimeValMicros()*1000;
272 if(ts.tv_sec != image->md->atime.tv_sec || ts.tv_nsec != image->md->atime.tv_nsec)
278 uint64_t cnt1 = image->md->cnt1 + 1;
279 if(cnt1 >= image->md->size[2]) cnt1 = 0;
285 clock_gettime(CLOCK_REALTIME, &image->md->writetime);
286 image->writetimearray[cnt1] = image->md->writetime;
288 image->md->atime = ts;
289 image->atimearray[cnt1] = ts;
292 image->array.F[cnt1] = val;
296 image->cntarray[cnt1] = image->md->cnt0;
297 image->md->cnt1 = cnt1;
301 ImageStreamIO_sempost(image,-1);
302 std::cerr <<
ipRecv.createUniqueKey() <<
" " << ts.tv_sec <<
" " << ts.tv_nsec <<
"\n";
#define IMAGESTRUCT_FLOAT
The base-class for MagAO-X applications.
int m_shutdown
Flag to signal it's time to shutdown. When not 0, the main loop exits.
int registerIndiPropertySet(pcf::IndiProperty &prop, const std::string &devName, const std::string &propName, int(*)(void *, const pcf::IndiProperty &))
Register an INDI property which is monitored for updates from others.
The MagAO-X indiTSAccumulator.
virtual int appStartup()
Startup function.
int setCallBack_all(const pcf::IndiProperty &ipRecv)
~indiTSAccumulator() noexcept
D'tor, declared and defined for noexcept.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
virtual void setupConfig()
indiTSAccumulator()
Default c'tor.
std::vector< element > m_elements
virtual int appLogic()
Implementation of the FSM for indiTSAccumulator.
std::map< std::string, property > m_properties
friend class indiTSAccumulator_test
virtual void loadConfig()
pcf::IndiProperty m_property
virtual int appShutdown()
Shutdown the app.
static int st_setCallBack_all(void *app, const pcf::IndiProperty &ipRecv)
const pcf::IndiProperty & ipRecv
constexpr static logPrioT LOG_CRITICAL
The process can not continue and will shut down (fatal)
constexpr static logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
element(const std::string &el)