JFConversionFloatingPoint: Integrate other bit depths/signs

This commit is contained in:
2023-11-07 15:36:49 +01:00
parent be546e9f76
commit 2dfd878d01
5 changed files with 184 additions and 17 deletions

View File

@@ -83,11 +83,18 @@ bool TestImagePusher::CheckImage(const DiffractionExperiment &x, const std::vect
logger.Error("Image empty");
no_errors = false;
} else {
std::vector<int16_t> decompressed_image;
std::vector<uint16_t> decompressed_image_16;
std::vector<uint32_t> decompressed_image_32;
// Image decompression
try {
JFJochDecompress(decompressed_image, x.GetCompressionAlgorithmEnum(),
if (x.GetPixelDepth() == 2)
JFJochDecompress(decompressed_image_16, x.GetCompressionAlgorithmEnum(),
receiver_generated_image, x.GetPixelsNum());
else
JFJochDecompress(decompressed_image_32, x.GetCompressionAlgorithmEnum(),
receiver_generated_image, x.GetPixelsNum());
} catch (const JFJochException &e) {
logger.Error(e.what());
no_errors = false;
@@ -100,18 +107,51 @@ bool TestImagePusher::CheckImage(const DiffractionExperiment &x, const std::vect
if (x.GetStorageCellNumber() > 1)
storage_cell = image_id % x.GetStorageCellNumber();
double result = CheckConversionWithGeomTransform(x, calibration,
raw_reference_image.data(),
decompressed_image.data(),
storage_cell);
double result = 0;
if (x.GetPixelDepth() == 2) {
if (x.IsPixelSigned())
result = CheckConversionWithGeomTransform(x, calibration,
raw_reference_image.data(),
(int16_t *) decompressed_image_16.data(),
storage_cell);
else
result = CheckConversionWithGeomTransform(x, calibration,
raw_reference_image.data(),
(uint16_t *) decompressed_image_16.data(),
storage_cell);
} else if (x.GetPixelDepth() == 4) {
if (x.IsPixelSigned())
result = CheckConversionWithGeomTransform(x, calibration,
raw_reference_image.data(),
(int32_t *) decompressed_image_32.data(),
storage_cell);
else
result = CheckConversionWithGeomTransform(x, calibration,
raw_reference_image.data(),
(uint32_t *) decompressed_image_32.data(),
storage_cell);
}
if (result > 0.5) {
logger.Error("Mean conversion error ({:.3f}) larger than threshold", result);
no_errors = false;
} else
logger.Info("Mean conversion error: {:.3f}", result);
} else if (x.GetDetectorMode() == DetectorMode::Raw) {
if (memcmp(raw_reference_image.data(), decompressed_image.data(), sizeof(uint16_t) * x.GetPixelsNum()) !=
0) {
size_t diff = 0;
if (x.GetPixelDepth() == 2) {
for (int i = 0; i < x.GetPixelsNum(); i++) {
if (raw_reference_image[i] != decompressed_image_16[i])
diff++;
}
} else {
for (int i = 0; i < x.GetPixelsNum(); i++) {
if (raw_reference_image[i] != decompressed_image_32[i])
diff++;
}
}
if (diff != 0) {
logger.Error("Raw data mismatch");
no_errors = false;
}

View File

@@ -6,6 +6,29 @@ JFConversionFloatingPoint::JFConversionFloatingPoint()
: gain_g0(RAW_MODULE_SIZE), gain_g1(RAW_MODULE_SIZE), gain_g2(RAW_MODULE_SIZE),
pedestal_g0(RAW_MODULE_SIZE), pedestal_g1(RAW_MODULE_SIZE), pedestal_g2(RAW_MODULE_SIZE) {}
JFConversionFloatingPoint::JFConversionFloatingPoint(const DiffractionExperiment &experiment) : JFConversionFloatingPoint() {
summation = experiment.GetSummation();
pixel_signed = experiment.IsPixelSigned();
if (experiment.GetPixelDepth() == 2) {
if (pixel_signed) {
err_pixel = INT16_MIN;
overload_pixel = INT16_MAX;
} else {
err_pixel = UINT16_MAX;
overload_pixel = UINT16_MAX - 1;
}
} else if (experiment.GetPixelDepth() == 4) {
if (pixel_signed) {
err_pixel = INT32_MIN;
overload_pixel = INT32_MAX;
} else {
err_pixel = UINT32_MAX;
overload_pixel = UINT32_MAX - 1;
}
}
}
inline double one_over_gain_energy(double gain_factor, double energy) {
double tmp = gain_factor * energy;
if (!std::isfinite(tmp) || (tmp == 0.0))
@@ -115,8 +138,15 @@ void JFConversionFloatingPoint::ConvertFP(double *dest, const uint16_t *source)
break;
}
if (summation > 1)
expected *= summation;
if ((expected > overload_pixel) && !special_val)
expected = overload_pixel;
dest[i] = expected;
if ((!pixel_signed) && (expected < 0))
dest[i] = 0;
else
dest[i] = expected;
}
}

View File

@@ -16,9 +16,11 @@ class JFConversionFloatingPoint {
double err_pixel = INT16_MIN;
double overload_pixel = INT16_MAX;
int64_t summation = 1;
bool pixel_signed = true;
public:
JFConversionFloatingPoint();
JFConversionFloatingPoint(const DiffractionExperiment& experiment);
void Setup(const JFModuleGainCalibration &gain_calibration,
const JFModulePedestal &pedestal_g0,
const JFModulePedestal &pedestal_g1,

View File

@@ -25,6 +25,8 @@ template <class T> double Compare(T *source, std::vector<double> &reference, int
for (size_t i = 0; i < npixel; i++) {
double diff = reference[i] - source[i];
if (fabs(diff) >= 1000)
std::cout << i << " " << reference[i] << " " << source[i] << std::endl;
result += diff * diff;
}
@@ -36,8 +38,6 @@ template <class T> double MaxErrorOnConversion(T *source, std::vector<double> &r
for (size_t i = 0; i < npixel; i++) {
double val = abs(reference[i] - source[i]);
if (val >= 32768)
std::cout << i << " " << reference[i] << " " << source[i] << std::endl;
if (val > ret) ret = val;
}
return ret;
@@ -50,7 +50,7 @@ template <class T> double CheckConversion(const DiffractionExperiment &experimen
std::vector<double> conversion_ref(RAW_MODULE_SIZE);
JFConversionFloatingPoint conversion;
JFConversionFloatingPoint conversion(experiment);
conversion.Setup(calib.GainCalibration(0),
calib.Pedestal(0, 0, storage_cell),
calib.Pedestal(0, 1, storage_cell),
@@ -65,13 +65,23 @@ template <class T> double CheckConversionWithGeomTransform(const DiffractionExpe
const JFCalibration &calib,
const uint16_t *raw, T *converted,
size_t storage_cell = 0) {
T fill_value = INT16_MIN;
if (experiment.GetPixelDepth() == 4)
fill_value = INT32_MIN;
T fill_value;
if (sizeof(T) == 2) {
if (std::is_signed<T>::value)
fill_value = INT16_MIN;
else
fill_value = UINT16_MAX;
} else if (sizeof(T) == 4) {
if (std::is_signed<T>::value)
fill_value = INT32_MIN;
else
fill_value = UINT32_MAX;
}
std::vector<double> conversion_ref(experiment.GetModulesNum() * RAW_MODULE_SIZE);
std::vector<double> conversion_ref_transformed(experiment.GetPixelsNum(), fill_value);
JFConversionFloatingPoint conversion;
JFConversionFloatingPoint conversion(experiment);
for (int m = 0; m < experiment.GetModulesNum(); m ++) {
conversion.Setup(calib.GainCalibration(m),

View File

@@ -67,6 +67,91 @@ TEST_CASE("JFJochReceiverTest_Conversion", "[JFJochReceiver]") {
REQUIRE(!output.cancelled());
}
TEST_CASE("JFJochReceiverTest_Conversion_U16", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Conversion");
DiffractionExperiment x(DetectorGeometry(2));
const uint16_t nthreads = 4;
x.Mode(DetectorMode::Conversion);
x.PedestalG0Frames(0).NumTriggers(1).UseInternalPacketGenerator(true)
.ImagesPerTrigger(32).DataFileCount(16).PhotonEnergy_keV(12.4).Compression(JFJochProtoBuf::BSHUF_ZSTD).FPGAOutputMode(JFJochProtoBuf::UINT16);
REQUIRE(!x.IsPixelSigned());
std::vector<std::unique_ptr<AcquisitionDevice>> aq_devices;
for (int i = 0; i < x.GetDataStreamsNum(); i++) {
HLSSimulatedDevice *test;
test = new HLSSimulatedDevice(i, 64);
test->EnableLogging(&logger);
aq_devices.emplace_back(test);
}
JFJochProtoBuf::ReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE(ret);
REQUIRE(output.efficiency() == 1.0);
REQUIRE(output.images_sent() == x.GetImageNum());
REQUIRE(!output.cancelled());
}
TEST_CASE("JFJochReceiverTest_Conversion_I32", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Conversion");
DiffractionExperiment x(DetectorGeometry(2));
const uint16_t nthreads = 4;
x.Mode(DetectorMode::Conversion);
x.PedestalG0Frames(0).NumTriggers(1).UseInternalPacketGenerator(true)
.ImagesPerTrigger(32).DataFileCount(16).PhotonEnergy_keV(12.4).Compression(JFJochProtoBuf::BSHUF_ZSTD).FPGAOutputMode(JFJochProtoBuf::INT32);
std::vector<std::unique_ptr<AcquisitionDevice>> aq_devices;
for (int i = 0; i < x.GetDataStreamsNum(); i++) {
HLSSimulatedDevice *test;
test = new HLSSimulatedDevice(i, 64);
test->EnableLogging(&logger);
aq_devices.emplace_back(test);
}
JFJochProtoBuf::ReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE(ret);
REQUIRE(output.efficiency() == 1.0);
REQUIRE(output.images_sent() == x.GetImageNum());
REQUIRE(!output.cancelled());
}
TEST_CASE("JFJochReceiverTest_Conversion_Summation2", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Conversion");
DiffractionExperiment x(DetectorGeometry(2));
const uint16_t nthreads = 4;
x.Mode(DetectorMode::Conversion);
x.PedestalG0Frames(0).NumTriggers(1).UseInternalPacketGenerator(true)
.ImagesPerTrigger(32).DataFileCount(16).PhotonEnergy_keV(12.4).Compression(JFJochProtoBuf::BSHUF_ZSTD).Summation(2);
std::vector<std::unique_ptr<AcquisitionDevice>> aq_devices;
for (int i = 0; i < x.GetDataStreamsNum(); i++) {
HLSSimulatedDevice *test;
test = new HLSSimulatedDevice(i, 64);
test->EnableLogging(&logger);
aq_devices.emplace_back(test);
}
JFJochProtoBuf::ReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE(ret);
REQUIRE(output.efficiency() == 1.0);
REQUIRE(output.images_sent() == x.GetImageNum());
REQUIRE(!output.cancelled());
}
TEST_CASE("JFJochReceiverTest_Conversion_StorageCell", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Conversion_StorageCell");