JFConversion: Clean-up
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "DiffractionExperiment.h"
|
||||
#include "../compression/JFJochCompressor.h"
|
||||
#include "../jungfrau/JFConversion.h"
|
||||
|
||||
class FrameTransformation {
|
||||
const DiffractionExperiment& experiment;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
ADD_LIBRARY(JFCalibration STATIC
|
||||
JFCalibration.cpp JFCalibration.h
|
||||
JFConversion.h
|
||||
JFConversionFloatingPoint.cpp JFConversionFloatingPoint.h
|
||||
JFConversionFixedPoint.cpp JFConversionFixedPoint.h
|
||||
JFModulePedestal.cpp JFModulePedestal.h
|
||||
JFModuleGainCalibration.cpp JFModuleGainCalibration.h
|
||||
JFPedestalCalc.cpp JFPedestalCalc.h
|
||||
ProcessJFPacket.cpp ProcessJFPacket.h)
|
||||
)
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(JFPedestalCalc.cpp JFConversionFloatingPoint.cpp JFConversionFixedPoint.cpp PROPERTIES COMPILE_FLAGS -Ofast)
|
||||
SET_SOURCE_FILES_PROPERTIES(JFPedestalCalc.cpp JFConversionFloatingPoint.cpp PROPERTIES COMPILE_FLAGS -Ofast)
|
||||
|
||||
TARGET_LINK_LIBRARIES(JFCalibration JFJochProtoBuf Compression)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#ifndef JUNGFRAUJOCH_JFCONVERSION_H
|
||||
#define JUNGFRAUJOCH_JFCONVERSION_H
|
||||
|
||||
#include <cstddef>
|
||||
#include "JFModuleGainCalibration.h"
|
||||
#include "JFModulePedestal.h"
|
||||
|
||||
class JFConversion {
|
||||
public:
|
||||
virtual void Setup(const JFModuleGainCalibration &gain_calibration,
|
||||
const JFModulePedestal &pedestal_g0,
|
||||
const JFModulePedestal &pedestal_g1,
|
||||
const JFModulePedestal &pedestal_g2,
|
||||
double energy) = 0;
|
||||
|
||||
virtual void ConvertModule(int16_t* dest, const uint16_t* source) = 0;
|
||||
virtual void Sync() {};
|
||||
};
|
||||
|
||||
#endif //JUNGFRAUJOCH_JFCONVERSION_H
|
||||
@@ -1,124 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include "JFConversionFixedPoint.h"
|
||||
#include "../common/RawToConvertedGeometry.h"
|
||||
|
||||
#define FIXED_PRECISION 14
|
||||
|
||||
JFConversionFixedPoint::JFConversionFixedPoint() {
|
||||
gain_g0 = (int32_t *) std::aligned_alloc(64, RAW_MODULE_SIZE * sizeof(int32_t));
|
||||
gain_g1 = (int32_t *) std::aligned_alloc(64, RAW_MODULE_SIZE * sizeof(int32_t));
|
||||
gain_g2 = (int32_t *) std::aligned_alloc(64, RAW_MODULE_SIZE * sizeof(int32_t));
|
||||
pedestal_g0 = (uint16_t *) std::aligned_alloc(64, RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
pedestal_g1 = (uint16_t *) std::aligned_alloc(64, RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
pedestal_g2 = (uint16_t *) std::aligned_alloc(64, RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
JFConversionFixedPoint::~JFConversionFixedPoint() {
|
||||
std::free(gain_g0);
|
||||
std::free(gain_g1);
|
||||
std::free(gain_g2);
|
||||
std::free(pedestal_g0);
|
||||
std::free(pedestal_g1);
|
||||
std::free(pedestal_g2);
|
||||
}
|
||||
|
||||
inline int32_t one_over_gain_energy(double gain_factor, double energy) {
|
||||
double tmp = gain_factor * energy;
|
||||
if (!std::isfinite(tmp) || (tmp == 0.0))
|
||||
return INT16_MIN;
|
||||
else
|
||||
return std::lround((1 << FIXED_PRECISION) / (gain_factor * energy));
|
||||
}
|
||||
|
||||
void JFConversionFixedPoint::Setup(const JFModuleGainCalibration &gain_calibration,
|
||||
const JFModulePedestal &in_pedestal_g0,
|
||||
const JFModulePedestal &in_pedestal_g1,
|
||||
const JFModulePedestal &in_pedestal_g2,
|
||||
double energy) {
|
||||
auto &gain_arr = gain_calibration.GetGainCalibration();
|
||||
memcpy(pedestal_g0, in_pedestal_g0.GetPedestal(), RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
memcpy(pedestal_g1, in_pedestal_g1.GetPedestal(), RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
memcpy(pedestal_g2, in_pedestal_g2.GetPedestal(), RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
gain_g0[i] = one_over_gain_energy(gain_arr[i], energy);
|
||||
gain_g1[i] = one_over_gain_energy(gain_arr[i + RAW_MODULE_SIZE], energy);
|
||||
gain_g2[i] = one_over_gain_energy(gain_arr[i + 2 * RAW_MODULE_SIZE], energy);
|
||||
}
|
||||
}
|
||||
|
||||
inline int32_t jf_round(int32_t in) {
|
||||
const int32_t half = (1L << (FIXED_PRECISION-1));
|
||||
|
||||
if (in <= INT16_MIN * (1L << FIXED_PRECISION))
|
||||
return INT16_MIN * (1L << FIXED_PRECISION);
|
||||
else if (in >= INT16_MAX * (1L << FIXED_PRECISION))
|
||||
return INT16_MAX * (1L << FIXED_PRECISION);
|
||||
else if (in > 0)
|
||||
return in + half;
|
||||
else
|
||||
return in - half;
|
||||
}
|
||||
|
||||
void JFConversionFixedPoint::ConvertModule(int16_t *__restrict dest, const uint16_t *source) {
|
||||
auto gain_g0_aligned = std::assume_aligned<64>(gain_g0);
|
||||
auto gain_g1_aligned = std::assume_aligned<64>(gain_g1);
|
||||
auto gain_g2_aligned = std::assume_aligned<64>(gain_g2);
|
||||
auto pedestal_g0_aligned = std::assume_aligned<64>(pedestal_g0);
|
||||
auto pedestal_g1_aligned = std::assume_aligned<64>(pedestal_g1);
|
||||
auto pedestal_g2_aligned = std::assume_aligned<64>(pedestal_g2);
|
||||
|
||||
#pragma ivdep
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
uint16_t gainbits = source[i] & 0xc000;
|
||||
int32_t adc = source[i] & 0x3fff;
|
||||
|
||||
dest[i] = static_cast<int16_t>(jf_round((adc - pedestal_g0_aligned[i]) * gain_g0_aligned[i])
|
||||
/ (1L << FIXED_PRECISION));
|
||||
|
||||
int16_t val_1 = jf_round((adc - pedestal_g1_aligned[i]) * gain_g1_aligned[i])
|
||||
/ (1L << FIXED_PRECISION);
|
||||
|
||||
int16_t val_2 = jf_round((adc - pedestal_g2_aligned[i]) * gain_g2_aligned[i])
|
||||
/ (1L << FIXED_PRECISION);
|
||||
|
||||
if (gainbits == 0x4000)
|
||||
dest[i] = val_1;
|
||||
|
||||
if (gainbits == 0xc000)
|
||||
dest[i] = val_2;
|
||||
|
||||
if (gainbits == 0x8000)
|
||||
dest[i] = INT16_MIN;
|
||||
|
||||
if (source[i] == 0xffff)
|
||||
dest[i] = INT16_MIN;
|
||||
|
||||
if (source[i] == 0x4000)
|
||||
dest[i] = INT16_MIN;
|
||||
|
||||
if (source[i] == 0xc000)
|
||||
dest[i] = INT16_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
JFConversionFixedPoint::JFConversionFixedPoint(JFConversionFixedPoint &&other) noexcept {
|
||||
gain_g0 = other.gain_g0;
|
||||
other.gain_g0 = nullptr;
|
||||
|
||||
gain_g1 = other.gain_g1;
|
||||
other.gain_g1 = nullptr;
|
||||
|
||||
gain_g2 = other.gain_g2;
|
||||
other.gain_g2 = nullptr;
|
||||
|
||||
pedestal_g0 = other.pedestal_g0;
|
||||
other.pedestal_g0 = nullptr;
|
||||
|
||||
pedestal_g1 = other.pedestal_g1;
|
||||
other.pedestal_g1 = nullptr;
|
||||
|
||||
pedestal_g2 = other.pedestal_g2;
|
||||
other.pedestal_g2 = nullptr;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include "JFConversion.h"
|
||||
|
||||
#ifndef JUNGFRAUJOCH_JFCONVERSIONFIXEDPOINT_H
|
||||
#define JUNGFRAUJOCH_JFCONVERSIONFIXEDPOINT_H
|
||||
|
||||
class JFConversionFixedPoint : public JFConversion {
|
||||
uint16_t *pedestal_g0;
|
||||
uint16_t *pedestal_g1;
|
||||
uint16_t *pedestal_g2;
|
||||
int32_t *gain_g0;
|
||||
int32_t *gain_g1;
|
||||
int32_t *gain_g2;
|
||||
public:
|
||||
JFConversionFixedPoint();
|
||||
~JFConversionFixedPoint();
|
||||
JFConversionFixedPoint(JFConversionFixedPoint &&other) noexcept;
|
||||
JFConversionFixedPoint(const JFConversionFixedPoint &other) = delete;
|
||||
JFConversionFixedPoint& operator=(const JFConversionFixedPoint &other) = delete;
|
||||
|
||||
void Setup(const JFModuleGainCalibration &gain_calibration,
|
||||
const JFModulePedestal &pedestal_g0,
|
||||
const JFModulePedestal &pedestal_g1,
|
||||
const JFModulePedestal &pedestal_g2,
|
||||
double energy) override;
|
||||
void ConvertModule(int16_t *dest, const uint16_t *source) override;
|
||||
};
|
||||
|
||||
|
||||
#endif //JUNGFRAUJOCH_JFCONVERSIONFIXEDPOINT_H
|
||||
@@ -3,9 +3,9 @@
|
||||
#ifndef JUNGFRAUJOCH_JFCONVERSIONFLOATINGPOINT_H
|
||||
#define JUNGFRAUJOCH_JFCONVERSIONFLOATINGPOINT_H
|
||||
|
||||
#include "JFConversion.h"
|
||||
#include "JFCalibration.h"
|
||||
|
||||
class JFConversionFloatingPoint : public JFConversion {
|
||||
class JFConversionFloatingPoint {
|
||||
|
||||
std::vector<uint16_t> pedestal_g0;
|
||||
std::vector<uint16_t> pedestal_g1;
|
||||
@@ -20,8 +20,8 @@ public:
|
||||
const JFModulePedestal &pedestal_g0,
|
||||
const JFModulePedestal &pedestal_g1,
|
||||
const JFModulePedestal &pedestal_g2,
|
||||
double energy) override;
|
||||
void ConvertModule(int16_t *dest, const uint16_t *source) override;
|
||||
double energy);
|
||||
void ConvertModule(int16_t *dest, const uint16_t *source);
|
||||
void ConvertFP(float *dest, const uint16_t *source);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "ProcessJFPacket.h"
|
||||
#include "jf_packet.h"
|
||||
#include "../common/JFJochException.h"
|
||||
#include "JFConversionFixedPoint.h"
|
||||
|
||||
ProcessJFPacket::ProcessJFPacket(ThreadSafeFIFO<Completion> &in_c, ThreadSafeFIFO<WorkRequest> &in_wr,
|
||||
uint32_t nmodules)
|
||||
: m(2 * nmodules),
|
||||
c_fifo(in_c),
|
||||
wr_fifo(in_wr),
|
||||
module_info(2 * nmodules)
|
||||
{
|
||||
for (auto &i: module_info)
|
||||
i.c.frame_number = UINT64_MAX;
|
||||
}
|
||||
|
||||
ProcessJFPacket::~ProcessJFPacket() {
|
||||
for (auto &i: module_info) {
|
||||
if (i.c.frame_number != UINT64_MAX)
|
||||
c_fifo.Put(i.c);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessJFPacket::ProcessPacket(jf_udp_payload *datagram) {
|
||||
if (datagram->framenum == 0)
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Frame number cannot be zero");
|
||||
|
||||
uint64_t frame_number = datagram->framenum - 1;
|
||||
|
||||
uint32_t module_number = (datagram->xCoord % 64) / 2;
|
||||
bool second_half_module = (datagram->xCoord % 2 == 1);
|
||||
uint32_t packetnum = datagram->packetnum | (second_half_module ? 64 : 0);
|
||||
uint64_t module_info_location = (module_number * 2) | (frame_number % 2);
|
||||
|
||||
if (module_info_location > module_info.size())
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Module number out of bounds");
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> ul(m[module_info_location]);
|
||||
if (module_info[module_info_location].c.frame_number != frame_number) {
|
||||
if (module_info[module_info_location].c.frame_number != UINT64_MAX) {
|
||||
completed_descriptors++;
|
||||
c_fifo.Put(module_info[module_info_location].c);
|
||||
}
|
||||
auto wr = wr_fifo.GetBlocking();
|
||||
|
||||
module_info[module_info_location].c.type = Completion::Type::Image;
|
||||
module_info[module_info_location].c.frame_number = frame_number;
|
||||
module_info[module_info_location].c.timestamp = datagram->timestamp;
|
||||
module_info[module_info_location].c.bunchid = datagram->bunchid;
|
||||
module_info[module_info_location].c.exptime = datagram->exptime;
|
||||
module_info[module_info_location].c.debug = datagram->debug;
|
||||
module_info[module_info_location].c.packet_mask[0] = 0;
|
||||
module_info[module_info_location].c.packet_mask[1] = 0;
|
||||
module_info[module_info_location].c.packet_count = 0;
|
||||
module_info[module_info_location].c.module_number = module_number;
|
||||
|
||||
module_info[module_info_location].c.handle = wr.handle;
|
||||
module_info[module_info_location].ptr = wr.ptr;
|
||||
}
|
||||
|
||||
module_info[module_info_location].c.packet_count++;
|
||||
module_info[module_info_location].c.packet_mask[packetnum >= 64 ? 1 : 0] |= (1LU << (packetnum % 64));
|
||||
|
||||
uint16_t* dst = module_info[module_info_location].ptr + 4096 * packetnum;
|
||||
memcpy(dst, datagram->data, 4096 * sizeof(uint16_t));
|
||||
}
|
||||
packet_counter++;
|
||||
}
|
||||
|
||||
uint64_t ProcessJFPacket::GetCounter() {
|
||||
return packet_counter;
|
||||
}
|
||||
|
||||
uint32_t ProcessJFPacket::GetCompletedDescriptors() const {
|
||||
return completed_descriptors;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#ifndef JUNGFRAUJOCH_PROCESSJFPACKET_H
|
||||
#define JUNGFRAUJOCH_PROCESSJFPACKET_H
|
||||
|
||||
#include "../common/ThreadSafeFIFO.h"
|
||||
#include "../common/DiffractionExperiment.h"
|
||||
#include "../receiver/Completion.h"
|
||||
#include "JFConversion.h"
|
||||
#include "JFCalibration.h"
|
||||
#include "jf_packet.h"
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
struct ModuleInfo {
|
||||
uint16_t *ptr;
|
||||
Completion c;
|
||||
};
|
||||
|
||||
class ProcessJFPacket {
|
||||
std::atomic<uint32_t> completed_descriptors;
|
||||
std::vector<std::mutex> m;
|
||||
ThreadSafeFIFO<Completion> &c_fifo;
|
||||
ThreadSafeFIFO<WorkRequest> &wr_fifo;
|
||||
std::vector<ModuleInfo> module_info;
|
||||
std::atomic<uint64_t> packet_counter = 0;
|
||||
public:
|
||||
ProcessJFPacket(ThreadSafeFIFO<Completion> &c, ThreadSafeFIFO<WorkRequest> &wr, uint32_t nmodules);
|
||||
~ProcessJFPacket();
|
||||
void ProcessPacket(jf_udp_payload *datagram);
|
||||
uint64_t GetCounter();
|
||||
uint32_t GetCompletedDescriptors() const;
|
||||
};
|
||||
|
||||
|
||||
#endif //JUNGFRAUJOCH_PROCESSJFPACKET_H
|
||||
@@ -23,7 +23,7 @@ ADD_EXECUTABLE(CatchTest
|
||||
JFPedestalTest.cpp
|
||||
JFCalibrationTest.cpp
|
||||
RadialIntegrationTest.cpp
|
||||
StatusVectorTest.cpp ProcessRawPacketTest.cpp
|
||||
StatusVectorTest.cpp
|
||||
CBORTest.cpp ../tests/stream2.h ../tests/stream2.c
|
||||
JFConversionTest.cpp DetectorGeometryTest.cpp JFJochBrokerParserTest.cpp DetectorSetupTest.cpp DiffractionGeometryTest.cpp
|
||||
FPGAHLSBitshuffleTest.cpp
|
||||
|
||||
+1
-218
@@ -2,9 +2,8 @@
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include "../tests/FPGAUnitTest.h"
|
||||
#include "../jungfrau/JFConversionFloatingPoint.h"
|
||||
#include "../jungfrau/JFConversionFixedPoint.h"
|
||||
#include "../tests/FPGAUnitTest.h"
|
||||
|
||||
void SetupPedestal( JFModulePedestal &pedestal_g0, JFModulePedestal &pedestal_g1, JFModulePedestal &pedestal_g2) {
|
||||
auto ptr_g0 = pedestal_g0.GetPedestal();
|
||||
@@ -51,78 +50,6 @@ TEST_CASE("JFConversionFloatingPoint_G0","[JFConversion]") {
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFixedPoint_G0","[JFConversion]") {
|
||||
JFConversionFixedPoint conv;
|
||||
JFConversionFloatingPoint conv_fp;
|
||||
|
||||
JFModulePedestal pedestal_g0;
|
||||
JFModulePedestal pedestal_g1;
|
||||
JFModulePedestal pedestal_g2;
|
||||
|
||||
SetupPedestal(pedestal_g0, pedestal_g1, pedestal_g2);
|
||||
|
||||
JFModuleGainCalibration gain;
|
||||
|
||||
std::vector<double> energy{4.0, 6.0, 12.4, 25.0};
|
||||
for (auto &e: energy) {
|
||||
conv.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
conv_fp.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
|
||||
std::vector<uint16_t> input(RAW_MODULE_SIZE);
|
||||
std::vector<float> output_fp(RAW_MODULE_SIZE);
|
||||
std::vector<int16_t> output_16bit(RAW_MODULE_SIZE);
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
||||
input[i] = i % 16384;
|
||||
|
||||
conv.ConvertModule(output_16bit.data(), input.data());
|
||||
conv_fp.ConvertFP(output_fp.data(), input.data());
|
||||
|
||||
auto err = Compare(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
auto max_err = MaxErrorOnConversion(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
|
||||
std::cout << "Error on conversion " << err << " max error " << max_err << std::endl;
|
||||
REQUIRE(err < 0.5);
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFixedPoint_G0_TestFile","[JFConversion]") {
|
||||
JFConversionFixedPoint conv;
|
||||
JFConversionFloatingPoint conv_fp;
|
||||
|
||||
JFModulePedestal pedestal_g0;
|
||||
JFModulePedestal pedestal_g1;
|
||||
JFModulePedestal pedestal_g2;
|
||||
|
||||
SetupPedestal(pedestal_g0, pedestal_g1, pedestal_g2);
|
||||
|
||||
JFModuleGainCalibration gain = GainCalibrationFromTestFile();
|
||||
|
||||
std::vector<double> energy{4.0, 6.0, 12.4, 25.0};
|
||||
for (auto &e: energy) {
|
||||
conv.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
conv_fp.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
|
||||
std::vector<uint16_t> input(RAW_MODULE_SIZE);
|
||||
std::vector<float> output_fp(RAW_MODULE_SIZE);
|
||||
std::vector<int16_t> output_16bit(RAW_MODULE_SIZE);
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
||||
input[i] = i % 16384;
|
||||
|
||||
conv.ConvertModule(output_16bit.data(), input.data());
|
||||
conv_fp.ConvertFP(output_fp.data(), input.data());
|
||||
|
||||
auto err = Compare(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
auto max_err = MaxErrorOnConversion(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
|
||||
std::cout << "Error on conversion " << err << " max error " << max_err << std::endl;
|
||||
REQUIRE(err < 0.5);
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFloatingPoint_G1","[JFConversion]") {
|
||||
JFConversionFloatingPoint conv;
|
||||
|
||||
@@ -154,42 +81,6 @@ TEST_CASE("JFConversionFloatingPoint_G1","[JFConversion]") {
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFixedPoint_G1","[JFConversion]") {
|
||||
JFConversionFixedPoint conv;
|
||||
JFConversionFloatingPoint conv_fp;
|
||||
|
||||
JFModulePedestal pedestal_g0;
|
||||
JFModulePedestal pedestal_g1;
|
||||
JFModulePedestal pedestal_g2;
|
||||
|
||||
SetupPedestal(pedestal_g0, pedestal_g1, pedestal_g2);
|
||||
|
||||
JFModuleGainCalibration gain;
|
||||
|
||||
std::vector<double> energy{4.0, 6.0, 12.4, 25.0};
|
||||
for (auto &e: energy) {
|
||||
conv.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
conv_fp.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
|
||||
std::vector<uint16_t> input(RAW_MODULE_SIZE);
|
||||
std::vector<float> output_fp(RAW_MODULE_SIZE);
|
||||
std::vector<int16_t> output_16bit(RAW_MODULE_SIZE);
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
||||
input[i] = (i % 16384) | 0x4000;
|
||||
|
||||
conv.ConvertModule(output_16bit.data(), input.data());
|
||||
conv_fp.ConvertFP(output_fp.data(), input.data());
|
||||
|
||||
auto err = Compare(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
auto max_err = MaxErrorOnConversion(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
|
||||
std::cout << "Error on conversion " << err << " max error " << max_err << std::endl;
|
||||
REQUIRE(err < 0.5);
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFloatingPoint_G2","[JFConversion]") {
|
||||
JFConversionFloatingPoint conv;
|
||||
|
||||
@@ -220,111 +111,3 @@ TEST_CASE("JFConversionFloatingPoint_G2","[JFConversion]") {
|
||||
REQUIRE(err < 0.5);
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFixedPoint_G2","[JFConversion]") {
|
||||
JFConversionFixedPoint conv;
|
||||
JFConversionFloatingPoint conv_fp;
|
||||
|
||||
JFModulePedestal pedestal_g0;
|
||||
JFModulePedestal pedestal_g1;
|
||||
JFModulePedestal pedestal_g2;
|
||||
|
||||
SetupPedestal(pedestal_g0, pedestal_g1, pedestal_g2);
|
||||
|
||||
JFModuleGainCalibration gain;
|
||||
|
||||
std::vector<double> energy{4.0, 6.0, 12.4, 25.0};
|
||||
for (auto &e: energy) {
|
||||
conv.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
conv_fp.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
|
||||
std::vector<uint16_t> input(RAW_MODULE_SIZE);
|
||||
std::vector<float> output_fp(RAW_MODULE_SIZE);
|
||||
std::vector<int16_t> output_16bit(RAW_MODULE_SIZE);
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
||||
input[i] = (i % 16384) | 0xC000;
|
||||
|
||||
conv.ConvertModule(output_16bit.data(), input.data());
|
||||
conv_fp.ConvertFP(output_fp.data(), input.data());
|
||||
|
||||
auto err = Compare(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
auto max_err = MaxErrorOnConversion(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
|
||||
std::cout << "Error on conversion " << err << " max error " << max_err << std::endl;
|
||||
REQUIRE(err < 0.5);
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFixedPoint_G1_TestFile","[JFConversion]") {
|
||||
JFConversionFixedPoint conv;
|
||||
JFConversionFloatingPoint conv_fp;
|
||||
|
||||
JFModulePedestal pedestal_g0;
|
||||
JFModulePedestal pedestal_g1;
|
||||
JFModulePedestal pedestal_g2;
|
||||
|
||||
SetupPedestal(pedestal_g0, pedestal_g1, pedestal_g2);
|
||||
|
||||
JFModuleGainCalibration gain = GainCalibrationFromTestFile();
|
||||
|
||||
std::vector<double> energy{4.0, 6.0, 12.4, 25.0};
|
||||
for (auto &e: energy) {
|
||||
conv.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
conv_fp.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
|
||||
std::vector<uint16_t> input(RAW_MODULE_SIZE);
|
||||
std::vector<float> output_fp(RAW_MODULE_SIZE);
|
||||
std::vector<int16_t> output_16bit(RAW_MODULE_SIZE);
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
||||
input[i] = (i % 16384) | 0x4000;
|
||||
|
||||
conv.ConvertModule(output_16bit.data(), input.data());
|
||||
conv_fp.ConvertFP(output_fp.data(), input.data());
|
||||
|
||||
auto err = Compare(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
auto max_err = MaxErrorOnConversion(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
|
||||
std::cout << "Error on conversion " << err << " max error " << max_err << std::endl;
|
||||
REQUIRE(err < 0.5);
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JFConversionFixedPoint_G2_TestFile","[JFConversion]") {
|
||||
JFConversionFixedPoint conv;
|
||||
JFConversionFloatingPoint conv_fp;
|
||||
|
||||
JFModulePedestal pedestal_g0;
|
||||
JFModulePedestal pedestal_g1;
|
||||
JFModulePedestal pedestal_g2;
|
||||
|
||||
SetupPedestal(pedestal_g0, pedestal_g1, pedestal_g2);
|
||||
|
||||
JFModuleGainCalibration gain = GainCalibrationFromTestFile();
|
||||
|
||||
std::vector<double> energy{4.0, 6.0, 12.4, 25.0};
|
||||
for (auto &e: energy) {
|
||||
conv.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
conv_fp.Setup(gain, pedestal_g0, pedestal_g1, pedestal_g2, e);
|
||||
|
||||
std::vector<uint16_t> input(RAW_MODULE_SIZE);
|
||||
std::vector<float> output_fp(RAW_MODULE_SIZE);
|
||||
std::vector<int16_t> output_16bit(RAW_MODULE_SIZE);
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
||||
input[i] = (i % 16384) | 0xC000;
|
||||
|
||||
conv.ConvertModule(output_16bit.data(), input.data());
|
||||
conv_fp.ConvertFP(output_fp.data(), input.data());
|
||||
|
||||
auto err = Compare(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
auto max_err = MaxErrorOnConversion(output_16bit.data(), output_fp, RAW_MODULE_SIZE);
|
||||
|
||||
std::cout << "Error on conversion " << err << " max error " << max_err << std::endl;
|
||||
REQUIRE(err < 0.5);
|
||||
REQUIRE(max_err <= 1.0);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include "../jungfrau/ProcessJFPacket.h"
|
||||
#include "../jungfrau/jf_packet.h"
|
||||
#include "../common/DiffractionExperiment.h"
|
||||
|
||||
TEST_CASE("ProcessRawPacketTest_Empty") {
|
||||
ThreadSafeFIFO<Completion> c_fifo;
|
||||
ThreadSafeFIFO<WorkRequest> wr_fifo;
|
||||
{
|
||||
ProcessJFPacket process(c_fifo, wr_fifo, 2);
|
||||
|
||||
REQUIRE(process.GetCounter() == 0);
|
||||
}
|
||||
REQUIRE(c_fifo.Size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ProcessRawPacketTest") {
|
||||
ThreadSafeFIFO<Completion> c_fifo;
|
||||
ThreadSafeFIFO<WorkRequest> wr_fifo;
|
||||
|
||||
std::vector<uint16_t> array_0(RAW_MODULE_SIZE), array_1(RAW_MODULE_SIZE), array_2(RAW_MODULE_SIZE);
|
||||
|
||||
wr_fifo.Put(WorkRequest{.ptr = array_0.data(), .handle = 0});
|
||||
wr_fifo.Put(WorkRequest{.ptr = array_1.data(), .handle = 1});
|
||||
wr_fifo.Put(WorkRequest{.ptr = array_2.data(), .handle = 2});
|
||||
|
||||
DiffractionExperiment experiment(DetectorGeometry(8));
|
||||
experiment.DataStreams(2);
|
||||
|
||||
{
|
||||
ProcessJFPacket process(c_fifo, wr_fifo, 4);
|
||||
|
||||
jf_udp_payload datagram;
|
||||
|
||||
datagram.packetnum = 36;
|
||||
datagram.framenum = 1;
|
||||
datagram.bunchid = 84;
|
||||
datagram.data[0] = 6789;
|
||||
datagram.xCoord = 4;
|
||||
process.ProcessPacket(&datagram);
|
||||
|
||||
datagram.packetnum = 36;
|
||||
datagram.framenum = 2;
|
||||
datagram.bunchid = 84;
|
||||
datagram.data[0] = 6345;
|
||||
datagram.xCoord = 5;
|
||||
process.ProcessPacket(&datagram);
|
||||
|
||||
datagram.packetnum = 16;
|
||||
datagram.framenum = 3;
|
||||
datagram.bunchid = 84;
|
||||
datagram.data[0] = 6346;
|
||||
datagram.xCoord = 7;
|
||||
process.ProcessPacket(&datagram);
|
||||
|
||||
REQUIRE(process.GetCounter() == 3);
|
||||
}
|
||||
|
||||
REQUIRE(c_fifo.Size() == 3);
|
||||
Completion c;
|
||||
|
||||
REQUIRE(c_fifo.Get(c));
|
||||
CHECK(c.module_number == 2);
|
||||
CHECK(c.bunchid == 84);
|
||||
CHECK(c.frame_number == 0);
|
||||
CHECK(c.packet_count == 1);
|
||||
CHECK(c.packet_mask[0] == (1LU << 36));
|
||||
CHECK(c.packet_mask[1] == 0);
|
||||
|
||||
REQUIRE(c_fifo.Get(c));
|
||||
CHECK(c.module_number == 2);
|
||||
CHECK(c.bunchid == 84);
|
||||
CHECK(c.frame_number == 1);
|
||||
CHECK(c.packet_count == 1);
|
||||
CHECK(c.packet_mask[0] == 0);
|
||||
CHECK(c.packet_mask[1] == (1LU << 36));
|
||||
|
||||
|
||||
REQUIRE(c_fifo.Get(c));
|
||||
CHECK(c.module_number == 3);
|
||||
CHECK(c.bunchid == 84);
|
||||
CHECK(c.frame_number == 2);
|
||||
CHECK(c.packet_count == 1);
|
||||
CHECK(c.packet_mask[0] == 0);
|
||||
CHECK(c.packet_mask[1] == (1LU << 16));
|
||||
|
||||
CHECK(array_0[4096*36] == 6789);
|
||||
CHECK(array_1[4096*(36+64)] == 6345);
|
||||
CHECK(array_2[4096*(16+64)] == 6346);
|
||||
}
|
||||
@@ -5,16 +5,11 @@
|
||||
#include <iomanip>
|
||||
#include <future>
|
||||
|
||||
#include <numa.h>
|
||||
|
||||
#include "../jungfrau/JFPedestalCalc.h"
|
||||
#include "../common/Logger.h"
|
||||
#include "../jungfrau/JFCalibration.h"
|
||||
#include "../jungfrau/JFConversionFloatingPoint.h"
|
||||
#include "../jungfrau/JFConversionFixedPoint.h"
|
||||
#include "../tests/FPGAUnitTest.h"
|
||||
#include "../jungfrau/jf_packet.h"
|
||||
#include "../jungfrau/ProcessJFPacket.h"
|
||||
|
||||
void test_pedestal(Logger &logger) {
|
||||
size_t nframes = 5000;
|
||||
@@ -92,60 +87,10 @@ template <class T> void test_conversion(Logger &logger) {
|
||||
ntries * nframes * nmodules * RAW_MODULE_SIZE * sizeof(uint16_t) * 1000 * 1000/ ((double) elapsed.count() * 1024 * 1024 * 1024));
|
||||
}
|
||||
|
||||
void test_packet_processing(Logger &logger) {
|
||||
size_t nframes = 128;
|
||||
int64_t nmodules = 8;
|
||||
int64_t ntries = 8;
|
||||
|
||||
std::vector<jf_raw_packet> packets(nframes * nmodules * 128);
|
||||
std::vector<uint16_t> output(nframes * nmodules * CONVERTED_MODULE_SIZE);
|
||||
|
||||
std::vector<uint16_t> input(RAW_MODULE_SIZE);
|
||||
std::string image_path = "../../tests/test_data/mod5_raw0.bin";
|
||||
LoadBinaryFile(image_path, input.data(), RAW_MODULE_SIZE);
|
||||
|
||||
for (int frame = 0; frame < nframes; frame++) {
|
||||
for (int m = 0; m < nmodules; m++) {
|
||||
for (int p = 0; p < 128; p++) {
|
||||
packets.at((frame * 128 + p) * nmodules + m).jf.xCoord = (m * 2);
|
||||
packets.at((frame * 128 + p) * nmodules + m).jf.packetnum = p;
|
||||
packets.at((frame * 128 + p) * nmodules + m).jf.framenum = frame + 1;
|
||||
memcpy(packets.at((frame * 128 + p) * nmodules + m).jf.data, input.data() + 4096 * p, 4096 * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto start_time = std::chrono::system_clock::now();
|
||||
for (int z = 0; z < ntries; z++) {
|
||||
ThreadSafeFIFO<Completion> c;
|
||||
ThreadSafeFIFO<WorkRequest> wr;
|
||||
ProcessJFPacket process(c, wr, nmodules);
|
||||
|
||||
for (uint32_t i = 0; i < nmodules * nframes; i++)
|
||||
wr.Put(WorkRequest{
|
||||
.ptr = output.data() + i * RAW_MODULE_SIZE,
|
||||
.handle = i
|
||||
});
|
||||
for (auto &packet: packets)
|
||||
process.ProcessPacket(&packet.jf);
|
||||
}
|
||||
auto end_time = std::chrono::system_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
|
||||
|
||||
logger.Info("Packet analysis performance: {:5d} us/module {:5.2f} GB/s", std::lround(elapsed.count() / ((double) (ntries * nframes * nmodules))),
|
||||
ntries * nframes * nmodules * RAW_MODULE_SIZE * sizeof(uint16_t) * 1000 * 1000/ ((double) elapsed.count() * 1024 * 1024 * 1024));
|
||||
}
|
||||
|
||||
int main () {
|
||||
Logger logger("JFCalibrationPerfTest");
|
||||
test_pedestal(logger);
|
||||
|
||||
logger.Info("Floating point conversion");
|
||||
test_conversion<JFConversionFloatingPoint>(logger);
|
||||
|
||||
logger.Info("Fixed point conversion");
|
||||
test_conversion<JFConversionFixedPoint>(logger);
|
||||
|
||||
logger.Info("Packet processing");
|
||||
test_packet_processing(logger);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user