API
 
Loading...
Searching...
No Matches
dlDataCollection.hpp
Go to the documentation of this file.
1/** \file dlDataCollection.hpp
2 * \brief The MagAO-X generic ImageStreamIO stream integrator
3 *
4 * \ingroup app_files
5 */
6
7#ifndef dlDataCollection_hpp
8#define dlDataCollection_hpp
9
10#include <NvInfer.h>
11#include <cuda_fp16.h>
12#include <cuda_runtime_api.h>
13#include <iostream>
14#include <fstream>
15#include <vector>
16#include <limits>
17
18#include <mx/improc/eigenCube.hpp>
19#include <mx/improc/eigenImage.hpp>
20
21#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
22#include "../../magaox_git_version.h"
23
24using namespace nvinfer1;
25
26bool loadCSV(const std::string& filename, int numValues, float*& dest) {
27 std::ifstream file(filename);
28
29 if (!file.is_open()) {
30 std::cerr << "Error opening file!" << std::endl;
31 return false;
32 }
33
34 std::string line;
35
36
37 for (int i = 0; i < numValues; ++i) {
38 std::getline(file, line);
39 dest[i] = std::stof(line);
40 }
41 file.close();
42 return true;
43}
44
45
47 private:
48 size_t num_channels, num_rows, num_cols; // Dimensions of each image (rows x columns)
49 size_t num_images; // Total number of images the buffer can hold
50 float* buffer; // Buffer holding the images
51 size_t size; // Total number of elements in each image (rows * columns)
52 size_t head; // Index for the next write position
53 bool is_full; // Flag to check if buffer is full
54
55 public:
56 ImageBuffer(size_t _num_channels, size_t _num_rows, size_t _num_cols, size_t _num_images)
57 : num_channels(_num_channels), num_rows(_num_rows), num_cols(_num_cols),
58 num_images(_num_images),
59 size(_num_channels * _num_rows * _num_cols),
60 head(0), is_full(false) {
61
62 buffer = new float[size * num_images];
63 memset( buffer, 0, sizeof( float) * size * num_images);
64 }
65
67 delete buffer;
68 }
69
70 // Adds an image (array of floats) to the buffer (overwrites if full)
71 void add(float* image) {
72 memcpy(&buffer[head * size], image, sizeof(float) * size);
73 head = head + 1;
74 }
75
76 void clear(){
77 head = 0;
78 is_full = false;
79 }
80
81 void save(const std::string& filename) {
82 std::ofstream file(filename, std::ios::out | std::ios::binary);
83 if (!file) {
84 std::cerr << "Error opening file for writing: " << filename << std::endl;
85 return;
86 }
87
88 file.write(reinterpret_cast<char*>(buffer), sizeof(float) * size * num_images);
89
90 file.close();
91 }
92
93
94};
95
96namespace MagAOX
97{
98namespace app
99{
100
101class dlDataCollection : public MagAOXApp<true>, public dev::shmimMonitor<dlDataCollection>
102{
103 // Give the test harness access.
105
107
108 // The base shmimMonitor type
110
111 /// Floating point type in which to do all calculations.
112 typedef float realT;
113
114 public:
115 /** \name app::dev Configurations
116 *@{
117 */
118
119 ///@}
120
121 protected:
122 /** \name Configurable Parameters
123 *@{
124 */
125 std::string dataDirs; // Location where the data (onnx file, engine, WFS reference) is stored
126 std::string ampsDir; // Location where the data (onnx file, engine, WFS reference) is stored
127
128 int Nperset {0}; // Number of images per dataset file
129 int Nset {0}; // Number of images per dataset file
130 int NumFrameSkip {0}; // Number of frames to skip to ensure latency is not an issue
131 int Nmodes {0}; // Number of modes to control
132
133 int inputC {0};
134 int inputH {0};
135 int inputW {0};
136
137 float imageNorm; // Normalization constant for the image intensities
138 float modalNorm; // Normalization constant for the modal coefficients
139
140 int m_pupPix; // Number of pixels in the pupil used for the Neural Network
141 int pup_offset1_x; // Horizontal offset to the first set of pupils
142 int pup_offset1_y; // Vertical offset to the first set of pupils
143 int pup_offset2_x; // Horizontal offset to the second set of pupils
144 int pup_offset2_y; // Horizontal offset to the second set of pupils
146 unsigned long frame_counter{ 0 };
147 int long frame_wait{ 0 };
148 int long frame_saved{ 0 };
149
150 int Npup{ 4 }; // Number of pupils
151 float *modeval{ nullptr };
152 float *pp_image{ nullptr };
153 float *randomAmps{ nullptr };
156
157 size_t m_pwfsWidth{ 0 }; ///< The width of the image
158 size_t m_pwfsHeight{ 0 }; ///< The height of the image.
159
160 uint8_t m_pwfsDataType{ 0 }; ///< The ImageStreamIO type code.
161 size_t m_pwfsTypeSize{ 0 }; ///< The size of the type, in bytes.
162
163 // variables for sending the output to aol_modevals
164 std::string m_modevalChannel;
166 uint32_t m_modevalWidth {0}; ///< The width of the shmim
167 uint32_t m_modevalHeight {0}; ///< The height of the shmim
168 uint8_t m_modevalDataType {0}; ///< The ImageStreamIO type code.
169 size_t m_modevalTypeSize {0}; ///< The size of the type, in bytes.
170
171 bool m_modevalOpened {false};
172 bool m_modevalRestart {false};
173 int dataset_i{ 0 };
174 int Nact_across{ 50 };
175 int zeroPad { 2 };
176
177 public:
178 /// Default c'tor.
180
181 /// D'tor, declared and defined for noexcept.
185
186 virtual void setupConfig();
187
188 /// Implementation of loadConfig logic, separated for testing.
189 /** This is called by loadConfig().
190 */
191 int loadConfigImpl(
192 mx::app::appConfigurator &_config /**< [in] an application configuration from which to load values*/ );
193
194 virtual void loadConfig();
195
196 /// Startup function
197 /**
198 *
199 */
200 virtual int appStartup();
201
202 /// Implementation of the FSM for dlDataCollection.
203 /**
204 * \returns 0 on no critical error
205 * \returns -1 on an error requiring shutdown
206 */
207 virtual int appLogic();
208
209 /// Shutdown the app.
210 /**
211 *
212 */
213 virtual int appShutdown();
214
215 // Custom functions
216 int send_to_shmim();
217
218 void loadRandomAmps(int dataset_i);
219
220 // void build_engine(){};
221
222 protected:
223 int allocate( const dev::shmimT &dummy /**< [in] tag to differentiate shmimMonitor parents.*/ );
224
225 int processImage( void *curr_src, ///< [in] pointer to start of current frame.
226 const dev::shmimT &dummy ///< [in] tag to differentiate shmimMonitor parents.
227 );
228};
229
231{
232 int ki = 0;
233 for(uint32_t col_i=0; col_i < Nact_across; ++col_i){
234 for(uint32_t row_i=0; row_i < Nact_across; ++row_i){
236 ki += 1;
237 }
238 }
239
240 m_modevalStream.md[0].write = 1;
241 memcpy(m_modevalStream.array.raw, m_shaped_command.data(), Nmodes * sizeof(float));
242 m_modevalStream.md[0].cnt0++;
243 m_modevalStream.md[0].write = 0;
244
246
247 return 0;
248}
249
250inline dlDataCollection::dlDataCollection() : MagAOXApp( MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED )
251{
252 return;
253}
254
256{
257 std::cout << "setupConfig()" << std::endl;
259
260 config.add( "parameters.dataDirs",
261 "",
262 "parameters.dataDirs",
263 argType::Required,
264 "parameters",
265 "dataDirs",
266 false,
267 "string",
268 "The path to the directory with the onnx model." );
269
270 config.add( "parameters.ampsDir",
271 "",
272 "parameters.ampsDir",
273 argType::Required,
274 "parameters",
275 "ampsDir",
276 false,
277 "string",
278 "The path to the directory with the random amplitudes." );
279
280 config.add( "parameters.Nperset",
281 "",
282 "parameters.Nperset",
283 argType::Required,
284 "parameters",
285 "Nperset",
286 false,
287 "int",
288 "Number of images per dataset file" );
289
290 config.add( "parameters.Nset",
291 "",
292 "parameters.Nset",
293 argType::Required,
294 "parameters",
295 "Nset",
296 false,
297 "int",
298 "Number of dataset files to generate" );
299
300 config.add( "parameters.NumFrameSkip",
301 "",
302 "parameters.NumFrameSkip",
303 argType::Required,
304 "parameters",
305 "NumFrameSkip",
306 false,
307 "int",
308 "Number of frames to skip to ensure latency is not an issue" );
309
310 config.add( "parameters.imageNorm",
311 "",
312 "parameters.imageNorm",
313 argType::Required,
314 "parameters",
315 "imageNorm",
316 false,
317 "float",
318 "Normalization term for the preprocessed images." );
319
320 config.add( "parameters.modalNorm",
321 "",
322 "parameters.modalNorm",
323 argType::Required,
324 "parameters",
325 "modalNorm",
326 false,
327 "float",
328 "Normalization term for the modal coefficients." );
329
330 config.add( "parameters.channel",
331 "",
332 "parameters.channel",
333 argType::Required,
334 "parameters",
335 "channel",
336 false,
337 "string",
338 "The output channel." );
339
340 config.add( "parameters.Nmodes",
341 "",
342 "parameters.Nmodes",
343 argType::Required,
344 "parameters",
345 "Nmodes",
346 false,
347 "int",
348 "Number of modes to control." );
349
350 config.add( "parameters.m_pupPix",
351 "",
352 "parameters.m_pupPix",
353 argType::Required,
354 "parameters",
355 "m_pupPix",
356 false,
357 "int",
358 "Number of pixels across a PWFS pupil." );
359
360 config.add( "parameters.pup_offset1_x",
361 "",
362 "parameters.pup_offset1_x",
363 argType::Required,
364 "parameters",
365 "pup_offset1_x",
366 false,
367 "int",
368 "Horizontal offset to the top left of the closest set op PWFS pupils." );
369
370 config.add( "parameters.pup_offset1_y",
371 "",
372 "parameters.pup_offset1_y",
373 argType::Required,
374 "parameters",
375 "pup_offset1_y",
376 false,
377 "int",
378 "Vertical offset to the top left of the closest set op PWFS pupils." );
379
380 config.add( "parameters.pup_offset2_x",
381 "",
382 "parameters.pup_offset2_x",
383 argType::Required,
384 "parameters",
385 "pup_offset2_x",
386 false,
387 "int",
388 "Horizontal offset to the top left of the furthest set op PWFS pupils." );
389
390 config.add( "parameters.pup_offset2_y",
391 "",
392 "parameters.pup_offset2_y",
393 argType::Required,
394 "parameters",
395 "pup_offset2_y",
396 false,
397 "int",
398 "Vertical offset to the top left of the furthest set op PWFS pupils." );
399
400}
401
402inline int dlDataCollection::loadConfigImpl( mx::app::appConfigurator &_config )
403{
404 std::cout << "loadConfigImpl()" << std::endl;
406
407 _config( dataDirs, "parameters.dataDirs" );
408 _config( ampsDir, "parameters.ampsDir" );
409 _config( Nperset, "parameters.Nperset" );
410 _config( Nset, "parameters.Nset" );
411 _config( NumFrameSkip, "parameters.NumFrameSkip" );
412
413 _config( imageNorm, "parameters.imageNorm" );
414 _config( modalNorm, "parameters.modalNorm" );
415 _config( m_modevalChannel, "parameters.channel");
416
417 _config( Nmodes, "parameters.Nmodes" );
418 _config( m_pupPix, "parameters.m_pupPix" );
419 _config( pup_offset1_x, "parameters.pup_offset1_x" );
420 _config( pup_offset1_y, "parameters.pup_offset1_y" );
421 _config( pup_offset2_x, "parameters.pup_offset2_x" );
422 _config( pup_offset2_y, "parameters.pup_offset2_y" );
423
424 if( true )
425 {
426 std::cout << "Debug configuration loading: " << std::endl;
427 std::cout << "dataDirs: " << dataDirs << std::endl;
428 std::cout << "ampsDir: " << ampsDir << std::endl;
429 std::cout << "Nperset: " << Nperset << std::endl;
430 std::cout << "Nset: " << Nset << std::endl;
431 std::cout << "NumFrameSkip: " << NumFrameSkip << std::endl;
432 std::cout << "imageNorm: " << imageNorm << std::endl;
433 std::cout << "modalNorm: " << modalNorm << std::endl;
434 std::cout << "modeval Channel: " << m_modevalChannel << std::endl;
435
436 std::cout << "m_pupPix: " << m_pupPix << std::endl;
437 std::cout << "pup_offset1_x: " << pup_offset1_x << std::endl;
438 std::cout << "pup_offset1_y: " << pup_offset1_y << std::endl;
439 std::cout << "pup_offset2_x: " << pup_offset2_x << std::endl;
440 std::cout << "pup_offset2_y: " << pup_offset2_y << std::endl;
441 }
442
443 return 0;
444}
445
447{
448 loadConfigImpl( config );
449}
450
452{
453 if( shmimMonitorT::appStartup() < 0 )
454 {
455 return log<software_error, -1>( { __FILE__, __LINE__ } );
456 }
457
458 // state(stateCodes::READY);
460 return 0;
461}
462
464{
465 if( shmimMonitorT::appLogic() < 0 )
466 {
467 return log<software_error, -1>( { __FILE__, __LINE__ } );
468 }
469
470 std::unique_lock<std::mutex> lock( m_indiMutex );
471
472 if( shmimMonitorT::updateINDI() < 0 )
473 {
475 }
476
477 return 0;
478}
479
481{
483 for( int i = 0; i < Nmodes; ++i )
484 {
485 modeval[i] = 0;
486 }
488
489 if( pp_image )
490 {
491 delete[] pp_image;
492 }
493 if( randomAmps )
494 {
495 delete[] randomAmps;
496 }
497
498 if( modeval )
499 {
500 delete[] modeval;
501 }
502
503 return 0;
504}
505
506inline int dlDataCollection::allocate( const dev::shmimT &dummy )
507{
508 std::cout << "allocate()" << std::endl;
509 static_cast<void>( dummy ); // be unused
510
511 // Wavefront sensor setup
514 std::cout << "Width: " << m_pwfsWidth << " Height: " << m_pwfsHeight << std::endl;
515
517 std::cout << "Pixels: " << pixels_per_quadrant << std::endl;
518 pp_image = new float[Npup * pixels_per_quadrant];
519 modeval = new float[Nmodes];
520 randomAmps = new float[Nperset * Nmodes];
522 memset( pp_image, 0, sizeof( float ) * Npup * pixels_per_quadrant );
523 memset( modeval, 0, sizeof( float) * Nmodes);
524 memset( randomAmps, 0, sizeof( float) * Nperset * Nmodes);
527 std::cout << "Close shmims" << std::endl;
528 // Allocate the DM shmim interface
529 if(m_modevalOpened){
531 }
532
533 std::cout << "Open shmims" << std::endl;
534 m_modevalOpened = false;
535 m_modevalRestart = false; //Set this up front, since we're about to restart.
536
538 if(m_modevalStream.md[0].sem < 10){
540 }else{
541 m_modevalOpened = true;
542 }
543 }
544
545 std::cout << "Done!" << std::endl;
546 if(!m_modevalOpened){
548 return -1;
549 }else{
550 m_modevalWidth = m_modevalStream.md->size[0];
551 m_modevalHeight = m_modevalStream.md->size[1];
552
553 m_modevalDataType = m_modevalStream.md->datatype;
554 m_modevalTypeSize = sizeof(float);
555
556 log<text_log>( "Opened " + m_modevalChannel + " " + std::to_string(m_modevalWidth) + " x " + std::to_string(m_modevalHeight) + " with data type: " + std::to_string(m_modevalDataType), logPrio::LOG_NOTICE);
557 }
558
559
560 return 0;
561}
562
563inline void dlDataCollection::loadRandomAmps(int dataset_index){
564 std::string filename = ampsDir + "modeval_dataset_" + std::to_string(dataset_index) + ".csv";
565 std::cout << "Loading dataset from: " << filename << std::endl;
567}
568
569inline int dlDataCollection::processImage( void *curr_src, const dev::shmimT &dummy )
570{
571 static_cast<void>( dummy ); // be unused
572
573 // aol_imwfs2 is reference and dark subtracted and is power normalized.
574 //Eigen::Map<eigenImage<unsigned short>> pwfsIm(static_cast<unsigned short *>( curr_src ), m_pwfsHeight, m_pwfsWidth );
575 Eigen::Map<eigenImage<float>> pwfsIm(reinterpret_cast<float*>(curr_src), m_pwfsHeight, m_pwfsWidth);
576
577 // Split up the four pupils for the Neural Network.
578 int ki = 0;
579
580 for( int col_i = -zeroPad; col_i < (m_pupPix - zeroPad); ++col_i )
581 {
582 for( int row_i = -zeroPad; row_i < (m_pupPix - zeroPad); ++row_i )
583 {
584 if ((col_i < 0) or (col_i >= (m_pupPix - 2*zeroPad)) or (row_i < 0) or (row_i >= (m_pupPix - 2*zeroPad))){
585 pp_image[ki] = 0;
589 }
590 else {
595 }
596 ++ki;
597 }
598 }
599
600 for( int i = 0; i < Nmodes; ++i )
601 {
603 }
604
605 // Send to DM
607
608
609 // Check if we need to add image to buffer
612 frame_wait=0;
613 frame_saved++;
614 }
615
616 // Save dataset
617 if ((frame_saved%Nperset==0) and (frame_saved!=0)){
618 std::cout << "Saving dataset " << dataset_i << std::endl;
619 imagebuffer->save(dataDirs + "images_dataset_" + std::to_string(dataset_i) + ".bin");
621 dataset_i++;
622 if (dataset_i > Nset){
623 appShutdown();
624 }
626 frame_saved = 0;
627 }
628 frame_wait++;
630
631
632
633 return 0;
634}
635
636} // namespace app
637} // namespace MagAOX
638
639#endif // dlDataCollection_hpp
void save(const std::string &filename)
void add(float *image)
ImageBuffer(size_t _num_channels, size_t _num_rows, size_t _num_cols, size_t _num_images)
The base-class for MagAO-X applications.
Definition MagAOXApp.hpp:73
stateCodes::stateCodeT state()
Get the current state code.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
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.
int appShutdown()
Shuts down the shmimMonitor thread.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
uint8_t m_pwfsDataType
The ImageStreamIO type code.
uint32_t m_modevalHeight
The height of the shmim.
size_t m_pwfsHeight
The height of the image.
virtual int appLogic()
Implementation of the FSM for dlDataCollection.
virtual int appShutdown()
Shutdown the app.
uint32_t m_modevalWidth
The width of the shmim.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
virtual int appStartup()
Startup function.
size_t m_modevalTypeSize
The size of the type, in bytes.
float realT
Floating point type in which to do all calculations.
~dlDataCollection() noexcept
D'tor, declared and defined for noexcept.
size_t m_pwfsWidth
The width of the image.
size_t m_pwfsTypeSize
The size of the type, in bytes.
int allocate(const dev::shmimT &dummy)
uint8_t m_modevalDataType
The ImageStreamIO type code.
dev::shmimMonitor< dlDataCollection > shmimMonitorT
int processImage(void *curr_src, const dev::shmimT &dummy)
bool loadCSV(const std::string &filename, int numValues, float *&dest)
@ OPERATING
The device is operating, other than homing.
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition dm.hpp:26
static constexpr logPrioT LOG_NOTICE
A normal but significant condition.
Software ERR log entry.