Write single file option enabled. Minor issues:
Build Packages / build:rpm (rocky8_nocuda) (push) Failing after 6m2s
Build Packages / build:rpm (rocky9_nocuda) (push) Failing after 7m30s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Failing after 8m18s
Build Packages / DIALS processing test (push) Failing after 0s
Build Packages / build:rpm (rocky8_sls9) (push) Failing after 8m45s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Failing after 8m52s
Build Packages / Generate python client (push) Successful in 2m0s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (rocky9_sls9) (push) Failing after 10m28s
Build Packages / Build documentation (push) Successful in 2m27s
Build Packages / build:rpm (rocky9) (push) Failing after 11m35s
Build Packages / build:rpm (rocky8) (push) Failing after 11m47s
Build Packages / build:rpm (ubuntu2204) (push) Failing after 7m45s
Build Packages / build:rpm (ubuntu2404) (push) Failing after 6m16s
Build Packages / Unit tests (push) Successful in 56m23s
Build Packages / build:rpm (rocky8_nocuda) (push) Failing after 6m2s
Build Packages / build:rpm (rocky9_nocuda) (push) Failing after 7m30s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Failing after 8m18s
Build Packages / DIALS processing test (push) Failing after 0s
Build Packages / build:rpm (rocky8_sls9) (push) Failing after 8m45s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Failing after 8m52s
Build Packages / Generate python client (push) Successful in 2m0s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (rocky9_sls9) (push) Failing after 10m28s
Build Packages / Build documentation (push) Successful in 2m27s
Build Packages / build:rpm (rocky9) (push) Failing after 11m35s
Build Packages / build:rpm (rocky8) (push) Failing after 11m47s
Build Packages / build:rpm (ubuntu2204) (push) Failing after 7m45s
Build Packages / build:rpm (ubuntu2404) (push) Failing after 6m16s
Build Packages / Unit tests (push) Successful in 56m23s
1. What if write_master_file = false 2. Finalized file statistics use wrong name
This commit is contained in:
@@ -817,6 +817,274 @@ TEST_CASE("HDF5Writer_Link_VDS", "[HDF5][Full]") {
|
||||
REQUIRE (H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("HDF5Writer_NXmxIntegrated_Basic", "[HDF5][Full]") {
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
x.ImagesPerTrigger(5).ImagesPerFile(2).Compression(CompressionAlgorithm::NO_COMPRESSION)
|
||||
.FilePrefix("integrated_basic");
|
||||
x.SetFileWriterFormat(FileWriterFormat::NXmxIntegrated).OverwriteExistingFiles(true);
|
||||
|
||||
// NXmxIntegrated forces all images into one file
|
||||
REQUIRE(x.GetImagesPerFile() == x.GetImageNum());
|
||||
|
||||
{
|
||||
RegisterHDF5Filter();
|
||||
|
||||
StartMessage start_message;
|
||||
x.FillMessage(start_message);
|
||||
|
||||
REQUIRE(start_message.file_format == FileWriterFormat::NXmxIntegrated);
|
||||
// images_per_file should equal total images for integrated
|
||||
REQUIRE(start_message.images_per_file == x.GetImageNum());
|
||||
|
||||
EndMessage end_message;
|
||||
end_message.max_image_number = x.GetImageNum();
|
||||
|
||||
FileWriter writer(start_message);
|
||||
std::vector<int16_t> image(x.GetPixelsNum(), 42);
|
||||
|
||||
for (int i = 0; i < x.GetImageNum(); i++) {
|
||||
DataMessage message{};
|
||||
message.image = CompressedImage(image, x.GetXPixelsNum(), x.GetYPixelsNum());
|
||||
message.number = i;
|
||||
REQUIRE_NOTHROW(writer.Write(message));
|
||||
}
|
||||
|
||||
writer.WriteHDF5(end_message);
|
||||
auto stats = writer.Finalize();
|
||||
|
||||
// All images in one file — only one stats entry
|
||||
REQUIRE(stats.size() == 1);
|
||||
REQUIRE(stats[0].total_images == x.GetImageNum());
|
||||
}
|
||||
|
||||
// Single integrated file, no separate master or data files
|
||||
REQUIRE(std::filesystem::exists("integrated_basic.h5"));
|
||||
REQUIRE(!std::filesystem::exists("integrated_basic_master.h5"));
|
||||
REQUIRE(!std::filesystem::exists("integrated_basic_data_000001.h5"));
|
||||
|
||||
{
|
||||
HDF5ReadOnlyFile file("integrated_basic.h5");
|
||||
|
||||
// Data should be directly in the file
|
||||
std::unique_ptr<HDF5DataSet> dataset;
|
||||
REQUIRE_NOTHROW(dataset = std::make_unique<HDF5DataSet>(file, "/entry/data/data"));
|
||||
HDF5DataSpace file_space(*dataset);
|
||||
REQUIRE(file_space.GetNumOfDimensions() == 3);
|
||||
REQUIRE(file_space.GetDimensions()[0] == x.GetImageNum());
|
||||
REQUIRE(file_space.GetDimensions()[1] == x.GetYPixelsNum());
|
||||
REQUIRE(file_space.GetDimensions()[2] == x.GetXPixelsNum());
|
||||
|
||||
// Master metadata should also be present
|
||||
REQUIRE_NOTHROW(dataset = std::make_unique<HDF5DataSet>(file, "/entry/instrument/detector/beam_center_x"));
|
||||
REQUIRE(dataset->ReadScalar<float>() == Catch::Approx(x.GetBeamX_pxl()));
|
||||
|
||||
// No external links (unlike NXmxLegacy)
|
||||
REQUIRE_THROWS(std::make_unique<HDF5DataSet>(file, "/entry/data/data_000001"));
|
||||
}
|
||||
|
||||
// No leftover HDF5 objects
|
||||
REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
remove("integrated_basic.h5");
|
||||
}
|
||||
|
||||
TEST_CASE("HDF5Writer_NXmxIntegrated_WithSpots", "[HDF5][Full]") {
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
x.ImagesPerTrigger(3).Compression(CompressionAlgorithm::NO_COMPRESSION)
|
||||
.FilePrefix("integrated_spots");
|
||||
x.SetFileWriterFormat(FileWriterFormat::NXmxIntegrated).OverwriteExistingFiles(true);
|
||||
|
||||
{
|
||||
RegisterHDF5Filter();
|
||||
|
||||
StartMessage start_message;
|
||||
x.FillMessage(start_message);
|
||||
|
||||
EndMessage end_message;
|
||||
end_message.max_image_number = x.GetImageNum();
|
||||
|
||||
FileWriter writer(start_message);
|
||||
std::vector<int16_t> image(x.GetPixelsNum(), 10);
|
||||
|
||||
std::vector<SpotToSave> spots;
|
||||
spots.push_back({10.0f, 20.0f, 100.0f});
|
||||
spots.push_back({30.0f, 40.0f, 200.0f});
|
||||
|
||||
for (int i = 0; i < x.GetImageNum(); i++) {
|
||||
DataMessage message{};
|
||||
message.image = CompressedImage(image, x.GetXPixelsNum(), x.GetYPixelsNum());
|
||||
message.spots = spots;
|
||||
message.number = i;
|
||||
message.image_collection_efficiency = 1.0f;
|
||||
REQUIRE_NOTHROW(writer.Write(message));
|
||||
}
|
||||
|
||||
writer.WriteHDF5(end_message);
|
||||
auto stats = writer.Finalize();
|
||||
REQUIRE(stats.size() == 1);
|
||||
}
|
||||
|
||||
REQUIRE(std::filesystem::exists("integrated_spots.h5"));
|
||||
{
|
||||
HDF5ReadOnlyFile file("integrated_spots.h5");
|
||||
|
||||
// Detector plugin data should exist in the same file
|
||||
REQUIRE(file.Exists("/entry/detector"));
|
||||
|
||||
// Image data should exist
|
||||
std::unique_ptr<HDF5DataSet> dataset;
|
||||
REQUIRE_NOTHROW(dataset = std::make_unique<HDF5DataSet>(file, "/entry/data/data"));
|
||||
}
|
||||
|
||||
REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
remove("integrated_spots.h5");
|
||||
}
|
||||
|
||||
TEST_CASE("HDF5Writer_NXmxIntegrated_ZeroImages", "[HDF5][Full]") {
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
x.ImagesPerTrigger(5).Compression(CompressionAlgorithm::NO_COMPRESSION)
|
||||
.FilePrefix("integrated_zero");
|
||||
x.SetFileWriterFormat(FileWriterFormat::NXmxIntegrated).OverwriteExistingFiles(true);
|
||||
|
||||
{
|
||||
RegisterHDF5Filter();
|
||||
|
||||
StartMessage start_message;
|
||||
x.FillMessage(start_message);
|
||||
|
||||
EndMessage end_message;
|
||||
end_message.max_image_number = 0;
|
||||
|
||||
FileWriter writer(start_message);
|
||||
// Write no images — just finalize
|
||||
writer.WriteHDF5(end_message);
|
||||
auto stats = writer.Finalize();
|
||||
|
||||
// No data files created
|
||||
REQUIRE(stats.empty());
|
||||
}
|
||||
|
||||
// Master file should still exist with metadata
|
||||
REQUIRE(std::filesystem::exists("integrated_zero.h5"));
|
||||
{
|
||||
HDF5ReadOnlyFile file("integrated_zero.h5");
|
||||
REQUIRE(file.Exists("/entry"));
|
||||
// No data dataset since no images written
|
||||
REQUIRE_THROWS(std::make_unique<HDF5DataSet>(file, "/entry/data/data"));
|
||||
}
|
||||
|
||||
REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
remove("integrated_zero.h5");
|
||||
}
|
||||
|
||||
TEST_CASE("HDF5Writer_NXmxIntegrated_AzInt", "[HDF5][Full]") {
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
x.DetectorDistance_mm(50).BeamX_pxl(500).BeamY_pxl(500);
|
||||
x.QSpacingForAzimInt_recipA(0.1).QRangeForAzimInt_recipA(0.1, 4.0);
|
||||
x.ImagesPerTrigger(3).Compression(CompressionAlgorithm::NO_COMPRESSION)
|
||||
.FilePrefix("integrated_azint");
|
||||
x.SetFileWriterFormat(FileWriterFormat::NXmxIntegrated).OverwriteExistingFiles(true);
|
||||
|
||||
PixelMask pixel_mask(x);
|
||||
AzimuthalIntegration mapping(x, pixel_mask);
|
||||
|
||||
{
|
||||
RegisterHDF5Filter();
|
||||
|
||||
StartMessage start_message;
|
||||
x.FillMessage(start_message);
|
||||
start_message.az_int_bin_to_q = mapping.GetBinToQ();
|
||||
start_message.az_int_phi_bin_count = mapping.GetAzimuthalBinCount();
|
||||
start_message.az_int_q_bin_count = mapping.GetQBinCount();
|
||||
|
||||
EndMessage end_message;
|
||||
end_message.max_image_number = x.GetImageNum();
|
||||
|
||||
FileWriter writer(start_message);
|
||||
std::vector<int16_t> image(x.GetPixelsNum(), 5);
|
||||
|
||||
for (int i = 0; i < x.GetImageNum(); i++) {
|
||||
DataMessage message{};
|
||||
message.image = CompressedImage(image, x.GetXPixelsNum(), x.GetYPixelsNum());
|
||||
message.az_int_profile = std::vector<float>(mapping.GetBinNumber(), static_cast<float>(i));
|
||||
message.number = i;
|
||||
REQUIRE_NOTHROW(writer.Write(message));
|
||||
}
|
||||
|
||||
writer.WriteHDF5(end_message);
|
||||
auto stats = writer.Finalize();
|
||||
REQUIRE(stats.size() == 1);
|
||||
}
|
||||
|
||||
REQUIRE(std::filesystem::exists("integrated_azint.h5"));
|
||||
{
|
||||
HDF5ReadOnlyFile file("integrated_azint.h5");
|
||||
|
||||
// Azimuthal integration bin mapping should exist (written by plugin)
|
||||
std::unique_ptr<HDF5DataSet> dataset;
|
||||
REQUIRE_NOTHROW(dataset = std::make_unique<HDF5DataSet>(file, "/entry/azint/bin_to_q"));
|
||||
|
||||
// Per-image azint data should exist
|
||||
REQUIRE_NOTHROW(dataset = std::make_unique<HDF5DataSet>(file, "/entry/azint/image"));
|
||||
HDF5DataSpace space(*dataset);
|
||||
REQUIRE(space.GetNumOfDimensions() == 3);
|
||||
REQUIRE(space.GetDimensions()[0] == x.GetImageNum());
|
||||
}
|
||||
|
||||
REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
remove("integrated_azint.h5");
|
||||
}
|
||||
|
||||
TEST_CASE("HDF5Writer_NXmxIntegrated_OutOfOrder", "[HDF5][Full]") {
|
||||
// Test that out-of-order image delivery works with NXmxIntegrated
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
x.ImagesPerTrigger(5).Compression(CompressionAlgorithm::NO_COMPRESSION)
|
||||
.FilePrefix("integrated_ooo");
|
||||
x.SetFileWriterFormat(FileWriterFormat::NXmxIntegrated).OverwriteExistingFiles(true);
|
||||
|
||||
{
|
||||
RegisterHDF5Filter();
|
||||
|
||||
StartMessage start_message;
|
||||
x.FillMessage(start_message);
|
||||
|
||||
EndMessage end_message;
|
||||
end_message.max_image_number = x.GetImageNum();
|
||||
|
||||
FileWriter writer(start_message);
|
||||
std::vector<int16_t> image(x.GetPixelsNum(), 7);
|
||||
|
||||
// Write images out of order
|
||||
std::vector<int> order = {3, 1, 4, 0, 2};
|
||||
for (int idx : order) {
|
||||
DataMessage message{};
|
||||
message.image = CompressedImage(image, x.GetXPixelsNum(), x.GetYPixelsNum());
|
||||
message.number = idx;
|
||||
REQUIRE_NOTHROW(writer.Write(message));
|
||||
}
|
||||
|
||||
writer.WriteHDF5(end_message);
|
||||
auto stats = writer.Finalize();
|
||||
REQUIRE(stats.size() == 1);
|
||||
REQUIRE(stats[0].total_images == 5);
|
||||
}
|
||||
|
||||
REQUIRE(std::filesystem::exists("integrated_ooo.h5"));
|
||||
{
|
||||
HDF5ReadOnlyFile file("integrated_ooo.h5");
|
||||
std::unique_ptr<HDF5DataSet> dataset;
|
||||
REQUIRE_NOTHROW(dataset = std::make_unique<HDF5DataSet>(file, "/entry/data/data"));
|
||||
HDF5DataSpace file_space(*dataset);
|
||||
REQUIRE(file_space.GetDimensions()[0] == 5);
|
||||
}
|
||||
|
||||
REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
remove("integrated_ooo.h5");
|
||||
}
|
||||
|
||||
TEST_CASE("HDF5Writer_NoMasterFile", "[HDF5][Full]") {
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
Reference in New Issue
Block a user