Merge branch 'dev231218' into 'main'
Modifications in preparation to MAX IV experiment See merge request jungfraujoch/nextgendcu!21
This commit is contained in:
+21
-4
@@ -20,6 +20,23 @@ build:x86:gcc:
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
- make -j48 jfjoch
|
||||
|
||||
build:x86:gcc_writer:
|
||||
stage: build
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
tags:
|
||||
- gcc
|
||||
- x86
|
||||
needs: []
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- source /opt/rh/gcc-toolset-12/enable
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release -DJFJOCH_WRITER_ONLY=ON ..
|
||||
- make -j48 jfjoch
|
||||
|
||||
build:x86:driver:
|
||||
stage: build
|
||||
variables:
|
||||
@@ -49,7 +66,7 @@ build:x86:vitis_hls:
|
||||
- fpga/scripts/*
|
||||
- fpga/xdc/*
|
||||
- fpga/microblaze/*
|
||||
- common/Definitions.h
|
||||
- fpga/include/jfjoch_fpga.h
|
||||
script:
|
||||
- source /opt/Xilinx/Vitis_HLS/2022.1/settings64.sh
|
||||
- mkdir build
|
||||
@@ -69,10 +86,10 @@ build:x86:frontend:
|
||||
- npm install
|
||||
- npm run build
|
||||
- cd build
|
||||
- zip ../../frontend.zip *
|
||||
- zip -r ../../frontend.${CI_COMMIT_SHORT_SHA}.zip *
|
||||
artifacts:
|
||||
paths:
|
||||
- frontend.zip
|
||||
- frontend.${CI_COMMIT_SHORT_SHA}.zip
|
||||
expire_in: 1 week
|
||||
|
||||
test:x86:gcc:
|
||||
@@ -193,7 +210,7 @@ synthesis:vivado_pcie_100g:
|
||||
- fpga/hdl/*
|
||||
- fpga/scripts/*
|
||||
- fpga/xdc/*
|
||||
- common/Definitions.h
|
||||
- fpga/include/jfjoch_fpga.h
|
||||
tags:
|
||||
- vivado
|
||||
artifacts:
|
||||
|
||||
+6
-4
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.18)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.19)
|
||||
|
||||
PROJECT(Jungfraujoch VERSION 1.0 LANGUAGES C CXX)
|
||||
|
||||
@@ -40,12 +40,13 @@ ADD_SUBDIRECTORY(common)
|
||||
ADD_SUBDIRECTORY(writer)
|
||||
ADD_SUBDIRECTORY(frame_serialize)
|
||||
|
||||
ADD_SUBDIRECTORY(broker/pistache)
|
||||
|
||||
IF (JFJOCH_WRITER_ONLY)
|
||||
MESSAGE(STATUS "Compiling HDF5 writer only")
|
||||
SET(jfjoch_executables jfjoch_writer)
|
||||
SET(jfjoch_executables jfjoch_writer jfjoch_writer_http)
|
||||
ELSE()
|
||||
ADD_SUBDIRECTORY(broker)
|
||||
ADD_SUBDIRECTORY(etc)
|
||||
ADD_SUBDIRECTORY(fpga)
|
||||
ADD_SUBDIRECTORY(acquisition_device)
|
||||
ADD_SUBDIRECTORY(receiver)
|
||||
@@ -53,7 +54,8 @@ ELSE()
|
||||
ADD_SUBDIRECTORY(detector_control)
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
ADD_SUBDIRECTORY(tools)
|
||||
SET(jfjoch_executables jfjoch_broker jfjoch_writer CatchTest CompressionBenchmark HDF5DatasetWriteTest jfjoch_udp_simulator sls_detector_put sls_detector_get)
|
||||
# ADD_SUBDIRECTORY(export_images)
|
||||
SET(jfjoch_executables jfjoch_broker jfjoch_writer jfjoch_writer_http CatchTest CompressionBenchmark HDF5DatasetWriteTest jfjoch_udp_simulator sls_detector_put sls_detector_get)
|
||||
ENDIF()
|
||||
|
||||
ADD_CUSTOM_COMMAND(OUTPUT frontend_ui/build/index.html
|
||||
|
||||
@@ -32,6 +32,8 @@ Required:
|
||||
* HDF5 library version 1.10 or newer
|
||||
* ZeroMQ library
|
||||
* OpenSSL library
|
||||
* TIFF library + C++ binding (optional)
|
||||
* JPEG library (optional)
|
||||
|
||||
Optional:
|
||||
* CUDA compiler version 11 or newer - image analysis features won't work without it
|
||||
|
||||
@@ -54,7 +54,8 @@ void AcquisitionCounters::UpdateCounters(const Completion *c) {
|
||||
|
||||
if (c->module_number >= nmodules)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"UpdateCounters wrong module number: " + std::to_string(c->module_number) + " for frame " + std::to_string(c->frame_number));
|
||||
"UpdateCounters wrong module number: " + std::to_string(c->module_number) + " for frame " + std::to_string(c->frame_number) +
|
||||
" and handle " + std::to_string(c->handle));
|
||||
if (c->frame_number >= expected_frames)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"UpdateCounters frame number is out of bounds");
|
||||
|
||||
@@ -32,8 +32,7 @@ void *mmap_acquisition_buffer(size_t size, int16_t numa_node) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
AcquisitionDevice::AcquisitionDevice(uint16_t in_data_stream) :
|
||||
buffer_err(FPGA_BUFFER_LOCATION_SIZE) {
|
||||
AcquisitionDevice::AcquisitionDevice(uint16_t in_data_stream) {
|
||||
logger = nullptr;
|
||||
data_stream = in_data_stream;
|
||||
}
|
||||
@@ -53,13 +52,6 @@ void AcquisitionDevice::StartAction(const DiffractionExperiment &experiment, uin
|
||||
throw(JFJochException(JFJochExceptionCategory::InputParameterAboveMax,
|
||||
"Number of modules exceeds max possible for FPGA"));
|
||||
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
if (experiment.GetDetectorMode() == DetectorMode::Conversion)
|
||||
buffer_err[i] = PIXEL_OUT_LOST;
|
||||
else
|
||||
buffer_err[i] = -1;
|
||||
}
|
||||
|
||||
counters.Reset(experiment, data_stream);
|
||||
expected_frames = experiment.GetFrameNum() / experiment.GetSummation();
|
||||
|
||||
@@ -78,13 +70,25 @@ void AcquisitionDevice::StartAction(const DiffractionExperiment &experiment, uin
|
||||
StartSendingWorkRequests();
|
||||
|
||||
start_time = std::chrono::system_clock::now();
|
||||
|
||||
if (experiment.IsUsingInternalPacketGen())
|
||||
RunInternalGenerator(experiment);
|
||||
}
|
||||
|
||||
void AcquisitionDevice::WaitForActionComplete(bool pedestal_mode) {
|
||||
auto c = work_completion_queue.GetBlocking();
|
||||
|
||||
while (c.type != Completion::Type::End) {
|
||||
auto output = GetDeviceOutput(c.handle);
|
||||
DeviceOutput* output;
|
||||
|
||||
try {
|
||||
output = GetDeviceOutput(c.handle);
|
||||
} catch (const JFJochException &e) {
|
||||
if (logger)
|
||||
logger->ErrorException(e);
|
||||
continue;
|
||||
}
|
||||
|
||||
c.module_number = output->module_statistics.module_number;
|
||||
c.packet_count = output->module_statistics.packet_count;
|
||||
c.frame_number = output->module_statistics.frame_number;
|
||||
@@ -101,11 +105,22 @@ void AcquisitionDevice::WaitForActionComplete(bool pedestal_mode) {
|
||||
data_stream, c.frame_number, c.module_number, c.handle);
|
||||
SendWorkRequest(c.handle);
|
||||
} else if (pedestal_mode && !c.pedestal) {
|
||||
try {
|
||||
counters.UpdateCounters(&c);
|
||||
} catch (const JFJochException &e) {
|
||||
if (logger)
|
||||
logger->ErrorException(e);
|
||||
}
|
||||
SendWorkRequest(c.handle);
|
||||
} else
|
||||
counters.UpdateCounters(&c);
|
||||
|
||||
} else {
|
||||
try {
|
||||
counters.UpdateCounters(&c);
|
||||
} catch (const JFJochException &e) {
|
||||
if (logger)
|
||||
logger->ErrorException(e);
|
||||
SendWorkRequest(c.handle);
|
||||
}
|
||||
}
|
||||
if (logger != nullptr)
|
||||
logger->Debug("Data stream {} completion frame number {} module {} handle {}",
|
||||
data_stream, c.frame_number, c.module_number, c.handle);
|
||||
@@ -134,7 +149,7 @@ const DeviceOutput *AcquisitionDevice::GetDeviceOutput(size_t frame_number, uint
|
||||
if (handle != HandleNotValid)
|
||||
return GetDeviceOutput(handle);
|
||||
else
|
||||
return (DeviceOutput *) GetErrorFrameBuffer();
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Frame not collected");
|
||||
}
|
||||
|
||||
const DeviceOutput *AcquisitionDevice::GetDeviceOutputPedestal(size_t storage_cell, uint16_t module_number) const {
|
||||
@@ -142,11 +157,7 @@ const DeviceOutput *AcquisitionDevice::GetDeviceOutputPedestal(size_t storage_ce
|
||||
if (handle != HandleNotValid)
|
||||
return GetDeviceOutput(handle);
|
||||
else
|
||||
return (DeviceOutput *) GetErrorFrameBuffer();
|
||||
}
|
||||
|
||||
const int16_t *AcquisitionDevice::GetErrorFrameBuffer() const {
|
||||
return buffer_err.data();
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Frame not collected");
|
||||
}
|
||||
|
||||
const DeviceOutput *AcquisitionDevice::GetDeviceOutput(size_t handle) const {
|
||||
@@ -172,9 +183,9 @@ void AcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment &ex
|
||||
const std::vector<uint16_t> &v,
|
||||
const std::vector<float> &weights) {}
|
||||
|
||||
void AcquisitionDevice::MapBuffersStandard(size_t c2h_buffer_count, size_t h2c_buffer_count, int16_t numa_node) {
|
||||
void AcquisitionDevice::MapBuffersStandard(size_t c2h_buffer_count, int16_t numa_node) {
|
||||
try {
|
||||
for (int i = 0; i < std::max(c2h_buffer_count, h2c_buffer_count); i++)
|
||||
for (int i = 0; i < c2h_buffer_count; i++)
|
||||
buffer_device.emplace_back((DeviceOutput *) mmap_acquisition_buffer(FPGA_BUFFER_LOCATION_SIZE, numa_node));
|
||||
} catch (const JFJochException &e) {
|
||||
UnmapBuffers();
|
||||
@@ -267,3 +278,15 @@ void AcquisitionDevice::SetDefaultDataSource(AcquisitionDeviceSource id) {
|
||||
AcquisitionDeviceSource AcquisitionDevice::GetDataSource() {
|
||||
return AcquisitionDeviceSource::NONE;
|
||||
}
|
||||
|
||||
void AcquisitionDevice::RunInternalGenerator(const DiffractionExperiment &experiment) {
|
||||
FrameGeneratorConfig config{};
|
||||
config.frames = experiment.GetFrameNum() + DELAY_FRAMES_STOP_AND_QUIT + 1;
|
||||
config.modules = experiment.GetModulesNum(data_stream);
|
||||
config.bunchid = INT_PKT_GEN_BUNCHID;
|
||||
config.exptime = INT_PKT_GEN_EXPTTIME;
|
||||
config.debug = INT_PKT_GEN_DEBUG;
|
||||
config.dest_mac_addr = MacAddressFromStr(GetMACAddress());
|
||||
config.dest_ipv4_addr = IPv4AddressFromStr(GetIPv4Address());
|
||||
HW_RunInternalGenerator(config);
|
||||
}
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
#include "../common/ThreadSafeFIFO.h"
|
||||
#include "../jungfrau/JFCalibration.h"
|
||||
#include "../fpga/pcie_driver/ActionConfig.h"
|
||||
|
||||
#include "AcquisitionCounters.h"
|
||||
#include "Completion.h"
|
||||
#include "../fpga/host_library/DeviceOutput.h"
|
||||
#include "../fpga/include/jfjoch_fpga.h"
|
||||
#include "../common/NetworkAddressConvert.h"
|
||||
|
||||
struct AcquisitionDeviceStatistics {
|
||||
uint64_t good_packets;
|
||||
@@ -34,8 +34,6 @@ struct AcquisitionDeviceStatistics {
|
||||
enum class AcquisitionDeviceSource {MAC_100G, MAC_4x10G, FRAME_GENERATOR, NONE};
|
||||
|
||||
class AcquisitionDevice {
|
||||
std::vector<int16_t> buffer_err;
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> start_time;
|
||||
std::chrono::time_point<std::chrono::system_clock> end_time;
|
||||
|
||||
@@ -58,13 +56,13 @@ protected:
|
||||
uint32_t max_modules = 1;
|
||||
uint64_t mac_addr;
|
||||
uint32_t ipv4_addr;
|
||||
std::atomic<uint32_t> work_completion_count;
|
||||
explicit AcquisitionDevice(uint16_t data_stream);
|
||||
|
||||
void UnmapBuffers();
|
||||
void MapBuffersStandard(size_t c2h_buffer_count, size_t h2c_buffer_count, int16_t numa_node);
|
||||
void MapBuffersStandard(size_t c2h_buffer_count, int16_t numa_node);
|
||||
const DeviceOutput *GetDeviceOutput(size_t handle) const;
|
||||
DeviceOutput *GetDeviceOutput(size_t handle);
|
||||
virtual void HW_RunInternalGenerator(const FrameGeneratorConfig& config) = 0;
|
||||
public:
|
||||
AcquisitionDevice(const AcquisitionDevice &other) = delete;
|
||||
AcquisitionDevice &operator=(const AcquisitionDevice &other) = delete;
|
||||
@@ -89,9 +87,7 @@ public:
|
||||
AcquisitionDeviceStatistics GetStatistics() const;
|
||||
const DeviceOutput *GetDeviceOutput(size_t frame_number, uint16_t module_number) const;
|
||||
const DeviceOutput *GetDeviceOutputPedestal(size_t frame_number, uint16_t module_number) const;
|
||||
|
||||
void FrameBufferRelease(size_t frame_number, uint16_t module_number);
|
||||
const int16_t *GetErrorFrameBuffer() const;
|
||||
|
||||
// Calibration
|
||||
virtual void InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib);
|
||||
@@ -100,7 +96,7 @@ public:
|
||||
const std::vector<float> &weights);
|
||||
const AcquisitionCounters& Counters() const;
|
||||
|
||||
virtual void SetSpotFinderParameters(int16_t count_threshold, double snr_threshold) {};
|
||||
virtual void SetSpotFinderParameters(int32_t count_threshold, float snr_threshold) {};
|
||||
virtual std::string GetIPv4Address() const;
|
||||
virtual void SetIPv4Address(uint32_t ipv4_addr_network_order);
|
||||
virtual void SetMACAddress(uint64_t mac_addr_network_order);
|
||||
@@ -116,6 +112,7 @@ public:
|
||||
AcquisitionDeviceNetConfig GetNetConfig() const;
|
||||
|
||||
virtual uint32_t GetExpectedDescriptorsPerModule() const = 0;
|
||||
void RunInternalGenerator(const DiffractionExperiment& experiment);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -33,4 +33,14 @@ std::vector<AcquisitionDeviceNetConfig> AcquisitionDeviceGroup::GetNetworkConfig
|
||||
for (const auto &i: aq_devices)
|
||||
ret.push_back(i->GetNetConfig());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AcquisitionDeviceGroup::SetDefaultDataSource(AcquisitionDeviceSource id) {
|
||||
for (auto &i: aq_devices)
|
||||
i->SetDefaultDataSource(id);
|
||||
}
|
||||
|
||||
void AcquisitionDeviceGroup::EnableLogging(Logger *logger) {
|
||||
for (auto &i: aq_devices)
|
||||
i->EnableLogging(logger);
|
||||
}
|
||||
@@ -15,8 +15,9 @@ public:
|
||||
void Add(std::unique_ptr<AcquisitionDevice> &&device);
|
||||
void AddPCIeDevice(const std::string &device_name);
|
||||
void AddHLSDevice(int64_t buffer_size_modules);
|
||||
void AddMockDevice(int64_t buffer_size_modules);
|
||||
std::vector<AcquisitionDeviceNetConfig> GetNetworkConfig();
|
||||
void SetDefaultDataSource(AcquisitionDeviceSource id);
|
||||
void EnableLogging(Logger *logger);
|
||||
};
|
||||
|
||||
#endif //JUNGFRAUJOCH_ACQUISITIONDEVICEGROUP_H
|
||||
|
||||
@@ -2,7 +2,7 @@ ADD_LIBRARY(JungfraujochAcqusitionDevice STATIC
|
||||
AcquisitionDevice.cpp AcquisitionDevice.h
|
||||
AcquisitionCounters.cpp AcquisitionCounters.h
|
||||
HLSSimulatedDevice.cpp HLSSimulatedDevice.h
|
||||
Completion.cpp Completion.h ../fpga/pcie_driver/ActionConfig.h
|
||||
Completion.cpp Completion.h ../fpga/include/jfjoch_fpga.h
|
||||
PCIExpressDevice.cpp PCIExpressDevice.h
|
||||
FPGAAcquisitionDevice.cpp FPGAAcquisitionDevice.h
|
||||
AcquisitionDeviceGroup.cpp
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include "FPGAAcquisitionDevice.h"
|
||||
#include <random>
|
||||
#include <bitset>
|
||||
#include "../common/to_fixed.h"
|
||||
#include "FPGAAcquisitionDevice.h"
|
||||
|
||||
void FPGAAcquisitionDevice::StartSendingWorkRequests() {
|
||||
stop_work_requests = false;
|
||||
@@ -27,26 +25,47 @@ void FPGAAcquisitionDevice::Finalize() {
|
||||
void FPGAAcquisitionDevice::ReadWorkCompletionThread() {
|
||||
uint32_t values;
|
||||
|
||||
if (logger)
|
||||
logger->Debug("Starting read work completion thread for stream {}", data_stream);
|
||||
Completion c{};
|
||||
bool quit_loop = false;
|
||||
do {
|
||||
while (!HW_ReadMailbox(&values))
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
|
||||
c = parse_hw_completion(values);
|
||||
if (c.data_collection_id == data_collection_id) {
|
||||
work_completion_queue.PutBlocking(c);
|
||||
if (c.type == Completion::Type::End)
|
||||
quit_loop = true;
|
||||
} else if (logger) {
|
||||
if (c.type == Completion::Type::Start)
|
||||
logger->Warning("Stream {} Start completion with wrong data collection ID", data_stream);
|
||||
else
|
||||
logger->Warning("Stream {} Image completion with wrong data collection ID frame {} module {}",
|
||||
data_stream, c.frame_number, c.module_number);
|
||||
bool read;
|
||||
try {
|
||||
read = HW_ReadMailbox(&values);
|
||||
} catch (const JFJochException& e) {
|
||||
if (logger)
|
||||
logger->ErrorException(e);
|
||||
read = false;
|
||||
}
|
||||
|
||||
if (read) {
|
||||
c = parse_hw_completion(values);
|
||||
if (logger) {
|
||||
logger->Debug("Stream {} Completion data collection ID {} type {} frame {} module {}",
|
||||
data_stream,
|
||||
c.data_collection_id,
|
||||
(int)c.type,
|
||||
c.frame_number,
|
||||
c.module_number);
|
||||
}
|
||||
if (c.data_collection_id == data_collection_id) {
|
||||
work_completion_queue.PutBlocking(c);
|
||||
if (c.type == Completion::Type::End)
|
||||
quit_loop = true;
|
||||
} else if (logger) {
|
||||
if (c.type == Completion::Type::Start)
|
||||
logger->Warning("Stream {} Start completion with wrong data collection ID", data_stream);
|
||||
else
|
||||
logger->Warning("Stream {} Image completion with wrong data collection ID frame {} module {}",
|
||||
data_stream, c.frame_number, c.module_number);
|
||||
}
|
||||
} else
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
} while (!quit_loop);
|
||||
|
||||
if (logger)
|
||||
logger->Debug("Done read work completion thread for stream {}", data_stream);
|
||||
}
|
||||
|
||||
void FPGAAcquisitionDevice::SendWorkRequestThread() {
|
||||
@@ -73,6 +92,7 @@ void FPGAAcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment
|
||||
const std::vector<uint16_t> &v,
|
||||
const std::vector<float> &weights) {
|
||||
auto offset = experiment.GetFirstModuleOfDataStream(data_stream);
|
||||
size_t modules = experiment.GetModulesNum(data_stream);
|
||||
|
||||
if (v.size() != experiment.GetModulesNum() * RAW_MODULE_SIZE)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
@@ -82,22 +102,21 @@ void FPGAAcquisitionDevice::InitializeIntegrationMap(const DiffractionExperiment
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Mismatch regarding weights array");
|
||||
|
||||
size_t modules = experiment.GetModulesNum(data_stream);
|
||||
|
||||
if (modules > 2 * buffer_device.size())
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Not enough host/FPGA buffers to load all integration map values");
|
||||
|
||||
for (int m = 0; m < modules; m++)
|
||||
memcpy(buffer_device[m], v.data() + (offset + m) * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
|
||||
|
||||
for (int m = 0; m < modules; m++) {
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
buffer_device[modules + m]->pixels[i] = to_fixed(weights[(offset + m) * RAW_MODULE_SIZE + i], 15);
|
||||
}
|
||||
for (uint32_t m = 0; m < modules; m++) {
|
||||
memcpy(buffer_device[0]->pixels, v.data() + (offset + m) * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_INTEGRATION_MAP;
|
||||
LoadCalibration(0);
|
||||
}
|
||||
|
||||
for (uint32_t m = 0; m < modules; m++) {
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
||||
((float *)buffer_device[0]->pixels)[i] = weights[(offset + m) * RAW_MODULE_SIZE + i];
|
||||
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_INTEGRATION_WEIGHTS;
|
||||
LoadCalibration(0);
|
||||
}
|
||||
HW_LoadIntegrationMap(modules);
|
||||
}
|
||||
|
||||
void FPGAAcquisitionDevice::SetInternalGeneratorFrameForAllModules(const std::vector<uint16_t> &v) {
|
||||
@@ -111,14 +130,13 @@ void FPGAAcquisitionDevice::SetInternalGeneratorFrameForAllModules(const std::ve
|
||||
v.data(), RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
if (max_modules > buffer_device.size())
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Not enough host/FPGA buffers to load all integration map values");
|
||||
memcpy(buffer_device[0]->pixels, internal_pkt_gen_frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
|
||||
for (int m = 0; m < max_modules; m++)
|
||||
memcpy(buffer_device[m], internal_pkt_gen_frame.data() + m * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
|
||||
HW_LoadInternalGeneratorFrame(max_modules);
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_FRAME_GEN;
|
||||
for (uint32_t m = 0; m < max_modules; m++) {
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
LoadCalibration(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,10 +158,13 @@ void FPGAAcquisitionDevice::SetInternalGeneratorFrame(const std::vector<uint16_t
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Not enough host/FPGA buffers to load all integration map values");
|
||||
|
||||
for (int m = 0; m < nmodules; m++)
|
||||
memcpy(buffer_device[m], internal_pkt_gen_frame.data() + m * RAW_MODULE_SIZE, RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
|
||||
HW_LoadInternalGeneratorFrame(nmodules);
|
||||
for (uint32_t m = 0; m < nmodules; m++) {
|
||||
memcpy(buffer_device[0], internal_pkt_gen_frame.data() + m * RAW_MODULE_SIZE,
|
||||
RAW_MODULE_SIZE * sizeof(uint16_t));
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_FRAME_GEN;
|
||||
LoadCalibration(0);
|
||||
}
|
||||
}
|
||||
|
||||
void FPGAAcquisitionDevice::InitializeCalibration(const DiffractionExperiment &experiment, const JFCalibration &calib) {
|
||||
@@ -160,58 +181,87 @@ void FPGAAcquisitionDevice::InitializeCalibration(const DiffractionExperiment &e
|
||||
size_t modules = experiment.GetModulesNum(data_stream);
|
||||
size_t storage_cells = experiment.GetStorageCellNumber();
|
||||
|
||||
if (modules * (3 + 3 * storage_cells) > buffer_device.size())
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Not enough host/FPGA buffers to load all calibration constants");
|
||||
for (uint32_t m = 0; m < modules; m++) {
|
||||
if (experiment.IsFixedGainG1()) {
|
||||
calib.GainCalibration(m).ExportFixedG1(buffer_device[0]);
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_GAIN_G1;
|
||||
LoadCalibration(0);
|
||||
} else {
|
||||
if (experiment.IsUsingGainHG0())
|
||||
calib.GainCalibration(m).ExportHG0(buffer_device[0]);
|
||||
else
|
||||
calib.GainCalibration(m).ExportG0(buffer_device[0]);
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_GAIN_G0;
|
||||
LoadCalibration(0);
|
||||
|
||||
for (int m = 0; m < modules; m++) {
|
||||
calib.GainCalibration(m).ExportG0((uint16_t *) buffer_device[m]->pixels);
|
||||
calib.GainCalibration(m).ExportG1((uint16_t *) buffer_device[m + modules]->pixels);
|
||||
calib.GainCalibration(m).ExportG2((uint16_t *) buffer_device[m + modules * 2]->pixels);
|
||||
calib.GainCalibration(m).ExportG1(buffer_device[0]);
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_GAIN_G1;
|
||||
LoadCalibration(0);
|
||||
|
||||
calib.GainCalibration(m).ExportG2(buffer_device[0]);
|
||||
buffer_device[0]->module_statistics.module_number = m;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_GAIN_G2;
|
||||
LoadCalibration(0);
|
||||
}
|
||||
}
|
||||
|
||||
for (int s = 0; s < storage_cells; s++) {
|
||||
auto mask = calib.CalculateMask(experiment, s);
|
||||
for (int m = 0; m < modules; m++) {
|
||||
auto pedestal_g0 = calib.Pedestal(offset + m, 0, s).GetPedestal();
|
||||
auto pedestal_g1 = calib.Pedestal(offset + m, 1, s).GetPedestal();
|
||||
auto pedestal_g2 = calib.Pedestal(offset + m, 2, s).GetPedestal();
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
if (experiment.GetApplyPixelMaskInFPGA() && (mask[(offset + m) * RAW_MODULE_SIZE + i] != 0)) {
|
||||
buffer_device[(3 + 0 * storage_cells + s) * modules + m]->pixels[i] = 16384;
|
||||
buffer_device[(3 + 1 * storage_cells + s) * modules + m]->pixels[i] = 16384;
|
||||
buffer_device[(3 + 2 * storage_cells + s) * modules + m]->pixels[i] = 16384;
|
||||
} else {
|
||||
((uint16_t *) buffer_device[(3 + 0 * storage_cells + s) * modules + m]->pixels)[i] = pedestal_g0[i];
|
||||
((uint16_t *) buffer_device[(3 + 1 * storage_cells + s) * modules + m]->pixels)[i] = pedestal_g1[i];
|
||||
((uint16_t *) buffer_device[(3 + 2 * storage_cells + s) * modules + m]->pixels)[i] = pedestal_g2[i];
|
||||
}
|
||||
}
|
||||
|
||||
auto pedestal_g1 = calib.Pedestal(offset + m, 1, s).GetPedestal();
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
if (experiment.GetApplyPixelMaskInFPGA() && (mask[(offset + m) * RAW_MODULE_SIZE + i] != 0))
|
||||
buffer_device[0]->pixels[i] = 16384;
|
||||
else
|
||||
((uint16_t *) buffer_device[0]->pixels)[i] = pedestal_g1[i];
|
||||
}
|
||||
buffer_device[0]->module_statistics.module_number = m + modules * s;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_PEDESTAL_G1;
|
||||
LoadCalibration(0);
|
||||
|
||||
if (!experiment.IsFixedGainG1()) {
|
||||
auto pedestal_g0 = calib.Pedestal(offset + m, 0, s).GetPedestal();
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
if (experiment.GetApplyPixelMaskInFPGA() && (mask[(offset + m) * RAW_MODULE_SIZE + i] != 0))
|
||||
buffer_device[0]->pixels[i] = 16384;
|
||||
else
|
||||
((uint16_t *) buffer_device[0]->pixels)[i] = pedestal_g0[i];
|
||||
}
|
||||
buffer_device[0]->module_statistics.module_number = m + modules * s;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_PEDESTAL_G0;
|
||||
LoadCalibration(0);
|
||||
|
||||
auto pedestal_g2 = calib.Pedestal(offset + m, 2, s).GetPedestal();
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
if (experiment.GetApplyPixelMaskInFPGA() && (mask[(offset + m) * RAW_MODULE_SIZE + i] != 0))
|
||||
buffer_device[0]->pixels[i] = 16384;
|
||||
else
|
||||
((uint16_t *) buffer_device[0]->pixels)[i] = pedestal_g2[i];
|
||||
}
|
||||
buffer_device[0]->module_statistics.module_number = m + modules * s;
|
||||
buffer_device[0]->module_statistics.load_calibration_destination = LOAD_CALIBRATION_DEST_PEDESTAL_G2;
|
||||
LoadCalibration(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
HW_LoadCalibration(modules, storage_cells);
|
||||
}
|
||||
|
||||
union float_uint32 {
|
||||
float f;
|
||||
uint32_t u;
|
||||
};
|
||||
|
||||
inline uint32_t float2uint(float f) {
|
||||
float_uint32 fu;
|
||||
fu.f = f;
|
||||
return fu.u;
|
||||
}
|
||||
|
||||
void FPGAAcquisitionDevice::FillActionRegister(const DiffractionExperiment& x, DataCollectionConfig &job) {
|
||||
std::random_device rd;
|
||||
std::uniform_int_distribution<uint16_t> dist;
|
||||
|
||||
// Avoid data_collection_id of DATA_COLLECTION_ID_PURGE - this is reserved for cleaning unused work requests from the FPGA
|
||||
data_collection_id = dist(rd);
|
||||
while (data_collection_id == DATA_COLLECTION_ID_PURGE)
|
||||
data_collection_id = dist(rd);
|
||||
|
||||
job.nmodules = x.GetModulesNum(data_stream) - 1;
|
||||
job.nframes = x.GetFrameNum();
|
||||
job.one_over_energy = float2uint(1 / x.GetPhotonEnergy_keV());
|
||||
job.energy_kev = x.GetPhotonEnergy_keV();
|
||||
job.nstorage_cells = x.GetStorageCellNumber() - 1;
|
||||
job.mode = data_collection_id << 16;
|
||||
job.nsummation = x.GetSummation() - 1;
|
||||
@@ -235,6 +285,9 @@ void FPGAAcquisitionDevice::FillActionRegister(const DiffractionExperiment& x, D
|
||||
break;
|
||||
}
|
||||
|
||||
if (x.IsFixedGainG1())
|
||||
job.mode |= MODE_FIXG1;
|
||||
|
||||
if (!x.IsPixelSigned())
|
||||
job.mode |= MODE_UNSIGNED;
|
||||
if (x.GetPixelDepth() == 4)
|
||||
@@ -290,17 +343,17 @@ FPGAAcquisitionDevice::FPGAAcquisitionDevice(uint16_t data_stream)
|
||||
internal_pkt_gen_frame(RAW_MODULE_SIZE * MAX_MODULES_FPGA) {
|
||||
}
|
||||
|
||||
void FPGAAcquisitionDevice::SetSpotFinderParameters(int16_t count_threshold, double snr_threshold) {
|
||||
void FPGAAcquisitionDevice::SetSpotFinderParameters(int32_t count_threshold, float snr_threshold) {
|
||||
if (snr_threshold < 0) {
|
||||
if (logger)
|
||||
logger->Warning("Trying to set SNR threshold below zero: {}", snr_threshold );
|
||||
snr_threshold = 0;
|
||||
} else if (snr_threshold > 64) {
|
||||
} else if (snr_threshold > 16) {
|
||||
if (logger)
|
||||
logger->Warning("Trying to set SNR threshold too high: {}", snr_threshold );
|
||||
snr_threshold = 64;
|
||||
snr_threshold = 16;
|
||||
}
|
||||
SpotFinderParameters params{.count_threshold = count_threshold, .snr_threshold = to_fixed(snr_threshold, 2)};
|
||||
SpotFinderParameters params{.count_threshold = count_threshold, .snr_threshold = snr_threshold};
|
||||
HW_SetSpotFinderParameters(params);
|
||||
}
|
||||
|
||||
@@ -342,3 +395,7 @@ void FPGAAcquisitionDevice::SetDataSource(AcquisitionDeviceSource id) {
|
||||
uint32_t FPGAAcquisitionDevice::GetExpectedDescriptorsPerModule() const {
|
||||
return expected_descriptors_per_module;
|
||||
}
|
||||
|
||||
void FPGAAcquisitionDevice::LoadCalibration(uint32_t handle) {
|
||||
HW_LoadCalibration(LoadCalibrationConfig{.handle = handle});
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
#define JUNGFRAUJOCH_FPGAACQUISITIONDEVICE_H
|
||||
|
||||
#include "AcquisitionDevice.h"
|
||||
#include "../fpga/pcie_driver/ActionConfig.h"
|
||||
#include "../fpga/include/jfjoch_fpga.h"
|
||||
|
||||
class FPGAAcquisitionDevice : public AcquisitionDevice {
|
||||
uint16_t data_collection_id = 0;
|
||||
@@ -29,9 +29,8 @@ class FPGAAcquisitionDevice : public AcquisitionDevice {
|
||||
volatile bool stop_work_requests = false;
|
||||
void SendWorkRequestThread();
|
||||
|
||||
virtual void HW_LoadCalibration(uint32_t modules, uint32_t storage_cells) = 0;
|
||||
virtual void HW_LoadIntegrationMap(uint32_t modules) = 0;
|
||||
virtual void HW_LoadInternalGeneratorFrame(uint32_t modules) = 0;
|
||||
virtual void HW_LoadCalibration(const LoadCalibrationConfig &config) = 0;
|
||||
void LoadCalibration(uint32_t handle);
|
||||
virtual bool HW_ReadMailbox(uint32_t *values) = 0;
|
||||
virtual bool HW_SendWorkRequest(uint32_t handle) = 0;
|
||||
virtual void HW_SetSpotFinderParameters(const SpotFinderParameters ¶ms) = 0;
|
||||
@@ -57,7 +56,7 @@ public:
|
||||
void SetInternalGeneratorFrameForAllModules(const std::vector<uint16_t> &v);
|
||||
void SetInternalGeneratorFrame();
|
||||
std::vector<uint16_t> GetInternalGeneratorFrame() const override;
|
||||
void SetSpotFinderParameters(int16_t count_threshold, double snr_threshold) override;
|
||||
void SetSpotFinderParameters(int32_t count_threshold, float snr_threshold) override;
|
||||
AcquisitionDeviceSource GetDataSource() override;
|
||||
void SetDefaultDataSource(AcquisitionDeviceSource id) override;
|
||||
uint32_t GetExpectedDescriptorsPerModule() const override;
|
||||
|
||||
@@ -42,8 +42,7 @@ HLSSimulatedDevice::HLSSimulatedDevice(uint16_t data_stream, size_t in_frame_buf
|
||||
|
||||
max_modules = MAX_MODULES_FPGA;
|
||||
|
||||
MapBuffersStandard(in_frame_buffer_size_modules,
|
||||
(3 + 3 * 16) * max_modules + 2, numa_node);
|
||||
MapBuffersStandard(in_frame_buffer_size_modules, numa_node);
|
||||
|
||||
auto in_mem_location32 = (uint32_t *) dma_address_table.data();
|
||||
|
||||
@@ -142,35 +141,40 @@ void HLSSimulatedDevice::FPGA_StartAction(const DiffractionExperiment &experimen
|
||||
if (action_thread.joinable())
|
||||
action_thread.join();
|
||||
|
||||
run_counter += 1;
|
||||
run_data_collection = 1;
|
||||
cancel_data_collection = 0;
|
||||
idle = false;
|
||||
|
||||
while (!din_frame_generator.empty())
|
||||
din_frame_generator.read();
|
||||
|
||||
datamover_out.ClearCompletedDescriptors();
|
||||
if (experiment.IsUsingInternalPacketGen()) {
|
||||
data_source = STREAM_MERGE_SRC_FRAME_GEN;
|
||||
auto ret = frame_generator(din_frame_generator,
|
||||
hbm.data(),
|
||||
hbm.data(),
|
||||
hbm_if_size,
|
||||
experiment.GetFrameNum() + DELAY_FRAMES_STOP_AND_QUIT + 1,
|
||||
experiment.GetModulesNum(data_stream),
|
||||
mac_addr,
|
||||
mac_addr,
|
||||
ipv4_addr,
|
||||
ipv4_addr,
|
||||
INT_PKT_GEN_BUNCHID,
|
||||
INT_PKT_GEN_EXPTTIME,
|
||||
INT_PKT_GEN_DEBUG,
|
||||
cancel_data_collection);
|
||||
if (ret)
|
||||
throw JFJochException(JFJochExceptionCategory::AcquisitionDeviceError,
|
||||
"Error running internal packet generator");
|
||||
} else {
|
||||
data_source = STREAM_MERGE_SRC_100G;
|
||||
}
|
||||
|
||||
action_thread = std::thread(&HLSSimulatedDevice::HLSMainThread, this );
|
||||
}
|
||||
|
||||
void HLSSimulatedDevice::FrameGeneratorFuture(FrameGeneratorConfig config) {
|
||||
frame_generator(din_frame_generator,
|
||||
hbm.data(),
|
||||
hbm.data(),
|
||||
hbm_if_size,
|
||||
config.frames,
|
||||
config.modules,
|
||||
mac_addr,
|
||||
config.dest_mac_addr,
|
||||
ipv4_addr,
|
||||
config.dest_ipv4_addr,
|
||||
config.bunchid,
|
||||
config.exptime,
|
||||
config.debug,
|
||||
cancel_data_collection);
|
||||
}
|
||||
|
||||
void HLSSimulatedDevice::HW_RunInternalGenerator(const FrameGeneratorConfig &config) {
|
||||
frame_generator_future = std::async(std::launch::async, &HLSSimulatedDevice::FrameGeneratorFuture, this, config);
|
||||
}
|
||||
|
||||
void HLSSimulatedDevice::FPGA_EndAction() {
|
||||
if (action_thread.joinable())
|
||||
action_thread.join();
|
||||
@@ -189,10 +193,11 @@ bool HLSSimulatedDevice::HW_ReadMailbox(uint32_t *values) {
|
||||
values[0] = tmp;
|
||||
// equivalent to driver functionality
|
||||
if (ret) {
|
||||
uint32_t data_collection_id = (values[0] >> 16) & 0xFFFF;
|
||||
uint32_t handle = values[0] & 0xFFFF;
|
||||
if (handle == HANDLE_START)
|
||||
completion_count = 0;
|
||||
else if (handle != HANDLE_END) {
|
||||
else if ((handle != HANDLE_END) && (data_collection_id != DATA_COLLECTION_ID_PURGE)) {
|
||||
completion_count++;
|
||||
while (completion_count * DMA_DESCRIPTORS_PER_MODULE > datamover_out.GetCompletedDescriptors())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
@@ -215,6 +220,12 @@ bool HLSSimulatedDevice::HW_SendWorkRequest(uint32_t handle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline uint32_t float2uint(float f) {
|
||||
float_uint32 fu;
|
||||
fu.f = f;
|
||||
return fu.u;
|
||||
}
|
||||
|
||||
void HLSSimulatedDevice::HLSMainThread() {
|
||||
uint64_t counter_hbm;
|
||||
uint64_t counter_host;
|
||||
@@ -273,85 +284,135 @@ void HLSSimulatedDevice::HLSMainThread() {
|
||||
hls::stream<ap_uint<512>> spot_finder_result_1;
|
||||
|
||||
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
|
||||
ap_uint<1> idle_data_collection;
|
||||
volatile ap_uint<1> idle_data_collection = 1;
|
||||
ap_uint<1> load_to_hbm_idle;
|
||||
ap_uint<1> save_to_hbm_idle;
|
||||
ap_uint<1> integration_idle;
|
||||
ap_uint<1> stream_conv_idle;
|
||||
ap_uint<1> frame_summation_idle;
|
||||
|
||||
if (data_source == STREAM_MERGE_SRC_FRAME_GEN) {
|
||||
while (!din_frame_generator.empty())
|
||||
stream_merge(din_eth, din_eth_4x10G, din_frame_generator, network0, data_source);
|
||||
} else if (data_source == STREAM_MERGE_SRC_100G) {
|
||||
while (!din_eth.empty())
|
||||
stream_merge(din_eth, din_eth_4x10G, din_frame_generator, network0, data_source);
|
||||
} else if (data_source == STREAM_MERGE_SRC_4x10G) {
|
||||
while (!din_eth_4x10G.empty())
|
||||
stream_merge(din_eth, din_eth_4x10G, din_frame_generator, network0, data_source);
|
||||
}
|
||||
volatile bool done = false;
|
||||
volatile bool udp_done = false; // done AND udp_idle
|
||||
volatile bool sls_done = false; // done AND sls_idle
|
||||
|
||||
while(!network0.empty())
|
||||
ethernet(network0, ip1, arp1, mac_addr, eth_packets, clear_counters);
|
||||
// Sent gratuitous ARP message
|
||||
arp(arp1, dout_eth, mac_addr, ipv4_addr, 1, 1);
|
||||
|
||||
while(!ip1.empty())
|
||||
ipv4(ip1, udp1, icmp1, ipv4_addr);
|
||||
Logger logger_hls("HLS");
|
||||
|
||||
arp(arp1,
|
||||
dout_eth,
|
||||
mac_addr,
|
||||
ipv4_addr,
|
||||
1, run_data_collection);
|
||||
volatile rcv_state_t state = RCV_INIT;
|
||||
// Start data collection
|
||||
data_collection_fsm(raw0, raw1,
|
||||
addr0, addr1,
|
||||
run_data_collection,
|
||||
cancel_data_collection,
|
||||
idle_data_collection,
|
||||
cfg.mode,
|
||||
float2uint(cfg.energy_kev),
|
||||
cfg.nframes,
|
||||
cfg.nmodules,
|
||||
cfg.nstorage_cells,
|
||||
cfg.nsummation , state);
|
||||
|
||||
while (!arp1.empty()) {
|
||||
arp(arp1,
|
||||
dout_eth,
|
||||
mac_addr,
|
||||
ipv4_addr,
|
||||
1, run_data_collection);
|
||||
}
|
||||
run_data_collection = 0;
|
||||
data_collection_fsm(raw0, raw1,
|
||||
addr0, addr1,
|
||||
run_data_collection,
|
||||
cancel_data_collection,
|
||||
idle_data_collection,
|
||||
cfg.mode,
|
||||
float2uint(cfg.energy_kev),
|
||||
cfg.nframes,
|
||||
cfg.nmodules,
|
||||
cfg.nstorage_cells,
|
||||
cfg.nsummation, state);
|
||||
|
||||
// reset static counter
|
||||
arp(arp1,
|
||||
dout_eth,
|
||||
mac_addr,
|
||||
ipv4_addr,
|
||||
0, run_data_collection);
|
||||
hls_cores.emplace_back([&] {
|
||||
while (!udp_done) {
|
||||
if (din_eth.empty() && din_eth_4x10G.empty() && din_frame_generator.empty())
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
else
|
||||
stream_merge(din_eth, din_eth_4x10G, din_frame_generator, network0, data_source);
|
||||
}
|
||||
logger_hls.Info("Stream_merge done");
|
||||
});
|
||||
|
||||
while(!icmp1.empty())
|
||||
icmp(icmp1, dout_eth, icmp_packets, clear_counters);
|
||||
hls_cores.emplace_back([&] {
|
||||
while (!udp_done) {
|
||||
if (network0.empty())
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
else
|
||||
ethernet(network0, ip1, arp1, mac_addr, eth_packets, clear_counters);
|
||||
}
|
||||
logger_hls.Info("ethernet done");
|
||||
});
|
||||
|
||||
while (!udp1.empty())
|
||||
udp(udp1, udp2, udp_metadata, udp_packets, clear_counters);
|
||||
hls_cores.emplace_back([&] {
|
||||
while (!udp_done) {
|
||||
if (ip1.empty())
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
else
|
||||
ipv4(ip1, udp1, icmp1, ipv4_addr);
|
||||
}
|
||||
logger_hls.Info("ipv4 done");
|
||||
});
|
||||
|
||||
while (!udp2.empty())
|
||||
sls_detector(udp2, udp_metadata, raw0, addr0, sls_packets, udp_eth_err, udp_len_err, clear_counters);
|
||||
hls_cores.emplace_back([&] {
|
||||
ap_uint<1> udp_idle = 1;
|
||||
while (!done || !udp_idle) {
|
||||
if (udp1.empty())
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
else
|
||||
udp(udp1, udp2, udp_metadata, udp_packets, clear_counters, udp_idle);
|
||||
}
|
||||
udp_done = true;
|
||||
logger_hls.Info("udp done");
|
||||
});
|
||||
|
||||
hls_cores.emplace_back([&] {
|
||||
ap_uint<1> sls_idle = 1;
|
||||
while (!done || !sls_idle) {
|
||||
if (udp2.empty())
|
||||
std::this_thread::sleep_for(std::chrono::microseconds (10));
|
||||
else
|
||||
sls_detector(udp2, udp_metadata, raw0, addr0, sls_packets, udp_eth_err, udp_len_err, clear_counters, sls_idle);
|
||||
}
|
||||
sls_done = true;
|
||||
logger_hls.Info("sls_detector done");
|
||||
});
|
||||
|
||||
// 1. Parse incoming UDP packets
|
||||
idle_data_collection = 0;
|
||||
hls_cores.emplace_back([&] {
|
||||
while ((idle_data_collection == 0) || (!raw0.empty())) {
|
||||
while ((state != RCV_WAIT_FOR_START) || (idle_data_collection.read() == 0) || (!raw0.empty())) {
|
||||
data_collection_fsm(raw0, raw1,
|
||||
addr0, addr1,
|
||||
run_data_collection,
|
||||
cancel_data_collection,
|
||||
idle_data_collection,
|
||||
cfg.mode,
|
||||
cfg.one_over_energy,
|
||||
float2uint(cfg.energy_kev),
|
||||
cfg.nframes,
|
||||
cfg.nmodules,
|
||||
cfg.nstorage_cells,
|
||||
cfg.nsummation);
|
||||
run_data_collection = 0;
|
||||
cfg.nsummation,
|
||||
state);
|
||||
}
|
||||
done = true;
|
||||
|
||||
logger_hls.Info("data collection done");
|
||||
});
|
||||
|
||||
// 2. Cache images in HBM
|
||||
hls_cores.emplace_back([&] { save_to_hbm(raw1, converted_1, addr1, compl0, hbm_handles,
|
||||
datamover_out_hbm_0.GetDataStream(), datamover_out_hbm_1.GetDataStream(),
|
||||
datamover_out_hbm_0.GetCtrlStream(), datamover_out_hbm_1.GetCtrlStream(),
|
||||
hbm_if_size);});
|
||||
save_to_hbm_idle, hbm_if_size);});
|
||||
hls_cores.emplace_back([&] {frame_summation_reorder_compl(converted_1, converted_2, compl0, compl1);});
|
||||
|
||||
hls_cores.emplace_back([&] { load_from_hbm(converted_2, converted_3, compl1, compl2, hbm_handles,
|
||||
datamover_in_hbm_0.GetDataStream(), datamover_in_hbm_1.GetDataStream(),
|
||||
datamover_in_hbm_0.GetCtrlStream(), datamover_in_hbm_1.GetCtrlStream(),
|
||||
hbm_if_size);});
|
||||
load_to_hbm_idle, hbm_if_size);});
|
||||
|
||||
hls_cores.emplace_back([&] { pedestal(converted_3, converted_3a, compl2, compl2a,
|
||||
hbm.data(),
|
||||
@@ -393,126 +454,139 @@ void HLSSimulatedDevice::HLSMainThread() {
|
||||
hbm_if_size); });
|
||||
|
||||
// 6. Frame summation
|
||||
hls_cores.emplace_back([&] { frame_summation(converted_6, stream_768_0, compl5, compl6);});
|
||||
hls_cores.emplace_back([&] { frame_summation(converted_6, stream_768_0, compl5, compl6, frame_summation_idle);});
|
||||
|
||||
// 7. Integration of pixels
|
||||
hls_cores.emplace_back([&] { integration(stream_768_0, stream_768_1, integration_result_0, compl6, compl7,
|
||||
hbm.data(), hbm.data(), hbm.data(), hbm.data(), hbm_if_size);});
|
||||
hbm.data(), hbm.data(), hbm.data(), hbm.data(), integration_idle, hbm_if_size);});
|
||||
hls_cores.emplace_back([&] { axis_64_to_512(integration_result_0, integration_result_1);});
|
||||
|
||||
// 8. Spot finding
|
||||
hls_cores.emplace_back([&] { spot_finder(stream_768_1, stream_768_2, spot_finder_result_0, count_threshold, snr_threshold);});
|
||||
ap_uint<32> tmp_snr_threshold = float2uint(snr_threshold);
|
||||
hls_cores.emplace_back([&] { spot_finder(stream_768_1, stream_768_2, spot_finder_result_0,
|
||||
count_threshold,tmp_snr_threshold);});
|
||||
hls_cores.emplace_back([&] { axis_32_to_512(spot_finder_result_0, spot_finder_result_1);});
|
||||
|
||||
// 9. Reduce/extend 24-bit stream
|
||||
hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_2, converted_7);});
|
||||
hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_2, converted_7, stream_conv_idle);});
|
||||
|
||||
// 10. Prepare data to write to host memory
|
||||
hls_cores.emplace_back([&] {
|
||||
ap_uint<3> state;
|
||||
host_writer(converted_7, adu_histo_result, integration_result_1, spot_finder_result_1,
|
||||
compl7, datamover_out.GetDataStream(),
|
||||
datamover_out.GetCtrlStream(), work_request_stream, completion_stream,
|
||||
dma_address_table.data(), packets_processed, host_writer_idle);});
|
||||
dma_address_table.data(), packets_processed, host_writer_idle, cancel_data_collection, state);});
|
||||
|
||||
for (auto &i : hls_cores)
|
||||
i.join();
|
||||
|
||||
if (!din_eth.empty())
|
||||
throw std::runtime_error("din_eth queue not empty");
|
||||
if (frame_generator_future.valid())
|
||||
frame_generator_future.get();
|
||||
|
||||
if (!addr1.empty())
|
||||
throw std::runtime_error("Addr1 queue not empty");
|
||||
// reset static counter
|
||||
arp(arp1, dout_eth, mac_addr, ipv4_addr, 0, 1);
|
||||
try {
|
||||
while (!din_eth.empty())
|
||||
din_eth.read();
|
||||
|
||||
if (!addr2.empty())
|
||||
throw std::runtime_error("Addr2 queue not empty");
|
||||
if (!addr1.empty())
|
||||
throw std::runtime_error("Addr1 queue not empty");
|
||||
|
||||
if (!addr3.empty())
|
||||
throw std::runtime_error("Addr3 queue not empty");
|
||||
if (!addr2.empty())
|
||||
throw std::runtime_error("Addr2 queue not empty");
|
||||
|
||||
if (!raw1.empty())
|
||||
throw std::runtime_error("Raw1 queue not empty");
|
||||
if (!addr3.empty())
|
||||
throw std::runtime_error("Addr3 queue not empty");
|
||||
|
||||
if (!raw2.empty())
|
||||
throw std::runtime_error("Raw2 queue not empty");
|
||||
if (!raw1.empty())
|
||||
throw std::runtime_error("Raw1 queue not empty");
|
||||
|
||||
if (!raw3.empty())
|
||||
throw std::runtime_error("Raw3 queue not empty");
|
||||
if (!raw2.empty())
|
||||
throw std::runtime_error("Raw2 queue not empty");
|
||||
|
||||
if (!converted_0.empty())
|
||||
throw std::runtime_error("Converted_0 queue not empty");
|
||||
if (!raw3.empty())
|
||||
throw std::runtime_error("Raw3 queue not empty");
|
||||
|
||||
if (!converted_1.empty())
|
||||
throw std::runtime_error("Converted_1 queue not empty");
|
||||
if (!converted_0.empty())
|
||||
throw std::runtime_error("Converted_0 queue not empty");
|
||||
|
||||
if (!converted_2.empty())
|
||||
throw std::runtime_error("Converted_2 queue not empty");
|
||||
if (!converted_1.empty())
|
||||
throw std::runtime_error("Converted_1 queue not empty");
|
||||
|
||||
if (!converted_3.empty())
|
||||
throw std::runtime_error("Converted_3 queue not empty");
|
||||
if (!converted_2.empty())
|
||||
throw std::runtime_error("Converted_2 queue not empty");
|
||||
|
||||
if (!converted_4.empty())
|
||||
throw std::runtime_error("Converted_4 queue not empty");
|
||||
if (!converted_3.empty())
|
||||
throw std::runtime_error("Converted_3 queue not empty");
|
||||
|
||||
if (!converted_5.empty())
|
||||
throw std::runtime_error("Converted_5 queue not empty");
|
||||
if (!converted_4.empty())
|
||||
throw std::runtime_error("Converted_4 queue not empty");
|
||||
|
||||
if (!converted_6.empty())
|
||||
throw std::runtime_error("Converted_6 queue not empty");
|
||||
if (!converted_5.empty())
|
||||
throw std::runtime_error("Converted_5 queue not empty");
|
||||
|
||||
if (!converted_7.empty())
|
||||
throw std::runtime_error("Converted_7 queue not empty");
|
||||
if (!converted_6.empty())
|
||||
throw std::runtime_error("Converted_6 queue not empty");
|
||||
|
||||
if (!converted_8.empty())
|
||||
throw std::runtime_error("Converted_8 queue not empty");
|
||||
if (!converted_7.empty())
|
||||
throw std::runtime_error("Converted_7 queue not empty");
|
||||
|
||||
if (!compl0.empty())
|
||||
throw std::runtime_error("Compl0 queue not empty");
|
||||
if (!converted_8.empty())
|
||||
throw std::runtime_error("Converted_8 queue not empty");
|
||||
|
||||
if (!compl1.empty())
|
||||
throw std::runtime_error("Compl1 queue not empty");
|
||||
if (!compl0.empty())
|
||||
throw std::runtime_error("Compl0 queue not empty");
|
||||
|
||||
if (!compl2.empty())
|
||||
throw std::runtime_error("Compl2 queue not empty");
|
||||
if (!compl1.empty())
|
||||
throw std::runtime_error("Compl1 queue not empty");
|
||||
|
||||
if (!compl3.empty())
|
||||
throw std::runtime_error("Compl3 queue not empty");
|
||||
if (!compl2.empty())
|
||||
throw std::runtime_error("Compl2 queue not empty");
|
||||
|
||||
if (!compl4.empty())
|
||||
throw std::runtime_error("Compl4 queue not empty");
|
||||
if (!compl3.empty())
|
||||
throw std::runtime_error("Compl3 queue not empty");
|
||||
|
||||
if (!compl5.empty())
|
||||
throw std::runtime_error("Compl5 queue not empty");
|
||||
if (!compl4.empty())
|
||||
throw std::runtime_error("Compl4 queue not empty");
|
||||
|
||||
if (!compl6.empty())
|
||||
throw std::runtime_error("Compl6 queue not empty");
|
||||
if (!compl5.empty())
|
||||
throw std::runtime_error("Compl5 queue not empty");
|
||||
|
||||
if (!compl7.empty())
|
||||
throw std::runtime_error("Compl7 queue not empty");
|
||||
if (!compl6.empty())
|
||||
throw std::runtime_error("Compl6 queue not empty");
|
||||
|
||||
if (!stream_768_0.empty())
|
||||
throw std::runtime_error("Stream_768_0 queue not empty");
|
||||
if (!compl7.empty())
|
||||
throw std::runtime_error("Compl7 queue not empty");
|
||||
|
||||
if (!stream_768_1.empty())
|
||||
throw std::runtime_error("Stream_768_1 queue not empty");
|
||||
if (!stream_768_0.empty())
|
||||
throw std::runtime_error("Stream_768_0 queue not empty");
|
||||
|
||||
if (!stream_768_2.empty())
|
||||
throw std::runtime_error("Stream_768_2 queue not empty");
|
||||
if (!stream_768_1.empty())
|
||||
throw std::runtime_error("Stream_768_1 queue not empty");
|
||||
|
||||
if (!hbm_handles.empty())
|
||||
throw std::runtime_error("Handles queue not empty");
|
||||
if (!stream_768_2.empty())
|
||||
throw std::runtime_error("Stream_768_2 queue not empty");
|
||||
|
||||
if (!integration_result_0.empty())
|
||||
throw std::runtime_error("Integration result queue not empty");
|
||||
if (!hbm_handles.empty())
|
||||
throw std::runtime_error("Handles queue not empty");
|
||||
|
||||
if (!integration_result_1.empty())
|
||||
throw std::runtime_error("Integration result queue not empty");
|
||||
if (!integration_result_0.empty())
|
||||
throw std::runtime_error("Integration result queue not empty");
|
||||
|
||||
if (!datamover_in.GetDataStream().empty())
|
||||
throw std::runtime_error("Datamover queue is not empty");
|
||||
if (!integration_result_1.empty())
|
||||
throw std::runtime_error("Integration result queue not empty");
|
||||
|
||||
while (!datamover_out.IsIdle())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
if (!datamover_in.GetDataStream().empty())
|
||||
throw std::runtime_error("Datamover queue is not empty");
|
||||
|
||||
while (!datamover_out.IsIdle())
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
} catch (const std::runtime_error &e) {
|
||||
if (logger)
|
||||
logger->ErrorException(e);
|
||||
throw e;
|
||||
}
|
||||
if (logger)
|
||||
logger->Info("Packets Eth {} UDP {} SLS {} Proc {}", eth_packets, udp_packets, sls_packets, packets_processed);
|
||||
|
||||
@@ -525,77 +599,19 @@ void HLSSimulatedDevice::HW_GetStatus(DataCollectionStatus *status) const {
|
||||
status->ctrl_reg = ap_uint<1>(host_writer_idle) ? (1 << 4) : 0;
|
||||
status->max_modules = max_modules;
|
||||
status->hbm_size_bytes = hbm_if_size;
|
||||
status->run_counter = run_counter;
|
||||
}
|
||||
|
||||
void HLSSimulatedDevice::HW_LoadCalibration(uint32_t modules, uint32_t storage_cells) {
|
||||
|
||||
if (logger)
|
||||
logger->Info("Load calibration start");
|
||||
|
||||
int ret = load_calibration(hbm.data(),
|
||||
hbm.data(),
|
||||
modules,
|
||||
storage_cells,
|
||||
void HLSSimulatedDevice::HW_LoadCalibration(const LoadCalibrationConfig &config) {
|
||||
int ret = load_calibration(hbm.data(), hbm.data(),
|
||||
config,
|
||||
hbm_if_size,
|
||||
LOAD_CALIBRATION_DEST_CALIB,
|
||||
datamover_in.GetCtrlStream(),
|
||||
datamover_in.GetDataStream(),
|
||||
dma_address_table.data());
|
||||
if (ret)
|
||||
throw JFJochException(JFJochExceptionCategory::AcquisitionDeviceError,
|
||||
"Error in loading calibration");
|
||||
if (logger)
|
||||
logger->Info("Load calibration done");
|
||||
|
||||
if (!datamover_in.GetDataStream().empty())
|
||||
throw std::runtime_error("Datamover queue is not empty");
|
||||
}
|
||||
|
||||
void HLSSimulatedDevice::HW_LoadIntegrationMap(uint32_t modules) {
|
||||
if (logger)
|
||||
logger->Info("Load calibration start");
|
||||
|
||||
int ret = load_calibration(hbm.data(),
|
||||
hbm.data(),
|
||||
modules,
|
||||
0,
|
||||
hbm_if_size,
|
||||
LOAD_CALIBRATION_DEST_INTEGRATION,
|
||||
datamover_in.GetCtrlStream(),
|
||||
datamover_in.GetDataStream(),
|
||||
dma_address_table.data());
|
||||
|
||||
if (ret)
|
||||
throw JFJochException(JFJochExceptionCategory::AcquisitionDeviceError,
|
||||
"Error in loading calibration");
|
||||
|
||||
if (logger)
|
||||
logger->Info("Load integration_map");
|
||||
|
||||
if (!datamover_in.GetDataStream().empty())
|
||||
throw std::runtime_error("Datamover queue is not empty");
|
||||
}
|
||||
|
||||
void HLSSimulatedDevice::HW_LoadInternalGeneratorFrame(uint32_t modules) {
|
||||
if (logger)
|
||||
logger->Info("Load to frame generator");
|
||||
|
||||
int ret = load_calibration(hbm.data(),
|
||||
hbm.data(),
|
||||
modules,
|
||||
0,
|
||||
hbm_if_size,
|
||||
LOAD_CALIBRATION_DEST_FRAME_GEN,
|
||||
datamover_in.GetCtrlStream(),
|
||||
datamover_in.GetDataStream(),
|
||||
dma_address_table.data());
|
||||
|
||||
if (ret)
|
||||
throw JFJochException(JFJochExceptionCategory::AcquisitionDeviceError,
|
||||
"Error in loading calibration");
|
||||
|
||||
if (logger)
|
||||
logger->Info("Load to frame generator done");
|
||||
"Error in loading calibration " + std::to_string(ret));
|
||||
|
||||
if (!datamover_in.GetDataStream().empty())
|
||||
throw std::runtime_error("Datamover queue is not empty");
|
||||
@@ -612,4 +628,4 @@ void HLSSimulatedDevice::HW_SetDataSource(uint32_t val) {
|
||||
|
||||
uint32_t HLSSimulatedDevice::HW_GetDataSource() {
|
||||
return data_source;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@ class HLSSimulatedDevice : public FPGAAcquisitionDevice {
|
||||
AXI_STREAM din_frame_generator;
|
||||
AXI_STREAM dout_eth;
|
||||
|
||||
uint32_t run_counter = 0;
|
||||
|
||||
ap_uint<2> data_source = STREAM_MERGE_SRC_100G;
|
||||
ap_int<16> count_threshold = INT16_MAX;
|
||||
ap_uint<8> snr_threshold = 0;
|
||||
ap_int<32> count_threshold = -1;
|
||||
float snr_threshold = 0;
|
||||
|
||||
DataCollectionConfig cfg;
|
||||
|
||||
@@ -37,6 +39,7 @@ class HLSSimulatedDevice : public FPGAAcquisitionDevice {
|
||||
uint32_t completion_count;
|
||||
|
||||
std::thread action_thread;
|
||||
std::future<void> frame_generator_future;
|
||||
|
||||
Datamover<512> datamover_in;
|
||||
Datamover<512> datamover_out;
|
||||
@@ -59,14 +62,14 @@ class HLSSimulatedDevice : public FPGAAcquisitionDevice {
|
||||
bool HW_IsIdle() const override;
|
||||
bool HW_ReadMailbox(uint32_t *values) override;
|
||||
bool HW_SendWorkRequest(uint32_t handle) override;
|
||||
void HW_LoadCalibration(uint32_t modules, uint32_t storage_cells) override;
|
||||
void HW_LoadIntegrationMap(uint32_t modules) override;
|
||||
void HW_LoadInternalGeneratorFrame(uint32_t modules) override;
|
||||
void HW_LoadCalibration(const LoadCalibrationConfig &config) override;
|
||||
void HW_GetStatus(DataCollectionStatus *status) const override;
|
||||
void HW_SetSpotFinderParameters(const SpotFinderParameters ¶ms) override;
|
||||
uint32_t HW_GetDataSource() override;
|
||||
void HW_SetDataSource(uint32_t val) override;
|
||||
void HLSMainThread() ;
|
||||
void HW_RunInternalGenerator(const FrameGeneratorConfig &config) override;
|
||||
void FrameGeneratorFuture(FrameGeneratorConfig config);
|
||||
void HLSMainThread();
|
||||
public:
|
||||
HLSSimulatedDevice(uint16_t data_stream, size_t in_frame_buffer_size_modules, int16_t numa_node = -1);
|
||||
~HLSSimulatedDevice() override;
|
||||
|
||||
@@ -44,15 +44,10 @@ bool PCIExpressDevice::HW_SendWorkRequest(uint32_t handle) {
|
||||
|
||||
void PCIExpressDevice::FPGA_StartAction(const DiffractionExperiment &experiment) {
|
||||
dev.Start();
|
||||
if (experiment.IsUsingInternalPacketGen()) {
|
||||
FrameGeneratorConfig config{};
|
||||
config.frames = experiment.GetFrameNum() + DELAY_FRAMES_STOP_AND_QUIT + 1;
|
||||
config.modules = experiment.GetModulesNum(data_stream);
|
||||
}
|
||||
|
||||
config.dest_mac_addr = dev.GetMACAddress();
|
||||
config.dest_ipv4_addr = dev.GetIPv4Address();
|
||||
dev.RunFrameGenerator(config);
|
||||
}
|
||||
void PCIExpressDevice::HW_RunInternalGenerator(const FrameGeneratorConfig &config) {
|
||||
dev.RunFrameGenerator(config);
|
||||
}
|
||||
|
||||
void PCIExpressDevice::FPGA_EndAction() {
|
||||
@@ -107,18 +102,6 @@ std::string PCIExpressDevice::GetIPv4Address() const {
|
||||
return IPv4AddressToStr(dev.GetIPv4Address());
|
||||
}
|
||||
|
||||
void PCIExpressDevice::HW_LoadCalibration(uint32_t in_modules, uint32_t in_storage_cells) {
|
||||
dev.LoadCalibration(in_modules, in_storage_cells);
|
||||
}
|
||||
|
||||
void PCIExpressDevice::HW_LoadIntegrationMap(uint32_t in_modules) {
|
||||
dev.LoadIntegrationMap(in_modules);
|
||||
}
|
||||
|
||||
void PCIExpressDevice::HW_LoadInternalGeneratorFrame(uint32_t in_modules) {
|
||||
dev.LoadInternalGeneratorFrame(in_modules);
|
||||
}
|
||||
|
||||
void PCIExpressDevice::HW_SetSpotFinderParameters(const SpotFinderParameters ¶ms) {
|
||||
dev.SetSpotFinderParameters(params);
|
||||
}
|
||||
@@ -139,3 +122,7 @@ void PCIExpressDevice::HW_SetDataSource(uint32_t val) {
|
||||
return dev.SetDataSource(val);
|
||||
}
|
||||
|
||||
void PCIExpressDevice::HW_LoadCalibration(const LoadCalibrationConfig &config) {
|
||||
dev.LoadCalibration(config);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,20 +9,19 @@
|
||||
class PCIExpressDevice : public FPGAAcquisitionDevice {
|
||||
JungfraujochDevice dev;
|
||||
|
||||
void HW_LoadCalibration(const LoadCalibrationConfig &config) override;
|
||||
bool HW_ReadMailbox(uint32_t *values) override;
|
||||
bool HW_SendWorkRequest(uint32_t handle) override;
|
||||
void FPGA_StartAction(const DiffractionExperiment &experiment) override;
|
||||
bool HW_IsIdle() const final;
|
||||
void HW_WriteActionRegister(const DataCollectionConfig *job) override;
|
||||
void HW_ReadActionRegister(DataCollectionConfig *job) override;
|
||||
void HW_LoadCalibration(uint32_t modules, uint32_t storage_cells) override;
|
||||
void HW_LoadIntegrationMap(uint32_t modules) override;
|
||||
void HW_LoadInternalGeneratorFrame(uint32_t modules) override;
|
||||
void HW_SetSpotFinderParameters(const SpotFinderParameters ¶ms) override;
|
||||
uint32_t HW_GetDataSource() override;
|
||||
void HW_SetDataSource(uint32_t val) override;
|
||||
void FPGA_EndAction() override;
|
||||
uint32_t GetNumKernelBuffers() const;
|
||||
void HW_RunInternalGenerator(const FrameGeneratorConfig &config) override;
|
||||
public:
|
||||
explicit PCIExpressDevice(uint16_t data_stream);
|
||||
PCIExpressDevice(uint16_t data_stream, uint16_t pci_slot);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
ADD_SUBDIRECTORY(pistache)
|
||||
|
||||
AUX_SOURCE_DIRECTORY(gen/model MODEL_SOURCES)
|
||||
ADD_LIBRARY(JFJochAPI STATIC ${MODEL_SOURCES} gen/api/DefaultApi.cpp gen/api/DefaultApi.h)
|
||||
|
||||
|
||||
+88
-21
@@ -38,22 +38,29 @@ inline org::openapitools::server::model::Spot_finding_settings Convert(const Spo
|
||||
inline org::openapitools::server::model::Measurement_statistics Convert(const MeasurementStatistics &input) {
|
||||
org::openapitools::server::model::Measurement_statistics ret{};
|
||||
|
||||
ret.setFilePrefix(input.file_prefix);
|
||||
if (!input.file_prefix.empty())
|
||||
ret.setFilePrefix(input.file_prefix);
|
||||
|
||||
ret.setImagesExpected(input.images_expected);
|
||||
ret.setImagesCollected(input.images_collected);
|
||||
ret.setImagesSent(input.images_sent);
|
||||
ret.setMaxImageNumberSent(input.max_image_number_sent);
|
||||
ret.setCollectionEfficiency(input.collection_efficiency);
|
||||
if (input.collection_efficiency >= 0.0)
|
||||
ret.setCollectionEfficiency(input.collection_efficiency);
|
||||
ret.setCompressionRatio(input.compression_ratio);
|
||||
|
||||
ret.setCancelled(input.cancelled);
|
||||
ret.setMaxReceiverDelay(input.max_receive_delay);
|
||||
|
||||
ret.setIndexingRate(input.indexing_rate);
|
||||
|
||||
ret.setDetectorWidth(input.detector_width);
|
||||
ret.setDetectorHeight(input.detector_height);
|
||||
ret.setDetectorPixelDepth(input.detector_pixel_depth);
|
||||
|
||||
ret.setBkgEstimate(input.bkg_estimate);
|
||||
if (input.indexing_rate >= 0.0)
|
||||
ret.setIndexingRate(input.indexing_rate);
|
||||
|
||||
if (input.bkg_estimate >= 0.0)
|
||||
ret.setBkgEstimate(input.bkg_estimate);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -69,6 +76,8 @@ inline DetectorSettings Convert(const org::openapitools::server::model::Detector
|
||||
|
||||
ret.use_internal_packet_generator = input.isInternalFrameGenerator();
|
||||
ret.collect_raw_data = input.isCollectRawData();
|
||||
ret.fixed_gain_g1 = input.isFixedGainG1();
|
||||
ret.use_gain_hg0 = input.isUseGainHg0();
|
||||
|
||||
if (input.pedestalG0FramesIsSet())
|
||||
ret.pedestal_g0_frames = input.getPedestalG0Frames();
|
||||
@@ -91,7 +100,8 @@ inline org::openapitools::server::model::Detector_settings Convert(const Detecto
|
||||
ret.setStorageCellCount(input.storage_cell_count);
|
||||
ret.setInternalFrameGenerator(input.use_internal_packet_generator);
|
||||
ret.setCollectRawData(input.collect_raw_data);
|
||||
|
||||
ret.setFixedGainG1(input.fixed_gain_g1);
|
||||
ret.setUseGainHg0(input.use_gain_hg0);
|
||||
ret.setPedestalG0Frames(input.pedestal_g0_frames.value());
|
||||
ret.setPedestalG1Frames(input.pedestal_g1_frames.value());
|
||||
ret.setPedestalG2Frames(input.pedestal_g2_frames.value());
|
||||
@@ -125,10 +135,8 @@ inline org::openapitools::server::model::Broker_status Convert(const BrokerStatu
|
||||
}
|
||||
if (input.progress.has_value())
|
||||
ret.setProgress(input.progress.value());
|
||||
if (input.indexing_rate.has_value())
|
||||
if (input.indexing_rate.has_value() && (input.indexing_rate >= 0.0))
|
||||
ret.setIndexingRate(input.indexing_rate.value());
|
||||
if (input.receiver_send_buffers_avail.has_value())
|
||||
ret.setReceiverSendBuffersAvail(input.receiver_send_buffers_avail.value());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -274,22 +282,32 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
|
||||
if (input.transmissionIsSet())
|
||||
ret.attenuator_transmission = input.getTransmission();
|
||||
|
||||
if (input.omegaIsSet()) {
|
||||
ret.omega_step = input.getOmega().getStep();
|
||||
ret.omega_start = input.getOmega().getStart();
|
||||
if (input.getOmega().getVector().size() == 3) {
|
||||
auto v = input.getOmega().getVector();
|
||||
ret.omega_axis = Coord(v[0], v[1], v[2]);
|
||||
} else
|
||||
ret.omega_axis = Coord(0, 0, 0);
|
||||
}
|
||||
|
||||
if (input.roiSumAreaIsSet()) {
|
||||
ret.roi_sum_area = ROIRectangle{
|
||||
.x_min = static_cast<size_t>(input.getRoiSumArea().getXMin()),
|
||||
.x_max = static_cast<size_t>(input.getRoiSumArea().getXMax()),
|
||||
.y_min = static_cast<size_t>(input.getRoiSumArea().getYMin()),
|
||||
.y_max = static_cast<size_t>(input.getRoiSumArea().getYMax())
|
||||
};
|
||||
}
|
||||
ret.space_group_number = input.spaceGroupNumberIsSet() ? input.getSpaceGroupNumber() : 0;
|
||||
ret.sample_name = input.getSampleName();
|
||||
|
||||
ret.header_appendix = input.getHeaderAppendix();
|
||||
ret.image_appendix = input.getImageAppendix();
|
||||
ret.save_calibration = input.saveCalibrationIsSet() && input.isSaveCalibration();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void ProcessOutput(const T& output, Pistache::Http::ResponseWriter &response) {
|
||||
std::stringstream s;
|
||||
assert(output.validate(s));
|
||||
|
||||
nlohmann::json j;
|
||||
to_json(j, output);
|
||||
response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json));
|
||||
}
|
||||
|
||||
JFJochBrokerHttp::JFJochBrokerHttp(const DiffractionExperiment &experiment, std::shared_ptr<Pistache::Rest::Router> &rtr)
|
||||
: DefaultApi(rtr) {
|
||||
@@ -314,6 +332,7 @@ JFJochServices &JFJochBrokerHttp::Services() {
|
||||
|
||||
void JFJochBrokerHttp::cancel_post(Pistache::Http::ResponseWriter &response) {
|
||||
state_machine.Cancel();
|
||||
response.send(Pistache::Http::Code::Ok);
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::deactivate_post(Pistache::Http::ResponseWriter &response) {
|
||||
@@ -408,8 +427,11 @@ void JFJochBrokerHttp::config_spot_finding_put(
|
||||
response.send(Pistache::Http::Code::Ok);
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::plot_adu_histogram_get(Pistache::Http::ResponseWriter &response) {
|
||||
PlotRequest req{.type = PlotType::ADUHistorgram};
|
||||
void JFJochBrokerHttp::plot_saturated_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) {
|
||||
PlotRequest req{.type = PlotType::SaturatedPixels, .binning = 0};
|
||||
if (plotRequest.binningIsSet())
|
||||
req.binning = plotRequest.getBinning();
|
||||
auto plot = state_machine.GetPlots(req);
|
||||
ProcessOutput(Convert(plot), response);
|
||||
}
|
||||
@@ -539,4 +561,49 @@ void JFJochBrokerHttp::GetStaticFile(const Pistache::Rest::Request &request, Pis
|
||||
JFJochBrokerHttp &JFJochBrokerHttp::FrontendDirectory(const std::string &directory) {
|
||||
frontend_directory = directory;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::plot_error_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) {
|
||||
PlotRequest req{.type = PlotType::ErrorPixels, .binning = 0};
|
||||
if (plotRequest.binningIsSet())
|
||||
req.binning = plotRequest.getBinning();
|
||||
auto plot = state_machine.GetPlots(req);
|
||||
ProcessOutput(Convert(plot), response);
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::plot_strong_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) {
|
||||
PlotRequest req{.type = PlotType::StrongPixels, .binning = 0};
|
||||
if (plotRequest.binningIsSet())
|
||||
req.binning = plotRequest.getBinning();
|
||||
auto plot = state_machine.GetPlots(req);
|
||||
ProcessOutput(Convert(plot), response);
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::plot_image_collection_efficiency_post(
|
||||
const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) {
|
||||
PlotRequest req{.type = PlotType::ImageCollectionEfficiency, .binning = 0};
|
||||
if (plotRequest.binningIsSet())
|
||||
req.binning = plotRequest.getBinning();
|
||||
auto plot = state_machine.GetPlots(req);
|
||||
ProcessOutput(Convert(plot), response);
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::plot_receiver_delay_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) {
|
||||
PlotRequest req{.type = PlotType::ReceiverDelay, .binning = 0};
|
||||
if (plotRequest.binningIsSet())
|
||||
req.binning = plotRequest.getBinning();
|
||||
auto plot = state_machine.GetPlots(req);
|
||||
ProcessOutput(Convert(plot), response);
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::plot_roi_sum_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) {
|
||||
PlotRequest req{.type = PlotType::ROISum, .binning = 0};
|
||||
if (plotRequest.binningIsSet())
|
||||
req.binning = plotRequest.getBinning();
|
||||
auto plot = state_machine.GetPlots(req);
|
||||
ProcessOutput(Convert(plot), response);
|
||||
}
|
||||
@@ -38,7 +38,21 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi {
|
||||
void config_spot_finding_put(const org::openapitools::server::model::Spot_finding_settings &spotFindingSettings,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
|
||||
void plot_adu_histogram_get(Pistache::Http::ResponseWriter &response) override;
|
||||
void plot_roi_sum_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
|
||||
void plot_saturated_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
void plot_error_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
void plot_strong_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
|
||||
void plot_receiver_delay_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
|
||||
void plot_image_collection_efficiency_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
|
||||
void plot_bkg_estimate_post(const org::openapitools::server::model::Plot_request &plotRequest,
|
||||
Pistache::Http::ResponseWriter &response) override;
|
||||
@@ -77,6 +91,18 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi {
|
||||
void GetStaticFile(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
std::pair<Pistache::Http::Code, std::string> handleOperationException(const std::exception &ex) const noexcept override;
|
||||
|
||||
template <class T>
|
||||
void ProcessOutput(const T& output, Pistache::Http::ResponseWriter &response) {
|
||||
std::stringstream s;
|
||||
if(!output.validate(s)) {
|
||||
logger.Error(s.str());
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, s.str(), MIME(Text, Plain));
|
||||
}
|
||||
|
||||
nlohmann::json j;
|
||||
to_json(j, output);
|
||||
response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json));
|
||||
}
|
||||
public:
|
||||
JFJochBrokerHttp(const DiffractionExperiment& experiment, std::shared_ptr<Pistache::Rest::Router> &rtr);
|
||||
void AddDetectorSetup(const DetectorSetup &setup);
|
||||
|
||||
@@ -246,6 +246,16 @@ void ParseFacilityConfiguration(const nlohmann::json &input, const std::string&
|
||||
experiment.InstrumentName(GET_STR(j, "instrument_name"));
|
||||
experiment.InstrumentNameShort(GET_STR(j, "instrument_name_short"));
|
||||
|
||||
if (j.contains("omega_axis")) {
|
||||
if (j["omega_axis"].is_array() && (j["omega_axis"].size() == 3))
|
||||
experiment.DefaultOmegaAxis(Coord(j["omega_axis"][0].get<float>(),
|
||||
j["omega_axis"][1].get<float>(),
|
||||
j["omega_axis"][2].get<float>()));
|
||||
else
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"omega_axis must be float array of 3");
|
||||
}
|
||||
|
||||
experiment.PedestalG0Frames(GET_I64(j, "pedestal_g0_frames"));
|
||||
experiment.PedestalG1Frames(GET_I64(j, "pedestal_g1_frames"));
|
||||
experiment.PedestalG2Frames(GET_I64(j, "pedestal_g2_frames"));
|
||||
@@ -264,7 +274,7 @@ void ParseAcquisitionDeviceGroup(const nlohmann::json &input, const std::string&
|
||||
const auto &j = input[tag];
|
||||
|
||||
std::string dev_type = GET_STR(j, "type");
|
||||
|
||||
bool use_4x10g = GET_BOOL(j, "use_4x10g", false);
|
||||
int64_t buffer_size = GET_I64(j, "buffer_size", 1024);
|
||||
int64_t dev_count = GET_I64(j, "count", 1);
|
||||
|
||||
@@ -284,6 +294,11 @@ void ParseAcquisitionDeviceGroup(const nlohmann::json &input, const std::string&
|
||||
} else
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Device type unknown");
|
||||
|
||||
if (use_4x10g)
|
||||
aq_devices.SetDefaultDataSource(AcquisitionDeviceSource::MAC_4x10G);
|
||||
else
|
||||
aq_devices.SetDefaultDataSource(AcquisitionDeviceSource::MAC_100G);
|
||||
|
||||
std::vector<std::string> ipv4_addr = GET_STR_ARR(j, "ipv4_addr");
|
||||
if (ipv4_addr.size() != aq_devices.size())
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "../common/DiffractionExperiment.h"
|
||||
#include "JFJochBrokerHttp.h"
|
||||
#include "../acquisition_device/AcquisitionDeviceGroup.h"
|
||||
#include "../frame_serialize/ZMQPreviewPublisher.h"
|
||||
#include "../frame_serialize/ZMQStream2PreviewPublisher.h"
|
||||
|
||||
DetectorGeometry ParseStandardDetectorGeometry(const nlohmann::json &j);
|
||||
DetectorGeometry ParseCustomDetectorGeometry(const nlohmann::json &j);
|
||||
|
||||
+27
-20
@@ -14,12 +14,13 @@ void JFJochServices::Start(const DiffractionExperiment& experiment, const JFCali
|
||||
receiver->Start(experiment, &calibration);
|
||||
else
|
||||
receiver->Start(experiment, nullptr);
|
||||
|
||||
if (detector && !experiment.IsUsingInternalPacketGen()) {
|
||||
logger.Info(" ... detector start");
|
||||
detector->Start(experiment);
|
||||
}
|
||||
}
|
||||
|
||||
if (detector && !experiment.IsUsingInternalPacketGen()) {
|
||||
logger.Info(" ... detector start");
|
||||
detector->Start(experiment);
|
||||
}
|
||||
logger.Info(" Done!");
|
||||
}
|
||||
|
||||
@@ -37,7 +38,7 @@ void JFJochServices::On(const DiffractionExperiment &x) {
|
||||
logger.Info(" ... done");
|
||||
}
|
||||
|
||||
JFJochServicesOutput JFJochServices::Stop(const JFCalibration &calibration) {
|
||||
JFJochServicesOutput JFJochServices::Stop() {
|
||||
JFJochServicesOutput ret;
|
||||
|
||||
std::unique_ptr<JFJochException> exception;
|
||||
@@ -49,8 +50,8 @@ JFJochServicesOutput JFJochServices::Stop(const JFCalibration &calibration) {
|
||||
|
||||
logger.Info(" ... Receiver efficiency: {} % Max delay: {} Compression ratio {}x",
|
||||
static_cast<int>(ret.receiver_output.efficiency * 100.0),
|
||||
ret.receiver_output.max_receive_delay,
|
||||
static_cast<int>(std::round(ret.receiver_output.compressed_ratio)));
|
||||
ret.receiver_output.status.max_receive_delay,
|
||||
static_cast<int>(std::round(ret.receiver_output.status.compressed_ratio)));
|
||||
if (ret.receiver_output.efficiency < 1.0) {
|
||||
for (int i = 0; i < ret.receiver_output.received_packets.size(); i++) {
|
||||
if (ret.receiver_output.received_packets[i] != ret.receiver_output.expected_packets[i])
|
||||
@@ -63,20 +64,25 @@ JFJochServicesOutput JFJochServices::Stop(const JFCalibration &calibration) {
|
||||
exception = std::make_unique<JFJochException>(e);
|
||||
}
|
||||
logger.Info("Receiver finished with success");
|
||||
}
|
||||
|
||||
if (detector) {
|
||||
logger.Info("Stopping detector");
|
||||
try {
|
||||
if (detector) {
|
||||
logger.Info("Stopping detector");
|
||||
try {
|
||||
|
||||
detector->Stop();
|
||||
logger.Info(" ... done");
|
||||
} catch (JFJochException &e) {
|
||||
logger.Error(" ... finished with error {}", e.what());
|
||||
exception = std::make_unique<JFJochException>(e);
|
||||
detector->Stop();
|
||||
logger.Info(" ... done");
|
||||
} catch (JFJochException &e) {
|
||||
logger.Error(" ... finished with error {}", e.what());
|
||||
exception = std::make_unique<JFJochException>(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.Info("No receiver - sleeping for 30 seconds");
|
||||
std::this_thread::sleep_for(std::chrono::seconds(30));
|
||||
logger.Info("Sleep done");
|
||||
}
|
||||
|
||||
|
||||
if (exception)
|
||||
throw JFJochException(*exception);
|
||||
|
||||
@@ -84,10 +90,11 @@ JFJochServicesOutput JFJochServices::Stop(const JFCalibration &calibration) {
|
||||
}
|
||||
|
||||
void JFJochServices::Cancel() {
|
||||
if (detector)
|
||||
detector->Stop();
|
||||
if (receiver != nullptr)
|
||||
if (receiver != nullptr) {
|
||||
if (detector)
|
||||
detector->Stop();
|
||||
receiver->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
JFJochServices &JFJochServices::Receiver(JFJochReceiverService *input) {
|
||||
@@ -135,6 +142,6 @@ void JFJochServices::SetSpotFindingSettings(const SpotFindingSettings &settings)
|
||||
}
|
||||
|
||||
void JFJochServices::Trigger() {
|
||||
if (detector)
|
||||
if (detector && (receiver != nullptr))
|
||||
detector->Trigger();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
void On(const DiffractionExperiment& experiment);
|
||||
void Off();
|
||||
void Start(const DiffractionExperiment& experiment, const JFCalibration &calibration);
|
||||
JFJochServicesOutput Stop(const JFCalibration &calibration);
|
||||
JFJochServicesOutput Stop();
|
||||
void Cancel();
|
||||
void Trigger();
|
||||
|
||||
|
||||
+148
-67
@@ -24,11 +24,20 @@ void LoadDatasetSettings(DiffractionExperiment& experiment, const DatasetSetting
|
||||
experiment.SampleName(settings.sample_name);
|
||||
experiment.Compression(settings.compression);
|
||||
experiment.SaveCalibration(settings.save_calibration);
|
||||
experiment.OmegaStart(settings.omega_start).OmegaStep(settings.omega_step);
|
||||
if (settings.omega_axis.Length() == 0.0f)
|
||||
experiment.OmegaAxis();
|
||||
else
|
||||
experiment.OmegaAxis(settings.omega_axis);
|
||||
|
||||
experiment.ImageAppendix(settings.image_appendix);
|
||||
experiment.HeaderAppendix(settings.header_appendix);
|
||||
if (settings.summation == 0)
|
||||
experiment.Summation(1);
|
||||
else
|
||||
experiment.Summation(settings.summation);
|
||||
experiment.FPGAOutputMode(settings.fpga_pixel_output);
|
||||
experiment.ROISummation(settings.roi_sum_area);
|
||||
} catch (...) {
|
||||
experiment = tmp;
|
||||
throw;
|
||||
@@ -52,6 +61,9 @@ void ApplyDetectorSettings(DiffractionExperiment& experiment, const DetectorSett
|
||||
else
|
||||
experiment.Mode(DetectorMode::Conversion);
|
||||
|
||||
experiment.UsingGainHG0(settings.use_gain_hg0);
|
||||
experiment.FixedGainG1(settings.fixed_gain_g1);
|
||||
|
||||
if (settings.pedestal_g0_frames)
|
||||
experiment.PedestalG0Frames(settings.pedestal_g0_frames.value());
|
||||
if (settings.pedestal_g1_frames)
|
||||
@@ -76,9 +88,9 @@ void ApplyRadialIntegrationSettings(DiffractionExperiment& experiment, const Rad
|
||||
experiment.ApplyPolarizationCorr(false);
|
||||
|
||||
experiment.ApplySolidAngleCorr(settings.solid_angle_correction);
|
||||
experiment.LowQForRadialInt_recipA(settings.low_q_recipA);
|
||||
experiment.HighQForRadialInt_recipA(settings.high_q_recipA);
|
||||
experiment.QSpacingForRadialInt_recipA(settings.q_spacing);
|
||||
experiment.LowQForAzimInt_recipA(settings.low_q_recipA);
|
||||
experiment.HighQForAzimInt_recipA(settings.high_q_recipA);
|
||||
experiment.QSpacingForAzimInt_recipA(settings.q_spacing);
|
||||
} catch (...) {
|
||||
experiment = tmp;
|
||||
throw;
|
||||
@@ -91,32 +103,36 @@ data_processing_settings(DiffractionExperiment::DefaultDataProcessingSettings())
|
||||
|
||||
}
|
||||
|
||||
void JFJochStateMachine::ImportPedestalG0(const JFJochReceiverOutput &receiver_output) {
|
||||
bool JFJochStateMachine::ImportPedestalG0(const JFJochReceiverOutput &receiver_output) {
|
||||
if (receiver_output.pedestal_result.empty())
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (receiver_output.pedestal_result.size() != experiment.GetModulesNum() * experiment.GetStorageCellNumber())
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mismatch in pedestal output");
|
||||
|
||||
size_t gain_level = experiment.IsFixedGainG1() ? 1 : 0;
|
||||
|
||||
for (int s = 0; s < experiment.GetStorageCellNumber(); s++) {
|
||||
for (int module = 0; module < experiment.GetModulesNum(); module++)
|
||||
calibration->Pedestal(module, 0, s)
|
||||
calibration->Pedestal(module, gain_level, s)
|
||||
= receiver_output.pedestal_result[module + s * experiment.GetModulesNum()];
|
||||
}
|
||||
SetCalibrationStatistics(calibration->GetModuleStatistics());
|
||||
return true;
|
||||
}
|
||||
|
||||
void JFJochStateMachine::ImportPedestal(const JFJochReceiverOutput &receiver_output, size_t gain_level,
|
||||
size_t storage_cell) {
|
||||
bool JFJochStateMachine::ImportPedestalG1G2(const JFJochReceiverOutput &receiver_output, size_t gain_level,
|
||||
size_t storage_cell) {
|
||||
if (receiver_output.pedestal_result.empty())
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (receiver_output.pedestal_result.size() != experiment.GetModulesNum() * experiment.GetStorageCellNumber())
|
||||
if (receiver_output.pedestal_result.size() != experiment.GetModulesNum())
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mismatch in pedestal output");
|
||||
|
||||
for (int i = 0; i < receiver_output.pedestal_result.size(); i++)
|
||||
calibration->Pedestal(i, gain_level, storage_cell) = receiver_output.pedestal_result[i];
|
||||
SetCalibrationStatistics(calibration->GetModuleStatistics());
|
||||
return true;
|
||||
}
|
||||
|
||||
void JFJochStateMachine::TakePedestalInternalAll(std::unique_lock<std::mutex> &ul) {
|
||||
@@ -135,10 +151,11 @@ void JFJochStateMachine::TakePedestalInternalAll(std::unique_lock<std::mutex> &u
|
||||
|
||||
try {
|
||||
TakePedestalInternalG0(ul);
|
||||
|
||||
for (int i = 0; i < experiment.GetStorageCellNumber(); i++) {
|
||||
TakePedestalInternalG1(ul, i);
|
||||
TakePedestalInternalG2(ul, i);
|
||||
if (!experiment.IsFixedGainG1()) {
|
||||
for (int i = 0; i < experiment.GetStorageCellNumber(); i++) {
|
||||
TakePedestalInternalG1(ul, i);
|
||||
TakePedestalInternalG2(ul, i);
|
||||
}
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
logger.Error("Pedestal sequence error {}", e.what());
|
||||
@@ -148,33 +165,45 @@ void JFJochStateMachine::TakePedestalInternalAll(std::unique_lock<std::mutex> &u
|
||||
logger.Info("Pedestal sequence done");
|
||||
}
|
||||
|
||||
|
||||
void JFJochStateMachine::TakePedestalInternalG0(std::unique_lock<std::mutex> &ul) {
|
||||
state = JFJochState::Pedestal;
|
||||
DiffractionExperiment local_experiment(experiment);
|
||||
local_experiment.Mode(DetectorMode::PedestalG0);
|
||||
if (local_experiment.IsFixedGainG1())
|
||||
local_experiment.Mode(DetectorMode::PedestalG1);
|
||||
else
|
||||
local_experiment.Mode(DetectorMode::PedestalG0);
|
||||
|
||||
if (local_experiment.GetStorageCellNumber() == 1)
|
||||
local_experiment.StorageCellStart(15);
|
||||
else
|
||||
local_experiment.StorageCellStart(0);
|
||||
|
||||
if (!cancel_sequence && (local_experiment.GetPedestalG0Frames() > 0)) {
|
||||
services.Start(local_experiment, *calibration);
|
||||
services.Trigger();
|
||||
ul.unlock();
|
||||
// Allow to cancel/abort during the pedestal data collection
|
||||
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
|
||||
auto pedestal_output = services.Stop(*calibration);
|
||||
ul.lock();
|
||||
|
||||
// SetFullMeasurementOutput(pedestal_output);
|
||||
ImportPedestalG0(pedestal_output.receiver_output);
|
||||
if (cancel_sequence) {
|
||||
state = JFJochState::Inactive;
|
||||
return;
|
||||
}
|
||||
state = JFJochState::Idle;
|
||||
if (local_experiment.GetPedestalG0Frames() == 0) {
|
||||
state = JFJochState::Idle;
|
||||
return;
|
||||
}
|
||||
|
||||
state = JFJochState::Pedestal;
|
||||
services.Start(local_experiment, *calibration);
|
||||
services.Trigger();
|
||||
ul.unlock();
|
||||
// Allow to cancel/abort during the pedestal data collection
|
||||
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
|
||||
auto pedestal_output = services.Stop();
|
||||
ul.lock();
|
||||
|
||||
SetFullMeasurementOutput(pedestal_output);
|
||||
if (ImportPedestalG0(pedestal_output.receiver_output))
|
||||
state = JFJochState::Idle;
|
||||
else
|
||||
state = JFJochState::Inactive;
|
||||
}
|
||||
|
||||
void JFJochStateMachine::TakePedestalInternalG1(std::unique_lock<std::mutex> &ul, int32_t storage_cell) {
|
||||
state = JFJochState::Pedestal;
|
||||
DiffractionExperiment local_experiment(experiment);
|
||||
local_experiment.Mode(DetectorMode::PedestalG1);
|
||||
|
||||
@@ -183,23 +212,35 @@ void JFJochStateMachine::TakePedestalInternalG1(std::unique_lock<std::mutex> &ul
|
||||
else
|
||||
local_experiment.StorageCellStart(15);
|
||||
|
||||
if (!cancel_sequence && (local_experiment.GetPedestalG1Frames() > 0)) {
|
||||
services.Start(local_experiment, *calibration);
|
||||
services.Trigger();
|
||||
ul.unlock();
|
||||
// Allow to cancel/abort during the pedestal data collection
|
||||
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
|
||||
auto pedestal_output = services.Stop(*calibration);
|
||||
ul.lock();
|
||||
|
||||
// SetFullMeasurementOutput(pedestal_output);
|
||||
ImportPedestal(pedestal_output.receiver_output, 1, storage_cell);
|
||||
if (cancel_sequence) {
|
||||
state = JFJochState::Inactive;
|
||||
return;
|
||||
}
|
||||
state = JFJochState::Idle;
|
||||
|
||||
if (local_experiment.GetPedestalG1Frames() == 0) {
|
||||
state = JFJochState::Idle;
|
||||
return;
|
||||
}
|
||||
|
||||
state = JFJochState::Pedestal;
|
||||
services.Start(local_experiment, *calibration);
|
||||
services.Trigger();
|
||||
ul.unlock();
|
||||
// Allow to cancel/abort during the pedestal data collection
|
||||
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
|
||||
auto pedestal_output = services.Stop();
|
||||
ul.lock();
|
||||
|
||||
SetFullMeasurementOutput(pedestal_output);
|
||||
if (ImportPedestalG1G2(pedestal_output.receiver_output, 1, storage_cell))
|
||||
state = JFJochState::Idle;
|
||||
else
|
||||
state = JFJochState::Inactive;
|
||||
|
||||
}
|
||||
|
||||
void JFJochStateMachine::TakePedestalInternalG2(std::unique_lock<std::mutex> &ul, int32_t storage_cell) {
|
||||
state = JFJochState::Pedestal;
|
||||
DiffractionExperiment local_experiment(experiment);
|
||||
local_experiment.Mode(DetectorMode::PedestalG2);
|
||||
|
||||
@@ -208,19 +249,30 @@ void JFJochStateMachine::TakePedestalInternalG2(std::unique_lock<std::mutex> &ul
|
||||
else
|
||||
local_experiment.StorageCellStart(15);
|
||||
|
||||
if (!cancel_sequence && (local_experiment.GetPedestalG2Frames() > 0)) {
|
||||
services.Start(local_experiment, *calibration);
|
||||
services.Trigger();
|
||||
ul.unlock();
|
||||
// Allow to cancel/abort during the pedestal data collection
|
||||
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
|
||||
auto pedestal_output = services.Stop(*calibration);
|
||||
ul.lock();
|
||||
|
||||
// SetFullMeasurementOutput(pedestal_output);
|
||||
ImportPedestal(pedestal_output.receiver_output, 2, storage_cell);
|
||||
if (cancel_sequence) {
|
||||
state = JFJochState::Inactive;
|
||||
return;
|
||||
}
|
||||
state = JFJochState::Idle;
|
||||
|
||||
if (local_experiment.GetPedestalG2Frames() == 0) {
|
||||
state = JFJochState::Idle;
|
||||
return;
|
||||
}
|
||||
|
||||
state = JFJochState::Pedestal;
|
||||
services.Start(local_experiment, *calibration);
|
||||
services.Trigger();
|
||||
ul.unlock();
|
||||
// Allow to cancel/abort during the pedestal data collection
|
||||
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
|
||||
auto pedestal_output = services.Stop();
|
||||
ul.lock();
|
||||
|
||||
SetFullMeasurementOutput(pedestal_output);
|
||||
if (ImportPedestalG1G2(pedestal_output.receiver_output, 2, storage_cell))
|
||||
state = JFJochState::Idle;
|
||||
else
|
||||
state = JFJochState::Inactive;
|
||||
}
|
||||
|
||||
void JFJochStateMachine::Initialize() {
|
||||
@@ -292,6 +344,8 @@ void JFJochStateMachine::Start(const DatasetSettings& settings) {
|
||||
else
|
||||
experiment.StorageCellStart(0);
|
||||
|
||||
experiment.IncrementSeriesID();
|
||||
|
||||
try {
|
||||
state = JFJochState::Busy;
|
||||
services.SetSpotFindingSettings(GetSpotFindingSettings());
|
||||
@@ -321,7 +375,7 @@ c.wait(ul, [&] { return !IsRunning(); });
|
||||
|
||||
void JFJochStateMachine::MeasurementThread() {
|
||||
try {
|
||||
auto tmp_output = services.Stop(*calibration);
|
||||
auto tmp_output = services.Stop();
|
||||
SetFullMeasurementOutput(tmp_output);
|
||||
{
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
@@ -377,15 +431,17 @@ void JFJochStateMachine::SetFullMeasurementOutput(const JFJochServicesOutput &ou
|
||||
tmp.detector_width = experiment.GetXPixelsNum();
|
||||
tmp.detector_height = experiment.GetYPixelsNum();
|
||||
tmp.detector_pixel_depth = experiment.GetPixelDepth();
|
||||
tmp.images_expected = experiment.GetImageNum();
|
||||
|
||||
tmp.compression_ratio = output.receiver_output.compressed_ratio;
|
||||
tmp.compression_ratio = output.receiver_output.status.compressed_ratio;
|
||||
tmp.collection_efficiency = output.receiver_output.efficiency;
|
||||
tmp.images_collected = output.receiver_output.images_sent;
|
||||
tmp.cancelled = output.receiver_output.cancelled;
|
||||
tmp.max_image_number_sent = output.receiver_output.max_image_number_sent;
|
||||
tmp.max_receive_delay = output.receiver_output.max_receive_delay;
|
||||
tmp.indexing_rate = output.receiver_output.indexing_rate;
|
||||
tmp.bkg_estimate = output.receiver_output.bkg_estimate;
|
||||
tmp.images_collected = output.receiver_output.status.images_collected;
|
||||
tmp.images_sent = output.receiver_output.status.images_sent;
|
||||
tmp.cancelled = output.receiver_output.status.cancelled;
|
||||
tmp.max_image_number_sent = output.receiver_output.status.max_image_number_sent;
|
||||
tmp.max_receive_delay = output.receiver_output.status.max_receive_delay;
|
||||
tmp.indexing_rate = output.receiver_output.status.indexing_rate;
|
||||
tmp.bkg_estimate = output.receiver_output.status.bkg_estimate;
|
||||
|
||||
measurement_statistics = tmp;
|
||||
}
|
||||
@@ -398,6 +454,7 @@ void JFJochStateMachine::ClearAndSetMeasurementStatistics() {
|
||||
tmp.detector_height = experiment.GetXPixelsNum();
|
||||
tmp.detector_width = experiment.GetYPixelsNum();
|
||||
tmp.detector_pixel_depth = experiment.GetPixelDepth();
|
||||
tmp.images_expected = experiment.GetImageNum();
|
||||
measurement_statistics = tmp;
|
||||
}
|
||||
|
||||
@@ -407,8 +464,31 @@ void JFJochStateMachine::ClearMeasurementStatistics() {
|
||||
}
|
||||
|
||||
std::optional<MeasurementStatistics> JFJochStateMachine::GetMeasurementStatistics() const {
|
||||
std::unique_lock<std::mutex> ul(last_receiver_output_mutex);
|
||||
return measurement_statistics;
|
||||
|
||||
auto rcv_status = services.GetReceiverStatus();
|
||||
if (rcv_status) {
|
||||
MeasurementStatistics tmp;
|
||||
|
||||
tmp.file_prefix = experiment.GetFilePrefix();
|
||||
tmp.detector_width = experiment.GetXPixelsNum();
|
||||
tmp.detector_height = experiment.GetYPixelsNum();
|
||||
tmp.detector_pixel_depth = experiment.GetPixelDepth();
|
||||
tmp.images_expected = experiment.GetImageNum();
|
||||
|
||||
tmp.compression_ratio = rcv_status->compressed_ratio;
|
||||
tmp.collection_efficiency = -1.0;
|
||||
tmp.images_collected = rcv_status->images_collected;
|
||||
tmp.images_sent = rcv_status->images_sent;
|
||||
tmp.cancelled = rcv_status->cancelled;
|
||||
tmp.max_image_number_sent = rcv_status->max_image_number_sent;
|
||||
tmp.max_receive_delay = rcv_status->max_receive_delay;
|
||||
tmp.indexing_rate = rcv_status->indexing_rate;
|
||||
tmp.bkg_estimate = rcv_status->bkg_estimate;
|
||||
return tmp;
|
||||
} else {
|
||||
std::unique_lock<std::mutex> ul(last_receiver_output_mutex);
|
||||
return measurement_statistics;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<JFCalibrationModuleStatistics> JFJochStateMachine::GetCalibrationStatistics() const {
|
||||
@@ -434,6 +514,8 @@ DetectorSettings JFJochStateMachine::GetDetectorSettings() const {
|
||||
ret.pedestal_g1_frames = experiment.GetPedestalG1Frames();
|
||||
ret.pedestal_g2_frames = experiment.GetPedestalG2Frames();
|
||||
ret.storage_cell_delay_ns = experiment.GetStorageCellDelay().count();
|
||||
ret.fixed_gain_g1 = experiment.IsFixedGainG1();
|
||||
ret.use_gain_hg0 = experiment.IsUsingGainHG0();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -468,7 +550,6 @@ BrokerStatus JFJochStateMachine::GetStatus() const {
|
||||
if (rcv_status) {
|
||||
ret.progress = rcv_status.value().progress;
|
||||
ret.indexing_rate = rcv_status.value().indexing_rate;
|
||||
ret.receiver_send_buffers_avail = rcv_status.value().send_buffers_avail;
|
||||
}
|
||||
} catch (JFJochException &e) {} // ignore exception in getting receiver status (don't really care, e.g. if receiver is down)
|
||||
|
||||
@@ -563,9 +644,9 @@ RadialIntegrationSettings JFJochStateMachine::GetRadialIntegrationSettings() con
|
||||
ret.polarization_factor = experiment.GetPolarizationFactor();
|
||||
ret.solid_angle_correction = experiment.GetApplySolidAngleCorr();
|
||||
|
||||
ret.q_spacing = experiment.GetQSpacingForRadialInt_recipA();
|
||||
ret.low_q_recipA = experiment.GetLowQForRadialInt_recipA();
|
||||
ret.high_q_recipA = experiment.GetHighQForRadialInt_recipA();
|
||||
ret.q_spacing = experiment.GetQSpacingForAzimInt_recipA();
|
||||
ret.low_q_recipA = experiment.GetLowQForAzimInt_recipA();
|
||||
ret.high_q_recipA = experiment.GetHighQForAzimInt_recipA();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ struct BrokerStatus {
|
||||
JFJochState broker_state;
|
||||
std::optional<float> progress;
|
||||
std::optional<float> indexing_rate;
|
||||
std::optional<float> receiver_send_buffers_avail;
|
||||
};
|
||||
|
||||
struct DetectorListElement {
|
||||
@@ -37,7 +36,9 @@ struct DetectorList {
|
||||
|
||||
struct MeasurementStatistics {
|
||||
std::string file_prefix;
|
||||
int64_t images_expected;
|
||||
int64_t images_collected;
|
||||
int64_t images_sent;
|
||||
int64_t max_image_number_sent;
|
||||
float collection_efficiency;
|
||||
float compression_ratio;
|
||||
@@ -78,6 +79,15 @@ struct DatasetSettings {
|
||||
bool save_calibration;
|
||||
std::optional<float> total_flux;
|
||||
std::optional<float> attenuator_transmission;
|
||||
|
||||
std::optional<float> omega_step;
|
||||
float omega_start;
|
||||
Coord omega_axis;
|
||||
|
||||
std::string image_appendix;
|
||||
std::string header_appendix;
|
||||
|
||||
std::optional<ROIRectangle> roi_sum_area;
|
||||
};
|
||||
|
||||
struct DetectorSettings {
|
||||
@@ -87,7 +97,8 @@ struct DetectorSettings {
|
||||
int64_t storage_cell_count;
|
||||
bool use_internal_packet_generator;
|
||||
bool collect_raw_data;
|
||||
|
||||
bool use_gain_hg0;
|
||||
bool fixed_gain_g1;
|
||||
std::optional<int64_t> pedestal_g0_frames;
|
||||
std::optional<int64_t> pedestal_g1_frames;
|
||||
std::optional<int64_t> pedestal_g2_frames;
|
||||
@@ -141,8 +152,8 @@ class JFJochStateMachine {
|
||||
void MeasurementThread();
|
||||
void PedestalThread(std::unique_lock<std::mutex> ul);
|
||||
void InitializeThread(std::unique_lock<std::mutex> ul);
|
||||
void ImportPedestal(const JFJochReceiverOutput &receiver_output, size_t gain_level, size_t storage_cell = 0);
|
||||
void ImportPedestalG0(const JFJochReceiverOutput &receiver_output);
|
||||
bool ImportPedestalG1G2(const JFJochReceiverOutput &receiver_output, size_t gain_level, size_t storage_cell = 0);
|
||||
bool ImportPedestalG0(const JFJochReceiverOutput &receiver_output);
|
||||
bool IsRunning() const; // Is state Busy/Pedestal/Measure
|
||||
std::optional<std::string> CheckError();
|
||||
|
||||
|
||||
+204
-21
@@ -45,13 +45,18 @@ void DefaultApi::setupRoutes() {
|
||||
Routes::Post(*router, base + "/deactivate", Routes::bind(&DefaultApi::deactivate_post_handler, this));
|
||||
Routes::Post(*router, base + "/initialize", Routes::bind(&DefaultApi::initialize_post_handler, this));
|
||||
Routes::Post(*router, base + "/pedestal", Routes::bind(&DefaultApi::pedestal_post_handler, this));
|
||||
Routes::Get(*router, base + "/plot/adu_histogram", Routes::bind(&DefaultApi::plot_adu_histogram_get_handler, this));
|
||||
Routes::Post(*router, base + "/plot/bkg_estimate", Routes::bind(&DefaultApi::plot_bkg_estimate_post_handler, this));
|
||||
Routes::Post(*router, base + "/plot/error_pixel", Routes::bind(&DefaultApi::plot_error_pixel_post_handler, this));
|
||||
Routes::Post(*router, base + "/plot/image_collection_efficiency", Routes::bind(&DefaultApi::plot_image_collection_efficiency_post_handler, this));
|
||||
Routes::Get(*router, base + "/plot/indexing_rate_per_file", Routes::bind(&DefaultApi::plot_indexing_rate_per_file_get_handler, this));
|
||||
Routes::Post(*router, base + "/plot/indexing_rate", Routes::bind(&DefaultApi::plot_indexing_rate_post_handler, this));
|
||||
Routes::Get(*router, base + "/plot/rad_int", Routes::bind(&DefaultApi::plot_rad_int_get_handler, this));
|
||||
Routes::Get(*router, base + "/plot/rad_int_per_file", Routes::bind(&DefaultApi::plot_rad_int_per_file_get_handler, this));
|
||||
Routes::Post(*router, base + "/plot/receiver_delay", Routes::bind(&DefaultApi::plot_receiver_delay_post_handler, this));
|
||||
Routes::Post(*router, base + "/plot/roi_sum", Routes::bind(&DefaultApi::plot_roi_sum_post_handler, this));
|
||||
Routes::Post(*router, base + "/plot/saturated_pixel", Routes::bind(&DefaultApi::plot_saturated_pixel_post_handler, this));
|
||||
Routes::Post(*router, base + "/plot/spot_count", Routes::bind(&DefaultApi::plot_spot_count_post_handler, this));
|
||||
Routes::Post(*router, base + "/plot/strong_pixel", Routes::bind(&DefaultApi::plot_strong_pixel_post_handler, this));
|
||||
Routes::Post(*router, base + "/start", Routes::bind(&DefaultApi::start_post_handler, this));
|
||||
Routes::Get(*router, base + "/statistics/calibration", Routes::bind(&DefaultApi::statistics_calibration_get_handler, this));
|
||||
Routes::Get(*router, base + "/statistics/data_collection", Routes::bind(&DefaultApi::statistics_data_collection_get_handler, this));
|
||||
@@ -372,26 +377,6 @@ void DefaultApi::pedestal_post_handler(const Pistache::Rest::Request &, Pistache
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_adu_histogram_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
try {
|
||||
this->plot_adu_histogram_get(response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_bkg_estimate_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
@@ -425,6 +410,72 @@ void DefaultApi::plot_bkg_estimate_post_handler(const Pistache::Rest::Request &r
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_error_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
// Getting the body param
|
||||
|
||||
Plot_request plotRequest;
|
||||
|
||||
try {
|
||||
nlohmann::json::parse(request.body()).get_to(plotRequest);
|
||||
plotRequest.validate();
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleParsingException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this->plot_error_pixel_post(plotRequest, response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_image_collection_efficiency_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
// Getting the body param
|
||||
|
||||
Plot_request plotRequest;
|
||||
|
||||
try {
|
||||
nlohmann::json::parse(request.body()).get_to(plotRequest);
|
||||
plotRequest.validate();
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleParsingException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this->plot_image_collection_efficiency_post(plotRequest, response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_indexing_rate_per_file_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
@@ -518,6 +569,105 @@ void DefaultApi::plot_rad_int_per_file_get_handler(const Pistache::Rest::Request
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_receiver_delay_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
// Getting the body param
|
||||
|
||||
Plot_request plotRequest;
|
||||
|
||||
try {
|
||||
nlohmann::json::parse(request.body()).get_to(plotRequest);
|
||||
plotRequest.validate();
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleParsingException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this->plot_receiver_delay_post(plotRequest, response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_roi_sum_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
// Getting the body param
|
||||
|
||||
Plot_request plotRequest;
|
||||
|
||||
try {
|
||||
nlohmann::json::parse(request.body()).get_to(plotRequest);
|
||||
plotRequest.validate();
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleParsingException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this->plot_roi_sum_post(plotRequest, response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_saturated_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
// Getting the body param
|
||||
|
||||
Plot_request plotRequest;
|
||||
|
||||
try {
|
||||
nlohmann::json::parse(request.body()).get_to(plotRequest);
|
||||
plotRequest.validate();
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleParsingException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this->plot_saturated_pixel_post(plotRequest, response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_spot_count_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
@@ -551,6 +701,39 @@ void DefaultApi::plot_spot_count_post_handler(const Pistache::Rest::Request &req
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::plot_strong_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
// Getting the body param
|
||||
|
||||
Plot_request plotRequest;
|
||||
|
||||
try {
|
||||
nlohmann::json::parse(request.body()).get_to(plotRequest);
|
||||
plotRequest.validate();
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleParsingException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this->plot_strong_pixel_post(plotRequest, response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
} catch (std::exception &e) {
|
||||
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
|
||||
response.send(errorInfo.first, errorInfo.second);
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::start_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
@@ -67,13 +67,18 @@ private:
|
||||
void deactivate_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void initialize_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void pedestal_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_adu_histogram_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_bkg_estimate_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_error_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_image_collection_efficiency_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_indexing_rate_per_file_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_indexing_rate_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_rad_int_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_rad_int_per_file_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_receiver_delay_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_roi_sum_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_saturated_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_spot_count_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void plot_strong_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void start_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void statistics_calibration_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void statistics_data_collection_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
@@ -187,13 +192,6 @@ private:
|
||||
/// </remarks>
|
||||
virtual void pedestal_post(Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate ADU histogram
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ADU histogram for all images within current data collection
|
||||
/// </remarks>
|
||||
virtual void plot_adu_histogram_get(Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate background estimate plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
@@ -202,6 +200,22 @@ private:
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_bkg_estimate_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate error pixels plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Count of error pixels per image; binning is configurable
|
||||
/// </remarks>
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_error_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate image collection efficiency plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ratio of collected and expected packets per image; binning is configurable
|
||||
/// </remarks>
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_image_collection_efficiency_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate indexing rate per file
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
@@ -231,6 +245,30 @@ private:
|
||||
/// </remarks>
|
||||
virtual void plot_rad_int_per_file_get(Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate receiver delay plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Amount of frames the receiver is behind the FPGA for each image - used for internal debugging; binning is configurable
|
||||
/// </remarks>
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_receiver_delay_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate ROI sum plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sum of ROI rectangle per image; binning is configurable
|
||||
/// </remarks>
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_roi_sum_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate saturated pixels plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Count of saturated pixels per image; binning is configurable
|
||||
/// </remarks>
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_saturated_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate spot count plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
@@ -239,6 +277,14 @@ private:
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_spot_count_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Generate strong pixels plot
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Count of strong pixels per image (from spot finding); binning is configurable
|
||||
/// </remarks>
|
||||
/// <param name="plotRequest"> (optional)</param>
|
||||
virtual void plot_strong_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Start detector
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
|
||||
@@ -26,8 +26,6 @@ Broker_status::Broker_status()
|
||||
m_ProgressIsSet = false;
|
||||
m_Indexing_rate = 0.0f;
|
||||
m_Indexing_rateIsSet = false;
|
||||
m_Receiver_send_buffers_avail = 0.0f;
|
||||
m_Receiver_send_buffers_availIsSet = false;
|
||||
|
||||
}
|
||||
|
||||
@@ -76,25 +74,6 @@ bool Broker_status::validate(std::stringstream& msg, const std::string& pathPref
|
||||
const std::string currentValuePath = _pathPrefix + ".indexingRate";
|
||||
|
||||
|
||||
if (value < static_cast<float>(0.0))
|
||||
{
|
||||
success = false;
|
||||
msg << currentValuePath << ": must be greater than or equal to 0.0;";
|
||||
}
|
||||
if (value > static_cast<float>(1.0))
|
||||
{
|
||||
success = false;
|
||||
msg << currentValuePath << ": must be less than or equal to 1.0;";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (receiverSendBuffersAvailIsSet())
|
||||
{
|
||||
const float& value = m_Receiver_send_buffers_avail;
|
||||
const std::string currentValuePath = _pathPrefix + ".receiverSendBuffersAvail";
|
||||
|
||||
|
||||
if (value < static_cast<float>(0.0))
|
||||
{
|
||||
success = false;
|
||||
@@ -123,10 +102,7 @@ bool Broker_status::operator==(const Broker_status& rhs) const
|
||||
((!progressIsSet() && !rhs.progressIsSet()) || (progressIsSet() && rhs.progressIsSet() && getProgress() == rhs.getProgress())) &&
|
||||
|
||||
|
||||
((!indexingRateIsSet() && !rhs.indexingRateIsSet()) || (indexingRateIsSet() && rhs.indexingRateIsSet() && getIndexingRate() == rhs.getIndexingRate())) &&
|
||||
|
||||
|
||||
((!receiverSendBuffersAvailIsSet() && !rhs.receiverSendBuffersAvailIsSet()) || (receiverSendBuffersAvailIsSet() && rhs.receiverSendBuffersAvailIsSet() && getReceiverSendBuffersAvail() == rhs.getReceiverSendBuffersAvail()))
|
||||
((!indexingRateIsSet() && !rhs.indexingRateIsSet()) || (indexingRateIsSet() && rhs.indexingRateIsSet() && getIndexingRate() == rhs.getIndexingRate()))
|
||||
|
||||
;
|
||||
}
|
||||
@@ -144,8 +120,6 @@ void to_json(nlohmann::json& j, const Broker_status& o)
|
||||
j["progress"] = o.m_Progress;
|
||||
if(o.indexingRateIsSet())
|
||||
j["indexing_rate"] = o.m_Indexing_rate;
|
||||
if(o.receiverSendBuffersAvailIsSet())
|
||||
j["receiver_send_buffers_avail"] = o.m_Receiver_send_buffers_avail;
|
||||
|
||||
}
|
||||
|
||||
@@ -162,11 +136,6 @@ void from_json(const nlohmann::json& j, Broker_status& o)
|
||||
j.at("indexing_rate").get_to(o.m_Indexing_rate);
|
||||
o.m_Indexing_rateIsSet = true;
|
||||
}
|
||||
if(j.find("receiver_send_buffers_avail") != j.end())
|
||||
{
|
||||
j.at("receiver_send_buffers_avail").get_to(o.m_Receiver_send_buffers_avail);
|
||||
o.m_Receiver_send_buffers_availIsSet = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -212,23 +181,6 @@ void Broker_status::unsetIndexing_rate()
|
||||
{
|
||||
m_Indexing_rateIsSet = false;
|
||||
}
|
||||
float Broker_status::getReceiverSendBuffersAvail() const
|
||||
{
|
||||
return m_Receiver_send_buffers_avail;
|
||||
}
|
||||
void Broker_status::setReceiverSendBuffersAvail(float const value)
|
||||
{
|
||||
m_Receiver_send_buffers_avail = value;
|
||||
m_Receiver_send_buffers_availIsSet = true;
|
||||
}
|
||||
bool Broker_status::receiverSendBuffersAvailIsSet() const
|
||||
{
|
||||
return m_Receiver_send_buffers_availIsSet;
|
||||
}
|
||||
void Broker_status::unsetReceiver_send_buffers_avail()
|
||||
{
|
||||
m_Receiver_send_buffers_availIsSet = false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace org::openapitools::server::model
|
||||
|
||||
@@ -77,13 +77,6 @@ public:
|
||||
void setIndexingRate(float const value);
|
||||
bool indexingRateIsSet() const;
|
||||
void unsetIndexing_rate();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
float getReceiverSendBuffersAvail() const;
|
||||
void setReceiverSendBuffersAvail(float const value);
|
||||
bool receiverSendBuffersAvailIsSet() const;
|
||||
void unsetReceiver_send_buffers_avail();
|
||||
|
||||
friend void to_json(nlohmann::json& j, const Broker_status& o);
|
||||
friend void from_json(const nlohmann::json& j, Broker_status& o);
|
||||
@@ -94,8 +87,6 @@ protected:
|
||||
bool m_ProgressIsSet;
|
||||
float m_Indexing_rate;
|
||||
bool m_Indexing_rateIsSet;
|
||||
float m_Receiver_send_buffers_avail;
|
||||
bool m_Receiver_send_buffers_availIsSet;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -47,6 +47,12 @@ Dataset_settings::Dataset_settings()
|
||||
m_Total_fluxIsSet = false;
|
||||
m_Transmission = 0.0f;
|
||||
m_TransmissionIsSet = false;
|
||||
m_OmegaIsSet = false;
|
||||
m_Header_appendix = "";
|
||||
m_Header_appendixIsSet = false;
|
||||
m_Image_appendix = "";
|
||||
m_Image_appendixIsSet = false;
|
||||
m_Roi_sum_areaIsSet = false;
|
||||
m_Unit_cellIsSet = false;
|
||||
|
||||
}
|
||||
@@ -197,7 +203,7 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -255,6 +261,18 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
|
||||
((!transmissionIsSet() && !rhs.transmissionIsSet()) || (transmissionIsSet() && rhs.transmissionIsSet() && getTransmission() == rhs.getTransmission())) &&
|
||||
|
||||
|
||||
((!omegaIsSet() && !rhs.omegaIsSet()) || (omegaIsSet() && rhs.omegaIsSet() && getOmega() == rhs.getOmega())) &&
|
||||
|
||||
|
||||
((!headerAppendixIsSet() && !rhs.headerAppendixIsSet()) || (headerAppendixIsSet() && rhs.headerAppendixIsSet() && getHeaderAppendix() == rhs.getHeaderAppendix())) &&
|
||||
|
||||
|
||||
((!imageAppendixIsSet() && !rhs.imageAppendixIsSet()) || (imageAppendixIsSet() && rhs.imageAppendixIsSet() && getImageAppendix() == rhs.getImageAppendix())) &&
|
||||
|
||||
|
||||
((!roiSumAreaIsSet() && !rhs.roiSumAreaIsSet()) || (roiSumAreaIsSet() && rhs.roiSumAreaIsSet() && getRoiSumArea() == rhs.getRoiSumArea())) &&
|
||||
|
||||
|
||||
((!unitCellIsSet() && !rhs.unitCellIsSet()) || (unitCellIsSet() && rhs.unitCellIsSet() && getUnitCell() == rhs.getUnitCell()))
|
||||
|
||||
;
|
||||
@@ -294,6 +312,14 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
|
||||
j["total_flux"] = o.m_Total_flux;
|
||||
if(o.transmissionIsSet())
|
||||
j["transmission"] = o.m_Transmission;
|
||||
if(o.omegaIsSet())
|
||||
j["omega"] = o.m_Omega;
|
||||
if(o.headerAppendixIsSet())
|
||||
j["header_appendix"] = o.m_Header_appendix;
|
||||
if(o.imageAppendixIsSet())
|
||||
j["image_appendix"] = o.m_Image_appendix;
|
||||
if(o.roiSumAreaIsSet())
|
||||
j["roi_sum_area"] = o.m_Roi_sum_area;
|
||||
if(o.unitCellIsSet())
|
||||
j["unit_cell"] = o.m_Unit_cell;
|
||||
|
||||
@@ -357,6 +383,26 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
|
||||
j.at("transmission").get_to(o.m_Transmission);
|
||||
o.m_TransmissionIsSet = true;
|
||||
}
|
||||
if(j.find("omega") != j.end())
|
||||
{
|
||||
j.at("omega").get_to(o.m_Omega);
|
||||
o.m_OmegaIsSet = true;
|
||||
}
|
||||
if(j.find("header_appendix") != j.end())
|
||||
{
|
||||
j.at("header_appendix").get_to(o.m_Header_appendix);
|
||||
o.m_Header_appendixIsSet = true;
|
||||
}
|
||||
if(j.find("image_appendix") != j.end())
|
||||
{
|
||||
j.at("image_appendix").get_to(o.m_Image_appendix);
|
||||
o.m_Image_appendixIsSet = true;
|
||||
}
|
||||
if(j.find("roi_sum_area") != j.end())
|
||||
{
|
||||
j.at("roi_sum_area").get_to(o.m_Roi_sum_area);
|
||||
o.m_Roi_sum_areaIsSet = true;
|
||||
}
|
||||
if(j.find("unit_cell") != j.end())
|
||||
{
|
||||
j.at("unit_cell").get_to(o.m_Unit_cell);
|
||||
@@ -583,6 +629,74 @@ void Dataset_settings::unsetTransmission()
|
||||
{
|
||||
m_TransmissionIsSet = false;
|
||||
}
|
||||
org::openapitools::server::model::Rotation_axis Dataset_settings::getOmega() const
|
||||
{
|
||||
return m_Omega;
|
||||
}
|
||||
void Dataset_settings::setOmega(org::openapitools::server::model::Rotation_axis const& value)
|
||||
{
|
||||
m_Omega = value;
|
||||
m_OmegaIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::omegaIsSet() const
|
||||
{
|
||||
return m_OmegaIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetOmega()
|
||||
{
|
||||
m_OmegaIsSet = false;
|
||||
}
|
||||
std::string Dataset_settings::getHeaderAppendix() const
|
||||
{
|
||||
return m_Header_appendix;
|
||||
}
|
||||
void Dataset_settings::setHeaderAppendix(std::string const& value)
|
||||
{
|
||||
m_Header_appendix = value;
|
||||
m_Header_appendixIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::headerAppendixIsSet() const
|
||||
{
|
||||
return m_Header_appendixIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetHeader_appendix()
|
||||
{
|
||||
m_Header_appendixIsSet = false;
|
||||
}
|
||||
std::string Dataset_settings::getImageAppendix() const
|
||||
{
|
||||
return m_Image_appendix;
|
||||
}
|
||||
void Dataset_settings::setImageAppendix(std::string const& value)
|
||||
{
|
||||
m_Image_appendix = value;
|
||||
m_Image_appendixIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::imageAppendixIsSet() const
|
||||
{
|
||||
return m_Image_appendixIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetImage_appendix()
|
||||
{
|
||||
m_Image_appendixIsSet = false;
|
||||
}
|
||||
org::openapitools::server::model::Dataset_settings_roi_sum_area Dataset_settings::getRoiSumArea() const
|
||||
{
|
||||
return m_Roi_sum_area;
|
||||
}
|
||||
void Dataset_settings::setRoiSumArea(org::openapitools::server::model::Dataset_settings_roi_sum_area const& value)
|
||||
{
|
||||
m_Roi_sum_area = value;
|
||||
m_Roi_sum_areaIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::roiSumAreaIsSet() const
|
||||
{
|
||||
return m_Roi_sum_areaIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetRoi_sum_area()
|
||||
{
|
||||
m_Roi_sum_areaIsSet = false;
|
||||
}
|
||||
org::openapitools::server::model::Dataset_settings_unit_cell Dataset_settings::getUnitCell() const
|
||||
{
|
||||
return m_Unit_cell;
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
#define Dataset_settings_H_
|
||||
|
||||
|
||||
#include "Rotation_axis.h"
|
||||
#include <string>
|
||||
#include "Dataset_settings_roi_sum_area.h"
|
||||
#include "Dataset_settings_unit_cell.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -162,6 +164,34 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
org::openapitools::server::model::Rotation_axis getOmega() const;
|
||||
void setOmega(org::openapitools::server::model::Rotation_axis const& value);
|
||||
bool omegaIsSet() const;
|
||||
void unsetOmega();
|
||||
/// <summary>
|
||||
/// Header appendix, added as user_data to start message
|
||||
/// </summary>
|
||||
std::string getHeaderAppendix() const;
|
||||
void setHeaderAppendix(std::string const& value);
|
||||
bool headerAppendixIsSet() const;
|
||||
void unsetHeader_appendix();
|
||||
/// <summary>
|
||||
/// Image appendix, added as user_data to image message
|
||||
/// </summary>
|
||||
std::string getImageAppendix() const;
|
||||
void setImageAppendix(std::string const& value);
|
||||
bool imageAppendixIsSet() const;
|
||||
void unsetImage_appendix();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
org::openapitools::server::model::Dataset_settings_roi_sum_area getRoiSumArea() const;
|
||||
void setRoiSumArea(org::openapitools::server::model::Dataset_settings_roi_sum_area const& value);
|
||||
bool roiSumAreaIsSet() const;
|
||||
void unsetRoi_sum_area();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
org::openapitools::server::model::Dataset_settings_unit_cell getUnitCell() const;
|
||||
void setUnitCell(org::openapitools::server::model::Dataset_settings_unit_cell const& value);
|
||||
bool unitCellIsSet() const;
|
||||
@@ -202,6 +232,14 @@ protected:
|
||||
bool m_Total_fluxIsSet;
|
||||
float m_Transmission;
|
||||
bool m_TransmissionIsSet;
|
||||
org::openapitools::server::model::Rotation_axis m_Omega;
|
||||
bool m_OmegaIsSet;
|
||||
std::string m_Header_appendix;
|
||||
bool m_Header_appendixIsSet;
|
||||
std::string m_Image_appendix;
|
||||
bool m_Image_appendixIsSet;
|
||||
org::openapitools::server::model::Dataset_settings_roi_sum_area m_Roi_sum_area;
|
||||
bool m_Roi_sum_areaIsSet;
|
||||
org::openapitools::server::model::Dataset_settings_unit_cell m_Unit_cell;
|
||||
bool m_Unit_cellIsSet;
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "Dataset_settings_roi_sum_area.h"
|
||||
#include "Helpers.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace org::openapitools::server::model
|
||||
{
|
||||
|
||||
Dataset_settings_roi_sum_area::Dataset_settings_roi_sum_area()
|
||||
{
|
||||
m_X_min = 0L;
|
||||
m_X_max = 0L;
|
||||
m_Y_min = 0L;
|
||||
m_Y_max = 0L;
|
||||
|
||||
}
|
||||
|
||||
void Dataset_settings_roi_sum_area::validate() const
|
||||
{
|
||||
std::stringstream msg;
|
||||
if (!validate(msg))
|
||||
{
|
||||
throw org::openapitools::server::helpers::ValidationException(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
bool Dataset_settings_roi_sum_area::validate(std::stringstream& msg) const
|
||||
{
|
||||
return validate(msg, "");
|
||||
}
|
||||
|
||||
bool Dataset_settings_roi_sum_area::validate(std::stringstream& msg, const std::string& pathPrefix) const
|
||||
{
|
||||
bool success = true;
|
||||
const std::string _pathPrefix = pathPrefix.empty() ? "Dataset_settings_roi_sum_area" : pathPrefix;
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Dataset_settings_roi_sum_area::operator==(const Dataset_settings_roi_sum_area& rhs) const
|
||||
{
|
||||
return
|
||||
|
||||
|
||||
(getXMin() == rhs.getXMin())
|
||||
&&
|
||||
|
||||
(getXMax() == rhs.getXMax())
|
||||
&&
|
||||
|
||||
(getYMin() == rhs.getYMin())
|
||||
&&
|
||||
|
||||
(getYMax() == rhs.getYMax())
|
||||
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
bool Dataset_settings_roi_sum_area::operator!=(const Dataset_settings_roi_sum_area& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json& j, const Dataset_settings_roi_sum_area& o)
|
||||
{
|
||||
j = nlohmann::json();
|
||||
j["x_min"] = o.m_X_min;
|
||||
j["x_max"] = o.m_X_max;
|
||||
j["y_min"] = o.m_Y_min;
|
||||
j["y_max"] = o.m_Y_max;
|
||||
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& j, Dataset_settings_roi_sum_area& o)
|
||||
{
|
||||
j.at("x_min").get_to(o.m_X_min);
|
||||
j.at("x_max").get_to(o.m_X_max);
|
||||
j.at("y_min").get_to(o.m_Y_min);
|
||||
j.at("y_max").get_to(o.m_Y_max);
|
||||
|
||||
}
|
||||
|
||||
int64_t Dataset_settings_roi_sum_area::getXMin() const
|
||||
{
|
||||
return m_X_min;
|
||||
}
|
||||
void Dataset_settings_roi_sum_area::setXMin(int64_t const value)
|
||||
{
|
||||
m_X_min = value;
|
||||
}
|
||||
int64_t Dataset_settings_roi_sum_area::getXMax() const
|
||||
{
|
||||
return m_X_max;
|
||||
}
|
||||
void Dataset_settings_roi_sum_area::setXMax(int64_t const value)
|
||||
{
|
||||
m_X_max = value;
|
||||
}
|
||||
int64_t Dataset_settings_roi_sum_area::getYMin() const
|
||||
{
|
||||
return m_Y_min;
|
||||
}
|
||||
void Dataset_settings_roi_sum_area::setYMin(int64_t const value)
|
||||
{
|
||||
m_Y_min = value;
|
||||
}
|
||||
int64_t Dataset_settings_roi_sum_area::getYMax() const
|
||||
{
|
||||
return m_Y_max;
|
||||
}
|
||||
void Dataset_settings_roi_sum_area::setYMax(int64_t const value)
|
||||
{
|
||||
m_Y_max = value;
|
||||
}
|
||||
|
||||
|
||||
} // namespace org::openapitools::server::model
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
/*
|
||||
* Dataset_settings_roi_sum_area.h
|
||||
*
|
||||
* Rectangle for ROI summation
|
||||
*/
|
||||
|
||||
#ifndef Dataset_settings_roi_sum_area_H_
|
||||
#define Dataset_settings_roi_sum_area_H_
|
||||
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace org::openapitools::server::model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Rectangle for ROI summation
|
||||
/// </summary>
|
||||
class Dataset_settings_roi_sum_area
|
||||
{
|
||||
public:
|
||||
Dataset_settings_roi_sum_area();
|
||||
virtual ~Dataset_settings_roi_sum_area() = default;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validate the current data in the model. Throws a ValidationException on failure.
|
||||
/// </summary>
|
||||
void validate() const;
|
||||
|
||||
/// <summary>
|
||||
/// Validate the current data in the model. Returns false on error and writes an error
|
||||
/// message into the given stringstream.
|
||||
/// </summary>
|
||||
bool validate(std::stringstream& msg) const;
|
||||
|
||||
/// <summary>
|
||||
/// Helper overload for validate. Used when one model stores another model and calls it's validate.
|
||||
/// Not meant to be called outside that case.
|
||||
/// </summary>
|
||||
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
|
||||
|
||||
bool operator==(const Dataset_settings_roi_sum_area& rhs) const;
|
||||
bool operator!=(const Dataset_settings_roi_sum_area& rhs) const;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/// Dataset_settings_roi_sum_area members
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getXMin() const;
|
||||
void setXMin(int64_t const value);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getXMax() const;
|
||||
void setXMax(int64_t const value);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getYMin() const;
|
||||
void setYMin(int64_t const value);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getYMax() const;
|
||||
void setYMax(int64_t const value);
|
||||
|
||||
friend void to_json(nlohmann::json& j, const Dataset_settings_roi_sum_area& o);
|
||||
friend void from_json(const nlohmann::json& j, Dataset_settings_roi_sum_area& o);
|
||||
protected:
|
||||
int64_t m_X_min;
|
||||
|
||||
int64_t m_X_max;
|
||||
|
||||
int64_t m_Y_min;
|
||||
|
||||
int64_t m_Y_max;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace org::openapitools::server::model
|
||||
|
||||
#endif /* Dataset_settings_roi_sum_area_H_ */
|
||||
@@ -38,6 +38,10 @@ Detector_settings::Detector_settings()
|
||||
m_Pedestal_g2_framesIsSet = false;
|
||||
m_Storage_cell_delay_ns = 0L;
|
||||
m_Storage_cell_delay_nsIsSet = false;
|
||||
m_Fixed_gain_g1 = false;
|
||||
m_Fixed_gain_g1IsSet = false;
|
||||
m_Use_gain_hg0 = false;
|
||||
m_Use_gain_hg0IsSet = false;
|
||||
|
||||
}
|
||||
|
||||
@@ -135,7 +139,7 @@ bool Detector_settings::validate(std::stringstream& msg, const std::string& path
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -169,7 +173,13 @@ bool Detector_settings::operator==(const Detector_settings& rhs) const
|
||||
((!pedestalG2FramesIsSet() && !rhs.pedestalG2FramesIsSet()) || (pedestalG2FramesIsSet() && rhs.pedestalG2FramesIsSet() && getPedestalG2Frames() == rhs.getPedestalG2Frames())) &&
|
||||
|
||||
|
||||
((!storageCellDelayNsIsSet() && !rhs.storageCellDelayNsIsSet()) || (storageCellDelayNsIsSet() && rhs.storageCellDelayNsIsSet() && getStorageCellDelayNs() == rhs.getStorageCellDelayNs()))
|
||||
((!storageCellDelayNsIsSet() && !rhs.storageCellDelayNsIsSet()) || (storageCellDelayNsIsSet() && rhs.storageCellDelayNsIsSet() && getStorageCellDelayNs() == rhs.getStorageCellDelayNs())) &&
|
||||
|
||||
|
||||
((!fixedGainG1IsSet() && !rhs.fixedGainG1IsSet()) || (fixedGainG1IsSet() && rhs.fixedGainG1IsSet() && isFixedGainG1() == rhs.isFixedGainG1())) &&
|
||||
|
||||
|
||||
((!useGainHg0IsSet() && !rhs.useGainHg0IsSet()) || (useGainHg0IsSet() && rhs.useGainHg0IsSet() && isUseGainHg0() == rhs.isUseGainHg0()))
|
||||
|
||||
;
|
||||
}
|
||||
@@ -199,6 +209,10 @@ void to_json(nlohmann::json& j, const Detector_settings& o)
|
||||
j["pedestal_g2_frames"] = o.m_Pedestal_g2_frames;
|
||||
if(o.storageCellDelayNsIsSet())
|
||||
j["storage_cell_delay_ns"] = o.m_Storage_cell_delay_ns;
|
||||
if(o.fixedGainG1IsSet())
|
||||
j["fixed_gain_g1"] = o.m_Fixed_gain_g1;
|
||||
if(o.useGainHg0IsSet())
|
||||
j["use_gain_hg0"] = o.m_Use_gain_hg0;
|
||||
|
||||
}
|
||||
|
||||
@@ -245,6 +259,16 @@ void from_json(const nlohmann::json& j, Detector_settings& o)
|
||||
j.at("storage_cell_delay_ns").get_to(o.m_Storage_cell_delay_ns);
|
||||
o.m_Storage_cell_delay_nsIsSet = true;
|
||||
}
|
||||
if(j.find("fixed_gain_g1") != j.end())
|
||||
{
|
||||
j.at("fixed_gain_g1").get_to(o.m_Fixed_gain_g1);
|
||||
o.m_Fixed_gain_g1IsSet = true;
|
||||
}
|
||||
if(j.find("use_gain_hg0") != j.end())
|
||||
{
|
||||
j.at("use_gain_hg0").get_to(o.m_Use_gain_hg0);
|
||||
o.m_Use_gain_hg0IsSet = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -392,6 +416,40 @@ void Detector_settings::unsetStorage_cell_delay_ns()
|
||||
{
|
||||
m_Storage_cell_delay_nsIsSet = false;
|
||||
}
|
||||
bool Detector_settings::isFixedGainG1() const
|
||||
{
|
||||
return m_Fixed_gain_g1;
|
||||
}
|
||||
void Detector_settings::setFixedGainG1(bool const value)
|
||||
{
|
||||
m_Fixed_gain_g1 = value;
|
||||
m_Fixed_gain_g1IsSet = true;
|
||||
}
|
||||
bool Detector_settings::fixedGainG1IsSet() const
|
||||
{
|
||||
return m_Fixed_gain_g1IsSet;
|
||||
}
|
||||
void Detector_settings::unsetFixed_gain_g1()
|
||||
{
|
||||
m_Fixed_gain_g1IsSet = false;
|
||||
}
|
||||
bool Detector_settings::isUseGainHg0() const
|
||||
{
|
||||
return m_Use_gain_hg0;
|
||||
}
|
||||
void Detector_settings::setUseGainHg0(bool const value)
|
||||
{
|
||||
m_Use_gain_hg0 = value;
|
||||
m_Use_gain_hg0IsSet = true;
|
||||
}
|
||||
bool Detector_settings::useGainHg0IsSet() const
|
||||
{
|
||||
return m_Use_gain_hg0IsSet;
|
||||
}
|
||||
void Detector_settings::unsetUse_gain_hg0()
|
||||
{
|
||||
m_Use_gain_hg0IsSet = false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace org::openapitools::server::model
|
||||
|
||||
@@ -77,14 +77,14 @@ public:
|
||||
bool storageCellCountIsSet() const;
|
||||
void unsetStorage_cell_count();
|
||||
/// <summary>
|
||||
///
|
||||
/// Use internal frame generator in FPGA instead of getting data from a real detector
|
||||
/// </summary>
|
||||
bool isInternalFrameGenerator() const;
|
||||
void setInternalFrameGenerator(bool const value);
|
||||
bool internalFrameGeneratorIsSet() const;
|
||||
void unsetInternal_frame_generator();
|
||||
/// <summary>
|
||||
///
|
||||
/// Turn off conversion of pixel read-out to photon count
|
||||
/// </summary>
|
||||
bool isCollectRawData() const;
|
||||
void setCollectRawData(bool const value);
|
||||
@@ -112,12 +112,26 @@ public:
|
||||
bool pedestalG2FramesIsSet() const;
|
||||
void unsetPedestal_g2_frames();
|
||||
/// <summary>
|
||||
///
|
||||
/// Delay between two storage cells
|
||||
/// </summary>
|
||||
int64_t getStorageCellDelayNs() const;
|
||||
void setStorageCellDelayNs(int64_t const value);
|
||||
bool storageCellDelayNsIsSet() const;
|
||||
void unsetStorage_cell_delay_ns();
|
||||
/// <summary>
|
||||
/// Fix gain to G1 (can be useful for storage cells)
|
||||
/// </summary>
|
||||
bool isFixedGainG1() const;
|
||||
void setFixedGainG1(bool const value);
|
||||
bool fixedGainG1IsSet() const;
|
||||
void unsetFixed_gain_g1();
|
||||
/// <summary>
|
||||
/// Use high G0 (for low energy applications)
|
||||
/// </summary>
|
||||
bool isUseGainHg0() const;
|
||||
void setUseGainHg0(bool const value);
|
||||
bool useGainHg0IsSet() const;
|
||||
void unsetUse_gain_hg0();
|
||||
|
||||
friend void to_json(nlohmann::json& j, const Detector_settings& o);
|
||||
friend void from_json(const nlohmann::json& j, Detector_settings& o);
|
||||
@@ -140,6 +154,10 @@ protected:
|
||||
bool m_Pedestal_g2_framesIsSet;
|
||||
int64_t m_Storage_cell_delay_ns;
|
||||
bool m_Storage_cell_delay_nsIsSet;
|
||||
bool m_Fixed_gain_g1;
|
||||
bool m_Fixed_gain_g1IsSet;
|
||||
bool m_Use_gain_hg0;
|
||||
bool m_Use_gain_hg0IsSet;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -23,8 +23,12 @@ Measurement_statistics::Measurement_statistics()
|
||||
{
|
||||
m_File_prefix = "";
|
||||
m_File_prefixIsSet = false;
|
||||
m_Images_expected = 0L;
|
||||
m_Images_expectedIsSet = false;
|
||||
m_Images_collected = 0L;
|
||||
m_Images_collectedIsSet = false;
|
||||
m_Images_sent = 0L;
|
||||
m_Images_sentIsSet = false;
|
||||
m_Max_image_number_sent = 0L;
|
||||
m_Max_image_number_sentIsSet = false;
|
||||
m_Collection_efficiency = 0.0f;
|
||||
@@ -67,7 +71,7 @@ bool Measurement_statistics::validate(std::stringstream& msg, const std::string&
|
||||
bool success = true;
|
||||
const std::string _pathPrefix = pathPrefix.empty() ? "Measurement_statistics" : pathPrefix;
|
||||
|
||||
|
||||
|
||||
if (collectionEfficiencyIsSet())
|
||||
{
|
||||
const float& value = m_Collection_efficiency;
|
||||
@@ -113,9 +117,15 @@ bool Measurement_statistics::operator==(const Measurement_statistics& rhs) const
|
||||
((!filePrefixIsSet() && !rhs.filePrefixIsSet()) || (filePrefixIsSet() && rhs.filePrefixIsSet() && getFilePrefix() == rhs.getFilePrefix())) &&
|
||||
|
||||
|
||||
((!imagesExpectedIsSet() && !rhs.imagesExpectedIsSet()) || (imagesExpectedIsSet() && rhs.imagesExpectedIsSet() && getImagesExpected() == rhs.getImagesExpected())) &&
|
||||
|
||||
|
||||
((!imagesCollectedIsSet() && !rhs.imagesCollectedIsSet()) || (imagesCollectedIsSet() && rhs.imagesCollectedIsSet() && getImagesCollected() == rhs.getImagesCollected())) &&
|
||||
|
||||
|
||||
((!imagesSentIsSet() && !rhs.imagesSentIsSet()) || (imagesSentIsSet() && rhs.imagesSentIsSet() && getImagesSent() == rhs.getImagesSent())) &&
|
||||
|
||||
|
||||
((!maxImageNumberSentIsSet() && !rhs.maxImageNumberSentIsSet()) || (maxImageNumberSentIsSet() && rhs.maxImageNumberSentIsSet() && getMaxImageNumberSent() == rhs.getMaxImageNumberSent())) &&
|
||||
|
||||
|
||||
@@ -158,8 +168,12 @@ void to_json(nlohmann::json& j, const Measurement_statistics& o)
|
||||
j = nlohmann::json();
|
||||
if(o.filePrefixIsSet())
|
||||
j["file_prefix"] = o.m_File_prefix;
|
||||
if(o.imagesExpectedIsSet())
|
||||
j["images_expected"] = o.m_Images_expected;
|
||||
if(o.imagesCollectedIsSet())
|
||||
j["images_collected"] = o.m_Images_collected;
|
||||
if(o.imagesSentIsSet())
|
||||
j["images_sent"] = o.m_Images_sent;
|
||||
if(o.maxImageNumberSentIsSet())
|
||||
j["max_image_number_sent"] = o.m_Max_image_number_sent;
|
||||
if(o.collectionEfficiencyIsSet())
|
||||
@@ -190,11 +204,21 @@ void from_json(const nlohmann::json& j, Measurement_statistics& o)
|
||||
j.at("file_prefix").get_to(o.m_File_prefix);
|
||||
o.m_File_prefixIsSet = true;
|
||||
}
|
||||
if(j.find("images_expected") != j.end())
|
||||
{
|
||||
j.at("images_expected").get_to(o.m_Images_expected);
|
||||
o.m_Images_expectedIsSet = true;
|
||||
}
|
||||
if(j.find("images_collected") != j.end())
|
||||
{
|
||||
j.at("images_collected").get_to(o.m_Images_collected);
|
||||
o.m_Images_collectedIsSet = true;
|
||||
}
|
||||
if(j.find("images_sent") != j.end())
|
||||
{
|
||||
j.at("images_sent").get_to(o.m_Images_sent);
|
||||
o.m_Images_sentIsSet = true;
|
||||
}
|
||||
if(j.find("max_image_number_sent") != j.end())
|
||||
{
|
||||
j.at("max_image_number_sent").get_to(o.m_Max_image_number_sent);
|
||||
@@ -265,6 +289,23 @@ void Measurement_statistics::unsetFile_prefix()
|
||||
{
|
||||
m_File_prefixIsSet = false;
|
||||
}
|
||||
int64_t Measurement_statistics::getImagesExpected() const
|
||||
{
|
||||
return m_Images_expected;
|
||||
}
|
||||
void Measurement_statistics::setImagesExpected(int64_t const value)
|
||||
{
|
||||
m_Images_expected = value;
|
||||
m_Images_expectedIsSet = true;
|
||||
}
|
||||
bool Measurement_statistics::imagesExpectedIsSet() const
|
||||
{
|
||||
return m_Images_expectedIsSet;
|
||||
}
|
||||
void Measurement_statistics::unsetImages_expected()
|
||||
{
|
||||
m_Images_expectedIsSet = false;
|
||||
}
|
||||
int64_t Measurement_statistics::getImagesCollected() const
|
||||
{
|
||||
return m_Images_collected;
|
||||
@@ -282,6 +323,23 @@ void Measurement_statistics::unsetImages_collected()
|
||||
{
|
||||
m_Images_collectedIsSet = false;
|
||||
}
|
||||
int64_t Measurement_statistics::getImagesSent() const
|
||||
{
|
||||
return m_Images_sent;
|
||||
}
|
||||
void Measurement_statistics::setImagesSent(int64_t const value)
|
||||
{
|
||||
m_Images_sent = value;
|
||||
m_Images_sentIsSet = true;
|
||||
}
|
||||
bool Measurement_statistics::imagesSentIsSet() const
|
||||
{
|
||||
return m_Images_sentIsSet;
|
||||
}
|
||||
void Measurement_statistics::unsetImages_sent()
|
||||
{
|
||||
m_Images_sentIsSet = false;
|
||||
}
|
||||
int64_t Measurement_statistics::getMaxImageNumberSent() const
|
||||
{
|
||||
return m_Max_image_number_sent;
|
||||
|
||||
@@ -68,6 +68,13 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getImagesExpected() const;
|
||||
void setImagesExpected(int64_t const value);
|
||||
bool imagesExpectedIsSet() const;
|
||||
void unsetImages_expected();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getImagesCollected() const;
|
||||
void setImagesCollected(int64_t const value);
|
||||
bool imagesCollectedIsSet() const;
|
||||
@@ -75,6 +82,13 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getImagesSent() const;
|
||||
void setImagesSent(int64_t const value);
|
||||
bool imagesSentIsSet() const;
|
||||
void unsetImages_sent();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getMaxImageNumberSent() const;
|
||||
void setMaxImageNumberSent(int64_t const value);
|
||||
bool maxImageNumberSentIsSet() const;
|
||||
@@ -148,8 +162,12 @@ public:
|
||||
protected:
|
||||
std::string m_File_prefix;
|
||||
bool m_File_prefixIsSet;
|
||||
int64_t m_Images_expected;
|
||||
bool m_Images_expectedIsSet;
|
||||
int64_t m_Images_collected;
|
||||
bool m_Images_collectedIsSet;
|
||||
int64_t m_Images_sent;
|
||||
bool m_Images_sentIsSet;
|
||||
int64_t m_Max_image_number_sent;
|
||||
bool m_Max_image_number_sentIsSet;
|
||||
float m_Collection_efficiency;
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "Rotation_axis.h"
|
||||
#include "Helpers.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace org::openapitools::server::model
|
||||
{
|
||||
|
||||
Rotation_axis::Rotation_axis()
|
||||
{
|
||||
m_Step = 0.0f;
|
||||
m_Start = 0.0f;
|
||||
m_StartIsSet = false;
|
||||
m_VectorIsSet = false;
|
||||
|
||||
}
|
||||
|
||||
void Rotation_axis::validate() const
|
||||
{
|
||||
std::stringstream msg;
|
||||
if (!validate(msg))
|
||||
{
|
||||
throw org::openapitools::server::helpers::ValidationException(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
bool Rotation_axis::validate(std::stringstream& msg) const
|
||||
{
|
||||
return validate(msg, "");
|
||||
}
|
||||
|
||||
bool Rotation_axis::validate(std::stringstream& msg, const std::string& pathPrefix) const
|
||||
{
|
||||
bool success = true;
|
||||
const std::string _pathPrefix = pathPrefix.empty() ? "Rotation_axis" : pathPrefix;
|
||||
|
||||
|
||||
if (vectorIsSet())
|
||||
{
|
||||
const std::vector<float>& value = m_Vector;
|
||||
const std::string currentValuePath = _pathPrefix + ".vector";
|
||||
|
||||
|
||||
if (value.size() < 3)
|
||||
{
|
||||
success = false;
|
||||
msg << currentValuePath << ": must have at least 3 elements;";
|
||||
}
|
||||
if (value.size() > 3)
|
||||
{
|
||||
success = false;
|
||||
msg << currentValuePath << ": must have at most 3 elements;";
|
||||
}
|
||||
{ // Recursive validation of array elements
|
||||
const std::string oldValuePath = currentValuePath;
|
||||
int i = 0;
|
||||
for (const float& value : value)
|
||||
{
|
||||
const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]";
|
||||
|
||||
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Rotation_axis::operator==(const Rotation_axis& rhs) const
|
||||
{
|
||||
return
|
||||
|
||||
|
||||
(getStep() == rhs.getStep())
|
||||
&&
|
||||
|
||||
|
||||
((!startIsSet() && !rhs.startIsSet()) || (startIsSet() && rhs.startIsSet() && getStart() == rhs.getStart())) &&
|
||||
|
||||
|
||||
((!vectorIsSet() && !rhs.vectorIsSet()) || (vectorIsSet() && rhs.vectorIsSet() && getVector() == rhs.getVector()))
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
bool Rotation_axis::operator!=(const Rotation_axis& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json& j, const Rotation_axis& o)
|
||||
{
|
||||
j = nlohmann::json();
|
||||
j["step"] = o.m_Step;
|
||||
if(o.startIsSet())
|
||||
j["start"] = o.m_Start;
|
||||
if(o.vectorIsSet() || !o.m_Vector.empty())
|
||||
j["vector"] = o.m_Vector;
|
||||
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& j, Rotation_axis& o)
|
||||
{
|
||||
j.at("step").get_to(o.m_Step);
|
||||
if(j.find("start") != j.end())
|
||||
{
|
||||
j.at("start").get_to(o.m_Start);
|
||||
o.m_StartIsSet = true;
|
||||
}
|
||||
if(j.find("vector") != j.end())
|
||||
{
|
||||
j.at("vector").get_to(o.m_Vector);
|
||||
o.m_VectorIsSet = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float Rotation_axis::getStep() const
|
||||
{
|
||||
return m_Step;
|
||||
}
|
||||
void Rotation_axis::setStep(float const value)
|
||||
{
|
||||
m_Step = value;
|
||||
}
|
||||
float Rotation_axis::getStart() const
|
||||
{
|
||||
return m_Start;
|
||||
}
|
||||
void Rotation_axis::setStart(float const value)
|
||||
{
|
||||
m_Start = value;
|
||||
m_StartIsSet = true;
|
||||
}
|
||||
bool Rotation_axis::startIsSet() const
|
||||
{
|
||||
return m_StartIsSet;
|
||||
}
|
||||
void Rotation_axis::unsetStart()
|
||||
{
|
||||
m_StartIsSet = false;
|
||||
}
|
||||
std::vector<float> Rotation_axis::getVector() const
|
||||
{
|
||||
return m_Vector;
|
||||
}
|
||||
void Rotation_axis::setVector(std::vector<float> const value)
|
||||
{
|
||||
m_Vector = value;
|
||||
m_VectorIsSet = true;
|
||||
}
|
||||
bool Rotation_axis::vectorIsSet() const
|
||||
{
|
||||
return m_VectorIsSet;
|
||||
}
|
||||
void Rotation_axis::unsetVector()
|
||||
{
|
||||
m_VectorIsSet = false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace org::openapitools::server::model
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
/*
|
||||
* Rotation_axis.h
|
||||
*
|
||||
* Definition of a crystal rotation axis
|
||||
*/
|
||||
|
||||
#ifndef Rotation_axis_H_
|
||||
#define Rotation_axis_H_
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace org::openapitools::server::model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Definition of a crystal rotation axis
|
||||
/// </summary>
|
||||
class Rotation_axis
|
||||
{
|
||||
public:
|
||||
Rotation_axis();
|
||||
virtual ~Rotation_axis() = default;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validate the current data in the model. Throws a ValidationException on failure.
|
||||
/// </summary>
|
||||
void validate() const;
|
||||
|
||||
/// <summary>
|
||||
/// Validate the current data in the model. Returns false on error and writes an error
|
||||
/// message into the given stringstream.
|
||||
/// </summary>
|
||||
bool validate(std::stringstream& msg) const;
|
||||
|
||||
/// <summary>
|
||||
/// Helper overload for validate. Used when one model stores another model and calls it's validate.
|
||||
/// Not meant to be called outside that case.
|
||||
/// </summary>
|
||||
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
|
||||
|
||||
bool operator==(const Rotation_axis& rhs) const;
|
||||
bool operator!=(const Rotation_axis& rhs) const;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/// Rotation_axis members
|
||||
|
||||
/// <summary>
|
||||
/// Angle step in degrees
|
||||
/// </summary>
|
||||
float getStep() const;
|
||||
void setStep(float const value);
|
||||
/// <summary>
|
||||
/// Start angle in degrees
|
||||
/// </summary>
|
||||
float getStart() const;
|
||||
void setStart(float const value);
|
||||
bool startIsSet() const;
|
||||
void unsetStart();
|
||||
/// <summary>
|
||||
/// Rotation axis - vector with only zeros means using default value (set in a configuration file)
|
||||
/// </summary>
|
||||
std::vector<float> getVector() const;
|
||||
void setVector(std::vector<float> const value);
|
||||
bool vectorIsSet() const;
|
||||
void unsetVector();
|
||||
|
||||
friend void to_json(nlohmann::json& j, const Rotation_axis& o);
|
||||
friend void from_json(const nlohmann::json& j, Rotation_axis& o);
|
||||
protected:
|
||||
float m_Step;
|
||||
|
||||
float m_Start;
|
||||
bool m_StartIsSet;
|
||||
std::vector<float> m_Vector;
|
||||
bool m_VectorIsSet;
|
||||
|
||||
};
|
||||
|
||||
} // namespace org::openapitools::server::model
|
||||
|
||||
#endif /* Rotation_axis_H_ */
|
||||
+207
-11
@@ -5,6 +5,32 @@ info:
|
||||
version: 1.0.0
|
||||
components:
|
||||
schemas:
|
||||
rotation_axis:
|
||||
description: Definition of a crystal rotation axis
|
||||
type: object
|
||||
required:
|
||||
- step
|
||||
properties:
|
||||
step:
|
||||
type: number
|
||||
format: float
|
||||
example: 0.1
|
||||
description: Angle step in degrees
|
||||
start:
|
||||
type: number
|
||||
format: float
|
||||
example: 50
|
||||
description: Start angle in degrees
|
||||
default: 0
|
||||
vector:
|
||||
type: array
|
||||
description: Rotation axis - vector with only zeros means using default value (set in a configuration file)
|
||||
default: [ 0, 0, 0 ]
|
||||
items:
|
||||
type: number
|
||||
format: float
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
dataset_settings:
|
||||
type: object
|
||||
required:
|
||||
@@ -115,6 +141,39 @@ components:
|
||||
description: |
|
||||
/entry/instrument/attenuator/attenuator_transmission
|
||||
Transmission of attenuator (filter) [no units]
|
||||
omega:
|
||||
$ref: "#/components/schemas/rotation_axis"
|
||||
header_appendix:
|
||||
type: string
|
||||
description: Header appendix, added as user_data to start message
|
||||
image_appendix:
|
||||
type: string
|
||||
description: Image appendix, added as user_data to image message
|
||||
roi_sum_area:
|
||||
type: object
|
||||
description: Rectangle for ROI summation
|
||||
required:
|
||||
- x_min
|
||||
- x_max
|
||||
- y_min
|
||||
- y_max
|
||||
properties:
|
||||
x_min:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 12
|
||||
x_max:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 14
|
||||
y_min:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 25
|
||||
y_max:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 32
|
||||
unit_cell:
|
||||
type: object
|
||||
description: Units of angstrom and degree
|
||||
@@ -150,7 +209,6 @@ components:
|
||||
type: number
|
||||
format: float
|
||||
example: 90
|
||||
|
||||
detector_settings:
|
||||
type: object
|
||||
required:
|
||||
@@ -174,9 +232,11 @@ components:
|
||||
internal_frame_generator:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Use internal frame generator in FPGA instead of getting data from a real detector
|
||||
collect_raw_data:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Turn off conversion of pixel read-out to photon count
|
||||
pedestal_g0_frames:
|
||||
type: integer
|
||||
format: int64
|
||||
@@ -192,6 +252,15 @@ components:
|
||||
storage_cell_delay_ns:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Delay between two storage cells
|
||||
fixed_gain_g1:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Fix gain to G1 (can be useful for storage cells)
|
||||
use_gain_hg0:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Use high G0 (for low energy applications)
|
||||
spot_finding_settings:
|
||||
type: object
|
||||
required:
|
||||
@@ -308,9 +377,15 @@ components:
|
||||
properties:
|
||||
file_prefix:
|
||||
type: string
|
||||
images_expected:
|
||||
type: integer
|
||||
format: int64
|
||||
images_collected:
|
||||
type: integer
|
||||
format: int64
|
||||
images_sent:
|
||||
type: integer
|
||||
format: int64
|
||||
max_image_number_sent:
|
||||
type: integer
|
||||
format: int64
|
||||
@@ -374,12 +449,6 @@ components:
|
||||
example: 0.10
|
||||
minimum: 0.0
|
||||
maximum: 1.0
|
||||
receiver_send_buffers_avail:
|
||||
type: number
|
||||
format: float
|
||||
example: 0.8
|
||||
minimum: 0.0
|
||||
maximum: 1.0
|
||||
plot_request:
|
||||
type: object
|
||||
properties:
|
||||
@@ -828,10 +897,15 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
description: Exception error
|
||||
/plot/adu_histogram:
|
||||
get:
|
||||
summary: Generate ADU histogram
|
||||
description: ADU histogram for all images within current data collection
|
||||
/plot/saturated_pixel:
|
||||
post:
|
||||
summary: Generate saturated pixels plot
|
||||
description: Count of saturated pixels per image; binning is configurable
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot_request'
|
||||
responses:
|
||||
"200":
|
||||
description: Everything OK
|
||||
@@ -839,6 +913,128 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot'
|
||||
"400":
|
||||
description: Input parsing or validation error
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Exception error
|
||||
/plot/error_pixel:
|
||||
post:
|
||||
summary: Generate error pixels plot
|
||||
description: Count of error pixels per image; binning is configurable
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot_request'
|
||||
responses:
|
||||
"200":
|
||||
description: Everything OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot'
|
||||
"400":
|
||||
description: Input parsing or validation error
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Exception error
|
||||
/plot/strong_pixel:
|
||||
post:
|
||||
summary: Generate strong pixels plot
|
||||
description: Count of strong pixels per image (from spot finding); binning is configurable
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot_request'
|
||||
responses:
|
||||
"200":
|
||||
description: Everything OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot'
|
||||
"400":
|
||||
description: Input parsing or validation error
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Exception error
|
||||
/plot/roi_sum:
|
||||
post:
|
||||
summary: Generate ROI sum plot
|
||||
description: Sum of ROI rectangle per image; binning is configurable
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot_request'
|
||||
responses:
|
||||
"200":
|
||||
description: Everything OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot'
|
||||
"400":
|
||||
description: Input parsing or validation error
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Exception error
|
||||
/plot/receiver_delay:
|
||||
post:
|
||||
summary: Generate receiver delay plot
|
||||
description: Amount of frames the receiver is behind the FPGA for each image - used for internal debugging; binning is configurable
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot_request'
|
||||
responses:
|
||||
"200":
|
||||
description: Everything OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot'
|
||||
"400":
|
||||
description: Input parsing or validation error
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Exception error
|
||||
/plot/image_collection_efficiency:
|
||||
post:
|
||||
summary: Generate image collection efficiency plot
|
||||
description: Ratio of collected and expected packets per image; binning is configurable
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot_request'
|
||||
responses:
|
||||
"200":
|
||||
description: Everything OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/plot'
|
||||
"400":
|
||||
description: Input parsing or validation error
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Exception error
|
||||
/plot/indexing_rate_per_file:
|
||||
get:
|
||||
summary: Generate indexing rate per file
|
||||
|
||||
+22
-11
@@ -12,7 +12,7 @@
|
||||
#include "JFJochBrokerHttp.h"
|
||||
|
||||
#include "JFJochBrokerParser.h"
|
||||
#include "../frame_serialize/ZMQStream2Pusher.h"
|
||||
#include "../frame_serialize/ZMQStream2PusherGroup.h"
|
||||
|
||||
static Pistache::Http::Endpoint *httpEndpoint;
|
||||
|
||||
@@ -70,8 +70,8 @@ int main (int argc, char **argv) {
|
||||
}
|
||||
|
||||
std::unique_ptr<JFJochReceiverService> receiver;
|
||||
std::unique_ptr<ZMQStream2Pusher> image_pusher;
|
||||
std::unique_ptr<ZMQPreviewPublisher> preview_publisher;
|
||||
std::unique_ptr<ZMQStream2PusherGroup> image_pusher;
|
||||
std::unique_ptr<ZMQStream2PreviewPublisher> preview_publisher;
|
||||
|
||||
ZMQContext context;
|
||||
|
||||
@@ -82,12 +82,12 @@ int main (int argc, char **argv) {
|
||||
ParseAcquisitionDeviceGroup(input, "devices", aq_devices);
|
||||
if (aq_devices.size() > 0) {
|
||||
experiment.DataStreams(aq_devices.size());
|
||||
image_pusher = std::make_unique<ZMQStream2Pusher>(context, ParseStringArray(input, "zmq_image_addr"));
|
||||
image_pusher = std::make_unique<ZMQStream2PusherGroup>(context, ParseStringArray(input, "zmq_image_addr"));
|
||||
receiver = std::make_unique<JFJochReceiverService>(aq_devices, logger, *image_pusher);
|
||||
|
||||
std::string zmq_preview_addr = ParseString(input, "zmq_preview_addr");
|
||||
if (!zmq_preview_addr.empty()) {
|
||||
preview_publisher = std::make_unique<ZMQPreviewPublisher>(context, zmq_preview_addr);
|
||||
preview_publisher = std::make_unique<ZMQStream2PreviewPublisher>(context, zmq_preview_addr);
|
||||
receiver->PreviewPublisher(preview_publisher.get());
|
||||
}
|
||||
|
||||
@@ -101,27 +101,38 @@ int main (int argc, char **argv) {
|
||||
|
||||
ParseFacilityConfiguration(input, "cfg", experiment);
|
||||
|
||||
logger.Info("Source {} Instrument {} Default rotation axis {:.2f},{:.2f},{:.2f}",
|
||||
experiment.GetSourceName(), experiment.GetInstrumentName(),
|
||||
experiment.GetDefaultOmegaAxis().x,
|
||||
experiment.GetDefaultOmegaAxis().y,
|
||||
experiment.GetDefaultOmegaAxis().z);
|
||||
|
||||
Pistache::Address addr(Pistache::Ipv4::any(), Pistache::Port(http_port));
|
||||
|
||||
httpEndpoint = new Pistache::Http::Endpoint((addr));
|
||||
|
||||
std::vector<int> sigs{SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
||||
setUpUnixSignals(sigs);
|
||||
|
||||
auto router = std::make_shared<Pistache::Rest::Router>();
|
||||
|
||||
auto opts = Pistache::Http::Endpoint::options().threads(8);
|
||||
opts.flags(Pistache::Tcp::Options::ReuseAddr);
|
||||
httpEndpoint->init(opts);
|
||||
|
||||
std::vector<int> sigs{SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
||||
setUpUnixSignals(sigs);
|
||||
|
||||
JFJochBrokerHttp broker(experiment, router);
|
||||
broker.FrontendDirectory(input["frontend_directory"]);
|
||||
ParseDetectorSetup(input, "detectors", broker);
|
||||
|
||||
if (receiver)
|
||||
broker.Services().Receiver(receiver.get());
|
||||
if (input["verbose"].is_boolean()) {
|
||||
logger.Verbose(input["verbose"]);
|
||||
aq_devices.EnableLogging(&logger);
|
||||
}
|
||||
|
||||
// broker.Services().Detector();
|
||||
if (receiver) {
|
||||
broker.Services().Receiver(receiver.get());
|
||||
broker.Services().Detector();
|
||||
}
|
||||
|
||||
httpEndpoint->setHandler(router->handler());
|
||||
httpEndpoint->serve();
|
||||
|
||||
+68
-16
File diff suppressed because one or more lines are too long
+15
-1
@@ -6,6 +6,14 @@ ADUHistogram::ADUHistogram() : histogram(ADU_HISTO_BIN_COUNT) {
|
||||
|
||||
}
|
||||
|
||||
void ADUHistogram::Add(const std::vector<uint64_t>& input) {
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
if (input.size() != ADU_HISTO_BIN_COUNT)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Wrong vector input to ADUHistogram::Add");
|
||||
for (int i = 0; i < ADU_HISTO_BIN_COUNT; i++)
|
||||
histogram[i] += input[i];
|
||||
}
|
||||
|
||||
void ADUHistogram::Add(const DeviceOutput &output) {
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
for (int i = 0; i < ADU_HISTO_BIN_COUNT; i++)
|
||||
@@ -26,4 +34,10 @@ Plot ADUHistogram::GetPlot() const {
|
||||
ret.y[i] = histogram[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void ADUHistogram::Restart() {
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
for (int i = 0; i < ADU_HISTO_BIN_COUNT; i++)
|
||||
histogram[i] = 0;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,11 @@ class ADUHistogram {
|
||||
std::vector<uint64_t> histogram;
|
||||
public:
|
||||
explicit ADUHistogram();
|
||||
void Add(const std::vector<uint64_t>& input);
|
||||
void Add(const DeviceOutput &output);
|
||||
const std::vector<uint64_t>& GetHistogram() const;
|
||||
Plot GetPlot() const;
|
||||
void Restart();
|
||||
};
|
||||
|
||||
#endif //JUNGFRAUJOCH_ADUHISTOGRAM_H
|
||||
|
||||
@@ -29,13 +29,11 @@ ADD_LIBRARY( CommonFunctions STATIC
|
||||
JFJochException.h
|
||||
Definitions.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/GitInfo.cpp GitInfo.h
|
||||
FrameTransformation.cpp FrameTransformation.h
|
||||
ThreadSafeFIFO.h
|
||||
DiffractionSpot.cpp DiffractionSpot.h
|
||||
StatusVector.h
|
||||
SpotToSave.h
|
||||
NetworkAddressConvert.h NetworkAddressConvert.cpp
|
||||
to_fixed.h
|
||||
DetectorGeometry.cpp DetectorGeometry.h
|
||||
DetectorModuleGeometry.cpp DetectorModuleGeometry.h
|
||||
DetectorSetup.h DetectorSetup.cpp ZeroCopyReturnValue.h Histogram.h DiffractionGeometry.h
|
||||
@@ -44,7 +42,7 @@ ADD_LIBRARY( CommonFunctions STATIC
|
||||
ADUHistogram.cpp ADUHistogram.h
|
||||
RawToConvertedGeometryCore.h
|
||||
Plot.h
|
||||
../fpga/host_library/DeviceOutput.h
|
||||
../fpga/include/jfjoch_fpga.h
|
||||
ZMQWrappers.cpp ZMQWrappers.h)
|
||||
|
||||
TARGET_LINK_LIBRARIES(CommonFunctions Compression JFCalibration libzmq -lrt)
|
||||
|
||||
+3
-55
@@ -3,20 +3,15 @@
|
||||
#ifndef DEFINITIONS_H
|
||||
#define DEFINITIONS_H
|
||||
|
||||
#define WVL_1A_IN_KEV 12.39854f
|
||||
#include "../fpga/include/jfjoch_fpga.h"
|
||||
|
||||
#define DELAY_FRAMES_STOP_AND_QUIT 5
|
||||
#define RAW_MODULE_LINES (512L)
|
||||
#define RAW_MODULE_COLS (1024L)
|
||||
#define RAW_MODULE_SIZE (RAW_MODULE_LINES * RAW_MODULE_COLS)
|
||||
#define WVL_1A_IN_KEV 12.39854f
|
||||
|
||||
#define CONVERTED_MODULE_LINES (514L)
|
||||
#define CONVERTED_MODULE_COLS (1030L)
|
||||
#define CONVERTED_MODULE_SIZE (CONVERTED_MODULE_LINES * CONVERTED_MODULE_COLS)
|
||||
#define JUNGFRAU_PACKET_SIZE_BYTES (8192)
|
||||
|
||||
#define FPGA_BUFFER_LOCATION_SIZE (RAW_MODULE_SIZE * sizeof(short) * 4) // account for space for data processing results and 32-bit frames
|
||||
|
||||
#define MIN_COUNT_TIME_IN_US 5
|
||||
#define MIN_FRAME_TIME_HALF_SPEED_IN_US 1000
|
||||
#define MIN_FRAME_TIME_FULL_SPEED_IN_US 470
|
||||
@@ -27,58 +22,11 @@
|
||||
#define MIN_ENERGY 0.1
|
||||
#define MAX_ENERGY 25.0
|
||||
|
||||
#define PEDESTAL_WINDOW_SIZE 128
|
||||
#define PEDESTAL_WRONG 16384
|
||||
|
||||
#define FRAME_TIME_PEDE_G1G2_IN_US (10*1000)
|
||||
|
||||
#define GAIN_G0_MULTIPLIER 32
|
||||
#define GAIN_G1_MULTIPLIER (-1)
|
||||
#define GAIN_G2_MULTIPLIER (-1)
|
||||
|
||||
#define DEFAULT_G0_FACTOR (41.0)
|
||||
#define DEFAULT_G1_FACTOR (-1.439)
|
||||
#define DEFAULT_G2_FACTOR (-0.1145)
|
||||
|
||||
#define TASK_NO_DATA_STREAM UINT16_MAX
|
||||
|
||||
// For FPGA
|
||||
#define ACTION_TYPE 0x52324158
|
||||
#define RELEASE_LEVEL 0x004A
|
||||
|
||||
#define MODE_CONV 0x0001L
|
||||
#define MODE_32BIT 0x0002L
|
||||
#define MODE_UNSIGNED 0x0004L
|
||||
#define MODE_PEDESTAL_G0 0x0010L
|
||||
#define MODE_PEDESTAL_G1 0x0020L
|
||||
#define MODE_PEDESTAL_G2 0x0040L
|
||||
|
||||
#define STREAM_MERGE_SRC_NONE 0
|
||||
#define STREAM_MERGE_SRC_100G 1
|
||||
#define STREAM_MERGE_SRC_4x10G 2
|
||||
#define STREAM_MERGE_SRC_FRAME_GEN 3
|
||||
|
||||
#define PIXEL_OUT_LOST (INT16_MIN)
|
||||
|
||||
#define LOAD_CALIBRATION_DEST_CALIB 0
|
||||
#define LOAD_CALIBRATION_DEST_INTEGRATION 1
|
||||
#define LOAD_CALIBRATION_DEST_FRAME_GEN 2
|
||||
|
||||
#define HANDLE_START (65534)
|
||||
#define HANDLE_END (65535)
|
||||
|
||||
#define INT_PKT_GEN_DEBUG 0x0
|
||||
#define INT_PKT_GEN_BUNCHID 0xCACACACACA
|
||||
#define INT_PKT_GEN_EXPTTIME 10000
|
||||
|
||||
#define FPGA_INTEGRATION_BIN_COUNT 1024
|
||||
|
||||
#define MAX_MODULES_FPGA 32
|
||||
#define MAX_FPGA_SUMMATION 256
|
||||
|
||||
#define ADU_HISTO_BIN_WIDTH 32
|
||||
#define ADU_HISTO_BIN_COUNT (65536/ ADU_HISTO_BIN_WIDTH)
|
||||
|
||||
#define DMA_DESCRIPTORS_PER_MODULE 5
|
||||
#define DEFAULT_HG0_FACTOR (100.0)
|
||||
|
||||
#endif //DEFINITIONS_H
|
||||
|
||||
@@ -98,3 +98,25 @@ int64_t DetectorGeometry::GetSlowDirectionStep(int64_t m) const {
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Wrong module number");
|
||||
return GetDirectionStep(modules[m].GetSlowAxis());
|
||||
}
|
||||
|
||||
Coord DetectorGeometry::GetFastDirection(int64_t module_number) const {
|
||||
return GetDirection(modules[module_number].GetFastAxis());
|
||||
}
|
||||
|
||||
Coord DetectorGeometry::GetSlowDirection(int64_t module_number) const {
|
||||
return GetDirection(modules[module_number].GetSlowAxis());
|
||||
}
|
||||
|
||||
Coord DetectorGeometry::GetDirection(DetectorModuleGeometry::Direction direction) {
|
||||
switch (direction) {
|
||||
case DetectorModuleGeometry::Direction::Xneg:
|
||||
return {-1, 0, 0};
|
||||
case DetectorModuleGeometry::Direction::Yneg:
|
||||
return { 0, -1, 0};
|
||||
case DetectorModuleGeometry::Direction::Ypos:
|
||||
return { 0, 1, 0};
|
||||
default:
|
||||
case DetectorModuleGeometry::Direction::Xpos:
|
||||
return { 1, 0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include "Coord.h"
|
||||
#include "DetectorModuleGeometry.h"
|
||||
|
||||
class DetectorGeometry {
|
||||
@@ -12,6 +13,7 @@ class DetectorGeometry {
|
||||
int64_t height;
|
||||
std::vector<DetectorModuleGeometry> modules;
|
||||
[[nodiscard]] int64_t GetDirectionStep(DetectorModuleGeometry::Direction direction) const;
|
||||
[[nodiscard]] static Coord GetDirection(DetectorModuleGeometry::Direction direction) ;
|
||||
public:
|
||||
DetectorGeometry(const std::vector<DetectorModuleGeometry> &pixel_0);
|
||||
DetectorGeometry(int32_t nmodules,
|
||||
@@ -25,6 +27,8 @@ public:
|
||||
[[nodiscard]] int64_t GetPixel0(int64_t module_number) const;
|
||||
[[nodiscard]] int64_t GetFastDirectionStep(int64_t module_number) const;
|
||||
[[nodiscard]] int64_t GetSlowDirectionStep(int64_t module_number) const;
|
||||
[[nodiscard]] Coord GetFastDirection(int64_t module_number) const;
|
||||
[[nodiscard]] Coord GetSlowDirection(int64_t module_number) const;
|
||||
};
|
||||
|
||||
#endif //JUNGFRAUJOCH_DETECTORGEOMETRY_H
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
DiffractionExperiment::DiffractionExperiment() : DiffractionExperiment(DetectorGeometry(8, 2)) {}
|
||||
|
||||
DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : detector(det_setup) {
|
||||
default_omega_axis = {1, 0, 0};
|
||||
|
||||
dataset.photon_energy_keV = WVL_1A_IN_KEV;
|
||||
dataset.detector_distance_mm = 100;
|
||||
|
||||
@@ -29,8 +31,9 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
|
||||
dataset.compression = CompressionAlgorithm::BSHUF_LZ4;
|
||||
|
||||
dataset.rad_int_polarization_corr = false;
|
||||
dataset.rad_int_solid_angle_corr = false;
|
||||
dataset.rad_int_solid_angle_corr = true;
|
||||
dataset.save_calibration = false;
|
||||
dataset.omega_rotation_axis = default_omega_axis;
|
||||
|
||||
internal_fpga_packet_generator = false;
|
||||
|
||||
@@ -63,6 +66,11 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
|
||||
pedestal_g1_frames = 0;
|
||||
pedestal_g2_frames = 0;
|
||||
|
||||
fix_gain_g1 = false;
|
||||
use_gain_hg0 = false;
|
||||
|
||||
series_id = 0;
|
||||
|
||||
Mode(DetectorMode::Conversion);
|
||||
}
|
||||
|
||||
@@ -223,36 +231,36 @@ DiffractionExperiment &DiffractionExperiment::MaskChipEdges(bool input) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment& DiffractionExperiment::LowResForRadialInt_A(float input) {
|
||||
check_min("Low Resolution for radial integration", input, 0.1);
|
||||
check_max("Low Resolution for radial integration", input, 500.0);
|
||||
DiffractionExperiment& DiffractionExperiment::LowResForAzimInt_A(float input) {
|
||||
check_min("Low Resolution for azimuthal integration", input, 0.1);
|
||||
check_max("Low Resolution for azimuthal integration", input, 500.0);
|
||||
low_q = 2 * static_cast<float>(M_PI) / input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment& DiffractionExperiment::HighResForRadialInt_A(float input) {
|
||||
check_min("High Resolution for radial integration", input, 0.1);
|
||||
check_max("High Resolution for radial integration", input, 500.0);
|
||||
DiffractionExperiment& DiffractionExperiment::HighResForAzimInt_A(float input) {
|
||||
check_min("High Resolution for azimuthal integration", input, 0.1);
|
||||
check_max("High Resolution for azimuthal integration", input, 500.0);
|
||||
high_q = 2 * static_cast<float>(M_PI) / input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment& DiffractionExperiment::LowQForRadialInt_recipA(float input) {
|
||||
check_min("Low Q for radial integration", input, 0.001);
|
||||
check_max("Low Q for radial integration", input, 10.0);
|
||||
DiffractionExperiment& DiffractionExperiment::LowQForAzimInt_recipA(float input) {
|
||||
check_min("Low Q for azimuthal integration", input, 0.001);
|
||||
check_max("Low Q for azimuthal integration", input, 10.0);
|
||||
low_q = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment& DiffractionExperiment::HighQForRadialInt_recipA(float input) {
|
||||
check_min("High Q for radial integration", input, 0.001);
|
||||
check_max("High Q for radial integration", input, 10.0);
|
||||
DiffractionExperiment& DiffractionExperiment::HighQForAzimInt_recipA(float input) {
|
||||
check_min("High Q for azimuthal integration", input, 0.001);
|
||||
check_max("High Q for azimuthal integration", input, 10.0);
|
||||
high_q = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment& DiffractionExperiment::QSpacingForRadialInt_recipA(float input) {
|
||||
check_min("Q spacing for radial integration", input, 0.01);
|
||||
DiffractionExperiment& DiffractionExperiment::QSpacingForAzimInt_recipA(float input) {
|
||||
check_min("Q spacing for azimuthal integration", input, 0.01);
|
||||
q_spacing = input;
|
||||
return *this;
|
||||
}
|
||||
@@ -460,7 +468,10 @@ std::string DiffractionExperiment::GetFilePrefix() const {
|
||||
}
|
||||
|
||||
int64_t DiffractionExperiment::GetDataFileCount() const {
|
||||
return dataset.data_file_count;
|
||||
if (GetStorageCellNumber() > 1)
|
||||
return GetStorageCellNumber();
|
||||
else
|
||||
return dataset.data_file_count;
|
||||
}
|
||||
|
||||
CompressionAlgorithm DiffractionExperiment::GetCompressionAlgorithm() const {
|
||||
@@ -510,15 +521,16 @@ int64_t DiffractionExperiment::GetDataStreamsNum() const {
|
||||
}
|
||||
|
||||
int64_t DiffractionExperiment::GetModulesNum(uint16_t data_stream) const {
|
||||
if (data_stream == TASK_NO_DATA_STREAM)
|
||||
return detector.GetModulesNum();
|
||||
|
||||
if (data_stream >= GetDataStreamsNum())
|
||||
if (data_stream >= GetDataStreamsNum())
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Non existing data stream");
|
||||
|
||||
return (detector.GetModulesNum() + (GetDataStreamsNum() - 1) - data_stream) / GetDataStreamsNum();
|
||||
}
|
||||
|
||||
int64_t DiffractionExperiment::GetModulesNum() const {
|
||||
return detector.GetModulesNum();
|
||||
}
|
||||
|
||||
int64_t DiffractionExperiment::GetFirstModuleOfDataStream(uint16_t data_stream) const {
|
||||
if (data_stream >= GetDataStreamsNum())
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Non exisiting data stream");
|
||||
@@ -666,14 +678,14 @@ int64_t DiffractionExperiment::GetStorageCellStart() const {
|
||||
return storage_cell_start;
|
||||
}
|
||||
|
||||
float DiffractionExperiment::GetLowQForRadialInt_recipA() const {
|
||||
float DiffractionExperiment::GetLowQForAzimInt_recipA() const {
|
||||
return low_q;
|
||||
}
|
||||
float DiffractionExperiment::GetHighQForRadialInt_recipA() const {
|
||||
float DiffractionExperiment::GetHighQForAzimInt_recipA() const {
|
||||
return high_q;
|
||||
}
|
||||
|
||||
float DiffractionExperiment::GetQSpacingForRadialInt_recipA() const {
|
||||
float DiffractionExperiment::GetQSpacingForAzimInt_recipA() const {
|
||||
return q_spacing;
|
||||
}
|
||||
|
||||
@@ -707,8 +719,10 @@ SpotFindingSettings DiffractionExperiment::DefaultDataProcessingSettings() {
|
||||
SpotFindingSettings ret{};
|
||||
ret.signal_to_noise_threshold = 3;
|
||||
ret.photon_count_threshold = 16;
|
||||
ret.min_pix_per_spot = 1;
|
||||
ret.min_pix_per_spot = 2;
|
||||
ret.max_pix_per_spot = 50;
|
||||
ret.low_resolution_limit = 20.0;
|
||||
ret.high_resolution_limit = 2.5;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -721,8 +735,8 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
|
||||
message.incident_energy = GetPhotonEnergy_keV() * 1e3f;
|
||||
message.image_size_x = GetXPixelsNum();
|
||||
message.image_size_y = GetYPixelsNum();
|
||||
message.min_value = GetUnderflow();
|
||||
message.saturation_value = GetOverflow();
|
||||
message.saturation_value = GetOverflow() - 1;
|
||||
message.error_value = GetUnderflow();
|
||||
message.frame_time = GetImageTime().count() * 1e-6f;
|
||||
message.count_time = GetImageCountTime().count() * 1e-6f;
|
||||
message.number_of_images = GetImageNum();
|
||||
@@ -756,6 +770,15 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
|
||||
message.instrument_name = GetInstrumentName();
|
||||
message.instrument_name_short = GetInstrumentNameShort();
|
||||
message.summation = GetSummation();
|
||||
message.user_data = GetHeaderAppendix();
|
||||
message.roi_summation_area = GetROISummation();
|
||||
|
||||
if (GetOmegaStep())
|
||||
message.goniometer["omega"] = GoniometerAxis{.increment = GetOmegaStep().value(), .start = GetOmegaStart(),
|
||||
.axis = {GetOmegaAxis().x, GetOmegaAxis().y, GetOmegaAxis().z}};
|
||||
|
||||
message.series_id = GetSeriesID();
|
||||
message.series_unique_id = GetSeriesIDString();
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::ApplyPixelMaskInFPGA(bool input) {
|
||||
@@ -973,3 +996,126 @@ std::optional<float> DiffractionExperiment::GetAttenuatorTransmission() const {
|
||||
std::optional<float> DiffractionExperiment::GetTotalFlux() const {
|
||||
return dataset.total_flux;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaStep(const std::optional<float> &input) {
|
||||
if (input && (input == 0.0f))
|
||||
dataset.omega_step.reset();
|
||||
else
|
||||
dataset.omega_step = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaStart(const float input) {
|
||||
dataset.omega_start = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::optional<float> DiffractionExperiment::GetOmegaStep() const {
|
||||
return dataset.omega_step;
|
||||
}
|
||||
|
||||
float DiffractionExperiment::GetOmegaStart() const {
|
||||
return dataset.omega_start;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::UsingGainHG0(bool input) {
|
||||
use_gain_hg0 = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::FixedGainG1(bool input) {
|
||||
fix_gain_g1 = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool DiffractionExperiment::IsFixedGainG1() const {
|
||||
return fix_gain_g1;
|
||||
}
|
||||
|
||||
bool DiffractionExperiment::IsUsingGainHG0() const {
|
||||
return use_gain_hg0;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::HeaderAppendix(const std::string &input) {
|
||||
dataset.header_appendix = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::ImageAppendix(const std::string &input) {
|
||||
dataset.image_appendix = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string DiffractionExperiment::GetHeaderAppendix() const {
|
||||
return dataset.header_appendix;
|
||||
}
|
||||
|
||||
std::string DiffractionExperiment::GetImageAppendix() const {
|
||||
return dataset.image_appendix;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaAxis(const Coord &c) {
|
||||
if (c.Length() == 0.0)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Cannot use empty vector for omega");
|
||||
|
||||
dataset.omega_rotation_axis = c.Normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaAxis() {
|
||||
dataset.omega_rotation_axis = default_omega_axis;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Coord DiffractionExperiment::GetOmegaAxis() const {
|
||||
return dataset.omega_rotation_axis;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::DefaultOmegaAxis(const Coord &c) {
|
||||
if (c.Length() == 0.0)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Cannot use empty vector for omega axis");
|
||||
|
||||
default_omega_axis = c.Normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Coord DiffractionExperiment::GetDefaultOmegaAxis() const {
|
||||
return default_omega_axis;
|
||||
}
|
||||
|
||||
uint64_t DiffractionExperiment::GetSeriesID() const {
|
||||
return series_id;
|
||||
}
|
||||
|
||||
std::string DiffractionExperiment::GetSeriesIDString() const {
|
||||
return std::to_string(series_id) + ": " + dataset.file_prefix;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::IncrementSeriesID() {
|
||||
series_id++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Coord DiffractionExperiment::GetModuleFastDirection(uint16_t module_number) const {
|
||||
return detector.GetGeometry().GetFastDirection(module_number);
|
||||
}
|
||||
|
||||
Coord DiffractionExperiment::GetModuleSlowDirection(uint16_t module_number) const {
|
||||
return detector.GetGeometry().GetSlowDirection(module_number);
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::ROISummation(const std::optional<ROIRectangle> &input) {
|
||||
if (input) {
|
||||
check_max("Max X for ROI summation", input->x_max, GetXPixelsNum() - 1);
|
||||
check_max("Max Y for ROI summation", input->y_max, GetYPixelsNum() - 1);
|
||||
|
||||
check_max("Min X for ROI summation", input->x_min, input->x_max);
|
||||
check_max("Min Y for ROI summation", input->y_min, input->y_max);
|
||||
}
|
||||
dataset.roi_sum = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::optional<ROIRectangle> DiffractionExperiment::GetROISummation() const {
|
||||
return dataset.roi_sum;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ class DiffractionExperiment {
|
||||
int64_t pedestal_g0_frames;
|
||||
int64_t pedestal_g1_frames;
|
||||
int64_t pedestal_g2_frames;
|
||||
bool use_gain_hg0;
|
||||
bool fix_gain_g1;
|
||||
|
||||
std::chrono::microseconds preview_period;
|
||||
|
||||
@@ -82,6 +84,9 @@ class DiffractionExperiment {
|
||||
std::string instrument_name_short;
|
||||
|
||||
bool debug_pixel_mask;
|
||||
Coord default_omega_axis;
|
||||
|
||||
uint64_t series_id;
|
||||
|
||||
// Dataset settings
|
||||
struct {
|
||||
@@ -112,6 +117,13 @@ class DiffractionExperiment {
|
||||
bool save_calibration;
|
||||
std::optional<float> total_flux;
|
||||
std::optional<float> attenuator_transmission;
|
||||
std::optional<float> omega_step;
|
||||
float omega_start;
|
||||
std::string image_appendix;
|
||||
std::string header_appendix;
|
||||
|
||||
Coord omega_rotation_axis;
|
||||
std::optional<ROIRectangle> roi_sum;
|
||||
} dataset;
|
||||
|
||||
constexpr static const int64_t max_spot_count = 100;
|
||||
@@ -151,11 +163,11 @@ public:
|
||||
DiffractionExperiment& MaskChipEdges(bool input);
|
||||
DiffractionExperiment& SetUnitCell(const std::optional<UnitCell> &cell);
|
||||
|
||||
DiffractionExperiment& LowResForRadialInt_A(float input);
|
||||
DiffractionExperiment& HighResForRadialInt_A(float input);
|
||||
DiffractionExperiment& LowQForRadialInt_recipA(float input);
|
||||
DiffractionExperiment& HighQForRadialInt_recipA(float input);
|
||||
DiffractionExperiment& QSpacingForRadialInt_recipA(float input);
|
||||
DiffractionExperiment& LowResForAzimInt_A(float input);
|
||||
DiffractionExperiment& HighResForAzimInt_A(float input);
|
||||
DiffractionExperiment& LowQForAzimInt_recipA(float input);
|
||||
DiffractionExperiment& HighQForAzimInt_recipA(float input);
|
||||
DiffractionExperiment& QSpacingForAzimInt_recipA(float input);
|
||||
|
||||
DiffractionExperiment& SpaceGroupNumber(int64_t input);
|
||||
DiffractionExperiment& StorageCells(int64_t input);
|
||||
@@ -169,6 +181,18 @@ public:
|
||||
DiffractionExperiment& ApplyPixelMaskInFPGA(bool input);
|
||||
DiffractionExperiment& AttenuatorTransmission(const std::optional<float> &input);
|
||||
DiffractionExperiment& TotalFlux(const std::optional<float> &input);
|
||||
DiffractionExperiment& OmegaStep(const std::optional<float> &input);
|
||||
DiffractionExperiment& OmegaStart(const float input);
|
||||
DiffractionExperiment& OmegaAxis(const Coord &c);
|
||||
DiffractionExperiment& OmegaAxis();
|
||||
DiffractionExperiment& DefaultOmegaAxis(const Coord &c);
|
||||
|
||||
DiffractionExperiment& UsingGainHG0(bool input);
|
||||
DiffractionExperiment& FixedGainG1(bool input);
|
||||
DiffractionExperiment& HeaderAppendix(const std::string& input);
|
||||
DiffractionExperiment& ImageAppendix(const std::string& input);
|
||||
DiffractionExperiment& IncrementSeriesID();
|
||||
DiffractionExperiment& ROISummation(const std::optional<ROIRectangle>& input);
|
||||
|
||||
void FillMessage(StartMessage &message) const;
|
||||
|
||||
@@ -217,7 +241,8 @@ public:
|
||||
int64_t GetMaxCompressedSize() const;
|
||||
|
||||
int64_t GetDataStreamsNum() const;
|
||||
int64_t GetModulesNum(uint16_t data_stream = TASK_NO_DATA_STREAM) const;
|
||||
int64_t GetModulesNum(uint16_t data_stream) const;
|
||||
int64_t GetModulesNum() const;
|
||||
int64_t GetFirstModuleOfDataStream(uint16_t data_stream) const;
|
||||
|
||||
int64_t GetPixelsNum() const;
|
||||
@@ -227,6 +252,9 @@ public:
|
||||
int64_t GetModuleFastDirectionStep(uint16_t module_number) const;
|
||||
int64_t GetModuleSlowDirectionStep(uint16_t module_number) const;
|
||||
|
||||
Coord GetModuleFastDirection(uint16_t module_number) const;
|
||||
Coord GetModuleSlowDirection(uint16_t module_number) const;
|
||||
|
||||
std::chrono::microseconds GetPreviewPeriod() const;
|
||||
int64_t GetPreviewStride() const;
|
||||
|
||||
@@ -246,9 +274,9 @@ public:
|
||||
|
||||
Coord LabCoord(float detector_x, float detector_y) const;
|
||||
|
||||
float GetLowQForRadialInt_recipA() const;
|
||||
float GetHighQForRadialInt_recipA() const;
|
||||
float GetQSpacingForRadialInt_recipA() const;
|
||||
float GetLowQForAzimInt_recipA() const;
|
||||
float GetHighQForAzimInt_recipA() const;
|
||||
float GetQSpacingForAzimInt_recipA() const;
|
||||
|
||||
float GetLowQForBkgEstimate_recipA() const;
|
||||
float GetHighQForBkgEstimate_recipA() const;
|
||||
@@ -292,6 +320,19 @@ public:
|
||||
std::vector<DetectorModuleConfig> GetDetectorModuleConfig(const std::vector<AcquisitionDeviceNetConfig>& net_config) const;
|
||||
std::optional<float> GetAttenuatorTransmission() const;
|
||||
std::optional<float> GetTotalFlux() const;
|
||||
std::optional<float> GetOmegaStep() const;
|
||||
float GetOmegaStart() const;
|
||||
Coord GetOmegaAxis() const;
|
||||
Coord GetDefaultOmegaAxis() const;
|
||||
|
||||
bool IsFixedGainG1() const;
|
||||
bool IsUsingGainHG0() const;
|
||||
std::string GetHeaderAppendix() const;
|
||||
std::string GetImageAppendix() const;
|
||||
|
||||
uint64_t GetSeriesID() const;
|
||||
std::string GetSeriesIDString() const;
|
||||
std::optional<ROIRectangle> GetROISummation() const;
|
||||
};
|
||||
|
||||
inline int64_t CalculateStride(const std::chrono::microseconds &frame_time, const std::chrono::microseconds &preview_time) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "DiffractionSpot.h"
|
||||
#include "DiffractionGeometry.h"
|
||||
#include "RawToConvertedGeometry.h"
|
||||
|
||||
DiffractionSpot::DiffractionSpot(uint32_t col, uint32_t line, int64_t in_photons) {
|
||||
if (in_photons < 0) in_photons = 0;
|
||||
@@ -65,3 +66,9 @@ void DiffractionSpot::AddPixel(uint32_t col, uint32_t line, int64_t photons) {
|
||||
this->max_photons = std::max(this->max_photons, photons);
|
||||
this->pixel_count += 1;
|
||||
}
|
||||
|
||||
void DiffractionSpot::ConvertToImageCoordinates(const DiffractionExperiment &experiment, uint16_t module_number) {
|
||||
auto c_out = RawToConvertedCoordinate(experiment, module_number, RawCoord());
|
||||
this->x = c_out.x * (float) photons;
|
||||
this->y = c_out.y * (float) photons;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
int64_t MaxCount() const;
|
||||
Coord RawCoord() const;
|
||||
Coord LabCoord(const DiffractionExperiment &experiment) const;
|
||||
void ConvertToImageCoordinates(const DiffractionExperiment& experiment, uint16_t module_number);
|
||||
double GetResolution(const DiffractionExperiment &experiment) const;
|
||||
Coord ReciprocalCoord(const DiffractionExperiment &experiment) const;
|
||||
operator SpotToSave() const;
|
||||
|
||||
+2
-1
@@ -7,7 +7,8 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
enum class PlotType {BkgEstimate, RadInt, SpotCount, IndexingRate, IndexingRatePerFile, ADUHistorgram};
|
||||
enum class PlotType {BkgEstimate, RadInt, SpotCount, IndexingRate, IndexingRatePerFile, SaturatedPixels,
|
||||
ErrorPixels, ImageCollectionEfficiency, ReceiverDelay, StrongPixels, ROISum};
|
||||
|
||||
struct PlotRequest {
|
||||
PlotType type;
|
||||
|
||||
@@ -36,6 +36,18 @@ inline std::pair<int64_t, int64_t> RawToConvertedCoordinate(const DiffractionExp
|
||||
return {pixel % experiment.GetXPixelsNum() , pixel / experiment.GetXPixelsNum()};
|
||||
}
|
||||
|
||||
inline Coord RawToConvertedCoordinate(const DiffractionExperiment& experiment, uint32_t module_number, const Coord &c) {
|
||||
int64_t pixel0 = experiment.GetPixel0OfModule(module_number);
|
||||
|
||||
Coord pixel0_coord(pixel0 % experiment.GetXPixelsNum(),
|
||||
pixel0 / experiment.GetXPixelsNum(),
|
||||
0);
|
||||
|
||||
return pixel0_coord
|
||||
+ experiment.GetModuleFastDirection(module_number) * (c.x + (static_cast<int32_t>(c.x) / 256) * 2)
|
||||
+ experiment.GetModuleSlowDirection(module_number) * (c.y + (static_cast<int32_t>(c.y) / 256) * 2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ConvertedToRawGeometry(const DiffractionExperiment &experiment, T *destination, const T *source) {
|
||||
for (size_t module_number = 0; module_number < experiment.GetModulesNum(); module_number++) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <cmath>
|
||||
|
||||
#include "Plot.h"
|
||||
|
||||
|
||||
+37
-6
@@ -27,6 +27,8 @@ ZMQSocket::ZMQSocket(ZMQContext &context, ZMQSocketType in_socket_type) : socket
|
||||
|
||||
if (socket == nullptr)
|
||||
throw JFJochException(JFJochExceptionCategory::ZeroMQ, "zmq_socket failed");
|
||||
|
||||
EnableKeepAlive();
|
||||
}
|
||||
|
||||
void ZMQSocket::Bind(const std::string &addr) {
|
||||
@@ -50,17 +52,21 @@ void ZMQSocket::Send() {
|
||||
throw JFJochException(JFJochExceptionCategory::ZeroMQ, "zmq_send() failed: " + std::string(std::strerror(errno)));
|
||||
}
|
||||
|
||||
void ZMQSocket::Send(const void *buf, size_t buf_size, bool blocking, bool multipart) {
|
||||
bool ZMQSocket::Send(const void *buf, size_t buf_size, bool blocking, bool multipart) {
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
if (zmq_send(socket, buf, buf_size, (blocking ? 0 : ZMQ_DONTWAIT) | (multipart ? ZMQ_SNDMORE : 0)) != buf_size) {
|
||||
if (errno != EAGAIN)
|
||||
if (zmq_send(socket, buf, buf_size, (blocking ? 0 : ZMQ_DONTWAIT) | (multipart ? ZMQ_SNDMORE : 0)) == buf_size)
|
||||
return true;
|
||||
else {
|
||||
if ((errno == EAGAIN) || (errno == EINTR))
|
||||
return false;
|
||||
else
|
||||
throw JFJochException(JFJochExceptionCategory::ZeroMQ,
|
||||
"zmq_send(buf) failed: " + std::string(std::strerror(errno)));
|
||||
}
|
||||
}
|
||||
|
||||
void ZMQSocket::Send(const std::string &s, bool blocking, bool multipart) {
|
||||
Send((void *) s.c_str(), s.size(), blocking, multipart);
|
||||
bool ZMQSocket::Send(const std::string &s, bool blocking, bool multipart) {
|
||||
return Send((void *) s.c_str(), s.size(), blocking, multipart);
|
||||
}
|
||||
|
||||
void ZMQSocket::Send(const int32_t &value) {
|
||||
@@ -122,6 +128,16 @@ ZMQSocket &ZMQSocket::NoReceiveTimeout() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZMQSocket &ZMQSocket::SendTimeout(std::chrono::milliseconds input) {
|
||||
SetSocketOption(ZMQ_SNDTIMEO, input.count());
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZMQSocket &ZMQSocket::NoSendTimeout() {
|
||||
SetSocketOption(ZMQ_SNDTIMEO, -1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZMQSocket &ZMQSocket::ReceiverBufferSize(int32_t bytes) {
|
||||
SetSocketOption(ZMQ_RCVBUF, bytes);
|
||||
return *this;
|
||||
@@ -168,4 +184,19 @@ ZMQSocket &ZMQSocket::NoLinger() {
|
||||
ZMQSocket &ZMQSocket::Conflate(bool input) {
|
||||
SetSocketOption(ZMQ_CONFLATE, input ? 1 : 0);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
ZMQSocket &ZMQSocket::EnableKeepAlive() {
|
||||
SetSocketOption(ZMQ_TCP_KEEPALIVE, 1);
|
||||
SetSocketOption(ZMQ_TCP_KEEPALIVE_CNT, 10);
|
||||
SetSocketOption(ZMQ_TCP_KEEPALIVE_IDLE, 60);
|
||||
SetSocketOption(ZMQ_TCP_KEEPALIVE_INTVL, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string ZMQSocket::GetEndpointName() {
|
||||
char tmp[256];
|
||||
size_t len = 255;
|
||||
zmq_getsockopt(socket, ZMQ_LAST_ENDPOINT, tmp, &len);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
+11
-7
@@ -43,6 +43,10 @@ public:
|
||||
void Bind(const std::string& addr);
|
||||
ZMQSocket &NoReceiveTimeout();
|
||||
ZMQSocket &ReceiveTimeout(std::chrono::milliseconds input);
|
||||
|
||||
ZMQSocket &NoSendTimeout();
|
||||
ZMQSocket &SendTimeout(std::chrono::milliseconds input);
|
||||
|
||||
ZMQSocket &Subscribe(const std::string &topic);
|
||||
ZMQSocket &SubscribeAll();
|
||||
ZMQSocket &NoLinger();
|
||||
@@ -58,9 +62,7 @@ public:
|
||||
zmq_msg_init(&zmq_msg);
|
||||
int64_t msg_size = zmq_msg_recv(&zmq_msg, socket, blocking ? 0 : ZMQ_DONTWAIT);
|
||||
if (msg_size < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return -1;
|
||||
if (errno == EINTR) // Timeout ?
|
||||
if ((errno == EAGAIN) || (errno == EINTR))
|
||||
return -1;
|
||||
else
|
||||
throw JFJochException(JFJochExceptionCategory::ZeroMQ, "zmq_msg_recv failed "
|
||||
@@ -81,16 +83,18 @@ public:
|
||||
}
|
||||
|
||||
void Send();
|
||||
void Send(const void *buf, size_t buf_size, bool blocking = true, bool multipart = false);
|
||||
bool Send(const void *buf, size_t buf_size, bool blocking = true, bool multipart = false);
|
||||
void SendZeroCopy(const void *buf, size_t buf_size, ZeroCopyReturnValue *zero_copy_ret_val);
|
||||
template <class T> void Send(const std::vector<T> &buf) {
|
||||
Send(buf.data(), buf.size() * sizeof(T));
|
||||
template <class T> bool Send(const std::vector<T> &buf) {
|
||||
return Send(buf.data(), buf.size() * sizeof(T));
|
||||
}
|
||||
void Send(const int32_t &value);
|
||||
void Send(const std::string &s, bool blocking = true, bool multipart = false);
|
||||
bool Send(const std::string &s, bool blocking = true, bool multipart = false);
|
||||
void Send(zmq_msg_t *msg);
|
||||
ZMQSocket &SendWaterMark(int32_t msgs);
|
||||
ZMQSocket &ReceiveWaterMark(int32_t msgs);
|
||||
ZMQSocket &EnableKeepAlive();
|
||||
std::string GetEndpointName();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#ifndef JUNGFRAUJOCH_TO_FIXED_H
|
||||
#define JUNGFRAUJOCH_TO_FIXED_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
|
||||
inline uint16_t to_fixed(double val, uint16_t fractional_bits) {
|
||||
// If val is result of division by zero, only reasonable value of output is zero (otherwise number could be interpreted improperly)
|
||||
uint32_t int_val = std::isfinite(val) ? (std::lround(val * (1<<fractional_bits))) : 0;
|
||||
// It is unlikely (but not impossible), that gain value will be lower than the smallest possible
|
||||
// Then reciprocal of gain could be more than allowed by data format. Protection is added for this condition
|
||||
if (int_val > UINT16_MAX) int_val = UINT16_MAX;
|
||||
return int_val;
|
||||
}
|
||||
|
||||
#endif //JUNGFRAUJOCH_TO_FIXED_H
|
||||
@@ -95,18 +95,32 @@ void DetectorWrapper::Start(const DiffractionExperiment& experiment) {
|
||||
|
||||
try {
|
||||
InternalStop();
|
||||
switch (experiment.GetDetectorMode()) {
|
||||
case DetectorMode::PedestalG1:
|
||||
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G1);
|
||||
break;
|
||||
case DetectorMode::PedestalG2:
|
||||
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G2);
|
||||
break;
|
||||
default:
|
||||
det.setGainMode(slsDetectorDefs::gainMode::DYNAMIC);
|
||||
break;
|
||||
if (experiment.IsFixedGainG1()) {
|
||||
if ((experiment.GetDetectorMode() == DetectorMode::PedestalG0) ||
|
||||
(experiment.GetDetectorMode() == DetectorMode::PedestalG2))
|
||||
throw JFJochException(JFJochExceptionCategory::Detector,
|
||||
"Pedestal G0/G2 doesn't make sense for fixed G1 mode");
|
||||
det.setGainMode(slsDetectorDefs::FIX_G1);
|
||||
} else {
|
||||
switch (experiment.GetDetectorMode()) {
|
||||
case DetectorMode::PedestalG1:
|
||||
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G1);
|
||||
break;
|
||||
case DetectorMode::PedestalG2:
|
||||
det.setGainMode(slsDetectorDefs::gainMode::FORCE_SWITCH_G2);
|
||||
break;
|
||||
default:
|
||||
det.setGainMode(slsDetectorDefs::gainMode::DYNAMIC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (experiment.IsUsingGainHG0())
|
||||
det.setSettings(slsDetectorDefs::HIGHGAIN0);
|
||||
else
|
||||
det.setSettings(slsDetectorDefs::GAIN0);
|
||||
|
||||
|
||||
det.setNextFrameNumber(1);
|
||||
|
||||
if (experiment.GetNumTriggers() == 1) {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
INSTALL(FILES broker.json DESTINATION etc)
|
||||
+2
-1
@@ -14,8 +14,9 @@
|
||||
"preview_period_us": "1 s",
|
||||
"detector_ipv4": "10.10.85.0"
|
||||
},
|
||||
"frontend_directory":"/home/jungfrau/nextgendcu/frontend/build",
|
||||
"numa_policy": "n2g2",
|
||||
"zmq_image_addr": ["tcp://10.10.1.243:5500", "tcp://10.10.1.243:5501", "tcp://10.10.1.243:5502", "tcp://10.10.1.243:5503"],
|
||||
"zmq_image_addr": ["tcp://0.0.0.0:5500", "tcp://0.0.0.0:5501", "tcp://0.0.0.0:5502", "tcp://0.0.0.0:5503"],
|
||||
"zmq_preview_addr": "tcp://0.0.0.0:5400",
|
||||
"receiver_threads": 64,
|
||||
"send_buffer_count": 2048,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
FIND_PACKAGE(TIFF COMPONENTS CXX)
|
||||
FIND_PACKAGE(JPEG)
|
||||
|
||||
ADD_LIBRARY(ExportImage STATIC WriteTIFF.cpp WriteTIFF.h WriteJPEG.cpp WriteJPEG.h)
|
||||
|
||||
IF (${TIFF_FOUND})
|
||||
TARGET_COMPILE_DEFINITIONS(ExportImage PUBLIC -DJFJOCH_USE_TIFF)
|
||||
TARGET_INCLUDE_DIRECTORIES(ExportImage PRIVATE ${TIFF_INCLUDE_DIR})
|
||||
TARGET_LINK_LIBRARIES(ExportImage PUBLIC ${TIFF_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
IF (${JPEG_FOUND})
|
||||
TARGET_COMPILE_DEFINITIONS(ExportImage PUBLIC -DJFJOCH_USE_JPEG)
|
||||
TARGET_INCLUDE_DIRECTORIES(ExportImage PRIVATE ${JPEG_INCLUDE_DIR})
|
||||
TARGET_LINK_LIBRARIES(ExportImage PUBLIC ${JPEG_LIBRARIES})
|
||||
ENDIF()
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (2019-2024) Paul Scherrer Institute
|
||||
|
||||
#ifdef JFJOCH_USE_JPEG
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <jpeglib.h>
|
||||
#endif
|
||||
|
||||
void WriteJPEG(const std::vector<char> &input, size_t width, size_t height) {
|
||||
unsigned char *buf;
|
||||
unsigned long buf_size;
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_mem_dest(&cinfo, &buf, &buf_size);
|
||||
|
||||
cinfo.image_width = width;
|
||||
cinfo.image_height = height;
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
/*set the quality [0..100] */
|
||||
jpeg_set_quality (&cinfo, 75, true);
|
||||
jpeg_start_compress(&cinfo, true);
|
||||
|
||||
JSAMPROW row_pointer; /* pointer to a single row */
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height) {
|
||||
row_pointer = (JSAMPROW) (input.data() + cinfo.next_scanline*(sizeof(char)>>3)*width);
|
||||
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#ifndef JUNGFRAUJOCH_WRITEJPEG_H
|
||||
#define JUNGFRAUJOCH_WRITEJPEG_H
|
||||
|
||||
|
||||
#endif //JUNGFRAUJOCH_WRITEJPEG_H
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (2019-2024) Paul Scherrer Institute
|
||||
|
||||
#include "WriteTIFF.h"
|
||||
#include "../common/JFJochException.h"
|
||||
|
||||
#ifdef JFJOCH_USE_TIFF
|
||||
#include <tiffio.h>
|
||||
#include <tiffio.hxx>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
void WriteTIFF(TIFF *tiff, void *buff, size_t cols, size_t lines, size_t elem_size, bool is_signed) {
|
||||
#ifndef JFJOCH_USE_TIFF
|
||||
throw JFJochException(JFJochExceptionCategory::TIFFGeneratorError, "Compiled without TIFF support");
|
||||
#else
|
||||
if (tiff == nullptr)
|
||||
throw JFJochException(JFJochExceptionCategory::TIFFGeneratorError, "TIFFStreamOpen error");
|
||||
|
||||
TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, cols); // set the width of the image
|
||||
TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, lines); // set the height of the image
|
||||
TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); // set number of channels per pixel
|
||||
TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, elem_size * 8); // set the size of the channels
|
||||
TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW); // setc ompression to LZW
|
||||
TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, lines);
|
||||
if (is_signed)
|
||||
TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
|
||||
else
|
||||
TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||
|
||||
if (TIFFWriteEncodedStrip(tiff, 0, buff, cols * lines * elem_size) < 0)
|
||||
throw JFJochException(JFJochExceptionCategory::TIFFGeneratorError, "TIFFWriteEncodedStrip error");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string WriteTIFFToString(void *buff, size_t cols, size_t lines, size_t elem_size, bool is_signed) {
|
||||
#ifndef JFJOCH_USE_TIFF
|
||||
throw JFJochException(JFJochExceptionCategory::TIFFGeneratorError, "Compiled without TIFF support");
|
||||
#else
|
||||
std::stringstream os;
|
||||
|
||||
TIFF *tiff = TIFFStreamOpen("x", (std::ostream *) &os);
|
||||
WriteTIFF(tiff, buff, cols, lines, elem_size, is_signed);
|
||||
TIFFClose(tiff);
|
||||
|
||||
return os.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WriteTIFFToFile(const std::string &filename, void *buff, size_t cols, size_t lines, size_t elem_size,
|
||||
bool is_signed) {
|
||||
#ifndef JFJOCH_USE_TIFF
|
||||
throw JFJochException(JFJochExceptionCategory::TIFFGeneratorError, "Compiled without TIFF support");
|
||||
#else
|
||||
TIFF *tiff = TIFFOpen(filename.c_str(), "w");
|
||||
|
||||
WriteTIFF(tiff, buff, cols, lines, elem_size, is_signed);
|
||||
|
||||
TIFFClose(tiff);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (2019-2024) Paul Scherrer Institute
|
||||
|
||||
#ifndef JUNGFRAUJOCH_WRITETIFF_H
|
||||
#define JUNGFRAUJOCH_WRITETIFF_H
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string WriteTIFFToString(void *buff, size_t cols, size_t lines, size_t elem_size, bool is_signed = false);
|
||||
void WriteTIFFToFile(const std::string &filename, void *buff, size_t cols, size_t lines, size_t elem_size,
|
||||
bool is_signed = false);
|
||||
|
||||
#endif //JUNGFRAUJOCH_WRITETIFF_H
|
||||
+7
-3
@@ -113,6 +113,10 @@ For RHEL9 this needs to built from source - [Xilinx/XRT github repository](https
|
||||
Irrespective of the method use to upload firmware, it is necessary to do cold reboot the server (with a short power interruption to PCIe devices).
|
||||
Currently, this is best done by powering the server off and on again. More efficient procedure is yet to be tested.
|
||||
|
||||
## Reset card
|
||||
To reset the card it is enough to do a standard warm reboot.
|
||||
|
||||
Loading new image from the flash requires cold reboot, where power is cut for the card for a short time.
|
||||
## Hardware verification
|
||||
|
||||
To test that FPGA board is working properly without access to a JUNGFRAU detector, you can use `jfjoch_action_test` tool.
|
||||
@@ -123,7 +127,7 @@ This number is incremented after each change of functionality of the card or int
|
||||
This ensures consistency between the FPGA card, driver and user application. Changes within the design (e.g. size of FIFOs),
|
||||
that are invisible to interactions with host do not require change in release number.
|
||||
|
||||
To check release number, look for constant `RELEASE_NUMBER` in [common/Definitions.h](../common/Definitions.h) header file.
|
||||
To check release number, look for constant `RELEASE_NUMBER` in [include/jfjoch_fpga.h](include/jfjoch_fpga.h) header file.
|
||||
For FPGA design, release number is also included in the generated bitstream name.
|
||||
|
||||
In case there is mismatch in release number between card and kernel driver, the latter will not create the character device and return error (check `dmesg`).
|
||||
@@ -172,14 +176,14 @@ FPGA setup can be done via 32-bit registers:
|
||||
| 0x010060 | 64 | Valid detector packets processed by the card | R | cleared on reset |
|
||||
| 0x010066 | 64 | Packets flagged as errors by CMAC | R | cleared on reset |
|
||||
| 0x010100 | 32 | Spot finder photon count threshold | R/W | |
|
||||
| 0x010104 | 32 | Spot finder signal-to-noise ratio threshold (in fixed-point: 6 int. + 4 frac. bit format) | R/W | |
|
||||
| 0x010104 | 32 | Spot finder signal-to-noise ratio threshold (single-precision float) | R/W | |
|
||||
| 0x010200 | 64 | MAC address of FPGA card | R/W | network byte order |
|
||||
| 0x010208 | 32 | IPv4 address of FPGA card | R/W | network byte order |
|
||||
| 0x01020C | 32 | Number of detector modules (value minus one: 0 => 1 module, 1 => 2 modules, etc.) | R/W | |
|
||||
| 0x010210 | 32 | Data collection mode | R/W | |
|
||||
| | | Bit 0 - Conversion to photons | | |
|
||||
| | | Bit 16:31 - Data collection ID (carried with completions) | | |
|
||||
| 0x010214 | 32 | One over energy in keV (in fixed-point:12 int. + 24 frac. bit format) | R/W | |
|
||||
| 0x010214 | 32 | Photon energy in keV (single-precision float) | R/W | |
|
||||
| 0x010218 | 32 | Number of frames expected in the data collection (defines termination condition) | R/W | |
|
||||
| 0x01021C | 32 | Number of storage cells | R/W | |
|
||||
| 0x010220 | 32 | Summation on card (value minus one: 0 => summation of 1, 1 => summation of 2, etc.) | R/W | |
|
||||
|
||||
+41
-15
@@ -14,10 +14,12 @@
|
||||
|
||||
`define ADDR_ACTION_TYPE 16'h0010
|
||||
`define ADDR_RELEASE_LEVEL 16'h0014
|
||||
`define ADDR_MAX_MODULES_FPGA 16'h0020
|
||||
|
||||
`define ADDR_MAX_MODULES_FPGA 16'h0020
|
||||
`define ADDR_RUN_COUNTER 16'h0024
|
||||
`define ADDR_STALLS_HOST_LO 16'h0028
|
||||
`define ADDR_STALLS_HOST_HI 16'h002C
|
||||
|
||||
`define ADDR_STALLS_HBM_LO 16'h0030
|
||||
`define ADDR_STALLS_HBM_HI 16'h0034
|
||||
`define ADDR_FIFO_STATUS 16'h0038
|
||||
@@ -56,7 +58,7 @@
|
||||
`define ADDR_NMODULES 16'h020C
|
||||
|
||||
`define ADDR_DATA_COL_MODE 16'h0210
|
||||
`define ADDR_ONE_OVER_ENERGY 16'h0214
|
||||
`define ADDR_ENERGY_KEV 16'h0214
|
||||
`define ADDR_NFRAMES 16'h0218
|
||||
`define ADDR_NSTORAGE_CELLS 16'h021C
|
||||
|
||||
@@ -95,21 +97,31 @@ module action_config
|
||||
output reg [31:0] data_collection_mode ,
|
||||
output reg [47:0] fpga_mac_addr ,
|
||||
output reg [31:0] fpga_ipv4_addr ,
|
||||
output reg [31:0] one_over_energy ,
|
||||
output reg [31:0] energy_kev ,
|
||||
output reg [31:0] nframes ,
|
||||
output reg [4:0] nmodules ,
|
||||
output reg [3:0] nstorage_cells ,
|
||||
output reg [7:0] nsummation ,
|
||||
output reg [1:0] data_source ,
|
||||
output wire [31:0] hbm_size_bytes ,
|
||||
output reg [15:0] spot_finder_count_threshold,
|
||||
output reg [7:0] spot_finder_snr_threshold,
|
||||
output reg [31:0] spot_finder_count_threshold,
|
||||
output reg [31:0] spot_finder_snr_threshold,
|
||||
|
||||
output reg data_collection_start ,
|
||||
output reg data_collection_cancel ,
|
||||
input data_collection_idle ,
|
||||
|
||||
input host_writer_idle ,
|
||||
input load_from_hbm_idle ,
|
||||
input save_to_hbm_idle ,
|
||||
input frame_summation_idle ,
|
||||
input integration_idle ,
|
||||
input stream_conv_idle ,
|
||||
input udp_idle ,
|
||||
input sls_detector_idle ,
|
||||
|
||||
input [2:0] host_writer_state ,
|
||||
|
||||
input calib_data_fifo_empty ,
|
||||
input calib_data_fifo_full ,
|
||||
input calib_addr_fifo_empty ,
|
||||
@@ -214,6 +226,8 @@ localparam
|
||||
reg [31:0] reg_udp_err_len;
|
||||
reg [31:0] reg_udp_err_eth;
|
||||
|
||||
reg [31:0] reg_data_acquisition_count;
|
||||
|
||||
reg [31:0] reg_fifo_status;
|
||||
reg reg_data_collection_idle;
|
||||
//------------------------Instantiation------------------
|
||||
@@ -317,8 +331,8 @@ always @(posedge clk) begin
|
||||
`ADDR_DATA_COL_MODE: begin
|
||||
rdata <= data_collection_mode;
|
||||
end
|
||||
`ADDR_ONE_OVER_ENERGY: begin
|
||||
rdata <= one_over_energy;
|
||||
`ADDR_ENERGY_KEV: begin
|
||||
rdata <= energy_kev;
|
||||
end
|
||||
`ADDR_NFRAMES: begin
|
||||
rdata <= nframes;
|
||||
@@ -431,6 +445,9 @@ always @(posedge clk) begin
|
||||
`ADDR_SPOT_FINDER_SNR_THR: begin
|
||||
rdata <= spot_finder_snr_threshold;
|
||||
end
|
||||
`ADDR_RUN_COUNTER: begin
|
||||
rdata <= reg_data_acquisition_count;
|
||||
end
|
||||
default:
|
||||
rdata <= 32'hffffffff;
|
||||
endcase
|
||||
@@ -456,17 +473,26 @@ always @(posedge clk) begin
|
||||
reg_ctrl[2] <= data_collection_cancel;
|
||||
reg_ctrl[3] <= clear_counters;
|
||||
reg_ctrl[4] <= host_writer_idle;
|
||||
reg_ctrl[5] <= load_from_hbm_idle;
|
||||
reg_ctrl[6] <= save_to_hbm_idle;
|
||||
reg_ctrl[7] <= frame_summation_idle;
|
||||
reg_ctrl[8] <= integration_idle;
|
||||
reg_ctrl[9] <= stream_conv_idle;
|
||||
reg_ctrl[12:10] <= host_writer_state;
|
||||
reg_ctrl[16] <= mailbox_interrupt_0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn)
|
||||
if (!resetn) begin
|
||||
data_collection_start <= 1'b0;
|
||||
else if (!reg_data_collection_idle)
|
||||
reg_data_acquisition_count <= 32'h0;
|
||||
end else if (!reg_data_collection_idle)
|
||||
data_collection_start <= 1'b0;
|
||||
else if (w_hs && waddr == `ADDR_AP_CTRL && s_axi_WSTRB[0] && s_axi_WDATA[0])
|
||||
else if (w_hs && waddr == `ADDR_AP_CTRL && s_axi_WSTRB[0] && s_axi_WDATA[0]) begin
|
||||
reg_data_acquisition_count <= reg_data_acquisition_count + 32'h1;
|
||||
data_collection_start <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
@@ -529,10 +555,10 @@ end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn)
|
||||
one_over_energy <= 0;
|
||||
energy_kev <= 0;
|
||||
else if (reg_data_collection_idle) begin
|
||||
if (w_hs && waddr == `ADDR_ONE_OVER_ENERGY )
|
||||
one_over_energy <= (s_axi_WDATA[31:0] & wmask) | (one_over_energy & !wmask);
|
||||
if (w_hs && waddr == `ADDR_ENERGY_KEV )
|
||||
energy_kev <= (s_axi_WDATA[31:0] & wmask) | (energy_kev & !wmask);
|
||||
end
|
||||
end
|
||||
|
||||
@@ -585,14 +611,14 @@ always @(posedge clk) begin
|
||||
if (!resetn)
|
||||
spot_finder_snr_threshold <= 0;
|
||||
else if (w_hs && waddr == `ADDR_SPOT_FINDER_SNR_THR)
|
||||
spot_finder_snr_threshold <= (s_axi_WDATA[7:0] & wmask[7:0]) | (spot_finder_snr_threshold & !wmask[7:0]);
|
||||
spot_finder_snr_threshold <= (s_axi_WDATA[31:0] & wmask[31:0]) | (spot_finder_snr_threshold & !wmask[31:0]);
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn)
|
||||
spot_finder_count_threshold <= 0;
|
||||
else if (w_hs && waddr == `ADDR_SPOT_FINDER_CNT_THR)
|
||||
spot_finder_count_threshold <= (s_axi_WDATA[15:0] & wmask[15:0]) | (spot_finder_count_threshold & !wmask[15:0]);
|
||||
spot_finder_count_threshold <= (s_axi_WDATA[31:0] & wmask[31:0]) | (spot_finder_count_threshold & !wmask[31:0]);
|
||||
end
|
||||
|
||||
always @ (posedge clk) begin
|
||||
|
||||
@@ -3,7 +3,7 @@ ADD_LIBRARY( HLSSimulation STATIC
|
||||
data_collection_fsm.cpp
|
||||
timer.cpp
|
||||
hls_jfjoch.h
|
||||
../../common/Definitions.h
|
||||
../include/jfjoch_fpga.h
|
||||
load_calibration.cpp
|
||||
host_writer.cpp
|
||||
ethernet.cpp
|
||||
@@ -59,7 +59,7 @@ FUNCTION( MAKE_HLS_MODULE FUNCTION_NAME SRC_FILE TB_FILE)
|
||||
COMMAND ${CMAKE_COMMAND} -E env SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} HLS_FILE=${SRC_FILE} HLS_TOP_FUNCTION=${FUNCTION_NAME} HLS_TB_FILE=${TB_FILE} ${VIVADO_HLS} -f ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/synth_hls_function.tcl > hls_${FUNCTION_NAME}.log
|
||||
COMMAND ${CMAKE_COMMAND} -E env HLS_DIR=${CMAKE_CURRENT_BINARY_DIR}/${FUNCTION_NAME}/solution1 CURR_DIR=${CMAKE_CURRENT_BINARY_DIR} bash ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/check_hls.sh ${FUNCTION_NAME}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${FUNCTION_NAME}/solution1/impl/ip/psi_ch_hls_${FUNCTION_NAME}_1_0.zip .
|
||||
DEPENDS ${SRC_FILE} hls_jfjoch.h ../../common/Definitions.h)
|
||||
DEPENDS ${SRC_FILE} hls_jfjoch.h ../include/jfjoch_fpga.h)
|
||||
SET (HLS_IPS ${HLS_IPS} psi_ch_hls_${FUNCTION_NAME}_1_0.zip PARENT_SCOPE)
|
||||
ENDFUNCTION(MAKE_HLS_MODULE)
|
||||
|
||||
|
||||
+33
-3
@@ -23,14 +23,26 @@ void adu_histo(STREAM_512 &data_in,
|
||||
for (int i = 0; i < 64; i++)
|
||||
count[i][j] = 0;
|
||||
}
|
||||
ap_uint<24> saturated_pixels[32];
|
||||
ap_uint<24> err_pixels[32];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
saturated_pixels[i] = 0;
|
||||
err_pixels[i] = 0;
|
||||
}
|
||||
|
||||
ap_uint<16> in_val[32];
|
||||
ap_uint<256> bins_0, bins_1;
|
||||
|
||||
packet_512_t packet_in;
|
||||
data_in >> packet_in;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_in;
|
||||
ap_wait();
|
||||
}
|
||||
ap_uint<8> sum = ACT_REG_NSUMMATION(packet_in.data); // 0..255
|
||||
data_out << packet_in;
|
||||
|
||||
|
||||
axis_completion cmpl;
|
||||
s_axis_completion >> cmpl;
|
||||
@@ -47,8 +59,13 @@ void adu_histo(STREAM_512 &data_in,
|
||||
data_out << packet_in;
|
||||
|
||||
unpack32(packet_in.data, in_val);
|
||||
for (int j = 0; j < 32; j++)
|
||||
for (int j = 0; j < 32; j++) {
|
||||
count[k * 32 + j][in_val[j] / ADU_HISTO_BIN_WIDTH] += (cmpl.packet_mask[i / 64] ? 1 : 0);
|
||||
if (cmpl.packet_mask[i/64] && (in_val[j] == 0xc000))
|
||||
saturated_pixels[j]++;
|
||||
if (cmpl.packet_mask[i/64] && (in_val[j] == 0xffff))
|
||||
err_pixels[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
s_axis_completion >> cmpl;
|
||||
@@ -66,6 +83,19 @@ void adu_histo(STREAM_512 &data_in,
|
||||
}
|
||||
result_out << val;
|
||||
}
|
||||
ap_uint<32> saturated_pixels_total = 0;
|
||||
ap_uint<32> err_pixels_total = 0;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
#pragma HLS UNROLL
|
||||
saturated_pixels_total += saturated_pixels[i];
|
||||
saturated_pixels[i] = 0;
|
||||
err_pixels_total += err_pixels[i];
|
||||
err_pixels[i] = 0;
|
||||
}
|
||||
ap_uint<512> val_sat = 0;
|
||||
val_sat(31, 0) = saturated_pixels_total;
|
||||
val_sat(63,32) = err_pixels_total;
|
||||
result_out << val_sat;
|
||||
}
|
||||
m_axis_completion << cmpl;
|
||||
|
||||
|
||||
@@ -106,4 +106,3 @@ void arp(AXI_STREAM &arp_in,
|
||||
|
||||
prev_start = arp_start;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,18 +4,19 @@
|
||||
#include "hls_jfjoch.h"
|
||||
|
||||
void data_collection_fsm(AXI_STREAM ð_in,
|
||||
STREAM_512 &data_out,
|
||||
hls::stream<axis_addr> &addr_in,
|
||||
hls::stream<axis_addr> &addr_out,
|
||||
volatile ap_uint<1> &in_run,
|
||||
volatile ap_uint<1> &in_cancel,
|
||||
volatile ap_uint<1> &out_idle,
|
||||
ap_uint<32> mode,
|
||||
ap_uint<32> one_over_energy,
|
||||
ap_uint<32> nframes,
|
||||
ap_uint<5> nmodules,
|
||||
ap_uint<4> nstorage_cells,
|
||||
ap_uint<8> nsummation) {
|
||||
STREAM_512 &data_out,
|
||||
hls::stream<axis_addr> &addr_in,
|
||||
hls::stream<axis_addr> &addr_out,
|
||||
volatile ap_uint<1> &in_run,
|
||||
volatile ap_uint<1> &in_cancel,
|
||||
volatile ap_uint<1> &out_idle,
|
||||
ap_uint<32> mode,
|
||||
ap_uint<32> energy_kev,
|
||||
ap_uint<32> nframes,
|
||||
ap_uint<5> nmodules,
|
||||
ap_uint<4> nstorage_cells,
|
||||
ap_uint<8> nsummation,
|
||||
volatile rcv_state_t &data_collection_state) {
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
|
||||
#pragma HLS INTERFACE axis register both port=eth_in
|
||||
@@ -27,11 +28,12 @@ void data_collection_fsm(AXI_STREAM ð_in,
|
||||
#pragma HLS INTERFACE ap_none register port=out_idle
|
||||
|
||||
#pragma HLS INTERFACE ap_none register port=mode
|
||||
#pragma HLS INTERFACE ap_none register port=one_over_energy
|
||||
#pragma HLS INTERFACE ap_none register port=energy_kev
|
||||
#pragma HLS INTERFACE ap_none register port=nframes
|
||||
#pragma HLS INTERFACE ap_none register port=nmodules
|
||||
#pragma HLS INTERFACE ap_none register port=nstorage_cells
|
||||
#pragma HLS INTERFACE ap_none register port=nsummation
|
||||
#pragma HLS INTERFACE ap_none register port=data_collection_state
|
||||
|
||||
#pragma HLS PIPELINE II=1 style=flp
|
||||
|
||||
@@ -39,8 +41,6 @@ void data_collection_fsm(AXI_STREAM ð_in,
|
||||
packet_512_t packet_out;
|
||||
axis_addr addr;
|
||||
|
||||
enum rcv_state_t {RCV_WAIT_FOR_START = 0, RCV_WAIT_FOR_START_LOW = 1, RCV_START = 2, RCV_INIT = 3, RCV_GOOD = 4,
|
||||
RCV_FLUSH = 5, RCV_LAST = 6, RCV_FLUSH_IDLE = 7, RCV_IGNORE = 8};
|
||||
static rcv_state_t rcv_state = RCV_WAIT_FOR_START;
|
||||
|
||||
#pragma HLS RESET variable=rcv_state
|
||||
@@ -73,18 +73,18 @@ void data_collection_fsm(AXI_STREAM ð_in,
|
||||
out_idle = 0;
|
||||
packet_out.data = 0;
|
||||
ACT_REG_MODE(packet_out.data) = mode;
|
||||
ACT_REG_ONE_OVER_ENERGY(packet_out.data) = one_over_energy;
|
||||
ACT_REG_ENERGY_KEV_FLOAT(packet_out.data) = energy_kev;
|
||||
ACT_REG_NFRAMES(packet_out.data) = nframes;
|
||||
ACT_REG_NMODULES(packet_out.data) = nmodules;
|
||||
ACT_REG_NSTORAGE_CELLS(packet_out.data) = nstorage_cells + 1;
|
||||
ACT_REG_NSUMMATION(packet_out.data) = nsummation;
|
||||
|
||||
packet_out.user = 0;
|
||||
packet_out.last = 0;
|
||||
packet_out.last = 1;
|
||||
packet_out.dest = 0;
|
||||
packet_out.id = 1;
|
||||
data_out << packet_out;
|
||||
|
||||
|
||||
rcv_state = RCV_INIT;
|
||||
break;
|
||||
case RCV_INIT:
|
||||
@@ -138,5 +138,6 @@ void data_collection_fsm(AXI_STREAM ð_in,
|
||||
rcv_state = RCV_WAIT_FOR_START;
|
||||
break;
|
||||
}
|
||||
data_collection_state = rcv_state;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,17 +36,18 @@ void ethernet(AXI_STREAM ð_in,
|
||||
|
||||
if (state == INSPECT_HEADER) {
|
||||
dest = DEST_IGNORE;
|
||||
if (fpga_mac_addr != 0) {
|
||||
if ((fpga_mac_addr != 0) || (packet_in.id == AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK)) {
|
||||
ap_uint<48> dest_mac = packet_in.data(47, 0);
|
||||
ap_uint<48> src_mac = packet_in.data(95, 48);
|
||||
ap_uint<16> ether_type = get_header_field_16(packet_in.data, 12 * 8);
|
||||
|
||||
if ((dest_mac == fpga_mac_addr) && (ether_type == ETHER_IP)) {
|
||||
if (((dest_mac == fpga_mac_addr) || (packet_in.id == AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK)) // don't check MAC address for 4x10G
|
||||
&& (ether_type == ETHER_IP)) {
|
||||
state = FORWARD;
|
||||
dest = DEST_IP;
|
||||
internal_counter++;
|
||||
} else if ((dest_mac == MAC_BROADCAST) && (ether_type == ETHER_ARP) && (packet_in.last)
|
||||
&& (packet_in.id == AXI_STREAM_ID_ENABLE_ARP_ICMP)) {
|
||||
&& (packet_in.id == AXI_STREAM_ID_FULL_NETWORK_STACK)) {
|
||||
state = FORWARD;
|
||||
dest = DEST_ARP;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ void generate_packet(STREAM_512 &data_out,
|
||||
ap_uint<64> bunchid,
|
||||
ap_uint<32> exptime,
|
||||
ap_uint<64> timestamp,
|
||||
ap_uint<32> debug) {
|
||||
ap_uint<32> debug,
|
||||
ap_uint<1> user = 0) {
|
||||
#pragma HLS PIPELINE II=130
|
||||
ap_uint<720> header = 0;
|
||||
|
||||
@@ -48,7 +49,7 @@ void generate_packet(STREAM_512 &data_out,
|
||||
packet.id = 0;
|
||||
packet.strb = UINT64_MAX;
|
||||
packet.keep = UINT64_MAX;
|
||||
packet.user = 0;
|
||||
packet.user = user;
|
||||
|
||||
data_out << packet;
|
||||
|
||||
@@ -109,6 +110,21 @@ int frame_generator(STREAM_512 &data_out,
|
||||
if (modules > MAX_MODULES_FPGA)
|
||||
return 1;
|
||||
|
||||
// send one packet with TUSER = 1, to reset on network cores on the way
|
||||
generate_packet(data_out,
|
||||
d_hbm_p0,
|
||||
d_hbm_p1,
|
||||
hbm_size_bytes,
|
||||
0, 0, 0,
|
||||
src_mac_addr,
|
||||
dest_mac_addr,
|
||||
src_ipv4_addr,
|
||||
dest_ipv4_addr,
|
||||
bunchid,
|
||||
exptime,
|
||||
exptime,
|
||||
debug, 1);
|
||||
|
||||
for (uint32_t f = 0; f < frames; f++) {
|
||||
ap_uint<1> local_cancel = in_cancel;
|
||||
if (local_cancel == 1)
|
||||
@@ -127,7 +143,7 @@ int frame_generator(STREAM_512 &data_out,
|
||||
bunchid + f,
|
||||
exptime,
|
||||
exptime * f,
|
||||
debug);
|
||||
debug, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,15 @@ ap_uint<768> extend_18_to_24(ap_int<576> input) {
|
||||
|
||||
void frame_summation(STREAM_576 &data_in, STREAM_768 &data_out,
|
||||
hls::stream<axis_completion > &s_axis_completion,
|
||||
hls::stream<axis_completion > &m_axis_completion) {
|
||||
hls::stream<axis_completion > &m_axis_completion,
|
||||
volatile ap_uint<1> &idle) {
|
||||
#pragma HLS INTERFACE axis register both port=data_in
|
||||
#pragma HLS INTERFACE axis register both port=data_out
|
||||
#pragma HLS INTERFACE axis register both port=s_axis_completion
|
||||
#pragma HLS INTERFACE axis register both port=m_axis_completion
|
||||
#pragma HLS INTERFACE ap_none register port=idle
|
||||
|
||||
idle = 1;
|
||||
|
||||
ap_uint<24 * 32> memory_0[16384];
|
||||
#pragma HLS BIND_STORAGE variable=memory_0 type=ram_t2p impl=uram latency=3
|
||||
@@ -35,9 +39,16 @@ void frame_summation(STREAM_576 &data_in, STREAM_768 &data_out,
|
||||
packet_576_t packet_in;
|
||||
packet_768_t packet_out;
|
||||
|
||||
data_in >> packet_in;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_768_t{.data = packet_in.data, .user = 0, .last = 0};
|
||||
ap_wait();
|
||||
idle = 0;
|
||||
ap_wait();
|
||||
}
|
||||
ap_uint<8> sum = ACT_REG_NSUMMATION(packet_in.data); // 0..255
|
||||
data_out << packet_768_t{.data = packet_in.data, .user = 0, .last = 0};
|
||||
|
||||
data_in >> packet_in;
|
||||
|
||||
@@ -108,4 +119,5 @@ void frame_summation(STREAM_576 &data_in, STREAM_768 &data_out,
|
||||
}
|
||||
m_axis_completion << cmpl;
|
||||
data_out << packet_768_t{.data = packet_in.data, .user = 1, .last = 0};
|
||||
}
|
||||
idle = 1;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,13 @@ void frame_summation_reorder_compl(STREAM_512 &data_in,
|
||||
}
|
||||
|
||||
packet_512_t packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << packet_in;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_in;
|
||||
ap_wait();
|
||||
}
|
||||
ap_uint<8> sum = ACT_REG_NSUMMATION(packet_in.data); // 0..255
|
||||
|
||||
axis_completion c;
|
||||
|
||||
@@ -60,8 +60,9 @@ int test(size_t nframes, int16_t min, int16_t max) {
|
||||
for (int i = 0; i < nframes; i++)
|
||||
compl_in << axis_completion{.packet_mask = packet_mask, .frame_number = 100 + i, .packet_count = 128, .last = 0};
|
||||
compl_in << axis_completion{.last = 1};
|
||||
ap_uint<1> idle;
|
||||
|
||||
frame_summation(input, output, compl_in, compl_out);
|
||||
frame_summation(input, output, compl_in, compl_out, idle);
|
||||
|
||||
if (compl_in.size() != 0) {
|
||||
std::cout << "compl_in should be empty: " << compl_in.size() << std::endl;
|
||||
|
||||
@@ -56,7 +56,8 @@ int test(size_t nframes, int16_t min, int16_t max) {
|
||||
compl_in << axis_completion{.packet_mask = packet_mask, .frame_number = 100 + i, .packet_count = 128, .last = 0};
|
||||
compl_in << axis_completion{.last = 1};
|
||||
|
||||
frame_summation(input, output, compl_in, compl_out);
|
||||
ap_uint<1> idle;
|
||||
frame_summation(input, output, compl_in, compl_out, idle);
|
||||
|
||||
if (compl_in.size() != 0) {
|
||||
std::cout << "compl_in should be empty: " << compl_in.size() << std::endl;
|
||||
|
||||
+32
-18
@@ -3,6 +3,8 @@
|
||||
#ifndef JUNGFRAUJOCH_HLS_JFJOCH_H
|
||||
#define JUNGFRAUJOCH_HLS_JFJOCH_H
|
||||
|
||||
#include "../include/jfjoch_fpga.h"
|
||||
|
||||
#include <ap_int.h>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -12,10 +14,11 @@
|
||||
#include <ap_axi_sdata.h>
|
||||
#include <hls_stream.h>
|
||||
#else
|
||||
#define ap_wait()
|
||||
#include "parallel_stream.h"
|
||||
#endif
|
||||
|
||||
#include "../../common/Definitions.h"
|
||||
#include "../include/jfjoch_fpga.h"
|
||||
|
||||
#define INT18_MAX (131071)
|
||||
#define INT18_MIN (-131072)
|
||||
@@ -23,12 +26,13 @@
|
||||
#define INT24_MAX 8388607
|
||||
#define INT24_MIN (-8388608)
|
||||
|
||||
#define AXI_STREAM_ID_ENABLE_ARP_ICMP 0
|
||||
#define AXI_STREAM_ID_DISABLE_ARP_ICMP 1
|
||||
#define AXI_STREAM_ID_FULL_NETWORK_STACK 0 // For 100G provide full network stack - enforce MAC/IPv4 and provide provide ARP/ICMP
|
||||
#define AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK 1 // For 4x10G the connection is direct detector-DCU, so no need to enforce MAC/IPv4 and to provide ARP and ICMP
|
||||
|
||||
typedef ap_ufixed<16,2, AP_RND_CONV> gainG0_t;
|
||||
typedef ap_ufixed<16,4, AP_RND_CONV> gainG1_t;
|
||||
typedef ap_ufixed<16,6, AP_RND_CONV> gainG2_t;
|
||||
typedef ap_ufixed<16,1, AP_RND_CONV> integration_factor_t;
|
||||
|
||||
typedef ap_ufixed<32,12,AP_RND_CONV> one_over_energy_t;
|
||||
|
||||
@@ -57,7 +61,7 @@ typedef hls::stream<packet_576_t> STREAM_576;
|
||||
typedef hls::stream<packet_768_t> STREAM_768;
|
||||
|
||||
#define ACT_REG_MODE(x) ((x)(32 , 0)) // 32 bit
|
||||
#define ACT_REG_ONE_OVER_ENERGY(x) ((x)(63 , 32)) // 32 bit
|
||||
#define ACT_REG_ENERGY_KEV_FLOAT(x) ((x)(63 , 32)) // 32 bit
|
||||
#define ACT_REG_NFRAMES(x) ((x)(95 , 64)) // 32 bit
|
||||
#define ACT_REG_NMODULES(x) ((x)(132, 128)) // 5 bit (0..31)
|
||||
#define ACT_REG_NSTORAGE_CELLS(x) ((x)(148, 144)) // 5 bit
|
||||
@@ -221,7 +225,8 @@ void udp(AXI_STREAM ð_in,
|
||||
AXI_STREAM &udp_payload_out,
|
||||
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > &udp_metadata_out,
|
||||
uint64_t& counter,
|
||||
volatile ap_uint<1> &in_clear_counters);
|
||||
volatile ap_uint<1> &in_clear_counters,
|
||||
volatile ap_uint<1> &idle);
|
||||
|
||||
void sls_detector(AXI_STREAM &udp_payload_in,
|
||||
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > &udp_metadata_in,
|
||||
@@ -230,7 +235,8 @@ void sls_detector(AXI_STREAM &udp_payload_in,
|
||||
uint64_t& counter,
|
||||
uint32_t& counter_eth_error,
|
||||
uint32_t& counter_len_error,
|
||||
volatile ap_uint<1> &in_clear_counters);
|
||||
volatile ap_uint<1> &in_clear_counters,
|
||||
volatile ap_uint<1> &idle);
|
||||
|
||||
// Image modification and analysis cores
|
||||
|
||||
@@ -276,8 +282,8 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
|
||||
void spot_finder(STREAM_768 &data_in,
|
||||
STREAM_768 &data_out,
|
||||
hls::stream<ap_axiu<32,1,1,1>> &strong_pixel_out,
|
||||
volatile ap_int<16> &in_count_threshold,
|
||||
volatile ap_uint<8> &in_snr_threshold);
|
||||
volatile ap_int<32> &in_count_threshold,
|
||||
volatile ap_uint<32> &in_snr_threshold);
|
||||
|
||||
void integration(STREAM_768 &data_in,
|
||||
STREAM_768 &data_out,
|
||||
@@ -288,10 +294,14 @@ void integration(STREAM_768 &data_in,
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
ap_uint<256> *d_hbm_p2,
|
||||
ap_uint<256> *d_hbm_p3,
|
||||
volatile ap_uint<1> &idle,
|
||||
ap_uint<32> hbm_size_bytes);
|
||||
|
||||
// Packet stream handling
|
||||
|
||||
enum rcv_state_t {RCV_WAIT_FOR_START = 0, RCV_WAIT_FOR_START_LOW = 1, RCV_START = 2, RCV_INIT = 3, RCV_GOOD = 4,
|
||||
RCV_FLUSH = 5, RCV_LAST = 6, RCV_FLUSH_IDLE = 7, RCV_IGNORE = 8};
|
||||
|
||||
void data_collection_fsm(AXI_STREAM ð_in,
|
||||
STREAM_512 &data_out,
|
||||
hls::stream<axis_addr> &addr_in,
|
||||
@@ -300,11 +310,12 @@ void data_collection_fsm(AXI_STREAM ð_in,
|
||||
volatile ap_uint<1> &in_cancel,
|
||||
volatile ap_uint<1> &out_idle,
|
||||
ap_uint<32> mode,
|
||||
ap_uint<32> one_over_energy,
|
||||
ap_uint<32> energy_kev,
|
||||
ap_uint<32> nframes,
|
||||
ap_uint<5> nmodules,
|
||||
ap_uint<4> nstorage_cells,
|
||||
ap_uint<8> nsummation);
|
||||
ap_uint<8> nsummation,
|
||||
volatile rcv_state_t &state);
|
||||
|
||||
void host_writer(STREAM_512 &data_in,
|
||||
hls::stream<ap_uint<512>> &adu_histo_in,
|
||||
@@ -317,7 +328,9 @@ void host_writer(STREAM_512 &data_in,
|
||||
hls::stream<ap_uint<32> > &m_axis_completion,
|
||||
const uint64_t *dma_address_table,
|
||||
volatile uint64_t &packets_processed,
|
||||
volatile ap_uint<1> &idle);
|
||||
volatile ap_uint<1> &idle,
|
||||
volatile ap_uint<1> &in_cancel,
|
||||
volatile ap_uint<3> &state);
|
||||
|
||||
void load_from_hbm(STREAM_512 &data_in,
|
||||
STREAM_512 &data_out,
|
||||
@@ -328,6 +341,7 @@ void load_from_hbm(STREAM_512 &data_in,
|
||||
hls::stream<ap_axiu<256,1,1,1> > &hbm_in_1,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_0_cmd,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_1_cmd,
|
||||
volatile ap_uint<1> &idle,
|
||||
ap_uint<32> hbm_size_bytes);
|
||||
|
||||
void save_to_hbm(STREAM_512 &data_in,
|
||||
@@ -339,6 +353,7 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_1,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_0_cmd,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_1_cmd,
|
||||
volatile ap_uint<1> &idle,
|
||||
ap_uint<32> hbm_size_bytes);
|
||||
|
||||
void timer_host(STREAM_512 &data_in,
|
||||
@@ -363,26 +378,25 @@ int frame_generator(STREAM_512 &data_out,
|
||||
ap_uint<32> debug,
|
||||
volatile ap_uint<1> &in_cancel);
|
||||
|
||||
|
||||
int load_calibration(ap_uint<256> *d_hbm_p0,
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
ap_uint<8> modules,
|
||||
ap_uint<5> storage_cells,
|
||||
const LoadCalibrationConfig &config,
|
||||
ap_uint<32> hbm_size_bytes,
|
||||
ap_uint<8> destination,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_in_cmd,
|
||||
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
|
||||
const uint64_t *handle_to_dma_address);
|
||||
const uint64_t *dma_address_table);
|
||||
|
||||
void frame_summation(STREAM_576 &data_in, STREAM_768 &data_out,
|
||||
hls::stream<axis_completion > &s_axis_completion,
|
||||
hls::stream<axis_completion > &m_axis_completion);
|
||||
hls::stream<axis_completion > &m_axis_completion,
|
||||
volatile ap_uint<1> &idle);
|
||||
|
||||
void frame_summation_reorder_compl(STREAM_512 &data_in,
|
||||
STREAM_512 &data_out,
|
||||
hls::stream<axis_completion > &s_axis_completion,
|
||||
hls::stream<axis_completion > &m_axis_completion);
|
||||
|
||||
void stream_24bit_conv(STREAM_768 &data_in, STREAM_512 &data_out);
|
||||
void stream_24bit_conv(STREAM_768 &data_in, STREAM_512 &data_out,
|
||||
volatile ap_uint<1> &idle);
|
||||
|
||||
#endif
|
||||
|
||||
+93
-32
@@ -1,12 +1,11 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include "hls_jfjoch.h"
|
||||
#include "../host_library/DeviceOutput.h"
|
||||
|
||||
#define o(field) offsetof(ModuleStatistics, field)
|
||||
#define sf(msg, field, s) msg(o(field)*8 + s - 1, o(field)*8)
|
||||
|
||||
inline ap_uint<512> fill_module_info(axis_completion &cmpl) {
|
||||
inline ap_uint<512> fill_module_info(axis_completion &cmpl, ap_uint<32> sat_pxl, ap_uint<32> err_pxl) {
|
||||
ap_uint<512> msg = 0;
|
||||
sf(msg, frame_number, 64) = cmpl.frame_number;
|
||||
sf(msg, timestamp, 64) = cmpl.timestamp;
|
||||
@@ -16,6 +15,8 @@ inline ap_uint<512> fill_module_info(axis_completion &cmpl) {
|
||||
sf(msg, pedestal, 32) = cmpl.pedestal;
|
||||
sf(msg, packet_count, 32) = cmpl.packet_count;
|
||||
sf(msg, module_number, 32) = cmpl.module;
|
||||
sf(msg, saturated_pixels, 32) = sat_pxl;
|
||||
sf(msg, err_pixels, 32) = err_pxl;
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -45,7 +46,9 @@ void host_writer(STREAM_512 &data_in,
|
||||
hls::stream<ap_uint<32> > &m_axis_completion,
|
||||
const uint64_t *dma_address_table,
|
||||
volatile uint64_t &packets_processed,
|
||||
volatile ap_uint<1> &idle) {
|
||||
volatile ap_uint<1> &idle,
|
||||
volatile ap_uint<1> &in_cancel,
|
||||
volatile ap_uint<3> &state) {
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
#pragma HLS INTERFACE register both axis port=data_in
|
||||
#pragma HLS INTERFACE register both axis port=adu_histo_in
|
||||
@@ -58,18 +61,32 @@ void host_writer(STREAM_512 &data_in,
|
||||
#pragma HLS INTERFACE register both axis port=s_axis_work_request
|
||||
#pragma HLS INTERFACE register ap_vld port=packets_processed
|
||||
#pragma HLS INTERFACE register ap_none port=idle
|
||||
#pragma HLS INTERFACE register ap_none port=in_cancel
|
||||
#pragma HLS INTERFACE register ap_none port=state
|
||||
|
||||
#pragma HLS INTERFACE mode=m_axi port=dma_address_table bundle=dma_address_table depth=65536 offset=off \
|
||||
max_read_burst_length=2 max_write_burst_length=2 latency=10 num_write_outstanding=1 num_read_outstanding=1
|
||||
|
||||
idle = 1;
|
||||
|
||||
state = 0;
|
||||
|
||||
ap_uint<16> req_handle;
|
||||
ap_uint<64> req_host_offset;
|
||||
|
||||
while (data_in.empty()) {
|
||||
if (!s_axis_work_request.empty()) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
read_request(s_axis_work_request, req_handle);
|
||||
write_completion(m_axis_completion, req_handle, DATA_COLLECTION_ID_PURGE);
|
||||
}
|
||||
}
|
||||
packet_512_t packet;
|
||||
data_in >> packet;
|
||||
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet;
|
||||
ap_wait();
|
||||
}
|
||||
ap_uint<32> data_collection_mode = ACT_REG_MODE(packet.data);
|
||||
ap_uint<32> data_collection_id = data_collection_mode(31, 16);
|
||||
ap_uint<1> mode_32bit = (data_collection_mode & MODE_32BIT) ? 1 : 0;
|
||||
@@ -80,11 +97,37 @@ void host_writer(STREAM_512 &data_in,
|
||||
|
||||
idle = 0;
|
||||
|
||||
size_t pixel_depth;
|
||||
if (mode_32bit)
|
||||
pixel_depth = 4;
|
||||
else
|
||||
pixel_depth = 2;
|
||||
|
||||
axis_completion cmpl;
|
||||
s_axis_completion >> cmpl;
|
||||
|
||||
state = 1;
|
||||
while (!cmpl.last) {
|
||||
read_request(s_axis_work_request, req_handle);
|
||||
req_host_offset = dma_address_table[req_handle];
|
||||
ap_uint<1> send_images = 1;
|
||||
|
||||
while (s_axis_work_request.empty() && !in_cancel.read()) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_wait();
|
||||
}
|
||||
if (s_axis_work_request.empty()) {
|
||||
send_images = 0;
|
||||
state = 2;
|
||||
} else
|
||||
state = 3;
|
||||
|
||||
// Either send_images == 0 (so collection can proceed without writing to host mem)
|
||||
// or s_axis_work_request is not empty (so collection can proceed with writing to host mem)
|
||||
if (send_images) {
|
||||
read_request(s_axis_work_request, req_handle);
|
||||
req_host_offset = dma_address_table[req_handle];
|
||||
send_images = (req_host_offset != 0);
|
||||
}
|
||||
|
||||
packet_512_t packet_out;
|
||||
packet_out.strb = UINT64_MAX;
|
||||
packet_out.keep = UINT64_MAX;
|
||||
@@ -93,20 +136,16 @@ void host_writer(STREAM_512 &data_in,
|
||||
packet_out.id = 0;
|
||||
packet_out.last = 0;
|
||||
|
||||
size_t pixel_depth;
|
||||
if (mode_32bit)
|
||||
pixel_depth = 4;
|
||||
else
|
||||
pixel_depth = 2;
|
||||
|
||||
setup_datamover(datamover_out_cmd, req_host_offset, RAW_MODULE_SIZE * pixel_depth);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, spot_finding_result),
|
||||
RAW_MODULE_SIZE * sizeof(uint16_t) / 16 + 64);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, integration_result),
|
||||
(FPGA_INTEGRATION_BIN_COUNT / 8) * 64);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, adu_histogram),
|
||||
ADU_HISTO_BIN_COUNT / 16 * 64);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, module_statistics), 2*64);
|
||||
if (send_images) {
|
||||
setup_datamover(datamover_out_cmd, req_host_offset, RAW_MODULE_SIZE * pixel_depth);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, spot_finding_result),
|
||||
RAW_MODULE_SIZE * sizeof(uint16_t) / 16 + 64);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, integration_result),
|
||||
(FPGA_INTEGRATION_BIN_COUNT / 8) * 64);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, adu_histogram),
|
||||
ADU_HISTO_BIN_COUNT / 16 * 64);
|
||||
setup_datamover(datamover_out_cmd, req_host_offset + offsetof(DeviceOutput, module_statistics), 2 * 64);
|
||||
}
|
||||
|
||||
if (pixel_depth == 2) {
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * 2 / 64; i++) {
|
||||
@@ -117,7 +156,8 @@ void host_writer(STREAM_512 &data_in,
|
||||
packet_out.last = 1;
|
||||
else
|
||||
packet_out.last = 0;
|
||||
host_memory_out << packet_out;
|
||||
if (send_images)
|
||||
host_memory_out << packet_out;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * 4 / 64; i++) {
|
||||
@@ -128,7 +168,8 @@ void host_writer(STREAM_512 &data_in,
|
||||
packet_out.last = 1;
|
||||
else
|
||||
packet_out.last = 0;
|
||||
host_memory_out << packet_out;
|
||||
if (send_images)
|
||||
host_memory_out << packet_out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +180,8 @@ void host_writer(STREAM_512 &data_in,
|
||||
#pragma HLS PIPELINE II=1
|
||||
spot_finder_in >> packet_out.data;
|
||||
packet_out.last = (i == RAW_MODULE_SIZE * sizeof(uint16_t) / (64 * 16) + 1 - 1);
|
||||
host_memory_out << packet_out;
|
||||
if (send_images)
|
||||
host_memory_out << packet_out;
|
||||
}
|
||||
|
||||
// 128 transfers x 512-bit
|
||||
@@ -147,7 +189,8 @@ void host_writer(STREAM_512 &data_in,
|
||||
#pragma HLS PIPELINE II=1
|
||||
integration_in >> packet_out.data;
|
||||
packet_out.last = (i == FPGA_INTEGRATION_BIN_COUNT / 8 - 1);
|
||||
host_memory_out << packet_out;
|
||||
if (send_images)
|
||||
host_memory_out << packet_out;
|
||||
}
|
||||
|
||||
// 128 transfers x 512-bit
|
||||
@@ -156,25 +199,43 @@ void host_writer(STREAM_512 &data_in,
|
||||
ap_uint<512> tmp;
|
||||
adu_histo_in >> packet_out.data;
|
||||
packet_out.last = (i == ADU_HISTO_BIN_COUNT / 16 - 1);
|
||||
host_memory_out << packet_out;
|
||||
if (send_images)
|
||||
host_memory_out << packet_out;
|
||||
}
|
||||
|
||||
packet_out.data = fill_module_info(cmpl);
|
||||
if (send_images)
|
||||
state = 5;
|
||||
else
|
||||
state = 4;
|
||||
|
||||
adu_histo_in >> packet_out.data;
|
||||
|
||||
packet_out.data = fill_module_info(cmpl, packet_out.data(31,0), packet_out.data(63,32));
|
||||
packet_out.last = 0;
|
||||
host_memory_out << packet_out;
|
||||
|
||||
if (send_images)
|
||||
host_memory_out << packet_out;
|
||||
|
||||
packet_out.data = cmpl.packet_mask;
|
||||
packet_out.last = 1;
|
||||
host_memory_out << packet_out;
|
||||
|
||||
write_completion(m_axis_completion, req_handle, data_collection_id);
|
||||
internal_packets_processed += cmpl.packet_count;
|
||||
packets_processed = internal_packets_processed;
|
||||
if (send_images)
|
||||
host_memory_out << packet_out;
|
||||
|
||||
if (send_images) {
|
||||
write_completion(m_axis_completion, req_handle, data_collection_id);
|
||||
internal_packets_processed += cmpl.packet_count;
|
||||
packets_processed = internal_packets_processed;
|
||||
}
|
||||
|
||||
state = 6;
|
||||
s_axis_completion >> cmpl;
|
||||
state = 7;
|
||||
}
|
||||
|
||||
data_in >> packet;
|
||||
|
||||
write_completion(m_axis_completion, HANDLE_END, data_collection_id);
|
||||
|
||||
idle = 1;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ void integration(STREAM_768 &data_in,
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
ap_uint<256> *d_hbm_p2,
|
||||
ap_uint<256> *d_hbm_p3,
|
||||
volatile ap_uint<1> &idle,
|
||||
ap_uint<32> hbm_size_bytes) {
|
||||
#pragma HLS INTERFACE register both axis port=data_in
|
||||
#pragma HLS INTERFACE register both axis port=data_out
|
||||
@@ -18,6 +19,8 @@ void integration(STREAM_768 &data_in,
|
||||
#pragma HLS INTERFACE register both axis port=m_axis_completion
|
||||
#pragma HLS INTERFACE register both axis port=s_axis_completion
|
||||
#pragma HLS INTERFACE register ap_none port=hbm_size_bytes
|
||||
#pragma HLS INTERFACE register ap_none port=idle
|
||||
|
||||
#pragma HLS INTERFACE m_axi port=d_hbm_p0 bundle=d_hbm_p0 depth=16384 offset=off \
|
||||
max_read_burst_length=16 max_write_burst_length=2 latency=120 num_write_outstanding=2 num_read_outstanding=8
|
||||
#pragma HLS INTERFACE m_axi port=d_hbm_p1 bundle=d_hbm_p1 depth=16384 offset=off \
|
||||
@@ -27,6 +30,8 @@ void integration(STREAM_768 &data_in,
|
||||
#pragma HLS INTERFACE m_axi port=d_hbm_p3 bundle=d_hbm_p3 depth=16384 offset=off \
|
||||
max_read_burst_length=16 max_write_burst_length=2 latency=120 num_write_outstanding=2 num_read_outstanding=8
|
||||
|
||||
idle = 1;
|
||||
|
||||
ap_fixed<50,34, AP_RND_CONV> sum[64][FPGA_INTEGRATION_BIN_COUNT];
|
||||
// log2(32768*512*1024/64) = 32 + sign 1 bit
|
||||
#pragma HLS BIND_STORAGE variable=sum type=ram_t2p impl=bram
|
||||
@@ -46,14 +51,20 @@ void integration(STREAM_768 &data_in,
|
||||
|
||||
ap_int<24> in_val[32];
|
||||
ap_uint<16> in_bin[32];
|
||||
ap_ufixed<16,1, AP_RND_CONV> in_coeff[32];
|
||||
integration_factor_t in_coeff[32];
|
||||
|
||||
ap_uint<256> bins_0, bins_1, coeff_0, coeff_1;
|
||||
|
||||
packet_768_t packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << packet_in;
|
||||
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_in;
|
||||
ap_wait();
|
||||
idle = 0;
|
||||
ap_wait();
|
||||
}
|
||||
ap_uint<32> offset_hbm_0 = 16 * hbm_size_bytes / 32;
|
||||
ap_uint<32> offset_hbm_1 = 17 * hbm_size_bytes / 32;
|
||||
ap_uint<32> offset_hbm_2 = 18 * hbm_size_bytes / 32;
|
||||
@@ -123,4 +134,5 @@ void integration(STREAM_768 &data_in,
|
||||
|
||||
data_in >> packet_in;
|
||||
data_out << packet_in;
|
||||
idle = 1;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ int main() {
|
||||
compl_in << axis_completion{.last = 1};
|
||||
input << packet_768_t{.user = 1};
|
||||
|
||||
integration(input, output, integration_result, compl_in, compl_out, hbm_0, hbm_1, hbm_2, hbm_3, 0);
|
||||
ap_uint<1> idle;
|
||||
|
||||
integration(input, output, integration_result, compl_in, compl_out, hbm_0, hbm_1, hbm_2, hbm_3, idle, 0);
|
||||
|
||||
if (input.size() != 0)
|
||||
ret = 1;
|
||||
|
||||
+27
-26
@@ -5,9 +5,9 @@
|
||||
#include "ip_header_checksum.h"
|
||||
|
||||
void ipv4(AXI_STREAM ð_in,
|
||||
AXI_STREAM &udp_out,
|
||||
AXI_STREAM &icmp_out,
|
||||
ap_uint<32> fpga_ipv4_addr) {
|
||||
AXI_STREAM &udp_out,
|
||||
AXI_STREAM &icmp_out,
|
||||
ap_uint<32> fpga_ipv4_addr) {
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
#pragma HLS INTERFACE axis register both port=eth_in
|
||||
#pragma HLS INTERFACE axis register both port=udp_out
|
||||
@@ -19,46 +19,47 @@ void ipv4(AXI_STREAM ð_in,
|
||||
enum ipv4_state {INSPECT_HEADER, FORWARD, DISCARD};
|
||||
static ipv4_state state = INSPECT_HEADER;
|
||||
static ipv4_dest dest;
|
||||
static uint64_t internal_counter = 0;
|
||||
|
||||
packet_512_t packet_in = eth_in.read();
|
||||
|
||||
if (state == INSPECT_HEADER) {
|
||||
dest = DEST_IGNORE;
|
||||
packet_512_t packet_in;
|
||||
if (eth_in.read_nb(packet_in)) {
|
||||
if (state == INSPECT_HEADER) {
|
||||
dest = DEST_IGNORE;
|
||||
ap_uint<4> ip_version = packet_in.data(eth_payload_pos + 8 - 1, eth_payload_pos + 4);
|
||||
ap_uint<8> ipv4_protocol = packet_in.data(eth_payload_pos + 80 - 1, eth_payload_pos + 72);
|
||||
|
||||
ap_uint<32> ipv4_dest_ip = packet_in.data(eth_payload_pos + 128 + 31, eth_payload_pos + 128);
|
||||
ap_uint<16> ipv4_header_checksum_check = computeCheckSum20B(packet_in.data(eth_payload_pos + 159, eth_payload_pos));
|
||||
ap_uint<16> ipv4_header_checksum_check = computeCheckSum20B(
|
||||
packet_in.data(eth_payload_pos + 159, eth_payload_pos));
|
||||
|
||||
if ((ip_version == 4) && (ipv4_dest_ip == fpga_ipv4_addr) && (ipv4_header_checksum_check == 0)) {
|
||||
if ((ip_version == 4)
|
||||
&& ((ipv4_dest_ip == fpga_ipv4_addr) ||
|
||||
(packet_in.id == AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK)) // don't check IPv4 address for 4x10G
|
||||
&& (ipv4_header_checksum_check == 0)) {
|
||||
// IP is version 4 + IP address is correct + checksum is OK
|
||||
// Possibly the conditions can be relaxed for broadcast ICMP
|
||||
if (ipv4_protocol == PROTOCOL_UDP) {
|
||||
state = FORWARD;
|
||||
dest = DEST_UDP;
|
||||
} else if ((ipv4_protocol == PROTOCOL_ICMP) && (packet_in.id == AXI_STREAM_ID_ENABLE_ARP_ICMP)) {
|
||||
} else if ((ipv4_protocol == PROTOCOL_ICMP) && (packet_in.id == AXI_STREAM_ID_FULL_NETWORK_STACK)) {
|
||||
state = FORWARD;
|
||||
dest = DEST_ICMP;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
switch (dest) {
|
||||
case DEST_UDP:
|
||||
udp_out.write(packet_in);
|
||||
break;
|
||||
case DEST_ICMP:
|
||||
icmp_out.write(packet_in);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (dest) {
|
||||
case DEST_UDP:
|
||||
udp_out.write(packet_in);
|
||||
break;
|
||||
case DEST_ICMP:
|
||||
icmp_out.write(packet_in);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (packet_in.last) {
|
||||
state = INSPECT_HEADER;
|
||||
internal_counter++;
|
||||
if (packet_in.last)
|
||||
state = INSPECT_HEADER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-15
@@ -1,10 +1,15 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#ifndef JFJOCH_HLS_NOSYNTH
|
||||
#include <hls_math.h>
|
||||
#else
|
||||
namespace hls {
|
||||
inline float recip(float f) {return 1.0f/f;}
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "hls_jfjoch.h"
|
||||
|
||||
#define HBM_BURST 16
|
||||
|
||||
// HBM and in-memory order:
|
||||
// (HBM) p0, p1 - gain G0
|
||||
// (HBM) p2, p3 - gain G1
|
||||
@@ -21,6 +26,7 @@ ap_uint<576> convert(ap_uint<512> data_in,
|
||||
ap_uint<256> packed_pedeG1_1, ap_uint<256> packed_pedeG1_2,
|
||||
ap_uint<256> packed_pedeG2_1, ap_uint<256> packed_pedeG2_2,
|
||||
ap_uint<1> save_raw,
|
||||
ap_uint<1> fixed_g1,
|
||||
one_over_energy_t one_over_energy_in_keV)
|
||||
{
|
||||
#pragma HLS PIPELINE
|
||||
@@ -51,14 +57,17 @@ ap_uint<576> convert(ap_uint<512> data_in,
|
||||
for (int i = 0; i < 32; i++) {
|
||||
ap_uint<2> gain = in_val[i](15,14);
|
||||
if (save_raw) for (int j = 0; j < 16; j++) out_val[i][j] = in_val[i][j];
|
||||
else if (gainG0[i] == 0) out_val[i] = INT18_MIN; // if G0 gain factor is zero - mask pixel
|
||||
else if (in_val[i] == 0xc000) out_val[i] = INT18_MAX; // can saturate G2 - overload
|
||||
else if ((gain == 0) && (gainG0[i] == 0)) out_val[i] = INT18_MIN; // if G0 gain factor is zero - mask pixel
|
||||
else if ((gain == 1) && (gainG1[i] == 0)) out_val[i] = INT18_MIN; // if G1 gain factor is zero - mask pixel
|
||||
else if ((gain == 3) && (gainG2[i] == 0)) out_val[i] = INT18_MIN; // if G2 gain factor is zero - mask pixel
|
||||
else if (in_val[i] == 0xc000) out_val[i] = fixed_g1 ? INT18_MIN : INT18_MAX; // can saturate G2 - overload (but not when fixed G1)
|
||||
else if (in_val[i] == 0xffff) out_val[i] = INT18_MIN; //error
|
||||
else if (in_val[i] == 0x4000) out_val[i] = INT18_MIN; //cannot saturate G1 - error
|
||||
else if (in_val[i] == 0x4000) out_val[i] = fixed_g1 ? INT18_MAX : INT18_MIN; // Cannot saturate G1 - error (but it is possible in fixed G1 mode)
|
||||
else if (gain == 2) out_val[i] = INT18_MIN; // invalid gain
|
||||
else if ((pedeG0[i] > 16383) && (gain == 0)) out_val[i] = INT18_MIN;
|
||||
else if ((pedeG1[i] > 16383) && (gain == 1)) out_val[i] = INT18_MIN;
|
||||
else if ((pedeG2[i] > 16383) && (gain == 3)) out_val[i] = INT18_MIN;
|
||||
else if ((gain != 1) && fixed_g1) out_val[i] = INT18_MIN; // With fixed gain G1, don't expected anything else!
|
||||
else {
|
||||
ap_fixed<18,16, AP_RND_CONV> val_diff = 0;
|
||||
ap_ufixed<25,6,AP_RND_CONV> val_gain = 0;
|
||||
@@ -67,7 +76,10 @@ ap_uint<576> convert(ap_uint<512> data_in,
|
||||
val_diff = adu - pedeG0[i];
|
||||
val_gain = ap_ufixed<25,6,AP_RND_CONV>(gainG0[i]) / 32;
|
||||
} else if (gain == 1) {
|
||||
val_diff = pedeG1[i] - adu;
|
||||
if (fixed_g1)
|
||||
val_diff = adu - pedeG1[i];
|
||||
else
|
||||
val_diff = pedeG1[i] - adu;
|
||||
val_gain = gainG1[i];
|
||||
} else {
|
||||
val_diff = pedeG2[i] - adu;
|
||||
@@ -132,19 +144,24 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
|
||||
|
||||
packet_512_t packet_in;
|
||||
packet_576_t packet_out;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
packet_out.data = packet_in.data;
|
||||
packet_out.last = packet_in.last;
|
||||
packet_out.user = packet_in.user;
|
||||
data_out << packet_out;
|
||||
ap_wait();
|
||||
}
|
||||
|
||||
data_in >> packet_in;
|
||||
packet_out.data = packet_in.data;
|
||||
packet_out.last = packet_in.last;
|
||||
packet_out.user = packet_in.user;
|
||||
data_out << packet_out;
|
||||
|
||||
float_uint32 in_one_over_energy;
|
||||
float_uint32 in_energy_kev;
|
||||
|
||||
ap_uint<64> mode = ACT_REG_MODE(packet_in.data);
|
||||
ap_uint<1> conversion = (mode & MODE_CONV) ? 1 : 0;
|
||||
ap_uint<1> fixed_g1 = (mode & MODE_FIXG1) ? 1 : 0;
|
||||
ap_uint<6> modules = ACT_REG_NMODULES(packet_in.data) + 1;
|
||||
in_one_over_energy.u = ACT_REG_ONE_OVER_ENERGY(packet_in.data);
|
||||
in_energy_kev.u = ACT_REG_ENERGY_KEV_FLOAT(packet_in.data);
|
||||
ap_uint<5> storage_cells = ACT_REG_NSTORAGE_CELLS(packet_in.data);
|
||||
|
||||
ap_uint<32> offset_hbm_0 = 0 * hbm_size_bytes / 32;
|
||||
@@ -160,7 +177,7 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
|
||||
ap_uint<32> offset_hbm_10 = 10 * hbm_size_bytes / 32;
|
||||
ap_uint<32> offset_hbm_11 = 11 * hbm_size_bytes / 32;
|
||||
|
||||
one_over_energy_t one_over_energy = in_one_over_energy.f;
|
||||
one_over_energy_t one_over_energy = hls::recip(in_energy_kev.f);
|
||||
|
||||
if (conversion) {
|
||||
axis_completion cmpl;
|
||||
@@ -216,6 +233,7 @@ void jf_conversion(STREAM_512 &data_in, STREAM_576 &data_out,
|
||||
packed_pedeG1_1, packed_pedeG1_2,
|
||||
packed_pedeG2_1, packed_pedeG2_2,
|
||||
packet_in.id[0],
|
||||
fixed_g1,
|
||||
one_over_energy);
|
||||
packet_out.last = packet_in.last;
|
||||
packet_out.user = packet_in.user;
|
||||
|
||||
+143
-92
@@ -1,46 +1,97 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#ifndef JFJOCH_HLS_NOSYNTH
|
||||
#include <hls_math.h>
|
||||
#else
|
||||
#include <cmath>
|
||||
namespace hls {
|
||||
inline bool isfinite(float f) {return std::isfinite(f);}
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "hls_jfjoch.h"
|
||||
|
||||
// Loads calibration from host memory based on 64-bit memory addresses loaded in in_mem_location
|
||||
// Expected structure in in_mem_location array:
|
||||
//
|
||||
// * gain factors for module m at location: 2 + gain level * NMODULES + m
|
||||
// * pedestal factors for module m and storage cell s at location: 2 + 3 * NMODULES + (gain level * 16 + s ) * NMODULES + m
|
||||
#define o(field) offsetof(ModuleStatistics, field)
|
||||
#define sf(msg, field, s) msg(o(field)*8 + s - 1, o(field)*8)
|
||||
|
||||
void read_config(hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
|
||||
ap_uint<32> &destination,
|
||||
ap_uint<16> &module_id) {
|
||||
#pragma HLS INLINE OFF
|
||||
ap_axiu<512, 1, 1, 1> data_packet;
|
||||
host_memory_in >> data_packet;
|
||||
|
||||
module_id = sf(data_packet.data, module_number, 32);
|
||||
destination = sf(data_packet.data, load_calibration_destination, 32);
|
||||
}
|
||||
|
||||
void read_module(ap_uint<256> *d_hbm_p0,
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
|
||||
size_t offset_hbm_0,
|
||||
size_t offset_hbm_1) {
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
|
||||
size_t offset_hbm_0,
|
||||
size_t offset_hbm_1) {
|
||||
#pragma HLS INLINE OFF
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(int16_t) / 64; i++) {
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(int16_t) / 64; i++) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
ap_axiu<512, 1, 1, 1> data_packet;
|
||||
host_memory_in >> data_packet;
|
||||
ap_axiu<512, 1, 1, 1> data_packet;
|
||||
host_memory_in >> data_packet;
|
||||
|
||||
d_hbm_p0[offset_hbm_0 + i] = data_packet.data(255, 0);
|
||||
d_hbm_p1[offset_hbm_1 + i] = data_packet.data(511, 256);
|
||||
}
|
||||
d_hbm_p0[offset_hbm_0 + i] = data_packet.data(255, 0);
|
||||
d_hbm_p1[offset_hbm_1 + i] = data_packet.data(511, 256);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, int MULT> ap_uint<256> convert(const ap_uint<512> &in) {
|
||||
//#pragma HLS INLINE
|
||||
ap_uint<256> tmp;
|
||||
for (int j = 0; j < 16; j++) {
|
||||
float_uint32 conv{};
|
||||
conv.u = in(j * 32 + 31, j * 32);
|
||||
float x = conv.f * MULT;
|
||||
T g;
|
||||
if (!hls::isfinite(x) || (x < 0.0))
|
||||
g = 0;
|
||||
else
|
||||
g = static_cast<T>(x);
|
||||
|
||||
for (int k = 0; k < 16; k++)
|
||||
tmp[j * 16 + k] = g[k];
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <class T, int MULT = 1>
|
||||
void read_module_float(ap_uint<256> *d_hbm_p0,
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
|
||||
size_t offset_hbm_0,
|
||||
size_t offset_hbm_1) {
|
||||
#pragma HLS INLINE OFF
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(int16_t) / 64; i++) {
|
||||
#pragma HLS PIPELINE II=2
|
||||
ap_axiu<512, 1, 1, 1> data_packet;
|
||||
|
||||
ap_uint<256> tmp;
|
||||
host_memory_in >> data_packet;
|
||||
d_hbm_p0[offset_hbm_0 + i] = convert<T, MULT>(data_packet.data);
|
||||
|
||||
host_memory_in >> data_packet;
|
||||
d_hbm_p1[offset_hbm_1 + i] = convert<T, MULT>(data_packet.data);
|
||||
}
|
||||
}
|
||||
|
||||
int load_calibration(ap_uint<256> *d_hbm_p0,
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
ap_uint<8> modules,
|
||||
ap_uint<5> storage_cells,
|
||||
ap_uint<32> hbm_size_bytes,
|
||||
ap_uint<8> destination,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_in_cmd,
|
||||
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
|
||||
const uint64_t *dma_address_table) {
|
||||
ap_uint<256> *d_hbm_p1,
|
||||
const LoadCalibrationConfig &config,
|
||||
ap_uint<32> hbm_size_bytes,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_in_cmd,
|
||||
hls::stream<ap_axiu<512,1,1,1> > &host_memory_in,
|
||||
const uint64_t *dma_address_table) {
|
||||
#pragma HLS INTERFACE mode=s_axilite port=return
|
||||
#pragma HLS INTERFACE register both axis port=datamover_in_cmd
|
||||
#pragma HLS INTERFACE register both axis port=host_memory_in
|
||||
|
||||
#pragma HLS INTERFACE mode=s_axilite port=modules
|
||||
#pragma HLS INTERFACE mode=s_axilite port=storage_cells
|
||||
#pragma HLS INTERFACE mode=s_axilite port=destination
|
||||
#pragma HLS INTERFACE mode=s_axilite port=config
|
||||
#pragma HLS INTERFACE mode=ap_none port=hbm_size_bytes
|
||||
|
||||
#pragma HLS INTERFACE mode=m_axi port=d_hbm_p0 bundle=d_hbm_p0 depth=512 offset=off \
|
||||
@@ -50,78 +101,78 @@ int load_calibration(ap_uint<256> *d_hbm_p0,
|
||||
#pragma HLS INTERFACE mode=m_axi port=dma_address_table bundle=dma_address_table depth=65536 offset=off \
|
||||
max_read_burst_length=2 max_write_burst_length=2 latency=10 num_write_outstanding=1 num_read_outstanding=1
|
||||
|
||||
if ((modules == 0) || (modules > MAX_MODULES_FPGA))
|
||||
return 1;
|
||||
uint64_t mem_addr = dma_address_table[config.handle];
|
||||
if (mem_addr == 0)
|
||||
return LOAD_CALIBRATION_ERR_HOST_ADDR;
|
||||
|
||||
if (destination == LOAD_CALIBRATION_DEST_CALIB) {
|
||||
if ((storage_cells == 0) || (storage_cells > 16))
|
||||
return 1;
|
||||
setup_datamover(datamover_in_cmd, mem_addr + offsetof(DeviceOutput, module_statistics), 64);
|
||||
ap_uint<16> module_id;
|
||||
ap_uint<32> destination;
|
||||
read_config(host_memory_in, destination, module_id);
|
||||
|
||||
for (int i = 0; i < 3 * (modules + storage_cells * modules); i++) {
|
||||
if (dma_address_table[i] == 0)
|
||||
return 2;
|
||||
}
|
||||
if (module_id > 2 * hbm_size_bytes / (RAW_MODULE_SIZE * sizeof(int16_t)))
|
||||
return LOAD_CALIBRATION_ERR_MODULE;
|
||||
|
||||
for (int i = 0; i < 3 * (modules + storage_cells * modules); i++)
|
||||
setup_datamover(datamover_in_cmd, dma_address_table[i], RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
size_t offset_hbm_0;
|
||||
size_t offset_hbm_1;
|
||||
|
||||
for (int c = 0; c < 3; c++) {
|
||||
for (int m = 0; m < modules; m++) {
|
||||
#pragma HLS PIPELINE OFF
|
||||
size_t offset_hbm_0 = (2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
size_t offset_hbm_1 = (2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < 3; c++) {
|
||||
for (int m = 0; m < modules * storage_cells; m++) {
|
||||
#pragma HLS PIPELINE OFF
|
||||
size_t offset_hbm_0 = (6 + 2 * c) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
size_t offset_hbm_1 =
|
||||
(6 + 2 * c + 1) * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
}
|
||||
}
|
||||
} else if (destination == LOAD_CALIBRATION_DEST_INTEGRATION) {
|
||||
// load maps
|
||||
|
||||
for (int i = 0; i < 2 * modules; i++) {
|
||||
if (dma_address_table[i] == 0)
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2 * modules; i++)
|
||||
setup_datamover(datamover_in_cmd, dma_address_table[i], RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
|
||||
for (int m = 0; m < modules; m++) {
|
||||
#pragma HLS PIPELINE OFF
|
||||
size_t offset_hbm_0 = 16 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
size_t offset_hbm_1 = 17 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
switch (destination) {
|
||||
case LOAD_CALIBRATION_DEST_GAIN_G0:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(float));
|
||||
offset_hbm_0 = 0 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 1 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module_float<gainG0_t, GAIN_G0_MULTIPLIER>(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_GAIN_G1:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(float));
|
||||
offset_hbm_0 = 2 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 3 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module_float<gainG1_t, GAIN_G1_MULTIPLIER>(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_GAIN_G2:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(float));
|
||||
offset_hbm_0 = 4 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 5 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module_float<gainG2_t, GAIN_G2_MULTIPLIER>(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_PEDESTAL_G0:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
offset_hbm_0 = 6 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 7 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
}
|
||||
// load weights
|
||||
for (int m = 0; m < modules; m++) {
|
||||
#pragma HLS PIPELINE OFF
|
||||
size_t offset_hbm_0 = 18 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
size_t offset_hbm_1 = 19 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_PEDESTAL_G1:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
offset_hbm_0 = 8 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 9 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
}
|
||||
} else if (destination == LOAD_CALIBRATION_DEST_FRAME_GEN) {
|
||||
for (int i = 0; i < modules; i++) {
|
||||
if (dma_address_table[i] == 0)
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < modules; i++)
|
||||
setup_datamover(datamover_in_cmd, dma_address_table[i], RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
|
||||
for (int m = 0; m < modules; m++) {
|
||||
#pragma HLS PIPELINE OFF
|
||||
size_t offset_hbm_0 = 20 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
size_t offset_hbm_1 = 21 * hbm_size_bytes / 32 + m * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_PEDESTAL_G2:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
offset_hbm_0 = 10 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 11 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
}
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_INTEGRATION_MAP:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
offset_hbm_0 = 16 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 17 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_INTEGRATION_WEIGHTS:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(float));
|
||||
offset_hbm_0 = 18 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 19 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module_float<integration_factor_t>(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
break;
|
||||
case LOAD_CALIBRATION_DEST_FRAME_GEN:
|
||||
setup_datamover(datamover_in_cmd, mem_addr, RAW_MODULE_SIZE * sizeof(int16_t));
|
||||
offset_hbm_0 = 20 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
offset_hbm_1 = 21 * hbm_size_bytes / 32 + module_id * RAW_MODULE_SIZE * sizeof(int16_t) / 64;
|
||||
read_module(d_hbm_p0, d_hbm_p1, host_memory_in, offset_hbm_0, offset_hbm_1);
|
||||
break;
|
||||
default:
|
||||
return LOAD_CALIBRATION_ERR_DEST;
|
||||
}
|
||||
return 0;
|
||||
return LOAD_CALIBRATION_OK;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ void load_from_hbm(STREAM_512 &data_in,
|
||||
hls::stream<ap_axiu<256,1,1,1> > &hbm_in_1,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_0_cmd,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_1_cmd,
|
||||
volatile ap_uint<1> &idle,
|
||||
ap_uint<32> hbm_size_bytes) {
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
#pragma HLS INTERFACE register both axis port=data_in
|
||||
@@ -22,15 +23,25 @@ void load_from_hbm(STREAM_512 &data_in,
|
||||
#pragma HLS INTERFACE register both axis port=hbm_in_1
|
||||
#pragma HLS INTERFACE register both axis port=datamover_0_cmd
|
||||
#pragma HLS INTERFACE register both axis port=datamover_1_cmd
|
||||
#pragma HLS INTERFACE register ap_none port=idle
|
||||
|
||||
#pragma HLS INTERFACE mode=ap_none port=hbm_size_bytes
|
||||
|
||||
idle = 1;
|
||||
|
||||
for (ap_uint<16> i = 0; i < hbm_size_bytes * 4 / (RAW_MODULE_SIZE * sizeof(uint16_t)); i++)
|
||||
m_axis_free_handles << i;
|
||||
packet_512_t packet;
|
||||
|
||||
packet_512_t packet;
|
||||
data_in >> packet;
|
||||
data_out << packet;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet;
|
||||
ap_wait();
|
||||
data_out << packet;
|
||||
ap_wait();
|
||||
idle = 0;
|
||||
ap_wait();
|
||||
}
|
||||
|
||||
ap_uint<32> offset_hbm_0 = 12 * hbm_size_bytes / 32;
|
||||
ap_uint<32> offset_hbm_1 = 14 * hbm_size_bytes / 32;
|
||||
@@ -76,4 +87,5 @@ void load_from_hbm(STREAM_512 &data_in,
|
||||
|
||||
data_in >> packet;
|
||||
data_out << packet;
|
||||
idle = 1;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,13 @@ void mask_missing(STREAM_512 &data_in,
|
||||
#pragma HLS INTERFACE register both axis port=s_axis_completion
|
||||
|
||||
packet_512_t packet;
|
||||
data_in >> packet;
|
||||
data_out << packet;
|
||||
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet;
|
||||
ap_wait();
|
||||
data_out << packet;
|
||||
ap_wait();
|
||||
}
|
||||
axis_completion cmpl;
|
||||
s_axis_completion >> cmpl;
|
||||
while (!cmpl.last) {
|
||||
|
||||
+12
-5
@@ -28,10 +28,11 @@ ap_uint<512> pack_and_reduce(const packed_pedestal_g0_t &in) {
|
||||
|
||||
unpack(in, tmp_full);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
ap_ufixed<16,14, AP_RND_CONV> tmp1 = tmp_full[i]; // returns limited precision!
|
||||
for (int j = 0; j < 16; j++) {
|
||||
ap_uint<16> tmp1 = tmp_full[i] + pedestal_g0_t(0.5); // returns only integer part
|
||||
if (tmp_full[i] > 16383)
|
||||
tmp1 = 16384;
|
||||
for (int j = 0; j < 16; j++)
|
||||
out[i*16+j] = tmp1[j];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -124,11 +125,17 @@ void pedestal(STREAM_512 &data_in, STREAM_512 &data_out,
|
||||
frame_count[i] = 0;
|
||||
|
||||
packet_512_t packet;
|
||||
data_in >> packet;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet;
|
||||
ap_wait();
|
||||
data_out << packet;
|
||||
ap_wait();
|
||||
}
|
||||
|
||||
ap_uint<8> conversion_mode = ACT_REG_MODE(packet.data);
|
||||
ap_uint<8> nmodules = ACT_REG_NMODULES(packet.data) + 1;
|
||||
ap_uint<5> nstoragecells = ACT_REG_NSTORAGE_CELLS(packet.data);
|
||||
data_out << packet;
|
||||
|
||||
ap_uint<1> pedestal_mode = ((conversion_mode & MODE_PEDESTAL_G0) != 0)
|
||||
|| ((conversion_mode & MODE_PEDESTAL_G1) != 0)
|
||||
|
||||
@@ -11,6 +11,7 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
hls::stream<ap_axiu<256,1,1,1> > &hbm_out_1,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_0_cmd,
|
||||
hls::stream<axis_datamover_ctrl> &datamover_1_cmd,
|
||||
volatile ap_uint<1> &idle,
|
||||
ap_uint<32> hbm_size_bytes) {
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
#pragma HLS INTERFACE register both axis port=data_in
|
||||
@@ -23,6 +24,9 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
#pragma HLS INTERFACE register both axis port=datamover_0_cmd
|
||||
#pragma HLS INTERFACE register both axis port=datamover_1_cmd
|
||||
#pragma HLS INTERFACE mode=ap_none port=hbm_size_bytes
|
||||
#pragma HLS INTERFACE register ap_none port=idle
|
||||
|
||||
idle = 1;
|
||||
|
||||
axis_completion cmpl[MAX_MODULES_FPGA*2];
|
||||
|
||||
@@ -34,12 +38,21 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
}
|
||||
|
||||
packet_512_t packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << packet_in;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_in;
|
||||
ap_wait();
|
||||
idle = 0;
|
||||
ap_wait();
|
||||
}
|
||||
|
||||
ap_uint<32> offset_hbm_0 = 12 * hbm_size_bytes / 32;
|
||||
ap_uint<32> offset_hbm_1 = 14 * hbm_size_bytes / 32;
|
||||
|
||||
data_in >> packet_in;
|
||||
|
||||
axis_addr addr;
|
||||
addr_in >> addr;
|
||||
|
||||
@@ -82,8 +95,6 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
setup_datamover(datamover_1_cmd, (offset_hbm_1 + offset) * 32, 4096);
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
data_in >> packet_in;
|
||||
|
||||
ap_axiu<256,1,1,1> packet_out;
|
||||
packet_out.keep = UINT32_MAX;
|
||||
packet_out.strb = UINT32_MAX;
|
||||
@@ -97,6 +108,8 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
|
||||
packet_out.data = packet_in.data(511, 256);
|
||||
hbm_out_1 << packet_out;
|
||||
|
||||
data_in >> packet_in;
|
||||
}
|
||||
|
||||
addr_in >> addr;
|
||||
@@ -117,7 +130,6 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
}
|
||||
}
|
||||
|
||||
data_in >> packet_in;
|
||||
data_out << packet_in;
|
||||
|
||||
m_axis_completion << axis_completion{.last = 1};
|
||||
@@ -125,4 +137,6 @@ void save_to_hbm(STREAM_512 &data_in,
|
||||
ap_uint<16> tmp = s_axis_free_handles.read();
|
||||
while (tmp != UINT16_MAX)
|
||||
tmp = s_axis_free_handles.read();
|
||||
|
||||
idle = 1;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ void sls_detector(AXI_STREAM &udp_payload_in,
|
||||
uint64_t& counter,
|
||||
uint32_t& counter_eth_error,
|
||||
uint32_t& counter_len_error,
|
||||
volatile ap_uint<1> &in_clear_counters) {
|
||||
volatile ap_uint<1> &in_clear_counters,
|
||||
volatile ap_uint<1> &idle) {
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
|
||||
#pragma HLS INTERFACE axis register both port=udp_payload_in
|
||||
@@ -21,6 +22,7 @@ void sls_detector(AXI_STREAM &udp_payload_in,
|
||||
#pragma HLS INTERFACE ap_vld register port=counter_eth_error
|
||||
#pragma HLS INTERFACE ap_vld register port=counter_len_error
|
||||
#pragma HLS INTERFACE ap_none register port=in_clear_counters
|
||||
#pragma HLS INTERFACE ap_none register port=idle
|
||||
|
||||
#pragma HLS pipeline II=1 style=flp
|
||||
|
||||
@@ -54,6 +56,9 @@ void sls_detector(AXI_STREAM &udp_payload_in,
|
||||
#pragma HLS RESET variable=internal_counter_len_error
|
||||
#pragma HLS RESET variable=state
|
||||
|
||||
if (state == INSPECT_HEADER && udp_metadata_in.empty())
|
||||
return;
|
||||
|
||||
if (udp_payload_in.read_nb(packet_in)) {
|
||||
|
||||
switch (state) {
|
||||
@@ -110,4 +115,9 @@ void sls_detector(AXI_STREAM &udp_payload_in,
|
||||
counter = internal_counter;
|
||||
counter_eth_error = internal_counter_eth_error;
|
||||
counter_len_error = internal_counter_len_error;
|
||||
|
||||
if (state == INSPECT_HEADER)
|
||||
idle = 1;
|
||||
else
|
||||
idle = 0;
|
||||
}
|
||||
+40
-19
@@ -27,8 +27,13 @@ struct spot_finder_packet {
|
||||
void spot_finder_in_stream(STREAM_768 &data_in,
|
||||
hls::stream<spot_finder_packet> &data_out) {
|
||||
packet_768_t packet_in;
|
||||
data_in >> packet_in;
|
||||
data_out << spot_finder_packet{.data = packet_in.data, .user = packet_in.user, .last = packet_in.last};
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << spot_finder_packet{.data = packet_in.data, .user = packet_in.user, .last = packet_in.last};
|
||||
ap_wait();
|
||||
}
|
||||
data_in >> packet_in;
|
||||
while (!packet_in.user) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
@@ -96,9 +101,12 @@ void spot_finder_prepare(hls::stream<spot_finder_packet> &data_in,
|
||||
hls::stream<ap_int<SUM2_BITWIDTH>> &sum2_out,
|
||||
hls::stream<ap_int<VALID_BITWIDTH>> &valid_out) {
|
||||
spot_finder_packet packet;
|
||||
data_in >> packet;
|
||||
data_out << packet;
|
||||
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet;
|
||||
data_out << packet;
|
||||
ap_wait();
|
||||
}
|
||||
ap_int<SUM_BITWIDTH> sum[32];
|
||||
ap_int<SUM2_BITWIDTH> sum2[32];
|
||||
ap_int<VALID_BITWIDTH> valid[32];
|
||||
@@ -139,7 +147,7 @@ void spot_finder_prepare(hls::stream<spot_finder_packet> &data_in,
|
||||
}
|
||||
|
||||
ap_uint<32> spot_finder_snr_threshold(ap_int<24> val[32],
|
||||
ap_uint<16> snr_threshold_2,
|
||||
ap_ufixed<20,16, AP_RND_CONV> snr_threshold_2,
|
||||
ap_int<SUM_BITWIDTH> sum,
|
||||
ap_int<SUM2_BITWIDTH> sum2,
|
||||
ap_int<VALID_BITWIDTH> valid_count) {
|
||||
@@ -148,7 +156,7 @@ ap_uint<32> spot_finder_snr_threshold(ap_int<24> val[32],
|
||||
return UINT32_MAX;
|
||||
|
||||
ap_int<SUM2_BITWIDTH+12> variance = valid_count * sum2 - sum * sum; // This is variance * valid_count^2
|
||||
ap_int<SUM2_BITWIDTH+12+16> threshold = ((variance * snr_threshold_2 + 8) / (4*4));
|
||||
ap_fixed<SUM2_BITWIDTH+12+16+1, SUM2_BITWIDTH+12+16> threshold = variance * snr_threshold_2;
|
||||
// snr_threshold is in units of 0.25
|
||||
|
||||
ap_uint<32> ret = 0;
|
||||
@@ -172,8 +180,7 @@ ap_uint<32> spot_finder_snr_threshold(ap_int<24> val[32],
|
||||
return ret;
|
||||
}
|
||||
|
||||
ap_uint<32> spot_finder_count_threshold(ap_int<24> val[32],
|
||||
ap_int<16> &count_threshold) {
|
||||
ap_uint<32> spot_finder_count_threshold(ap_int<24> val[32], ap_int<32> &count_threshold) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
if (count_threshold <= 0)
|
||||
return UINT32_MAX;
|
||||
@@ -193,12 +200,17 @@ void spot_finder_apply_threshold(hls::stream<spot_finder_packet> &data_in,
|
||||
hls::stream<ap_int<SUM2_BITWIDTH>> &sum2_in,
|
||||
hls::stream<ap_int<VALID_BITWIDTH>> &valid_in,
|
||||
hls::stream<ap_axiu<32,1,1,1>> &strong_pixel_out,
|
||||
volatile ap_int<16> &in_count_threshold,
|
||||
volatile ap_uint<8> &in_snr_threshold) {
|
||||
volatile ap_int<32> &in_count_threshold,
|
||||
volatile ap_uint<32> &in_snr_threshold) {
|
||||
spot_finder_packet packet_in;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_768_t{.data = packet_in.data, .user = packet_in.user, .last = packet_in.last};
|
||||
ap_wait();
|
||||
}
|
||||
|
||||
data_in >> packet_in;
|
||||
data_out << packet_768_t{.data = packet_in.data, .user = packet_in.user, .last = packet_in.last};
|
||||
|
||||
ap_int<SUM_BITWIDTH> sum[32];
|
||||
ap_int<SUM2_BITWIDTH> sum2[32];
|
||||
@@ -206,9 +218,18 @@ void spot_finder_apply_threshold(hls::stream<spot_finder_packet> &data_in,
|
||||
|
||||
data_in >> packet_in;
|
||||
while (!packet_in.user) {
|
||||
ap_int<16> count_threshold = in_count_threshold;
|
||||
ap_uint<8> snr_threshold = in_snr_threshold;
|
||||
ap_uint<16> snr_threshold_2 = snr_threshold * snr_threshold;
|
||||
ap_int<32> count_threshold = in_count_threshold;
|
||||
ap_uint<32> snr_threshold_u32 = in_snr_threshold;
|
||||
float_uint32 thr;
|
||||
thr.u = snr_threshold_u32;
|
||||
ap_ufixed<10,8, AP_RND_CONV> snr_threshold = thr.f;
|
||||
if (thr.f > 255)
|
||||
snr_threshold = 255;
|
||||
else if (thr.f <= 0)
|
||||
snr_threshold = 0;
|
||||
else
|
||||
snr_threshold = thr.f;
|
||||
ap_ufixed<20,16, AP_RND_CONV> snr_threshold_2 = snr_threshold * snr_threshold;
|
||||
ap_uint<32> strong_pixel_count = 0;
|
||||
for (int i = 0; i < RAW_MODULE_SIZE * sizeof(uint16_t) / 64; i++) {
|
||||
#pragma HLS PIPELINE II=1
|
||||
@@ -236,7 +257,7 @@ void spot_finder_apply_threshold(hls::stream<spot_finder_packet> &data_in,
|
||||
|
||||
// Save module statistics
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = count_threshold, .user = 0};
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = snr_threshold, .user = 0};
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = snr_threshold_u32, .user = 0};
|
||||
strong_pixel_out << ap_axiu<32,1,1,1>{.data = strong_pixel_count, .user = 0};
|
||||
|
||||
for (int i = 0; i < 13; i++)
|
||||
@@ -250,8 +271,8 @@ void spot_finder_apply_threshold(hls::stream<spot_finder_packet> &data_in,
|
||||
void spot_finder(STREAM_768 &data_in,
|
||||
STREAM_768 &data_out,
|
||||
hls::stream<ap_axiu<32,1,1,1>> &strong_pixel_out,
|
||||
volatile ap_int<16> &in_count_threshold,
|
||||
volatile ap_uint<8> &in_snr_threshold) {
|
||||
volatile ap_int<32> &in_count_threshold,
|
||||
volatile ap_uint<32> &in_snr_threshold) {
|
||||
#pragma HLS INTERFACE axis port=data_in
|
||||
#pragma HLS INTERFACE axis port=data_out
|
||||
#pragma HLS INTERFACE axis port=strong_pixel_out
|
||||
|
||||
@@ -11,8 +11,10 @@ int main() {
|
||||
STREAM_768 output;
|
||||
hls::stream<ap_axiu<32, 1, 1, 1>> strong_pixel;
|
||||
|
||||
ap_int<16> in_photon_count_threshold = 8;
|
||||
ap_uint<8> in_strong_pixel_threshold = 16;
|
||||
ap_int<32> in_photon_count_threshold = 8;
|
||||
float_uint32 in_strong_pixel_threshold;
|
||||
in_strong_pixel_threshold.f = 4.0f;
|
||||
ap_uint<32> local_strong_pixel_threshold = in_strong_pixel_threshold.u;
|
||||
|
||||
std::vector<int32_t> input_frame(nframes * RAW_MODULE_SIZE);
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
@@ -33,8 +35,7 @@ int main() {
|
||||
|
||||
input << packet_768_t{.user = 1};
|
||||
|
||||
spot_finder(input, output, strong_pixel, in_photon_count_threshold,
|
||||
in_strong_pixel_threshold);
|
||||
spot_finder(input, output, strong_pixel, in_photon_count_threshold,local_strong_pixel_threshold);
|
||||
|
||||
if (input.size() != 0)
|
||||
ret = 1;
|
||||
|
||||
@@ -70,19 +70,33 @@ ap_uint<512> reduce_24_to_16_unsigned(ap_int<24*32> input) {
|
||||
return pack32(tmp16);
|
||||
}
|
||||
|
||||
void stream_24bit_conv(STREAM_768 &data_in, STREAM_512 &data_out) {
|
||||
void stream_24bit_conv(STREAM_768 &data_in,
|
||||
STREAM_512 &data_out,
|
||||
volatile ap_uint<1> &idle) {
|
||||
#pragma HLS INTERFACE axis register both port=data_in
|
||||
#pragma HLS INTERFACE axis register both port=data_out
|
||||
|
||||
#pragma HLS INTERFACE ap_none register port=idle
|
||||
|
||||
idle = 1;
|
||||
|
||||
packet_768_t packet_in;
|
||||
packet_512_t packet_out;
|
||||
|
||||
data_in >> packet_in;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_512_t{.data = packet_in.data, .user = 0, .last = 1};
|
||||
ap_wait();
|
||||
idle = 0;
|
||||
ap_wait();
|
||||
}
|
||||
|
||||
ap_uint<32> data_collection_mode = ACT_REG_MODE(packet_in.data);
|
||||
ap_uint<1> write_32bit = ((data_collection_mode & MODE_32BIT) ? 1 : 0);
|
||||
ap_uint<1> write_unsigned = ((data_collection_mode & MODE_UNSIGNED) ? 1 : 0);
|
||||
|
||||
data_out << packet_512_t{.data = packet_in.data, .user = 0, .last = 0};
|
||||
|
||||
|
||||
data_in >> packet_in;
|
||||
|
||||
@@ -122,4 +136,5 @@ void stream_24bit_conv(STREAM_768 &data_in, STREAM_512 &data_out) {
|
||||
}
|
||||
}
|
||||
data_out << packet_512_t{.data = packet_in.data, .user = 1, .last = 0};
|
||||
idle = 1;
|
||||
}
|
||||
|
||||
@@ -28,15 +28,15 @@ void stream_merge(AXI_STREAM &input_100g,
|
||||
bool rcv_eth_4x10g = input_4x10g.read_nb(packet_in_eth_4x10g);
|
||||
|
||||
if (data_source_local == STREAM_MERGE_SRC_100G) {
|
||||
packet_in_eth_100g.id = AXI_STREAM_ID_ENABLE_ARP_ICMP;
|
||||
packet_in_eth_100g.id = AXI_STREAM_ID_FULL_NETWORK_STACK;
|
||||
if (rcv_eth_100g)
|
||||
data_out.write(packet_in_eth_100g);
|
||||
} else if (data_source_local == STREAM_MERGE_SRC_4x10G) {
|
||||
packet_in_eth_4x10g.id = AXI_STREAM_ID_DISABLE_ARP_ICMP;
|
||||
packet_in_eth_4x10g.id = AXI_STREAM_ID_SIMPLIFIED_NETWORK_STACK;
|
||||
if (rcv_eth_4x10g)
|
||||
data_out.write(packet_in_eth_4x10g);
|
||||
} else if (data_source_local == STREAM_MERGE_SRC_FRAME_GEN) {
|
||||
packet_in_frame_gen.id = AXI_STREAM_ID_DISABLE_ARP_ICMP;
|
||||
packet_in_frame_gen.id = AXI_STREAM_ID_FULL_NETWORK_STACK;
|
||||
if (rcv_frame_gen)
|
||||
data_out.write(packet_in_frame_gen);
|
||||
}
|
||||
|
||||
+8
-3
@@ -13,13 +13,18 @@ void timer_host(STREAM_512 &data_in, STREAM_512 &data_out,
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
packet_512_t packet_in;
|
||||
|
||||
data_in >> packet_in;
|
||||
{
|
||||
#pragma HLS PROTOCOL fixed
|
||||
data_in >> packet_in;
|
||||
ap_wait();
|
||||
data_out << packet_in;
|
||||
ap_wait();
|
||||
}
|
||||
beats = 0;
|
||||
uint64_t stalls_internal = 0;
|
||||
stalls = 0;
|
||||
uint64_t beats_internal = 0;
|
||||
beats = 0;
|
||||
|
||||
data_out << packet_in;
|
||||
|
||||
data_in >> packet_in;
|
||||
while (!packet_in.user) {
|
||||
|
||||
+7
-1
@@ -7,7 +7,8 @@ void udp(AXI_STREAM ð_in,
|
||||
AXI_STREAM &udp_payload_out,
|
||||
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > &udp_metadata_out,
|
||||
uint64_t& counter,
|
||||
volatile ap_uint<1> &in_clear_counters) {
|
||||
volatile ap_uint<1> &in_clear_counters,
|
||||
volatile ap_uint<1> &idle) {
|
||||
|
||||
#pragma HLS INTERFACE ap_ctrl_none port=return
|
||||
|
||||
@@ -16,6 +17,7 @@ void udp(AXI_STREAM ð_in,
|
||||
#pragma HLS INTERFACE axis register both port=udp_metadata_out
|
||||
#pragma HLS INTERFACE ap_vld register port=counter
|
||||
#pragma HLS INTERFACE ap_none register port=in_clear_counters
|
||||
#pragma HLS INTERFACE ap_none register port=idle
|
||||
|
||||
#pragma HLS pipeline II=1 style=flp
|
||||
|
||||
@@ -89,5 +91,9 @@ void udp(AXI_STREAM ð_in,
|
||||
}
|
||||
|
||||
counter = internal_counter;
|
||||
if (state == INSPECT_HEADER)
|
||||
idle = 1;
|
||||
else
|
||||
idle = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
ADD_LIBRARY(JungfraujochDevice STATIC
|
||||
JungfraujochDevice.cpp JungfraujochDevice.h)
|
||||
ADD_LIBRARY(JungfraujochDevice STATIC JungfraujochDevice.cpp JungfraujochDevice.h ../include/jfjoch_fpga.h)
|
||||
|
||||
TARGET_LINK_LIBRARIES(JungfraujochDevice CommonFunctions)
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#ifndef JUNGFRAUJOCH_DEVICEOUTPUT_H
|
||||
#define JUNGFRAUJOCH_DEVICEOUTPUT_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../common/Definitions.h"
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct IntegrationResult {
|
||||
uint32_t count;
|
||||
float sum;
|
||||
};
|
||||
|
||||
struct SpotFindingResult {
|
||||
char strong_pixel[RAW_MODULE_SIZE / 8];
|
||||
int32_t count_threshold;
|
||||
int32_t snr_threshold;
|
||||
int32_t strong_pixel_count;
|
||||
int32_t reserved[13];
|
||||
};
|
||||
|
||||
struct ModuleStatistics {
|
||||
uint64_t frame_number;
|
||||
uint64_t timestamp;
|
||||
uint64_t bunchid;
|
||||
uint64_t reserved_1;
|
||||
uint64_t reserved_2;
|
||||
uint32_t exptime;
|
||||
uint32_t debug;
|
||||
uint32_t pedestal;
|
||||
uint32_t packet_count;
|
||||
uint32_t module_number;
|
||||
uint32_t reserved_3;
|
||||
uint64_t packet_mask[4]; // This is reserved for 256 packets/module
|
||||
};
|
||||
|
||||
struct DeviceOutput {
|
||||
int16_t pixels[RAW_MODULE_SIZE * 2]; // accommodate 32-bit output
|
||||
SpotFindingResult spot_finding_result;
|
||||
IntegrationResult integration_result[FPGA_INTEGRATION_BIN_COUNT];
|
||||
uint32_t adu_histogram[ADU_HISTO_BIN_COUNT];
|
||||
ModuleStatistics module_statistics;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif //JUNGFRAUJOCH_DEVICEOUTPUT_H
|
||||
@@ -3,7 +3,8 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../../common/Definitions.h"
|
||||
|
||||
#include "../include/jfjoch_fpga.h"
|
||||
#include "JungfraujochDevice.h"
|
||||
|
||||
#include "../../common/JFJochException.h"
|
||||
@@ -22,6 +23,11 @@ JungfraujochDevice::JungfraujochDevice(const std::string &device_name, bool writ
|
||||
auto action_type = GetDataCollectionStatus().action_type;
|
||||
if (action_type != ACTION_TYPE)
|
||||
throw JFJochException(JFJochExceptionCategory::PCIeError, "Wrong device type");
|
||||
|
||||
auto action_release = GetDataCollectionStatus().release_level;
|
||||
if (action_release != RELEASE_LEVEL)
|
||||
throw JFJochException(JFJochExceptionCategory::PCIeError, "Mismatch of FPGA release between driver and library");
|
||||
|
||||
}
|
||||
|
||||
JungfraujochDevice::~JungfraujochDevice() {
|
||||
@@ -88,6 +94,8 @@ uint32_t JungfraujochDevice::GetNumaNode() const {
|
||||
}
|
||||
|
||||
void JungfraujochDevice::SetConfig(const DataCollectionConfig &config) {
|
||||
if (config.nframes > MAX_FRAMES)
|
||||
throw PCIeDeviceException("Cannot handle this many frames");
|
||||
if (ioctl(fd, IOCTL_JFJOCH_SET_CONFIG, &config) != 0)
|
||||
throw PCIeDeviceException("Failed writing config");
|
||||
}
|
||||
@@ -167,31 +175,11 @@ uint32_t JungfraujochDevice::ReadRegister(uint32_t addr) const {
|
||||
return config.val;
|
||||
}
|
||||
|
||||
void JungfraujochDevice::LoadCalibration(uint32_t modules, uint32_t storage_cells) {
|
||||
DataCollectionConfig config{
|
||||
.nmodules = modules,
|
||||
.nstorage_cells = storage_cells
|
||||
};
|
||||
void JungfraujochDevice::LoadCalibration(const LoadCalibrationConfig &config) {
|
||||
if (ioctl(fd, IOCTL_JFJOCH_LOAD_CALIB, &config) != 0)
|
||||
throw PCIeDeviceException("Failed uploading calibration");
|
||||
}
|
||||
|
||||
void JungfraujochDevice::LoadInternalGeneratorFrame(uint32_t modules) {
|
||||
DataCollectionConfig config{
|
||||
.nmodules = modules
|
||||
};
|
||||
if (ioctl(fd, IOCTL_JFJOCH_LOAD_INT_GEN, &config) != 0)
|
||||
throw PCIeDeviceException("Failed uploading internal generator frame");
|
||||
}
|
||||
|
||||
void JungfraujochDevice::LoadIntegrationMap(uint32_t modules) {
|
||||
DataCollectionConfig config{
|
||||
.nmodules = modules,
|
||||
};
|
||||
if (ioctl(fd, IOCTL_JFJOCH_LOAD_INT_MAP, &config) != 0)
|
||||
throw PCIeDeviceException("Failed uploading integration map");
|
||||
}
|
||||
|
||||
DeviceOutput *JungfraujochDevice::MapKernelBuffer(uint32_t id) {
|
||||
auto tmp = (DeviceOutput *) mmap(nullptr, FPGA_BUFFER_LOCATION_SIZE,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#define JUNGFRAUJOCH_JUNGFRAUJOCHDEVICE_H
|
||||
|
||||
#include <string>
|
||||
#include "../pcie_driver/ActionConfig.h"
|
||||
#include "DeviceOutput.h"
|
||||
#include "../include/jfjoch_fpga.h"
|
||||
|
||||
struct JungfraujochDeviceCompletion {
|
||||
uint16_t data_collection_id;
|
||||
@@ -91,15 +90,7 @@ public:
|
||||
|
||||
// Load calibration parameters
|
||||
// Function is synchronous - it will return when loading is done
|
||||
void LoadCalibration(uint32_t modules, uint32_t storage_cells);
|
||||
// Load frames for internal generator
|
||||
// Must be placed in first <modules> kernel buffer locations
|
||||
// Function is synchronous - it will return when loading is done
|
||||
void LoadInternalGeneratorFrame(uint32_t modules);
|
||||
// Load map of radial integration
|
||||
// Must be placed in first <modules> kernel buffer locations
|
||||
// Function is synchronous - it will return when loading is done
|
||||
void LoadIntegrationMap(uint32_t modules);
|
||||
void LoadCalibration(const LoadCalibrationConfig &config);
|
||||
|
||||
void SetSpotFinderParameters(const SpotFinderParameters ¶ms);
|
||||
SpotFinderParameters GetSpotFinderParameters();
|
||||
|
||||
@@ -27,20 +27,39 @@ The first step for using the card is configuring network. To use network, one ne
|
||||
|
||||
The card will receive MAC address automatically based on Xilinx assigned number, but IPv4 address has to be configured with `JungfraujochDevice::SetIPv4Address()` function. The card is equipped with a simple network stack - if both MAC and IPv4 addresses are set and 100G interface is used, the card will periodically send ARP gratuitous messages, it will also reply to ARP requests and to ICMP pings. Given 4x10G interface is designed for direct Jungfraujoch-detector configuration, without a switch, diagnostics functionality is not offered here at the moment.
|
||||
|
||||
### Mapping kernel buffers
|
||||
Next, kernel buffers need to be mapped to the user space. These buffers are allocated with memory physically continuous, simplyfing operation of the card and the driver. Count of these buffers can be checked with `JungfraujochDevice::GetBufferCount()` function. Buffers can be mapped with `JungfraujochDevice::MapKernelBuffer()` function and deallocated with `JungfraujochDevice::UnmapKernelBuffer()` functions. Structure of the kernel buffer is `DeviceOutput` and described in [include/jfjoch_fpga.h](../include/jfjoch_fpga.h) header file.
|
||||
|
||||
### Uploading calibration
|
||||
Will be contributed later, as there is planned modification to the interface
|
||||
Uploading calibration goes with two steps:
|
||||
|
||||
1. Copy the calibration data into one of kernel buffers mapped with `JungfraujochDevice::MapKernelBuffer()`. It requires to cast `DeviceOutput::pixels` element into a particular type (`float` or `uint16_t`).
|
||||
2. Execute `JungfraujochDevice::LoadCalibration()` function for the card to upload the data. This function is synchronous and will return when the calibration is uploaded.
|
||||
|
||||
The following can be uploaded:
|
||||
|
||||
| destination | Bit-width | Data type (per pixel) | Description | Allowed value |
|
||||
|-------------------------------------------|-----------|-----------------------|---------------------------------------|-----------------------------------------|
|
||||
| LOAD_CALIBRATION_DEST_GAIN_G0 | 32 | float | 1/(gain parameter) | 0 - 0.125 (0 = mask pixel) |
|
||||
| LOAD_CALIBRATION_DEST_GAIN_G1 | 32 | float | 1/(gain parameter) | -16.0 - 0.0 (0 = mask pixel) |
|
||||
| LOAD_CALIBRATION_DEST_GAIN_G2 | 32 | float | 1/(gain parameter) | -64.0 - 0.0 (0 = mask pixel) |
|
||||
| LOAD_CALIBRATION_DEST_PEDESTAL_G0 | 16 | uint16_t | pedestal, no fractional part | 0 - 16384 (16384 = mask pixel) |
|
||||
| LOAD_CALIBRATION_DEST_PEDESTAL_G1 | 16 | uint16_t | pedestal, no fractional part | 0 - 16384 (16384 = mask pixel) |
|
||||
| LOAD_CALIBRATION_DEST_PEDESTAL_G2 | 16 | uint16_t | pedestal, no fractional part | 0 - 16384 (16384 = mask pixel) |
|
||||
| LOAD_CALIBRATION_DEST_INTEGRATION_MAP | 16 | uint16_t | integration bin | 0 - 1023 (higher values = ignore pixel) |
|
||||
| LOAD_CALIBRATION_DEST_INTEGRATION_WEIGHTS | 32 | float | weight for the pixel | 0.0 - 2.0 |
|
||||
| LOAD_CALIBRATION_DEST_FRAME_GEN | 16 | uint16_t | raw pixel values for generated frames | 0 - 65534 |
|
||||
|
||||
|
||||
### Preparing data collection
|
||||
|
||||
Before any operation one needs to check if card is idle (not running data collection) with `JungfraujochDevice::IsIdle()` function. Most configuration parameters cannot be changed, when card is in not-idle state.
|
||||
|
||||
The card can be then configured with `JungfraujochDevice::SetConfig()` function. Details of the configuration data structure are given in [ActionConfig.h](../pcie_driver/ActionConfig.h) header file.
|
||||
|
||||
Next, kernel buffers need to be mapped to the user space. These buffers are allocated with memory physically continuous, simplyfing operation of the card and the driver. Count of these buffers can be checked with `JungfraujochDevice::GetBufferCount()` function. Buffers can be mapped with `JungfraujochDevice::MapKernelBuffer()` function and deallocated with `JungfraujochDevice::UnmapKernelBuffer()` functions. Structure of the kernel buffer is described in [DeviceOutput.h](DeviceOutput.h) header file.
|
||||
The card can be then configured with `JungfraujochDevice::SetConfig()` function. Details of the configuration data structure are given in [include/jfjoch_fpga.h](../include/jfjoch_fpga.h) header file.
|
||||
|
||||
### Data collection
|
||||
|
||||
Then one can start the card with `JungfraujochDevice::Start()` function. Final step is to wait for first completion (with value `HANDLE_START` defined in [Definitions.h](../../common/Definitions.h) as buffer number) using `JungfraujochDevice::ReadWorkCompletion()`.
|
||||
Then one can start the card with `JungfraujochDevice::Start()` function. Final step is to wait for first completion (with value `HANDLE_START` defined in [include/jfjoch_fpga.h](../include/jfjoch_fpga.h) as buffer number) using `JungfraujochDevice::ReadWorkCompletion()`.
|
||||
|
||||
Standard operation of the card requires exchange of buffer ownership between the host application and FPGA card. At the beginning all buffers are owned by host application and should be "given" to the card with `JungfraujochDevice::SendWorkRequest()` function. Then card will wait for the detector to send data. After full module is collected, data are written via Direct Memory Access to host memory and kernel driver is informed with an interrupt that data are ready. Host application can "learn" what was collected by the card by running `JungfraujochDevice::ReadWorkCompletion()` function. Buffer returned by the function is owned by the host application and is safe to process. After processing the buffer has to be given back to card via `JungfraujochDevice::SendWorkRequest()`. If the card doesn't receive enough work requests (open buffers) it won't be able to receive data, resulting in lost packets.
|
||||
|
||||
@@ -66,7 +85,7 @@ To load the data, one needs to place content of each module (in 16-bit) into res
|
||||
|
||||
One also needs to switch data source by executing `JungfraujochDevice::SetDataSource()` with respective value.
|
||||
|
||||
The next step is to do all the preparations to start data collection, up to `JungfraujochDevice::Start()` and completion handshake. Then one can run `JungfraujochDevice::RunFrameGenerator()` function, with parameters described in the [ActionConfig.h](../pcie_driver/ActionConfig.h) header file. The function is asynchronous, and will start generation, but doesn't wait for the end. Though one can assume that frame generator is done, when data collection is finished.
|
||||
The next step is to do all the preparations to start data collection, up to `JungfraujochDevice::Start()` and completion handshake. Then one can run `JungfraujochDevice::RunFrameGenerator()` function, with parameters described in the [include/jfjoch_fpga.h](../include/jfjoch_fpga.h) header file. The function is asynchronous, and will start generation, but doesn't wait for the end. Though one can assume that frame generator is done, when data collection is finished.
|
||||
|
||||
### Spot finding parameters
|
||||
Spot finding parameters can be updated with function `JungfraujochDevice::SetSpotFinderParameters()`.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user