From bc41e19a706833caa98a4095fa9ea11ec8b8c6a6 Mon Sep 17 00:00:00 2001 From: leonarski_f Date: Tue, 5 May 2026 19:36:14 +0200 Subject: [PATCH] HDF5NXmx: Improve error handling --- .gitea/workflows/build_and_test.yml | 1 + tests/jfjoch_hdf5_enospc_test.cpp | 9 ++- writer/FileWriter.cpp | 1 - writer/HDF5NXmx.cpp | 103 +++++++++++++++------------- 4 files changed, 64 insertions(+), 50 deletions(-) diff --git a/.gitea/workflows/build_and_test.yml b/.gitea/workflows/build_and_test.yml index f0c8d776..50a9166b 100644 --- a/.gitea/workflows/build_and_test.yml +++ b/.gitea/workflows/build_and_test.yml @@ -325,6 +325,7 @@ jobs: run: | cd build/tests LD_PRELOAD=enospc_shim.so ./jfjoch_hdf5_enospc_test HDF5File_enospc + LD_PRELOAD=enospc_shim.so ./jfjoch_hdf5_enospc_test FileWriter_enospc - name: Run hdf5 test shell: bash run: | diff --git a/tests/jfjoch_hdf5_enospc_test.cpp b/tests/jfjoch_hdf5_enospc_test.cpp index c43f15a0..0cc7201a 100644 --- a/tests/jfjoch_hdf5_enospc_test.cpp +++ b/tests/jfjoch_hdf5_enospc_test.cpp @@ -7,6 +7,7 @@ #include "../writer/HDF5Objects.h" #include "../writer/FileWriter.h" #include "../common/DiffractionExperiment.h" +#include TEST_CASE("HDF5File_enospc") { auto file = std::make_unique("enospc_test.h5"); @@ -25,7 +26,8 @@ TEST_CASE("FileWriter_enospc") { RegisterHDF5Filter(); DiffractionExperiment x(DetJF4M()); - x.FilePrefix("test02_1p10").ImagesPerTrigger(5).ImagesPerFile(2).Compression(CompressionAlgorithm::NO_COMPRESSION); + x.FilePrefix("fw_enospc").ImagesPerTrigger(5).ImagesPerFile(2).Compression(CompressionAlgorithm::NO_COMPRESSION) + .SetFileWriterFormat(FileWriterFormat::NXmxVDS); StartMessage start_message; x.FillMessage(start_message); @@ -40,6 +42,11 @@ TEST_CASE("FileWriter_enospc") { REQUIRE_THROWS(file_set.Write(message)); message.number = 2; REQUIRE_THROWS(file_set.Write(message)); + + EndMessage end_message{ + .max_image_number = 3 + }; + REQUIRE_THROWS(file_set.WriteHDF5(end_message)); } // No leftover HDF5 objects REQUIRE (H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0); diff --git a/writer/FileWriter.cpp b/writer/FileWriter.cpp index c7503786..4e90fd5c 100644 --- a/writer/FileWriter.cpp +++ b/writer/FileWriter.cpp @@ -15,7 +15,6 @@ FileWriter::FileWriter(const StartMessage &request) if (start_message.file_format) format = start_message.file_format.value(); - // defailt if (start_message.images_per_file <= 0) start_message.images_per_file = default_images_per_file; diff --git a/writer/HDF5NXmx.cpp b/writer/HDF5NXmx.cpp index f92a67ca..b368808b 100644 --- a/writer/HDF5NXmx.cpp +++ b/writer/HDF5NXmx.cpp @@ -699,56 +699,63 @@ void NXmx::ADUHistogram(const EndMessage &end) { } void NXmx::Finalize(const EndMessage &end) { - if (!hdf5_file) - throw JFJochException(JFJochExceptionCategory::FileWriteError, "HDF5 file already closed"); - if (end.end_date) { - hdf5_file->Attr("file_time", end.end_date.value()); - hdf5_file->SaveScalar("/entry/end_time", end.end_date.value()); - hdf5_file->SaveScalar("/entry/end_time_estimated", end.end_date.value()); - } else { - std::string time_now = time_UTC(std::chrono::system_clock::now()); - hdf5_file->Attr("file_time", time_now); - hdf5_file->SaveScalar("/entry/end_time", time_now); - hdf5_file->SaveScalar("/entry/end_time_estimated", time_now); + try { + if (!hdf5_file) + throw JFJochException(JFJochExceptionCategory::FileWriteError, "HDF5 file already closed"); + if (end.end_date) { + hdf5_file->Attr("file_time", end.end_date.value()); + hdf5_file->SaveScalar("/entry/end_time", end.end_date.value()); + hdf5_file->SaveScalar("/entry/end_time_estimated", end.end_date.value()); + } else { + std::string time_now = time_UTC(std::chrono::system_clock::now()); + hdf5_file->Attr("file_time", time_now); + hdf5_file->SaveScalar("/entry/end_time", time_now); + hdf5_file->SaveScalar("/entry/end_time_estimated", time_now); + } + + Detector(start_message, end); + Sample(start_message, end); + AzimuthalIntegration(start_message, end); + ADUHistogram(end); + + switch (start_message.file_format.value_or(FileWriterFormat::NXmxLegacy)) { + case FileWriterFormat::NXmxLegacy: + LinkToData(start_message, end); + break; + case FileWriterFormat::NXmxVDS: + LinkToData_VDS(start_message, end); + break; + case FileWriterFormat::NXmxIntegrated: + default: + break; + } + + if (end.rotation_lattice) + SaveVector(*hdf5_file, "/entry/MX/rotationLatticeIndexed", end.rotation_lattice->GetVector()) + ->Units("Angstrom"); + + if (end.rotation_lattice_type) + SaveScalar(*hdf5_file, "/entry/MX/rotationLatticeNiggliClass", end.rotation_lattice_type->niggli_class); + + if (end.indexing_rate) { + SaveScalar(*hdf5_file, "/entry/MX/imageIndexedMean", end.indexing_rate.value()); + } + if (end.bkg_estimate) { + SaveScalar(*hdf5_file, "/entry/MX/bkgEstimateMean", end.bkg_estimate.value()); + } + + if (!end.scale_factor.empty()) + SaveVector(*hdf5_file, "/entry/MX/imageScaleFactor", end.scale_factor); + + hdf5_file->Close(); + hdf5_file.reset(); + } catch (const JFJochException &e) { + hdf5_file.reset(); + std::error_code ec; + std::filesystem::remove(tmp_filename, ec); + throw; } - Detector(start_message, end); - Sample(start_message, end); - AzimuthalIntegration(start_message, end); - ADUHistogram(end); - - switch (start_message.file_format.value_or(FileWriterFormat::NXmxLegacy)) { - case FileWriterFormat::NXmxLegacy: - LinkToData(start_message, end); - break; - case FileWriterFormat::NXmxVDS: - LinkToData_VDS(start_message, end); - break; - case FileWriterFormat::NXmxIntegrated: - default: - break; - } - - if (end.rotation_lattice) - SaveVector(*hdf5_file, "/entry/MX/rotationLatticeIndexed", end.rotation_lattice->GetVector()) - ->Units("Angstrom"); - - if (end.rotation_lattice_type) - SaveScalar(*hdf5_file, "/entry/MX/rotationLatticeNiggliClass", end.rotation_lattice_type->niggli_class); - - if (end.indexing_rate) { - SaveScalar(*hdf5_file, "/entry/MX/imageIndexedMean", end.indexing_rate.value()); - } - if (end.bkg_estimate) { - SaveScalar(*hdf5_file, "/entry/MX/bkgEstimateMean", end.bkg_estimate.value()); - } - - if (!end.scale_factor.empty()) - SaveVector(*hdf5_file, "/entry/MX/imageScaleFactor", end.scale_factor); - - hdf5_file->Close(); - hdf5_file.reset(); - if (std::filesystem::exists(filename) && !overwrite) throw JFJochException(JFJochExceptionCategory::FileWriteError, "File already exists");