Mark unreadable frames in the reprocessing virtual dataset too

The master's own virtual dataset fills with the error marker, so a source file that cannot be
resolved reads as masked rather than as zero counts. The virtual dataset rugnux writes into
_process.h5 was left at HDF5's default fill of zero, which is a legitimate count - the same silent
failure, one file along.

The helper moves above its first user; it has to be set before SetVirtual.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VfYvJT5Nb71suJCowRBn5z
This commit is contained in:
2026-08-23 12:42:47 +02:00
co-authored by Claude Opus 5
parent b2058d1a79
commit a1b48e9454
+29 -24
View File
@@ -194,6 +194,30 @@ void NXmx::LinkToData_VDS(const StartMessage &start, const EndMessage &end) {
}
}
namespace {
void SetFillValue(HDF5Dcpl &dcpl, const HDF5DataType &data_type,
const std::optional<int64_t> &fill_value) {
if (!fill_value.has_value())
return;
const int64_t value = fill_value.value();
if (data_type.IsSigned()) {
switch (data_type.GetElemSize()) {
case 1: dcpl.SetFillValue8(static_cast<int8_t>(value)); break;
case 2: dcpl.SetFillValue16(static_cast<int16_t>(value)); break;
case 4: dcpl.SetFillValue32(static_cast<int32_t>(value)); break;
default: break;
}
} else {
switch (data_type.GetElemSize()) {
case 1: dcpl.SetFillValueU8(static_cast<uint8_t>(value)); break;
case 2: dcpl.SetFillValueU16(static_cast<uint16_t>(value)); break;
case 4: dcpl.SetFillValueU32(static_cast<uint32_t>(value)); break;
default: break;
}
}
}
}
void NXmx::LinkToData_ProcessingVDS(const StartMessage &start, const EndMessage &end) {
if (start.hdf5_source_data.empty() || end.max_image_number == 0)
return;
@@ -207,6 +231,11 @@ void NXmx::LinkToData_ProcessingVDS(const StartMessage &start, const EndMessage
HDF5DataSpace full_data_space({total_images, height, width});
HDF5Dcpl dcpl;
dcpl.SetChunking({1, height, width});
// Same reason as the master's own virtual dataset: a source file that cannot be resolved reads
// as the fill value, and HDF5's default fill is zero - which is a legitimate count. Fill with the
// error marker instead, so an unreadable frame is masked rather than integrated as blank. Must be
// set before SetVirtual.
SetFillValue(dcpl, HDF5DataType(start.bit_depth_image / 8, start.pixel_signed), start.error_value);
for (const auto &mapping: start.hdf5_source_data) {
if (mapping.image_count == 0)
@@ -282,30 +311,6 @@ void NXmx::LinkToReflections_VDS(const StartMessage &start, const EndMessage &en
}
}
namespace {
void SetFillValue(HDF5Dcpl &dcpl, const HDF5DataType &data_type,
const std::optional<int64_t> &fill_value) {
if (!fill_value.has_value())
return;
const int64_t value = fill_value.value();
if (data_type.IsSigned()) {
switch (data_type.GetElemSize()) {
case 1: dcpl.SetFillValue8(static_cast<int8_t>(value)); break;
case 2: dcpl.SetFillValue16(static_cast<int16_t>(value)); break;
case 4: dcpl.SetFillValue32(static_cast<int32_t>(value)); break;
default: break;
}
} else {
switch (data_type.GetElemSize()) {
case 1: dcpl.SetFillValueU8(static_cast<uint8_t>(value)); break;
case 2: dcpl.SetFillValueU16(static_cast<uint16_t>(value)); break;
case 4: dcpl.SetFillValueU32(static_cast<uint32_t>(value)); break;
default: break;
}
}
}
}
std::unique_ptr<HDF5DataSet> NXmx::VDS(const StartMessage &start,
const std::string &name,
const std::vector<hsize_t> &dim,