JFConversionFloatingPoint: Integrate other bit depths/signs
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user