diff --git a/reader/JFJochHDF5Reader.cpp b/reader/JFJochHDF5Reader.cpp index 88e30178..79771c59 100644 --- a/reader/JFJochHDF5Reader.cpp +++ b/reader/JFJochHDF5Reader.cpp @@ -5,6 +5,7 @@ #include "spdlog/fmt/fmt.h" #include "../image_analysis/bragg_integration/CalcISigma.h" #include "../image_analysis/spot_finding/SpotUtils.h" +#include "../common/GridScanSettings.h" std::vector GetDimension(HDF5Object& object, const std::string& path) { const auto dim = object.GetDimension(path); @@ -234,8 +235,18 @@ void JFJochHDF5Reader::ReadFile(const std::string& filename) { dataset->experiment.ImportInstrumentMetadata(metadata); if (master_file->Exists("/entry/sample/transformations")) { - auto omega = ReadAxis(master_file.get(), "omega"); - dataset->experiment.Goniometer(omega); + if (master_file->Exists("/entry/sample/transformations/omega")) { + auto omega = ReadAxis(master_file.get(), "omega"); + dataset->experiment.Goniometer(omega); + } else if (master_file->Exists("/entry/sample/grid_scan")) { + dataset->experiment.GridScan(GridScanSettings( + master_file->GetInt("/entry/sample/grid_scan/n_fast"), + master_file->GetFloat("/entry/sample/grid_scan/step_x") * 1e6f, + master_file->GetFloat("/entry/sample/grid_scan/step_y") * 1e6f, + master_file->GetOptBool("/entry/sample/grid_scan/snake_scan").value_or(false), + master_file->GetOptBool("/entry/sample/grid_scan/vertical_scan").value_or(false) + )); + } } auto tmp = master_file->ReadOptVector("/entry/sample/unit_cell"); diff --git a/tests/JFJochReaderTest.cpp b/tests/JFJochReaderTest.cpp index cef18455..ded0d293 100644 --- a/tests/JFJochReaderTest.cpp +++ b/tests/JFJochReaderTest.cpp @@ -271,6 +271,7 @@ TEST_CASE("JFJochReader_Goniometer", "[HDF5][Full]") { reader.ReadFile("test17_master.h5"); auto dataset = reader.GetDataset(); + REQUIRE(!dataset->experiment.GetGridScan().has_value()); REQUIRE(dataset->experiment.GetGoniometer().has_value()); CHECK(dataset->experiment.GetGoniometer()->GetStart_deg() == 95.0); @@ -285,6 +286,58 @@ TEST_CASE("JFJochReader_Goniometer", "[HDF5][Full]") { REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0); } +TEST_CASE("JFJochReader_GridScan", "[HDF5][Full]") { + DiffractionExperiment x(DetJF(1)); + + x.FilePrefix("test_reader_grid_scan").ImagesPerTrigger(950).OverwriteExistingFiles(true); + x.BeamX_pxl(100).BeamY_pxl(200).DetectorDistance_mm(150) + .IncidentEnergy_keV(WVL_1A_IN_KEV).PixelSigned(false).BitDepthImage(16) + .FrameTime(std::chrono::microseconds(500), std::chrono::microseconds(10)); + x.GridScan(GridScanSettings(25, -7.5, 8.0, true, true)); + + RegisterHDF5Filter(); + + std::vector image(x.GetPixelsNum(), 0); + { + StartMessage start_message; + x.FillMessage(start_message); + + FileWriter file_set(start_message); + + DataMessage message{}; + for (int i = 0; i < 5; i++) { + message.image = CompressedImage(image, x.GetXPixelsNum(), x.GetYPixelsNum()); + message.number = 0; + + REQUIRE_NOTHROW(file_set.WriteHDF5(message)); + } + + EndMessage end_message; + end_message.max_image_number = 4; + file_set.WriteHDF5(end_message); + + file_set.Finalize(); + } + { + JFJochHDF5Reader reader; + reader.ReadFile("test_reader_grid_scan_master.h5"); + auto dataset = reader.GetDataset(); + + + REQUIRE(!dataset->experiment.GetGoniometer().has_value()); + REQUIRE(dataset->experiment.GetGridScan().has_value()); + + CHECK(dataset->experiment.GetGridScan()->IsSnakeScan()); + CHECK(dataset->experiment.GetGridScan()->IsVerticalScan()); + CHECK(dataset->experiment.GetGridScan()->GetNFast() == 25); + CHECK(dataset->experiment.GetGridScan()->GetGridStepX_um() == Catch::Approx(-7.5)); + CHECK(dataset->experiment.GetGridScan()->GetGridStepY_um() == Catch::Approx(8.0)); + } + remove("test_reader_grid_scan_master.h5"); + + REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0); +} + TEST_CASE("JFJochReader_DataI16", "[HDF5][Full]") { DiffractionExperiment x(DetJF(1)); diff --git a/writer/HDF5NXmx.cpp b/writer/HDF5NXmx.cpp index 73119dc1..ed379120 100644 --- a/writer/HDF5NXmx.cpp +++ b/writer/HDF5NXmx.cpp @@ -586,6 +586,15 @@ void NXmx::Sample(const StartMessage &start, const EndMessage &end) { depends_on = "/entry/sample/transformations/" + start.goniometer->GetName() + "_helical_z"; } } else if (start.grid_scan.has_value()) { + HDF5Group grid_scan_group(group, "grid_scan"); + grid_scan_group.NXClass("NXcollection"); + + SaveScalar(grid_scan_group, "snake_scan", start.grid_scan->IsSnakeScan()); + SaveScalar(grid_scan_group, "vertical_scan", start.grid_scan->IsVerticalScan()); + SaveScalar(grid_scan_group, "n_fast", start.grid_scan->GetNFast()); + SaveScalar(grid_scan_group, "step_x", start.grid_scan->GetGridStepX_um() * 1e-6)->Units("m"); + SaveScalar(grid_scan_group, "step_y", start.grid_scan->GetGridStepY_um() * 1e-6)->Units("m"); + HDF5Group transformations(group, "transformations"); transformations.NXClass("NXtransformations"); hdf5_file->HardLink("/entry/sample/transformations","/entry/sample/goniometer");