10 #include <mx/improc/eigenCube.hpp>
11 #include <mx/ioutils/fits/fitsFile.hpp>
12 #include <mx/improc/eigenImage.hpp>
13 #include <mx/ioutils/stringUtils.hpp>
14 #include <mx/sys/timeUtils.hpp>
16 #include "../../libMagAOX/libMagAOX.hpp"
17 #include "../../magaox_git_version.h"
159 config.add(
"dm.modeCube",
"",
"dm.modeCube", argType::Required,
"dm",
"modeCube",
false,
"string",
"Full path to the FITS file containing the modes for this DM.");
160 config.add(
"dm.maxModes",
"",
"dm.maxModes", argType::Required,
"dm",
"maxModes",
false,
"int",
"The maximum number of modes to use (truncates the cube). If <=0 all modes in cube are used.");
161 config.add(
"dm.name",
"",
"dm.name", argType::Required,
"dm",
"name",
false,
"string",
"The descriptive name of this dm. Default is the channel name.");
162 config.add(
"dm.channelName",
"",
"dm.channelName", argType::Required,
"dm",
"channelName",
false,
"string",
"The name of the DM channel to write to.");
163 config.add(
"dm.maxModes",
"",
"dm.maxModes", argType::Required,
"dm",
"maxModes",
false,
"int",
"The maximum number of modes to use (truncates the cube).");
194 mx::fits::fitsFile<realT> ff;
203 mx::improc::eigenCube<realT> modes;
206 for(
int p =0; p < modes.planes(); ++p) modes.image(p) =
m_modes.image(p);
208 for(
int p =0; p < modes.planes(); ++p)
m_modes.image(p) = modes.image(p);
227 for(
size_t n=0; n <
m_amps.size(); ++n)
230 m_elNames[n] = mx::ioutils::convertToString<size_t, 4, '0'>(n);
313 log<software_error>({__FILE__, __LINE__});
338 for(
size_t n = 1; n<
m_amps.size(); ++n)
369 for(
size_t n = 0; n<
m_amps.size(); ++n)
382 if (
ipRecv.getName() == m_indiP_currAmps.getName())
385 for(
size_t n=0; n < m_amps.size(); ++n)
387 if(
ipRecv.find(m_elNames[n]))
389 realT amp =
ipRecv[m_elNames[n]].get<realT>();
400 return sendCommand();
407 return log<
software_error,-1>({__FILE__,__LINE__,
"invalid indi property name"});
412 if (
ipRecv.getName() == m_indiP_tgtAmps.getName())
415 for(
size_t n=0; n < m_amps.size(); ++n)
417 if(
ipRecv.find(m_elNames[n]))
419 realT amp =
ipRecv[m_elNames[n]].get<realT>();
430 return sendCommand();
437 return log<
software_error,-1>({__FILE__,__LINE__,
"invalid indi property name"});
452 static std::vector<float> lastamps(
m_amps.size(), std::numeric_limits<float>::max());
454 bool changed =
false;
455 for(
size_t p=0; p <
m_amps.size(); ++p)
457 if(
m_amps[p] != lastamps[p]) changed =
true;
460 if( changed || force )
462 for(
size_t p=0; p <
m_amps.size(); ++p)
The base-class for MagAO-X applications.
stateCodes::stateCodeT state()
Get the current state code.
int m_shutdown
Flag to signal it's time to shutdown. When not 0, the main loop exits.
indiDriver< MagAOXApp > * m_indiDriver
The INDI driver wrapper. Constructed and initialized by execute, which starts and stops communication...
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
The MagAO-X DM mode commander.
std::string m_dmChannelName
uint32_t m_width
The width of the image.
mx::improc::eigenCube< realT > m_modes
virtual int appShutdown()
Shutdown the app.
int recordDmModes(bool force=false)
INDI_NEWCALLBACK_DECL(dmMode, m_indiP_currAmps)
pcf::IndiProperty m_indiP_currAmps
dev::telemeter< dmMode > telemeterT
mx::improc::eigenImage< realT > m_shape
size_t m_typeSize
The size of the type, in bytes.
pcf::IndiProperty m_indiP_dm
std::vector< realT > m_amps
~dmMode() noexcept
D'tor, declared and defined for noexcept.
uint32_t m_height
The height of the image.
INDI_NEWCALLBACK_DECL(dmMode, m_indiP_tgtAmps)
virtual int appLogic()
Implementation of the FSM for dmMode.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
uint8_t m_dataType
The ImageStreamIO type code.
virtual int appStartup()
Startup function.
virtual void setupConfig()
virtual void loadConfig()
int recordTelem(const telem_dmmodes *)
std::vector< std::string > m_elNames
pcf::IndiProperty m_indiP_tgtAmps
#define REG_INDI_NEWPROP_NOCB(prop, propName, type)
Register a NEW INDI property with the class, with no callback.
#define REG_INDI_NEWPROP(prop, propName, type)
Register a NEW INDI property with the class, using the standard callback name.
@ READY
The device is ready for operation, but is not operating.
@ CONNECTED
The application has connected to the device or service.
@ NOTCONNECTED
The application is not connected to the device or service.
const pcf::IndiProperty & ipRecv
INDI_NEWCALLBACK_DEFN(acesxeCtrl, m_indiP_windspeed)(const pcf
constexpr static logPrioT LOG_CRITICAL
The process can not continue and will shut down (fatal)
constexpr static logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
constexpr static logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
A device base class which saves telemetry.
int appShutdown()
Perform telemeter application shutdown.
int loadConfig(appConfigurator &config)
Load the device section from an application configurator.
int appLogic()
Perform telemeter application logic.
int setupConfig(appConfigurator &config)
Setup an application configurator for the device section.
int appStartup()
Starts the telemetry log thread.
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
The type of the input message.
Log entry recording DM Mode Amplitudes.
A simple text log, a string-type log.