API
 
Loading...
Searching...
No Matches
openLoopPSDs.hpp
Go to the documentation of this file.
1/** \file openLoopPSDs.hpp
2 * \brief The MagAO-X openLoopPSDs app header file
3 *
4 * \ingroup openLoopPSDs_files
5 */
6
7#ifndef openLoopPSDs_hpp
8#define openLoopPSDs_hpp
9
10
11#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
12#include "../../magaox_git_version.h"
13
14#include <mx/sigproc/circularBuffer.hpp>
15#include <mx/sigproc/signalWindows.hpp>
16
17#include <mx/math/fft/fftwEnvironment.hpp>
18#include <mx/math/fft/fft.hpp>
19
20/** \defgroup openLoopPSDs
21 * \brief An application to calculate rolling PSDs of modal amplitudes
22 *
23 * <a href="../handbook/operating/software/apps/openLoopPSDs.html">Application Documentation</a>
24 *
25 * \ingroup apps
26 *
27 */
28
29/** \defgroup openLoopPSDs_files
30 * \ingroup openLoopPSDs
31 */
32
33namespace MagAOX
34{
35namespace app
36{
37
38/// Class for application to calculate rolling PSDs of modal amplitudes.
39/**
40 * \ingroup openLoopPSDs
41 */
42class openLoopPSDs : public MagAOXApp<true>, public dev::shmimMonitor<openLoopPSDs>
43{
44 friend class dev::shmimMonitor<openLoopPSDs>;
45
46public:
47
48 typedef float realT;
49 typedef std::complex<realT> complexT;
50
51 /// The base shmimMonitor type
53
54 /// The amplitude circular buffer type
55 typedef mx::sigproc::circularBufferIndex<float *, unsigned> ampCircBuffT;
56
57protected:
58
59 /** \name Configurable Parameters
60 *@{
61 */
62
63 std::string m_clPSDSource; ///< Device name for getting the C.L. PSDs. This is used as the shmim name (unless overriden) and this INDI device should have *.fps.current.
64
65 int m_nPSDHistory {100}; //
66
67 ///@}
68
69 int m_nModes; ///< the number of modes to calculate PSDs for.
70
73
74 std::vector<realT> m_freq;
75
76 IMAGE * m_olpsdStream {nullptr};
77
78public:
79 /// Default c'tor.
81
82 /// D'tor, declared and defined for noexcept.
85
86 virtual void setupConfig();
87
88 /// Implementation of loadConfig logic, separated for testing.
89 /** This is called by loadConfig().
90 */
91 int loadConfigImpl( mx::app::appConfigurator & _config /**< [in] an application configuration from which to load values*/);
92
93 virtual void loadConfig();
94
95 /// Startup function
96 /**
97 *
98 */
99 virtual int appStartup();
100
101 /// Implementation of the FSM for openLoopPSDs.
102 /**
103 * \returns 0 on no critical error
104 * \returns -1 on an error requiring shutdown
105 */
106 virtual int appLogic();
107
108 /// Shutdown the app.
109 /**
110 *
111 */
112 virtual int appShutdown();
113
114 //shmimMonitor Interface
115protected:
116
117 int allocate( const dev::shmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
118
120
121 int processImage( void * curr_src, ///< [in] pointer to start of current frame.
122 const dev::shmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
123 );
124
125
126 //INDI Interface
127protected:
128
129 pcf::IndiProperty m_indiP_clPSDSource;
131
132 pcf::IndiProperty m_indiP_fps;
133
134};
135
136openLoopPSDs::openLoopPSDs() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
137{
138
139 return;
140}
141
143{
145
146 config.add("psds.clPSDSource", "", "psds.clPSDSource", argType::Required, "psds", "clPSDSource", false, "string", "Device name for getting the C.L. PSDs. This is used as the shmim name (unless overriden) and this INDI device should have *.fps.current.");
147}
148
149int openLoopPSDs::loadConfigImpl( mx::app::appConfigurator & _config )
150{
151 _config(m_clPSDSource, "psds.clPSDSource");
152
155
156
157 return 0;
158}
159
161{
162 loadConfigImpl(config);
163}
164
166{
167 if(m_clPSDSource != "")
168 {
170 }
171 else
172 {
173 log<text_log>("must specify psds.clPSDSource\n", logPrio::LOG_ERROR);
174 m_shutdown = 1;
175 return -1;
176 }
177
178 createROIndiNumber( m_indiP_fps, "fps", "current", "Circular Buffer");
179 m_indiP_fps.add(pcf::IndiElement("current"));
180 m_indiP_fps["current"] = m_fps;
181
183 {
185 return -1;
186 }
187
189 {
190 return log<software_error,-1>({__FILE__, __LINE__});
191 }
192
194
195 return 0;
196}
197
199{
200 if( shmimMonitorT::appLogic() < 0)
201 {
202 return log<software_error,-1>({__FILE__,__LINE__});
203 }
204
205 std::unique_lock<std::mutex> lock(m_indiMutex);
206
208 {
210 }
211
212 return 0;
213}
214
216{
218
219 return 0;
220}
221
223{
224 static_cast<void>(dummy);
225
226 //Create the shared memory images
227 uint32_t imsize[3];
228
229 //First the frequency
232 imsize[2] = 1;
233
234 if(m_olpsdStream)
235 {
238 }
239 m_olpsdStream = (IMAGE *) malloc(sizeof(IMAGE));
240
242
243 return 0;
244}
245
246int openLoopPSDs::processImage( void * curr_src,
247 const dev::shmimT & dummy
248 )
249{
250 static_cast<void>(dummy);
251
252 float * src = static_cast<float *>(curr_src);
253
254 m_olpsdStream->md->write=1;
255
256 for(uint32_t n = 0; n < shmimMonitorT::m_height; ++n)
257 {
258 for(uint32_t f = 0; f < shmimMonitorT::m_width; ++f)
259 {
260 m_olpsdStream->array.F[n*shmimMonitorT::m_width + f] = src[n*shmimMonitorT::m_width + f]; // <- divide by t.f. here.
261 }
262 }
263
264 //Set the time of last write
266 m_olpsdStream->md->atime = m_olpsdStream->md->writetime;
267
268 //Update cnt1
269 m_olpsdStream->md->cnt1 = 0;
270
271 //Update cnt0
272 m_olpsdStream->md->cnt0 = 0;
273
274 m_olpsdStream->md->write=0;
276
277 return 0;
278}
279
280INDI_SETCALLBACK_DEFN(openLoopPSDs, m_indiP_clPSDSource )(const pcf::IndiProperty &ipRecv)
281{
282 if( ipRecv.getName() != m_indiP_clPSDSource.getName())
283 {
284 log<software_error>({__FILE__, __LINE__, "Invalid INDI property."});
285 return -1;
286 }
287
288 if( ipRecv.find("current") != true ) //this isn't valid
289 {
290 log<software_error>({__FILE__, __LINE__, "No current property in fps source."});
291 return 0;
292 }
293
294 std::lock_guard<std::mutex> guard(m_indiMutex);
295
296 realT fps = ipRecv["current"].get<realT>();
297
298 if(fps != m_fps)
299 {
300 m_fps = fps;
301 log<text_log>("set fps to " + std::to_string(m_fps), logPrio::LOG_NOTICE);
302 updateIfChanged(m_indiP_fps, "current", m_fps, INDI_IDLE);
303 shmimMonitorT::m_restart = true;
304 }
305
306 return 0;
307
308} //INDI_SETCALLBACK_DEFN(openLoopPSDs, m_indiP_clPSDSource)
309
310} //namespace app
311} //namespace MagAOX
312
313#endif //openLoopPSDs_hpp
#define IMAGESTRUCT_FLOAT
The base-class for MagAO-X applications.
Definition MagAOXApp.hpp:73
std::string m_configName
The name of the configuration file (minus .conf).
Definition MagAOXApp.hpp:83
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.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
int createROIndiNumber(pcf::IndiProperty &prop, const std::string &propName, const std::string &propLabel="", const std::string &propGroup="")
Create a ReadOnly INDI Number property.
int registerIndiPropertyReadOnly(pcf::IndiProperty &prop)
Register an INDI property which is read only.
std::mutex m_indiMutex
Mutex for locking INDI communications.
uint32_t m_width
The width of the images in the stream.
int setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
int updateINDI()
Update the INDI properties for this device controller.
int appLogic()
Checks the shmimMonitor thread.
uint32_t m_height
The height of the images in the stream.
std::string m_shmimName
The name of the shared memory image, is used in /tmp/<shmimName>.im.shm. Derived classes should set a...
int appShutdown()
Shuts down the shmimMonitor thread.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Class for application to calculate rolling PSDs of modal amplitudes.
pcf::IndiProperty m_indiP_clPSDSource
std::string m_clPSDSource
Device name for getting the C.L. PSDs. This is used as the shmim name (unless overriden) and this IND...
dev::shmimMonitor< openLoopPSDs > shmimMonitorT
The base shmimMonitor type.
pcf::IndiProperty m_indiP_fps
int m_nModes
the number of modes to calculate PSDs for.
virtual int appStartup()
Startup function.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
~openLoopPSDs() noexcept
D'tor, declared and defined for noexcept.
virtual int appShutdown()
Shutdown the app.
std::vector< realT > m_freq
INDI_SETCALLBACK_DECL(openLoopPSDs, m_indiP_clPSDSource)
int allocate(const dev::shmimT &dummy)
int processImage(void *curr_src, const dev::shmimT &dummy)
mx::sigproc::circularBufferIndex< float *, unsigned > ampCircBuffT
The amplitude circular buffer type.
std::complex< realT > complexT
virtual int appLogic()
Implementation of the FSM for openLoopPSDs.
#define INDI_SETCALLBACK_DEFN(class, prop)
Define the callback for a set property request.
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
@ OPERATING
The device is operating, other than homing.
#define INDI_IDLE
Definition indiUtils.hpp:28
const pcf::IndiProperty & ipRecv
updateIfChanged(m_indiP_angle, "target", m_angle)
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition dm.hpp:24
static constexpr logPrioT LOG_NOTICE
A normal but significant condition.
static constexpr logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
Software ERR log entry.