From 3602b634f845578a67b695ec62bdcd367476ddae Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Fri, 21 Nov 2025 17:54:15 +0100 Subject: [PATCH] jfjoch_viewer: Fix reading dataset with partial grid results --- reader/JFJochHDF5Reader.cpp | 4 +- tests/JFJochReaderTest.cpp | 82 +++++++++++++++++++++++++++++++++++-- writer/HDF5Objects.h | 2 +- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/reader/JFJochHDF5Reader.cpp b/reader/JFJochHDF5Reader.cpp index daaf89de..6b30301a 100644 --- a/reader/JFJochHDF5Reader.cpp +++ b/reader/JFJochHDF5Reader.cpp @@ -70,9 +70,9 @@ void JFJochHDF5Reader::ReadVector(std::vector &v, size_t nimages) { try { auto tmp = file.ReadOptVector(dataset_name); - if (tmp.size() == nimages) { + if (tmp.size() <= nimages) { v.resize(image0 + nimages); - for (int i = 0; i < nimages; i++) + for (int i = 0; i < tmp.size(); i++) v[image0 + i] = tmp[i]; } } catch (JFJochException &e) {} diff --git a/tests/JFJochReaderTest.cpp b/tests/JFJochReaderTest.cpp index 5bc5fb71..da8ac2c3 100644 --- a/tests/JFJochReaderTest.cpp +++ b/tests/JFJochReaderTest.cpp @@ -1050,9 +1050,83 @@ TEST_CASE("JFJochReader_NiggliClass", "[HDF5][Full]") { REQUIRE(!reader_image_2->ImageData().indexing_lattice); REQUIRE(!reader_image_2->ImageData().lattice_type); } - //remove("test95_master.h5"); - //remove("test95_data_000001.h5"); - //remove("test95_data_000002.h5"); + remove("test95_master.h5"); + remove("test95_data_000001.h5"); + remove("test95_data_000002.h5"); + + // No leftover HDF5 objects + REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0); +} + +TEST_CASE("JFJochReader_MissingEntries", "[HDF5][Full]") { + DiffractionExperiment x(DetJF(1)); + x.FilePrefix("test96").ImagesPerTrigger(4).OverwriteExistingFiles(true); + x.BitDepthImage(16).ImagesPerFile(10).SetFileWriterFormat(FileWriterFormat::NXmxLegacy).PixelSigned(true) + .IndexingAlgorithm(IndexingAlgorithmEnum::FFT); + x.Compression(CompressionAlgorithm::NO_COMPRESSION); + + std::vector image(x.GetPixelsNum()); + + RegisterHDF5Filter(); + { + StartMessage start_message; + x.FillMessage(start_message); + FileWriter file_set(start_message); + + DataMessage message{}; + message.number = 0; + message.image = CompressedImage(image, x.GetXPixelsNum(), x.GetYPixelsNum()); + message.indexing_result = true; + message.indexing_lattice = CrystalLattice(40, 50, 60, 90, 90, 90); + message.spot_count_indexed = 56; + message.spot_count = 85; + message.b_factor = 123.45; + message.spots = {SpotToSave{.x = 10, .y=50, .intensity = 80}}; + REQUIRE_NOTHROW(file_set.WriteHDF5(message)); + + message.number = 1; + message.indexing_result = false; + message.indexing_lattice = std::nullopt; + message.spot_count_indexed = std::nullopt; + message.spot_count = 70; + message.b_factor = std::nullopt; + message.spots = {SpotToSave{.x = 10, .y=50, .intensity = 80}}; + REQUIRE_NOTHROW(file_set.WriteHDF5(message)); + + EndMessage end_message; + end_message.max_image_number = 2; + file_set.WriteHDF5(end_message); + file_set.Finalize(); + } + { + JFJochHDF5Reader reader; + REQUIRE_NOTHROW(reader.ReadFile("test96_master.h5")); + auto dataset = reader.GetDataset(); + CHECK(dataset->experiment.GetImageNum() == 2); + + REQUIRE(dataset->b_factor.size() == 2); + REQUIRE(dataset->spot_count_indexed.size() == 2); + + CHECK(dataset->b_factor[0] == Catch::Approx(123.45)); + CHECK(dataset->b_factor[1] == 0.0); + CHECK(dataset->spot_count_indexed[0] == 56); + CHECK(dataset->spot_count_indexed[1] == 0); + + std::shared_ptr reader_image, reader_image_2; + + REQUIRE_NOTHROW(reader_image = reader.LoadImage(0)); + REQUIRE(reader_image); + REQUIRE(reader_image->ImageData().b_factor.has_value()); + CHECK(reader_image->ImageData().b_factor.value() == Catch::Approx(123.45)); + REQUIRE(reader_image->ImageData().spot_count_indexed.has_value()); + CHECK(reader_image->ImageData().spot_count_indexed.value() == 56); + + REQUIRE_NOTHROW(reader_image_2 = reader.LoadImage(1)); + REQUIRE(reader_image_2); + CHECK(!reader_image_2->ImageData().spot_count_indexed); + } + remove("test96_master.h5"); + remove("test96_data_000001.h5"); // No leftover HDF5 objects REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0); @@ -1318,4 +1392,4 @@ TEST_CASE("JFJochReader_InstrumentMetadata_Sample_RingCurrent", "[HDF5][Full]") remove("test_meta_master.h5"); REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0); -} \ No newline at end of file +} diff --git a/writer/HDF5Objects.h b/writer/HDF5Objects.h index c55c5592..fb336455 100644 --- a/writer/HDF5Objects.h +++ b/writer/HDF5Objects.h @@ -302,7 +302,7 @@ public: auto dims = file_space.GetDimensions(); // Allow scalar (0-D) to be read with n==0 as a convenience. if (file_space.GetNumOfDimensions() == 0) { - if (n != 0) throw JFJochException(JFJochExceptionCategory::HDF5, "Index out of bounds for scalar dataset"); + if (n != 0) return std::nullopt; return ReadScalar(); } if (file_space.GetNumOfDimensions() != 1)