Read any rotation axis by name, and tell a stationary axis from a sweep
Two things the goniometer handling conflated. The axis name is free-form everywhere that writes it - the API imposes only minLength, the CBOR map uses the name as its key, and tests/CBORTest.cpp round trips one literally called "z" - but the reader looked for exactly "/entry/sample/transformations/omega". A sweep recorded as "phi" therefore came back as stills, in the viewer and in rugnux, with nothing to indicate it. The reader now walks the transformations group and takes whichever axis is a rotation, preferring one that turns; the grid scan is read independently rather than as the else-branch of the same test, since a grid scan can be taken at a given head position. Second: "an axis is defined" and "the axis is turning" were the same question, answered inconsistently - GetImagesPerFile checked the increment, IsRotationIndexing did not, and the CBOR decoder deleted zero-increment axes outright so the ambiguity could never surface. GoniometerAxis::IsScanning now asks it explicitly and the call sites go through it, so a stationary axis can be carried without being mistaken for rotation data. That mistake is not hypothetical: RotationIndexerCounter leaves its stride at zero for a zero increment, and Process() then never fires, so indexing would silently never run. Keeping stationary axes is also what lets the writer state where the head was for a still or a grid scan, which is the next step. JFJochReader_Goniometer_NonOmegaName covers the naming case through the writer and back; nothing did before, because both existing round trips use "omega". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -395,6 +395,56 @@ TEST_CASE("JFJochReader_Goniometer", "[HDF5][Full]") {
|
||||
REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
}
|
||||
|
||||
// The axis name is free-form in the API, on the wire and in the writer - tests/CBORTest.cpp round
|
||||
// trips one literally called "z". The reader used to look only for "omega", so a sweep recorded
|
||||
// under any other name came back as stills, with nothing to indicate it. This is that case.
|
||||
TEST_CASE("JFJochReader_Goniometer_NonOmegaName", "[HDF5][Full]") {
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
x.FilePrefix("test17b").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.Goniometer(GoniometerAxis("phi", 12, 0.2f, Coord(-1,0,0),{}));
|
||||
|
||||
RegisterHDF5Filter();
|
||||
|
||||
std::vector<uint16_t> 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 = i;
|
||||
REQUIRE_NOTHROW(file_set.WriteHDF5(message));
|
||||
}
|
||||
|
||||
EndMessage end_message;
|
||||
end_message.max_image_number = 5;
|
||||
file_set.WriteHDF5(end_message);
|
||||
file_set.Finalize();
|
||||
}
|
||||
{
|
||||
JFJochHDF5Reader reader;
|
||||
reader.ReadFile("test17b_master.h5");
|
||||
auto dataset = reader.GetDataset();
|
||||
|
||||
REQUIRE(dataset->experiment.GetGoniometer().has_value());
|
||||
CHECK(dataset->experiment.GetGoniometer()->GetName() == "phi");
|
||||
CHECK(dataset->experiment.GetGoniometer()->GetStart_deg() == 12.0);
|
||||
CHECK(dataset->experiment.GetGoniometer()->GetIncrement_deg() == Catch::Approx(0.2f).margin(0.00001f));
|
||||
CHECK(dataset->experiment.GetGoniometer()->IsScanning());
|
||||
CHECK(dataset->experiment.GetGoniometer()->GetAxis().x == -1);
|
||||
}
|
||||
remove("test17b_master.h5");
|
||||
|
||||
REQUIRE(H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("JFJochReader_GridScan", "[HDF5][Full]") {
|
||||
DiffractionExperiment x(DetJF(1));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user