From c3236eed44935545c6973d698a85832709e795e0 Mon Sep 17 00:00:00 2001 From: jungfrau Date: Sun, 23 Aug 2026 08:31:35 -0400 Subject: [PATCH] Publish the underload, not the error marker, on the finalized-file socket The finalized-file notification has carried j["underload"] = error_value since the two meant the same thing. They stopped meaning the same thing when error_value became the marker the pixels actually store: UINTx_MAX for an unsigned image, where it used to be GetUnderflow()'s -1, a value no unsigned pixel can hold and which therefore excluded nothing. So for an unsigned 16-bit run the key went from -1 to 65535. A facility that forwards it into an XDS UNDERLOAD or a DIALS trusted range - which is what a key called "underload" is for - would reject every pixel below 65535, i.e. all of them. Nothing in HDF5 is affected and none of the writer tests look at this socket, so it fails silently and outside the file. The start message already carries underload_value, the lowest valid value: 0 for an unsigned image and INTx_MIN+1 for a signed one. Send that. The signed case moves too, from the marker itself to one above it, which is what the key has always claimed to be. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_011n8riB6X59oRjkrSHzNPAU --- writer/FileWriter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/writer/FileWriter.cpp b/writer/FileWriter.cpp index 316a69b5..e00f586e 100644 --- a/writer/FileWriter.cpp +++ b/writer/FileWriter.cpp @@ -189,8 +189,12 @@ void FileWriter::AddStats(const std::optional& s) { } if (start_message.space_group_number) j["space_group_number"] = start_message.space_group_number.value(); - if (start_message.error_value) - j["underload"] = start_message.error_value.value(); + // The lowest VALID value, not the error marker. These were the same field until the marker + // became the value the pixels actually carry: for an unsigned image that is UINTx_MAX, and a + // consumer feeding this key into an XDS UNDERLOAD or a DIALS trusted range would then reject + // every pixel below 65535. + if (start_message.underload_value) + j["underload"] = start_message.underload_value.value(); j["user_data"] = start_message.user_data; finalized_file_socket->Send(j.dump());