MockAcquisitionDevice: Add Internal Packet Generator

This commit is contained in:
2023-07-27 12:57:40 +02:00
parent 3217e5209e
commit 8a7b088b2f
4 changed files with 158 additions and 5 deletions

View File

@@ -108,7 +108,7 @@ DiffractionExperiment &DiffractionExperiment::Mode(DetectorMode input) {
}
DiffractionExperiment &DiffractionExperiment::DataStreams(int64_t input) {
check_max("Number of data streams", input, 7);
check_max("Number of data streams", input, 16);
check_min("Number of data streams", input, 1);
internal.set_ndatastreams(input);
return *this;

View File

@@ -4,11 +4,25 @@
#include "MockAcquisitionDevice.h"
#include "../common/JFJochException.h"
#include <bitset>
#include "../jungfrau/JFConversionFloatingPoint.h"
void MockAcquisitionDevice::Start(const DiffractionExperiment& experiment) {
idle = false;
cancel = false;
measure = std::async(std::launch::async, &MockAcquisitionDevice::MeasureThread, this);
if (experiment.IsUsingInternalPacketGen()) {
if (experiment.GetDetectorMode() == DetectorMode::Conversion) {
for (auto &i: buffer_device)
memcpy(i, internal_pkt_gen_frame_conv.data(), RAW_MODULE_SIZE * sizeof(uint16_t));
} else {
for (auto &i: buffer_device)
memcpy(i, internal_pkt_gen_frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t));
}
measure = std::async(std::launch::async, &MockAcquisitionDevice::InternalPacketGeneratorThread, this,
experiment.GetModulesNum(data_stream), experiment.GetFrameNum());
} else {
measure = std::async(std::launch::async, &MockAcquisitionDevice::MeasureThread, this);
}
}
void MockAcquisitionDevice::Cancel() {
@@ -20,10 +34,15 @@ void MockAcquisitionDevice::Cancel() {
}
MockAcquisitionDevice::MockAcquisitionDevice(uint16_t data_stream, size_t in_frame_buffer_size_modules)
: AcquisitionDevice(data_stream) {
: AcquisitionDevice(data_stream), internal_pkt_gen_frame(RAW_MODULE_SIZE), internal_pkt_gen_frame_conv(RAW_MODULE_SIZE) {
max_modules = 16;
MapBuffersStandard(in_frame_buffer_size_modules, 1, -1);
max_handle = in_frame_buffer_size_modules;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
internal_pkt_gen_frame[i] = i % 65536;
internal_pkt_gen_frame_conv[i] = i % 65536;
}
}
void MockAcquisitionDevice::SendCompletion(uint32_t handle, uint16_t module_number, uint64_t frame_number) {
@@ -74,6 +93,40 @@ void MockAcquisitionDevice::MeasureThread() {
idle = true;
}
void MockAcquisitionDevice::InternalPacketGeneratorThread(uint32_t nmodules, uint32_t nframes) {
work_completion_queue.Put(Completion{.type = Completion::Type::Start});
uint32_t curr_module = 0;
uint32_t curr_frame = 0;
while ((!cancel) && (curr_frame < nframes)) {
WorkRequest wr{};
if (work_request_queue.Get(wr)) {
Completion c{};
c.handle = wr.handle;
c.module_number = curr_module;
c.frame_number = curr_frame;
c.type = Completion::Type::Image;
c.packet_mask[0] = UINT64_MAX;
c.packet_mask[1] = UINT64_MAX;
c.packet_count = 128;
work_completion_queue.Put(c);
curr_module++;
if (curr_module == nmodules) {
curr_module = 0;
curr_frame++;
}
} else
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
work_completion_queue.Put(Completion{
.type = Completion::Type::End
});
idle = true;
}
void MockAcquisitionDevice::Terminate() {
mock_completions.Put(Completion{
.type = Completion::Type::End
@@ -91,4 +144,27 @@ std::string MockAcquisitionDevice::GetIPv4Address() const {
void MockAcquisitionDevice::Finalize() {
if (measure.valid())
measure.get();
}
}
void MockAcquisitionDevice::SetCustomInternalGeneratorFrame(const std::vector<uint16_t> &v) {
if (v.size() != RAW_MODULE_SIZE)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Error in size of custom internal generator frame");
internal_pkt_gen_frame = v;
internal_pkt_gen_frame_conv = v;
}
void MockAcquisitionDevice::InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) {
JFConversionFloatingPoint conv;
conv.Setup(calib.GainCalibration(experiment.GetFirstModuleOfDataStream(data_stream)),
calib.Pedestal(experiment.GetFirstModuleOfDataStream(data_stream),0),
calib.Pedestal(experiment.GetFirstModuleOfDataStream(data_stream),1),
calib.Pedestal(experiment.GetFirstModuleOfDataStream(data_stream),2),
experiment.GetPhotonEnergy_keV());
conv.ConvertModule((int16_t *) internal_pkt_gen_frame_conv.data(), internal_pkt_gen_frame.data());
}
std::vector<uint16_t> MockAcquisitionDevice::GetInternalGeneratorFrame() const {
return internal_pkt_gen_frame;
}

View File

@@ -15,12 +15,14 @@ class MockAcquisitionDevice : public AcquisitionDevice {
bool idle = true;
std::future<void> measure;
volatile bool cancel = false;
std::vector<uint16_t> internal_pkt_gen_frame;
std::vector<uint16_t> internal_pkt_gen_frame_conv;
ThreadSafeFIFO<Completion> mock_completions;
void SendCompletion(uint32_t handle, uint16_t module_number, uint64_t frame_number);
void Start(const DiffractionExperiment& experiment) override;
void MeasureThread();
void InternalPacketGeneratorThread(uint32_t nmodules, uint32_t nframes);
public:
MockAcquisitionDevice(uint16_t data_stream, size_t in_frame_buffer_size_modules);
void AddModule(uint64_t frame, uint16_t module_number, const uint16_t *data);
@@ -29,6 +31,13 @@ public:
std::string GetIPv4Address() const override;
void Cancel() override;
void Finalize() override;
// Warning - internal packet generator in MockAcquisitionDevice has one limitation:
// it assumes the same calibration for all modules of the device
// For routine receiver tests one should always set one module per device
void SetCustomInternalGeneratorFrame(const std::vector<uint16_t> &v);
std::vector<uint16_t> GetInternalGeneratorFrame() const override;
void InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) override;
};
#endif //JUNGFRAUJOCH_MOCKACQUISITIONDEVICE_H

View File

@@ -3,6 +3,7 @@
#include <catch2/catch.hpp>
#include "../receiver/MockAcquisitionDevice.h"
#include "../receiver/JFJochReceiverTest.h"
TEST_CASE("MockAcquisitionDevice") {
std::vector<uint16_t> module_data(RAW_MODULE_SIZE, 765);
@@ -37,3 +38,70 @@ TEST_CASE("MockAcquisitionDevice") {
RAW_MODULE_SIZE * sizeof(uint16_t)) == 0);
}
TEST_CASE("JFJochReceiverTest_Raw_MockAcquisitionDevice", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Raw_MockAcquisitionDevice");
logger.Verbose(true);
std::mt19937 g1(1387);
std::uniform_int_distribution<uint16_t> dist(0, 65535);
DiffractionExperiment x(DetectorGeometry(4));
const uint16_t nthreads = 4;
std::vector<uint16_t> test_frame(RAW_MODULE_SIZE);
x.Mode(DetectorMode::Raw);
x.PedestalG0Frames(0).NumTriggers(1).UseInternalPacketGenerator(true)
.ImagesPerTrigger(100).DataFileCount(16).PhotonEnergy_keV(12.4).Compression(JFJochProtoBuf::NO_COMPRESSION);
std::vector<std::unique_ptr<AcquisitionDevice>> aq_devices;
for (int i = 0; i < x.GetDataStreamsNum(); i++) {
for (auto &j: test_frame)
j = dist(g1);
auto *test = new MockAcquisitionDevice(i, 64);
test->EnableLogging(&logger);
test->SetCustomInternalGeneratorFrame(test_frame);
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.compressed_ratio() == 1.0);
REQUIRE(output.compressed_size() == x.GetImageNum() * x.GetPixelDepth() * x.GetPixelsNum());
REQUIRE(output.max_image_number_sent() == x.GetImageNum() - 1);
REQUIRE(!output.cancelled());
}
TEST_CASE("JFJochReceiverTest_Conversion_MockAcquisitionDevice", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Conversion");
DiffractionExperiment x(DetectorGeometry(8));
const uint16_t nthreads = 4;
x.Mode(DetectorMode::Conversion);
x.PedestalG0Frames(0).NumTriggers(1).UseInternalPacketGenerator(true).DataStreams(x.GetModulesNum())
.ImagesPerTrigger(32).DataFileCount(16).PhotonEnergy_keV(12.4).Compression(JFJochProtoBuf::BSHUF_ZSTD);
std::vector<std::unique_ptr<AcquisitionDevice>> aq_devices;
for (int i = 0; i < x.GetDataStreamsNum(); i++) {
AcquisitionDevice *test;
test = new MockAcquisitionDevice(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());
}