@@ -579,3 +579,170 @@ TEST_F(HDF5_IO_Test, LoadSpectraVolumeWithCallback_UserDataPassedThrough)
579579 ASSERT_NE (received_ptr, nullptr );
580580 EXPECT_EQ (*received_ptr, 42 );
581581}
582+
583+ TEST_F (HDF5_IO_Test, LoadSpectraVolumeWithCallback_TotalDimensionsPassedCorrectly)
584+ {
585+ MapsRawParams p;
586+ p.spectra_size = 16 ; p.rows = 3 ; p.cols = 5 ; p.detector_num = 0 ;
587+ std::string path = tmp (" cb_total_dims.h5" );
588+ ASSERT_EQ (0 , make_maps_raw_h5 (path, p));
589+
590+ size_t obs_total_rows = 0 , obs_total_cols = 0 ;
591+ data_struct::IO_Callback_Func_Def<float > cb =
592+ [&](size_t , size_t , size_t tr, size_t tc, size_t , data_struct::Spectra<float >* s, void *)
593+ { obs_total_rows = tr; obs_total_cols = tc; delete s; };
594+
595+ ASSERT_TRUE (io ()->load_spectra_volume_with_callback (path, {0 }, cb, nullptr ));
596+ EXPECT_EQ (obs_total_rows, p.rows );
597+ EXPECT_EQ (obs_total_cols, p.cols );
598+ }
599+
600+ TEST_F (HDF5_IO_Test, LoadSpectraVolumeWithCallback_TimingMetadataCorrect)
601+ {
602+ MapsRawParams p;
603+ p.spectra_size = 16 ; p.rows = 1 ; p.cols = 1 ; p.detector_num = 0 ;
604+ p.realtime = 0 .25f ; p.input_counts = 500 .0f ; p.output_counts = 500 .0f ;
605+ std::string path = tmp (" cb_timing.h5" );
606+ ASSERT_EQ (0 , make_maps_raw_h5 (path, p));
607+
608+ float obs_rt = -1 .f ;
609+ data_struct::IO_Callback_Func_Def<float > cb =
610+ [&](size_t , size_t , size_t , size_t , size_t , data_struct::Spectra<float >* s, void *)
611+ { if (s) { obs_rt = s->elapsed_realtime (); delete s; } };
612+
613+ ASSERT_TRUE (io ()->load_spectra_volume_with_callback (path, {0 }, cb, nullptr ));
614+ EXPECT_NEAR (obs_rt, p.realtime , 1e-5f );
615+ }
616+
617+ // ============================================================
618+ // load_spectra_volume — remaining detectors (2 and 3)
619+ // ============================================================
620+
621+ TEST_F (HDF5_IO_Test, LoadSpectraVolume_Detector2_LoadsData)
622+ {
623+ MapsRawParams p;
624+ p.spectra_size = 16 ; p.rows = 2 ; p.cols = 3 ; p.detector_num = 2 ;
625+ p.channel_ramp = true ;
626+ std::string path = tmp (" maps_raw_det2.h5" );
627+ ASSERT_EQ (0 , make_maps_raw_h5 (path, p));
628+
629+ data_struct::Spectra_Volume<float > vol;
630+ vol.resize_and_zero (p.rows , p.cols , p.spectra_size );
631+ ASSERT_TRUE (io ()->load_spectra_volume (path, 2 , &vol));
632+
633+ for (size_t s = 0 ; s < p.spectra_size ; ++s)
634+ EXPECT_FLOAT_EQ (vol[0 ][0 ][s], float (s + 1 )) << " s=" << s;
635+ }
636+
637+ TEST_F (HDF5_IO_Test, LoadSpectraVolume_Detector3_LoadsData)
638+ {
639+ MapsRawParams p;
640+ p.spectra_size = 16 ; p.rows = 2 ; p.cols = 3 ; p.detector_num = 3 ;
641+ p.channel_ramp = true ;
642+ std::string path = tmp (" maps_raw_det3.h5" );
643+ ASSERT_EQ (0 , make_maps_raw_h5 (path, p));
644+
645+ data_struct::Spectra_Volume<float > vol;
646+ vol.resize_and_zero (p.rows , p.cols , p.spectra_size );
647+ ASSERT_TRUE (io ()->load_spectra_volume (path, 3 , &vol));
648+
649+ for (size_t s = 0 ; s < p.spectra_size ; ++s)
650+ EXPECT_FLOAT_EQ (vol[0 ][0 ][s], float (s + 1 )) << " s=" << s;
651+ }
652+
653+ // ============================================================
654+ // load_spectra_volume — double precision type
655+ // ============================================================
656+
657+ TEST_F (HDF5_IO_Test, LoadSpectraVolume_Double_ChannelRamp)
658+ {
659+ MapsRawParams p;
660+ p.spectra_size = 16 ; p.rows = 2 ; p.cols = 3 ; p.detector_num = 0 ;
661+ p.channel_ramp = true ;
662+ std::string path = tmp (" maps_raw_double.h5" );
663+ ASSERT_EQ (0 , make_maps_raw_h5 (path, p));
664+
665+ data_struct::Spectra_Volume<double > vol;
666+ vol.resize_and_zero (p.rows , p.cols , p.spectra_size );
667+ ASSERT_TRUE (io ()->load_spectra_volume (path, 0 , &vol));
668+
669+ for (size_t s = 0 ; s < p.spectra_size ; ++s)
670+ EXPECT_NEAR (vol[0 ][0 ][s], double (s + 1 ), 1e-6 ) << " s=" << s;
671+ }
672+
673+ TEST_F (HDF5_IO_Test, LoadSpectraVolume_Double_NonExistentFile_ReturnsFalse)
674+ {
675+ data_struct::Spectra_Volume<double > vol;
676+ vol.resize_and_zero (2 , 3 , 16 );
677+ EXPECT_FALSE (io ()->load_spectra_volume <double >(" /no/such/file.h5" , 0 , &vol));
678+ }
679+
680+ // ============================================================
681+ // load_spectra_volume_with_callback — double precision type
682+ // ============================================================
683+
684+ TEST_F (HDF5_IO_Test, LoadSpectraVolumeWithCallback_Double_ChannelRamp)
685+ {
686+ MapsRawParams p;
687+ p.spectra_size = 16 ; p.rows = 2 ; p.cols = 3 ; p.detector_num = 0 ;
688+ p.channel_ramp = true ;
689+ std::string path = tmp (" cb_double.h5" );
690+ ASSERT_EQ (0 , make_maps_raw_h5 (path, p));
691+
692+ std::vector<data_struct::Spectra<double >> received;
693+ data_struct::IO_Callback_Func_Def<double > cb =
694+ [&](size_t , size_t , size_t , size_t , size_t , data_struct::Spectra<double >* s, void *)
695+ { if (s) { received.push_back (*s); delete s; } };
696+
697+ ASSERT_TRUE (io ()->load_spectra_volume_with_callback (path, {0 }, cb, nullptr ));
698+ ASSERT_FALSE (received.empty ());
699+
700+ for (auto & spec : received)
701+ for (size_t s = 0 ; s < p.spectra_size ; ++s)
702+ EXPECT_NEAR (spec[s], double (s + 1 ), 1e-6 ) << " s=" << s;
703+ }
704+
705+ // ============================================================
706+ // parse_str_val_to_int — additional edge cases
707+ // ============================================================
708+
709+ TEST (ParseStrValToInt, ParsesNegativeValue)
710+ {
711+ EXPECT_EQ ((parse_str_val_to_int<float >(" [" , " ]" , " val[-7]end" )), -7 );
712+ }
713+
714+ TEST (ParseStrValToInt, ParsesMultiDigitValue)
715+ {
716+ EXPECT_EQ ((parse_str_val_to_int<float >(" <" , " >" , " size<2048>px" )), 2048 );
717+ }
718+
719+ TEST (ParseStrValToInt, StartDelimiterAtEndOfString_ReturnsFalse)
720+ {
721+ // Start delimiter found but nothing after it
722+ EXPECT_EQ ((parse_str_val_to_int<float >(" [" , " ]" , " value[" )), -1 );
723+ }
724+
725+ // ============================================================
726+ // load_spectra_volume_emd_with_callback — error paths
727+ // ============================================================
728+
729+ TEST_F (HDF5_IO_Test, LoadSpectraVolumeEmdWithCallback_NonExistentFile_ReturnsFalse)
730+ {
731+ data_struct::IO_Callback_Func_Def<float > cb =
732+ [](size_t , size_t , size_t , size_t , size_t , data_struct::Spectra<float >* s, void *) { delete s; };
733+
734+ EXPECT_FALSE (io ()->load_spectra_volume_emd_with_callback (" /no/such/file.emd" , {0 }, cb, nullptr ));
735+ }
736+
737+ TEST_F (HDF5_IO_Test, LoadSpectraVolumeEmdWithCallback_EmptyH5File_ReturnsFalse)
738+ {
739+ std::string path = tmp (" empty_emd.h5" );
740+ hid_t fid = H5Fcreate (path.c_str (), H5F_ACC_TRUNC , H5P_DEFAULT , H5P_DEFAULT );
741+ ASSERT_GE (fid, 0 );
742+ H5Fclose (fid);
743+
744+ data_struct::IO_Callback_Func_Def<float > cb =
745+ [](size_t , size_t , size_t , size_t , size_t , data_struct::Spectra<float >* s, void *) { delete s; };
746+
747+ EXPECT_FALSE (io ()->load_spectra_volume_emd_with_callback (path, {0 }, cb, nullptr ));
748+ }
0 commit comments