MockAcquisitionDevice: Add Internal Packet Generator
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user