Version 1.0.0-rc.12

This commit is contained in:
2024-07-06 09:34:44 +02:00
parent 2b9ce9a26e
commit 6b5fddf2b7
105 changed files with 4717 additions and 3279 deletions

View File

@@ -316,7 +316,8 @@ release:
- build:x86:rpm
script:
- export PACKAGE_VERSION=`head -n1 VERSION`
- export PACKAGE_REGISTRY_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/jungfraujoch/${PACKAGE_VERSION}"
- export PACKAGE_VERSION_SEM=${PACKAGE_VERSION//_/-}
- export PACKAGE_REGISTRY_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/jungfraujoch/${PACKAGE_VERSION_SEM}"
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file jfjoch-driver-dkms-${PACKAGE_VERSION}-1.el8.noarch.rpm "${PACKAGE_REGISTRY_URL}/jfjoch-driver-dkms-${PACKAGE_VERSION}-1.el8.noarch.rpm"'
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file jfjoch-writer-${PACKAGE_VERSION}-1.el8.x86_64.rpm "${PACKAGE_REGISTRY_URL}/jfjoch-writer-${PACKAGE_VERSION}-1.el8.x86_64.rpm"'
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file jfjoch-${PACKAGE_VERSION}-1.el8.x86_64.rpm "${PACKAGE_REGISTRY_URL}/jfjoch-${PACKAGE_VERSION}-1.el8.x86_64.rpm"'
@@ -325,7 +326,7 @@ release:
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file jfjoch_fpga_pcie_100g.mcs "${PACKAGE_REGISTRY_URL}/jfjoch_fpga_pcie_100g.mcs"'
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file jfjoch_fpga_pcie_8x10g.mcs "${PACKAGE_REGISTRY_URL}/jfjoch_fpga_pcie_8x10g.mcs"'
- >
release-cli create --name "Release $PACKAGE_VERSION" --tag-name $PACKAGE_VERSION
release-cli create --name "Release $PACKAGE_VERSION_SEM" --tag-name $PACKAGE_VERSION_SEM
--assets-link "{\"name\":\"jfjoch_driver.tar.gz\",\"url\":\"${PACKAGE_REGISTRY_URL}/jfjoch_driver.tar.gz\"}"
--assets-link "{\"name\":\"jfjoch_frontend.tar.gz\",\"url\":\"${PACKAGE_REGISTRY_URL}/jfjoch_frontend.tar.gz\"}"
--assets-link "{\"name\":\"jfjoch_fpga_pcie_8x10g.mcs\",\"url\":\"${PACKAGE_REGISTRY_URL}/jfjoch_fpga_pcie_8x10g.mcs\"}"

View File

@@ -131,6 +131,10 @@ IF (NOT JFJOCH_WRITER_ONLY)
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/frontend_ui)
ADD_CUSTOM_TARGET(frontend DEPENDS frontend_ui/build/index.html)
ADD_CUSTOM_TARGET(openapi
COMMAND bash update_openapi.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/
DESTINATION /usr/src/jfjoch-1.0.0
COMPONENT driver-dkms

View File

@@ -1 +1 @@
1.0.0_rc.11
1.0.0_rc.12

View File

@@ -247,6 +247,11 @@ void FPGAAcquisitionDevice::FillActionRegister(const DiffractionExperiment& x, D
if (x.GetPixelDepth() == 4)
job.mode |= MODE_32BIT;
if (x.GetLossyCompressionPoisson()) {
job.mode |= MODE_SQROOT;
job.sqrtmult = x.GetLossyCompressionPoisson().value();
}
}
void FPGAAcquisitionDevice::Start(const DiffractionExperiment &experiment, uint32_t flag) {

View File

@@ -2,117 +2,29 @@
#include "HLSSimulatedDevice.h"
#include <bitset>
#include <arpa/inet.h>
#include "../fpga/hls/datamover_model.h"
#include "../fpga/hls/hls_jfjoch.h"
uint16_t checksum(const uint16_t *addr, size_t count) {
/* Compute Internet Checksum for "count" bytes
* beginning at location "addr".
*/
long sum = 0;
for (int i = 0; i < count / 2; i++)
sum += addr[i];
/* Add left-over byte, if any */
if (count % 2 == 1)
sum += ((uint8_t *) addr)[count / 2];
/* Fold 32-bit sum to 16 bits */
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
return ~sum;
}
HLSSimulatedDevice::HLSSimulatedDevice(uint16_t data_stream, size_t in_frame_buffer_size_modules, int16_t numa_node)
: FPGAAcquisitionDevice(data_stream),
datamover_in(Direction::Input, nullptr),
datamover_out(Direction::Output, nullptr),
datamover_out_hbm_0(Direction::Output, (char *) hbm.data()),
datamover_out_hbm_1(Direction::Output, (char *) hbm.data()),
datamover_in_hbm_0(Direction::Input, (char *) hbm.data()),
datamover_in_hbm_1(Direction::Input, (char *) hbm.data()),
idle(true), hbm(hbm_if_size / 32 * hbm_if_count),
dma_address_table(65536) {
: FPGAAcquisitionDevice(data_stream) {
mac_addr = 0xCCAA11223344;
ipv4_addr = 0x0132010A;
max_modules = MAX_MODULES_FPGA;
if (data_stream != 0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"HLS simulation can only work with 1 data_stream, due to use of static variables");
MapBuffersStandard(in_frame_buffer_size_modules, numa_node);
auto in_mem_location32 = (uint32_t *) dma_address_table.data();
for (int i = 0; i < buffer_device.size(); i++) {
in_mem_location32[2 * i ] = ((uint64_t) buffer_device[i]) & UINT32_MAX;
in_mem_location32[2 * i + 1] = ((uint64_t) buffer_device[i]) >> 32;
}
device = std::make_unique<HLSDevice>(buffer_device);
}
void HLSSimulatedDevice::CreateFinalPacket(const DiffractionExperiment& experiment) {
CreateJFPacket(experiment, UINT64_MAX, 0, 0, nullptr, false);
}
void HLSSimulatedDevice::SendPacket(char *buffer, int len, uint8_t user) {
auto obuff = (ap_uint<512> *)buffer;
for (int i = 0; i < (len + 63) / 64; i++) {
packet_512_t packet_in;
if (i == (len + 63) / 64 - 1) packet_in.last = 1;
else packet_in.last = 0;
packet_in.keep = 0xFFFFFFFFFFFFFFFF;
packet_in.user = user;
packet_in.data = obuff[i];
din_eth.write(packet_in);
}
device->CreateFinalPacket(experiment);
}
void HLSSimulatedDevice::CreateJFPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, int8_t adjust_axis, uint8_t user) {
char buff[256*64];
memset(buff, 0, 256*64);
auto packet = (jf_raw_packet *)buff;
packet->ether_type = htons(0x0800);
packet->sour_mac[0] = 0x00; // module 0
uint64_t tmp_mac = mac_addr;
for (int i = 0; i < 6; i++)
packet->dest_mac[i] = (tmp_mac >> (8*i)) % 256;
uint32_t half_module = 2 * module_number | ((eth_packet >= 64) ? 1 : 0);
packet->ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet->ipv4_header_total_length = htons(8268); // Big endian in IP header!
packet->ipv4_header_dest_ip = ipv4_addr;
packet->ipv4_header_sour_ip = experiment.GetSrcIPv4Address(data_stream, half_module);
packet->ipv4_header_ttl_protocol = htons(0x0011);
packet->ipv4_header_checksum = checksum( (uint16_t *) &packet->ipv4_header_h, 20); // checksum is already in network order
packet->udp_dest_port = htons(GetUDPPort()); // module number
packet->udp_sour_port = htons(0xDFAC);
packet->udp_length = htons(8248);
// JF headers are little endian
packet->jf.detectortype = SLS_DETECTOR_TYPE_JUNGFRAU;
packet->jf.timestamp = 0xABCDEF0000FEDCBAL;
packet->jf.bunchid = 0x1234567898765431L;
packet->jf.row = half_module;
packet->jf.column = 0;
packet->jf.framenum = frame_number;
packet->jf.packetnum = eth_packet % 64;
if (data != nullptr) {
for (int i = 0; i < 4096; i++)
packet->jf.data[i] = data[i];
}
packet->udp_checksum = htons(checksum( (uint16_t *) (buff+42), 8192+48));
SendPacket(buff, (130+adjust_axis)*64, user);
device->CreateJFPacket(experiment, frame_number, eth_packet, module_number, data, adjust_axis, user);
}
void HLSSimulatedDevice::CreateJFPackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
@@ -126,635 +38,67 @@ void HLSSimulatedDevice::CreateJFPackets(const DiffractionExperiment& experiment
void HLSSimulatedDevice::CreateEIGERPacket(const DiffractionExperiment &experiment, uint64_t frame_number,
uint32_t eth_packet, uint32_t module_number, uint32_t col, uint32_t row,
const uint16_t *data) {
char buff[256*64];
memset(buff, 0, 256*64);
auto packet = (eiger_raw_packet *)buff;
packet->ether_type = htons(0x0800);
packet->sour_mac[0] = 0x00; // module 0
uint64_t tmp_mac = mac_addr;
for (int i = 0; i < 6; i++)
packet->dest_mac[i] = (tmp_mac >> (8*i)) % 256;
packet->ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet->ipv4_header_total_length = htons(4172); // Big endian in IP header!
packet->ipv4_header_dest_ip = ipv4_addr;
packet->ipv4_header_sour_ip = experiment.GetSrcIPv4Address(data_stream, 0);
packet->ipv4_header_ttl_protocol = htons(0x0011);
packet->ipv4_header_checksum = checksum( (uint16_t *) &packet->ipv4_header_h, 20); // checksum is already in network order
packet->udp_dest_port = htons(GetUDPPort()); // module number
packet->udp_sour_port = htons(0xDFAC);
packet->udp_length = htons(4152);
// JF headers are little endian
packet->eiger.detectortype = SLS_DETECTOR_TYPE_EIGER;
packet->eiger.timestamp = 0xABCDEF0000FEDCBAL;
packet->eiger.bunchid = 0x1234567898765431L;
packet->eiger.row = (2 * module_number) | (row % 2);
packet->eiger.column = col % 2;
packet->eiger.framenum = frame_number;
packet->eiger.packetnum = eth_packet % 64;
if (data != nullptr) {
for (int i = 0; i < 2048; i++)
packet->eiger.data[i] = data[i];
}
packet->udp_checksum = htons(checksum( (uint16_t *) (buff+42), 4096+48));
SendPacket(buff, 66*64, 0);
}
AXI_STREAM & HLSSimulatedDevice::OutputStream() {
return dout_eth;
device->CreateEIGERPacket(experiment, frame_number, eth_packet, module_number, col, row, data);
}
void HLSSimulatedDevice::HW_ReadActionRegister(DataCollectionConfig *job) {
memcpy(job, &cfg, sizeof(DataCollectionConfig));
device->HW_ReadActionRegister(job);
}
void HLSSimulatedDevice::HW_WriteActionRegister(const DataCollectionConfig *job) {
memcpy(&cfg, job, sizeof(DataCollectionConfig));
device->HW_WriteActionRegister(job);
}
void HLSSimulatedDevice::FPGA_StartAction(const DiffractionExperiment &experiment) {
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();
action_thread = std::thread(&HLSSimulatedDevice::HLSMainThread, this );
}
void HLSSimulatedDevice::FrameGeneratorFuture(FrameGeneratorConfig config) {
frame_generator(din_frame_generator,
hbm.data(),
hbm.data(),
hbm_if_size,
mac_addr,
ipv4_addr,
cancel_data_collection,
config);
device->FPGA_StartAction(experiment);
}
void HLSSimulatedDevice::HW_RunInternalGenerator(const FrameGeneratorConfig &config) {
frame_generator_future = std::async(std::launch::async, &HLSSimulatedDevice::FrameGeneratorFuture, this, config);
device->HW_RunInternalGenerator(config);
}
void HLSSimulatedDevice::FPGA_EndAction() {
if (action_thread.joinable())
action_thread.join();
device->FPGA_EndAction();
}
HLSSimulatedDevice::~HLSSimulatedDevice() {
if (action_thread.joinable())
action_thread.join();
}
bool HLSSimulatedDevice::HW_ReadMailbox(uint32_t *values) {
std::unique_lock<std::mutex> ul(completion_mutex);
ap_uint<32> tmp;
bool ret = completion_stream.read_nb(tmp);
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) && (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));
}
}
return ret;
return device->HW_ReadMailbox(values);
}
void HLSSimulatedDevice::Cancel() {
cancel_data_collection = 1;
device->Cancel();
}
bool HLSSimulatedDevice::HW_IsIdle() const {
return idle && datamover_out.IsIdle();
return device->HW_IsIdle();
}
bool HLSSimulatedDevice::HW_SendWorkRequest(uint32_t handle) {
work_request_stream.write(handle);
return true;
}
inline uint32_t float2uint(float f) {
float_uint32 fu;
fu.f = f;
return fu.u;
}
void HLSSimulatedDevice::HLSMainThread() {
ap_uint<1> clear_counters = 0;
uint64_t packets_processed;
std::vector<std::thread> hls_cores;
STREAM_512 ip1, udp1, udp2, icmp1, arp1;
STREAM_512 network0;
STREAM_768 stream_768_0;
STREAM_768 stream_768_1;
STREAM_768 stream_768_2;
STREAM_768 stream_768_3;
STREAM_768 stream_768_4;
STREAM_768 stream_768_5;
STREAM_512 data_0;
hls::stream<ap_axiu<512, 1, 1, 1>, 2> data_1;
hls::stream<ap_axiu<512, 1, 1, 1>, 2> data_2;
STREAM_512 data_3;
STREAM_512 data_4;
STREAM_512 data_5;
STREAM_512 data_6;
STREAM_512 data_7;
STREAM_512 data_8;
STREAM_512 data_9;
STREAM_512 data_10;
STREAM_512 data_12;
STREAM_512 data_13;
hls::stream<axis_addr> addr0;
hls::stream<axis_addr> addr1;
hls::stream<axis_addr> addr2;
hls::stream<axis_addr> addr3;
hls::stream<axis_completion> axi_compl[12];
hls::stream<ap_uint<16>> hbm_handles;
hls::stream<ap_uint<512>> adu_histo_result;
hls::stream<ap_axiu<64,1,1,1>> integration_result_0;
hls::stream<ap_uint<512>> integration_result_1;
hls::stream<ap_axiu<32,1,1,1>> spot_finder_result_0;
hls::stream<ap_axiu<32,1,1,1>> spot_finder_result_1;
hls::stream<ap_uint<32>> spot_finder_conn_0;
hls::stream<ap_axiu<32,1,1,1>> spot_finder_result_2;
hls::stream<ap_uint<512>> spot_finder_result_3;
hls::stream<ap_uint<32>> spot_finder_mask_0;
hls::stream<ap_uint<256>> roi_calc_result_0;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
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;
volatile bool done = false;
volatile bool udp_done = false; // done AND udp_idle
volatile bool sls_done = false; // done AND sls_idle
// Sent gratuitous ARP message
arp(arp1, dout_eth, mac_addr, ipv4_addr, 1, 1);
Logger logger_hls("HLS");
volatile rcv_state_t state = RCV_INIT;
// Start data collection
data_collection_fsm(data_0, data_1,
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);
run_data_collection = 0;
data_collection_fsm(data_0, data_1,
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);
hls_cores.emplace_back([&] {
while (!udp_done) {
if (din_eth.empty() && din_frame_generator.empty())
std::this_thread::sleep_for(std::chrono::microseconds(10));
else
stream_merge(din_eth, din_frame_generator, network0, data_source);
}
logger_hls.Info("Stream_merge done");
});
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");
});
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");
});
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, data_0, addr0, sls_packets, udp_eth_err, udp_len_err, current_pulse_id,
clear_counters, sls_idle);
}
sls_done = true;
logger_hls.Info("sls_detector done");
});
// 1. Parse incoming UDP packets
hls_cores.emplace_back([&] {
while ((state != RCV_WAIT_FOR_START) || (idle_data_collection.read() == 0) || (!data_0.empty())) {
data_collection_fsm(data_0, data_1,
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);
}
done = true;
logger_hls.Info("data collection done");
});
// 2. Cache images in HBM
hls_cores.emplace_back([&] { save_to_hbm(addr1, axi_compl[0], hbm_handles,
datamover_out_hbm_0.GetCtrlStream(),
datamover_out_hbm_1.GetCtrlStream(),
save_to_hbm_idle,
hbm_if_size);});
hls_cores.emplace_back([&] { save_to_hbm_data(data_1,
data_3,
datamover_out_hbm_0.GetDataStream(),
datamover_out_hbm_1.GetDataStream());});
hls_cores.emplace_back([&] {frame_summation_reorder_compl(data_3, data_4, axi_compl[0], axi_compl[1]);});
hls_cores.emplace_back([&] { load_from_hbm(data_4, data_5, axi_compl[1], axi_compl[2], hbm_handles,
datamover_in_hbm_0.GetDataStream(), datamover_in_hbm_1.GetDataStream(),
datamover_in_hbm_0.GetCtrlStream(), datamover_in_hbm_1.GetCtrlStream(),
load_to_hbm_idle, hbm_if_size);});
hls_cores.emplace_back([&] { pedestal(data_5, data_6, axi_compl[2], axi_compl[3],
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm_if_size);});
// 3. Calculate histogram of ADU values
hls_cores.emplace_back([&] { adu_histo(data_6, data_7, adu_histo_result, axi_compl[3], axi_compl[4]);});
// 4. Mask missing pixels
hls_cores.emplace_back([&] { mask_missing(data_7, data_8, axi_compl[4], axi_compl[5]);});
// 5. Handle EIGER packets properly
hls_cores.emplace_back([&] { eiger_reorder(data_8, data_9, axi_compl[5], axi_compl[6]);});
// 6. Apply pedestal & gain corrections
hls_cores.emplace_back([&] { jf_conversion(data_9, stream_768_0,
axi_compl[6], axi_compl[7],
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm.data(),
hbm_if_size); });
// 7. Frame summation
hls_cores.emplace_back([&] { frame_summation(stream_768_0, stream_768_1, axi_compl[7], axi_compl[8], frame_summation_idle);});
// 8. Integration of pixels
hls_cores.emplace_back([&] { integration(stream_768_1, stream_768_2, integration_result_0, axi_compl[8], axi_compl[9],
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);});
// 9. Spot finding
ap_uint<32> tmp_snr_threshold = float2uint(spot_finder_parameters.snr_threshold);
ap_uint<32> min_d = float2uint(spot_finder_parameters.min_d);
ap_uint<32> max_d = float2uint(spot_finder_parameters.max_d);
ap_int<32> tmp_count_threshold = spot_finder_parameters.count_threshold;
ap_uint<32> min_pix_per_spot = spot_finder_parameters.min_pix_per_spot;
hls_cores.emplace_back([&] {
spot_finder_mask(stream_768_2,
stream_768_3,
spot_finder_mask_0,
axi_compl[9],
axi_compl[10],
hbm.data(),
hbm.data(),
min_d,
max_d,
hbm_if_size);
logger_hls.Info("spot_finder_mask done");
});
hls_cores.emplace_back([&] {
spot_finder(stream_768_3, spot_finder_mask_0, stream_768_4, spot_finder_result_0, tmp_count_threshold, tmp_snr_threshold);
logger_hls.Info("spot_finder done");
});
hls_cores.emplace_back([&] {
spot_finder_connectivity(spot_finder_result_0,
spot_finder_result_1,
spot_finder_conn_0);
logger_hls.Info("spot_finder_connectivity done");
});
hls_cores.emplace_back([&] {
spot_finder_merge(spot_finder_result_1,
spot_finder_conn_0,
spot_finder_result_2,
min_pix_per_spot);
logger_hls.Info("spot_finder_merge done");
});
hls_cores.emplace_back([&] {
axis_32_to_512(spot_finder_result_2, spot_finder_result_3);
logger_hls.Info("axis_32_to_512 done");
});
hls_cores.emplace_back([&] {
roi_calc(stream_768_4,
stream_768_5,
roi_calc_result_0,
axi_compl[10],
axi_compl[11],
hbm.data(),
hbm.data(),
hbm_if_size);
logger_hls.Info("roi_calc done");
});
// 10. Reduce/extend 24-bit stream
hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_5, data_12, stream_conv_idle);});
// 11. Prepare data to write to host memory
hls_cores.emplace_back([&] {
ap_uint<3> state;
host_writer(data_12, adu_histo_result, integration_result_1, spot_finder_result_3, roi_calc_result_0,
axi_compl[11], datamover_out.GetDataStream(),
datamover_out.GetCtrlStream(), work_request_stream, completion_stream,
dma_address_table.data(), packets_processed, host_writer_idle, cancel_data_collection, state);
logger_hls.Info("host_writer done");
});
for (auto &i : hls_cores)
i.join();
if (frame_generator_future.valid())
frame_generator_future.get();
// reset static counter
arp(arp1, dout_eth, mac_addr, ipv4_addr, 0, 1);
try {
while (!din_eth.empty())
din_eth.read();
if (!addr1.empty())
throw std::runtime_error("Addr1 queue not empty");
if (!addr2.empty())
throw std::runtime_error("Addr2 queue not empty");
if (!addr3.empty())
throw std::runtime_error("Addr3 queue not empty");
if (!data_1.empty())
throw std::runtime_error("data_1 queue not empty");
if (!data_2.empty())
throw std::runtime_error("data_2 queue not empty");
if (!data_3.empty())
throw std::runtime_error("data_3 queue not empty");
if (!data_4.empty())
throw std::runtime_error("data_4 queue not empty");
if (!data_5.empty())
throw std::runtime_error("data_5 queue not empty");
if (!data_7.empty())
throw std::runtime_error("data_7 queue not empty");
if (!data_8.empty())
throw std::runtime_error("data_8 queue not empty");
if (!data_9.empty())
throw std::runtime_error("data_9 queue not empty");
if (!data_10.empty())
throw std::runtime_error("data_10 queue not empty");
if (!data_12.empty())
throw std::runtime_error("data_12 queue not empty");
if (!data_13.empty())
throw std::runtime_error("data_13 queue not empty");
for (auto &c: axi_compl) {
if (!c.empty())
throw std::runtime_error("Compl queue not empty");
}
if (!stream_768_0.empty())
throw std::runtime_error("stream_768_0 queue not empty");
if (!stream_768_1.empty())
throw std::runtime_error("stream_768_1 queue not empty");
if (!stream_768_2.empty())
throw std::runtime_error("stream_768_2 queue not empty");
if (!stream_768_3.empty())
throw std::runtime_error("stream_768_3 queue not empty");
if (!stream_768_4.empty())
throw std::runtime_error("stream_768_4 queue not empty");
if (!hbm_handles.empty())
throw std::runtime_error("Handles queue not empty");
if (!integration_result_0.empty())
throw std::runtime_error("Integration result queue not empty");
if (!integration_result_1.empty())
throw std::runtime_error("Integration result queue not empty");
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);
idle = true;
return device->HW_SendWorkRequest(handle);
}
DataCollectionStatus HLSSimulatedDevice::GetDataCollectionStatus() const {
DataCollectionStatus status{};
union {
uint64_t u64;
double d;
} pulse_id_conv;
pulse_id_conv.u64 = current_pulse_id;
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;
status.current_pulseid = pulse_id_conv.d;
status.packets_udp = udp_packets;
status.packets_eth = eth_packets;
status.packets_sls = sls_packets;
return status;
return device->GetDataCollectionStatus();
}
void HLSSimulatedDevice::HW_LoadCalibration(const LoadCalibrationConfig &config) {
int ret = load_calibration(hbm.data(), hbm.data(),
config,
hbm_if_size,
datamover_in.GetCtrlStream(),
datamover_in.GetDataStream(),
dma_address_table.data());
if (ret)
throw JFJochException(JFJochExceptionCategory::AcquisitionDeviceError,
"Error in loading calibration " + std::to_string(ret));
if (!datamover_in.GetDataStream().empty())
throw std::runtime_error("Datamover queue is not empty");
device->HW_LoadCalibration(config);
}
void HLSSimulatedDevice::HW_SetSpotFinderParameters(const SpotFinderParameters &params) {
spot_finder_parameters = params;
device->HW_SetSpotFinderParameters(params);
}
void HLSSimulatedDevice::HW_SetDataSource(uint32_t val) {
data_source = val;
device->HW_SetDataSource(val);
}
uint32_t HLSSimulatedDevice::HW_GetDataSource() {
return data_source;
return device->HW_GetDataSource();
}
void HLSSimulatedDevice::CreateXfelBunchIDPacket(double pulse_id, uint32_t event_code) {
union {
uint64_t u64;
double d;
} pulse_id_conv;
pulse_id_conv.d = pulse_id;
bunchid_raw_packet packet{};
packet.ether_type = htons(0x0800);
for (int i = 0; i < 6; i++)
packet.dest_mac[i] = 0xFF;
packet.ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet.ipv4_header_total_length = htons(sizeof(bunchid_payload) + 8 + 20); // Big endian in IP header!
packet.ipv4_header_dest_ip = UINT32_MAX;
packet.ipv4_header_ttl_protocol = htons(0x0011);
packet.ipv4_header_checksum = checksum( (uint16_t *) &packet.ipv4_header_h, 20); // checksum is already in network order
packet.udp_length = htons(sizeof(bunchid_payload) + 8);
packet.payload.magicn[0] = BUNCHID_MAGICN;
packet.payload.magicn[1] = BUNCHID_MAGICN;
packet.payload.magicn[2] = BUNCHID_MAGICN;
packet.payload.bunchid_msb[0] = (pulse_id_conv.u64 >> 32) & UINT32_MAX;
packet.payload.bunchid_msb[1] = (pulse_id_conv.u64 >> 32) & UINT32_MAX;
packet.payload.bunchid_lsb[0] = pulse_id_conv.u64 & UINT32_MAX;
packet.payload.bunchid_lsb[1] = pulse_id_conv.u64 & UINT32_MAX;
packet.payload.montrig = event_code;
SendPacket((char *) &packet, sizeof(bunchid_raw_packet));
device->CreateXfelBunchIDPacket(pulse_id, event_code);
}

View File

@@ -5,61 +5,13 @@
#include <thread>
#include "../fpga/hls/hls_jfjoch.h"
#include "../fpga/hls/datamover_model.h"
#include "../common/DiffractionExperiment.h"
#include "FPGAAcquisitionDevice.h"
#include "../jungfrau/sls_packet.h"
#include "../fpga/hls/HLSDevice.h"
uint16_t checksum(const uint16_t *addr, size_t count);
#include "FPGAAcquisitionDevice.h"
class HLSSimulatedDevice : public FPGAAcquisitionDevice {
AXI_STREAM din_eth;
AXI_STREAM din_frame_generator;
AXI_STREAM dout_eth;
uint32_t run_counter = 0;
ap_uint<2> data_source = STREAM_MERGE_SRC_NETWORK;
SpotFinderParameters spot_finder_parameters;
uint64_t current_pulse_id = 0;
DataCollectionConfig cfg;
volatile bool idle;
constexpr static const size_t hbm_if_count = 32;
constexpr static const size_t hbm_if_size = 32*1024*1024LU;
std::vector<ap_uint<256>> hbm;
hls::stream<ap_uint<32> > work_request_stream;
hls::stream<ap_uint<32> > completion_stream;
std::mutex completion_mutex;
uint32_t completion_count;
std::thread action_thread;
std::future<void> frame_generator_future;
Datamover<512> datamover_in;
Datamover<512> datamover_out;
Datamover<256> datamover_in_hbm_0;
Datamover<256> datamover_in_hbm_1;
Datamover<256, 16> datamover_out_hbm_0;
Datamover<256, 16> datamover_out_hbm_1;
ap_uint<1> run_data_collection;
ap_uint<1> cancel_data_collection;
volatile ap_uint<1> host_writer_idle;
std::vector<uint64_t> dma_address_table;
uint64_t eth_packets = 0;
uint64_t icmp_packets = 0;
uint64_t udp_packets = 0;
uint64_t sls_packets = 0;
uint32_t udp_len_err = 0;
uint32_t udp_eth_err = 0;
std::unique_ptr<HLSDevice> device;
void HW_ReadActionRegister(DataCollectionConfig *job) override;
void HW_WriteActionRegister(const DataCollectionConfig *job) override;
@@ -74,12 +26,9 @@ class HLSSimulatedDevice : public FPGAAcquisitionDevice {
uint32_t HW_GetDataSource() override;
void HW_SetDataSource(uint32_t val) override;
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;
void SendPacket(char *buffer, int len, uint8_t user = 0);
~HLSSimulatedDevice() override = default;
void CreateJFPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, int8_t adjust_axis = 0, uint8_t user = 0);
void CreateJFPackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
@@ -90,7 +39,6 @@ public:
void CreateXfelBunchIDPacket(double bunchid, uint32_t event_code);
void CreateFinalPacket(const DiffractionExperiment& experiment);
DataCollectionStatus GetDataCollectionStatus() const override;
AXI_STREAM &OutputStream();
void Cancel() override;
};

View File

@@ -388,6 +388,8 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown compression");
}
if (input.poissonCompressionIsSet())
ret.LossyCompressionPoisson(input.getPoissonCompression());
if (input.unitCellIsSet())
ret.SetUnitCell(UnitCell{
@@ -423,7 +425,7 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
ret.ImagesPerFile(input.getImagesPerFile());
if (input.dataReductionFactorSerialmxIsSet())
ret.DataReductionFactorSerialMX(input.getDataReductionFactorSerialmx());
ret.LossyCompressionSerialMX(input.getDataReductionFactorSerialmx());
return ret;
}

39
broker/gen/api/ApiBase.h Normal file
View File

@@ -0,0 +1,39 @@
/**
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* ApiBase.h
*
* Generalization of the Api classes
*/
#ifndef ApiBase_H_
#define ApiBase_H_
#include <pistache/router.h>
#include <memory>
namespace org::openapitools::server::api
{
class ApiBase {
public:
explicit ApiBase(const std::shared_ptr<Pistache::Rest::Router>& rtr) : router(rtr) {};
virtual ~ApiBase() = default;
virtual void init() = 0;
protected:
const std::shared_ptr<Pistache::Rest::Router> router;
};
} // namespace org::openapitools::server::api
#endif /* ApiBase_H_ */

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -22,7 +22,7 @@ using namespace org::openapitools::server::model;
const std::string DefaultApi::base = "";
DefaultApi::DefaultApi(const std::shared_ptr<Pistache::Rest::Router>& rtr)
: router(rtr)
: ApiBase(rtr)
{
}

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -19,6 +19,8 @@
#define DefaultApi_H_
#include "ApiBase.h"
#include <pistache/http.h>
#include <pistache/router.h>
#include <pistache/http_headers.h>
@@ -42,15 +44,16 @@
#include "Roi_circle_list.h"
#include "Spot_finding_settings.h"
#include <string>
#include <vector>
namespace org::openapitools::server::api
{
class DefaultApi {
class DefaultApi : public ApiBase {
public:
explicit DefaultApi(const std::shared_ptr<Pistache::Rest::Router>& rtr);
virtual ~DefaultApi() = default;
void init();
~DefaultApi() override = default;
void init() override;
static const std::string base;
@@ -109,8 +112,6 @@ private:
void xfel_pulse_id_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void default_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
const std::shared_ptr<Pistache::Rest::Router> router;
/// <summary>
/// Helper function to handle unexpected Exceptions during Parameter parsing and validation.
/// May be overridden to return custom error formats. This is called inside a catch block.

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -114,7 +114,7 @@ bool Broker_status::operator!=(const Broker_status& rhs) const
void to_json(nlohmann::json& j, const Broker_status& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["state"] = o.m_State;
if(o.progressIsSet())
j["progress"] = o.m_Progress;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -78,8 +78,8 @@ public:
bool indexingRateIsSet() const;
void unsetIndexing_rate();
friend void to_json(nlohmann::json& j, const Broker_status& o);
friend void from_json(const nlohmann::json& j, Broker_status& o);
friend void to_json(nlohmann::json& j, const Broker_status& o);
friend void from_json(const nlohmann::json& j, Broker_status& o);
protected:
std::string m_State;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -98,7 +98,7 @@ bool Calibration_statistics_inner::operator!=(const Calibration_statistics_inner
void to_json(nlohmann::json& j, const Calibration_statistics_inner& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["module_number"] = o.m_Module_number;
j["storage_cell_number"] = o.m_Storage_cell_number;
j["pedestal_g0_mean"] = o.m_Pedestal_g0_mean;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -103,8 +103,8 @@ public:
int64_t getMaskedPixels() const;
void setMaskedPixels(int64_t const value);
friend void to_json(nlohmann::json& j, const Calibration_statistics_inner& o);
friend void from_json(const nlohmann::json& j, Calibration_statistics_inner& o);
friend void to_json(nlohmann::json& j, const Calibration_statistics_inner& o);
friend void from_json(const nlohmann::json& j, Calibration_statistics_inner& o);
protected:
int64_t m_Module_number;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -60,6 +60,8 @@ Dataset_settings::Dataset_settings()
m_Run_nameIsSet = false;
m_Experiment_group = "";
m_Experiment_groupIsSet = false;
m_Poisson_compression = 0L;
m_Poisson_compressionIsSet = false;
m_Unit_cellIsSet = false;
}
@@ -257,7 +259,26 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
}
}
if (poissonCompressionIsSet())
{
const int64_t& value = m_Poisson_compression;
const std::string currentValuePath = _pathPrefix + ".poissonCompression";
if (value < 0ll)
{
success = false;
msg << currentValuePath << ": must be greater than or equal to 0;";
}
if (value > 16ll)
{
success = false;
msg << currentValuePath << ": must be less than or equal to 16;";
}
}
return success;
}
@@ -336,6 +357,9 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
((!experimentGroupIsSet() && !rhs.experimentGroupIsSet()) || (experimentGroupIsSet() && rhs.experimentGroupIsSet() && getExperimentGroup() == rhs.getExperimentGroup())) &&
((!poissonCompressionIsSet() && !rhs.poissonCompressionIsSet()) || (poissonCompressionIsSet() && rhs.poissonCompressionIsSet() && getPoissonCompression() == rhs.getPoissonCompression())) &&
((!unitCellIsSet() && !rhs.unitCellIsSet()) || (unitCellIsSet() && rhs.unitCellIsSet() && getUnitCell() == rhs.getUnitCell()))
;
@@ -348,7 +372,7 @@ bool Dataset_settings::operator!=(const Dataset_settings& rhs) const
void to_json(nlohmann::json& j, const Dataset_settings& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
if(o.imagesPerTriggerIsSet())
j["images_per_trigger"] = o.m_Images_per_trigger;
if(o.ntriggerIsSet())
@@ -391,6 +415,8 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
j["run_name"] = o.m_Run_name;
if(o.experimentGroupIsSet())
j["experiment_group"] = o.m_Experiment_group;
if(o.poissonCompressionIsSet())
j["poisson_compression"] = o.m_Poisson_compression;
if(o.unitCellIsSet())
j["unit_cell"] = o.m_Unit_cell;
@@ -497,6 +523,11 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
j.at("experiment_group").get_to(o.m_Experiment_group);
o.m_Experiment_groupIsSet = true;
}
if(j.find("poisson_compression") != j.end())
{
j.at("poisson_compression").get_to(o.m_Poisson_compression);
o.m_Poisson_compressionIsSet = true;
}
if(j.find("unit_cell") != j.end())
{
j.at("unit_cell").get_to(o.m_Unit_cell);
@@ -860,6 +891,23 @@ void Dataset_settings::unsetExperiment_group()
{
m_Experiment_groupIsSet = false;
}
int64_t Dataset_settings::getPoissonCompression() const
{
return m_Poisson_compression;
}
void Dataset_settings::setPoissonCompression(int64_t const value)
{
m_Poisson_compression = value;
m_Poisson_compressionIsSet = true;
}
bool Dataset_settings::poissonCompressionIsSet() const
{
return m_Poisson_compressionIsSet;
}
void Dataset_settings::unsetPoisson_compression()
{
m_Poisson_compressionIsSet = false;
}
org::openapitools::server::model::Dataset_settings_unit_cell Dataset_settings::getUnitCell() const
{
return m_Unit_cell;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -215,6 +215,13 @@ public:
bool experimentGroupIsSet() const;
void unsetExperiment_group();
/// <summary>
/// Enable lossy compression of pixel values that preserves Poisson statistics. Requires to provide a numerical factor SQ. Pixel value P will be transformed to round(sqrt(P) * SQ), with rounding to the closest integer. Compression is turned off if the value is missing or it is set to zero.
/// </summary>
int64_t getPoissonCompression() const;
void setPoissonCompression(int64_t const value);
bool poissonCompressionIsSet() const;
void unsetPoisson_compression();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Dataset_settings_unit_cell getUnitCell() const;
@@ -222,8 +229,8 @@ public:
bool unitCellIsSet() const;
void unsetUnit_cell();
friend void to_json(nlohmann::json& j, const Dataset_settings& o);
friend void from_json(const nlohmann::json& j, Dataset_settings& o);
friend void to_json(nlohmann::json& j, const Dataset_settings& o);
friend void from_json(const nlohmann::json& j, Dataset_settings& o);
protected:
int64_t m_Images_per_trigger;
bool m_Images_per_triggerIsSet;
@@ -271,6 +278,8 @@ protected:
bool m_Run_nameIsSet;
std::string m_Experiment_group;
bool m_Experiment_groupIsSet;
int64_t m_Poisson_compression;
bool m_Poisson_compressionIsSet;
org::openapitools::server::model::Dataset_settings_unit_cell m_Unit_cell;
bool m_Unit_cellIsSet;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -185,7 +185,7 @@ bool Dataset_settings_unit_cell::operator!=(const Dataset_settings_unit_cell& rh
void to_json(nlohmann::json& j, const Dataset_settings_unit_cell& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["a"] = o.m_a;
j["b"] = o.m_b;
j["c"] = o.m_c;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -88,8 +88,8 @@ public:
float getGamma() const;
void setGamma(float const value);
friend void to_json(nlohmann::json& j, const Dataset_settings_unit_cell& o);
friend void from_json(const nlohmann::json& j, Dataset_settings_unit_cell& o);
friend void to_json(nlohmann::json& j, const Dataset_settings_unit_cell& o);
friend void from_json(const nlohmann::json& j, Dataset_settings_unit_cell& o);
protected:
float m_a;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -90,7 +90,7 @@ bool Detector_list::operator!=(const Detector_list& rhs) const
void to_json(nlohmann::json& j, const Detector_list& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["detectors"] = o.m_Detectors;
j["current_id"] = o.m_Current_id;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -70,8 +70,8 @@ public:
int64_t getCurrentId() const;
void setCurrentId(int64_t const value);
friend void to_json(nlohmann::json& j, const Detector_list& o);
friend void from_json(const nlohmann::json& j, Detector_list& o);
friend void to_json(nlohmann::json& j, const Detector_list& o);
friend void from_json(const nlohmann::json& j, Detector_list& o);
protected:
std::vector<org::openapitools::server::model::Detector_list_detectors_inner> m_Detectors;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -96,7 +96,7 @@ bool Detector_list_detectors_inner::operator!=(const Detector_list_detectors_inn
void to_json(nlohmann::json& j, const Detector_list_detectors_inner& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["id"] = o.m_Id;
j["description"] = o.m_Description;
j["nmodules"] = o.m_Nmodules;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -84,8 +84,8 @@ public:
int64_t getHeight() const;
void setHeight(int64_t const value);
friend void to_json(nlohmann::json& j, const Detector_list_detectors_inner& o);
friend void from_json(const nlohmann::json& j, Detector_list_detectors_inner& o);
friend void to_json(nlohmann::json& j, const Detector_list_detectors_inner& o);
friend void from_json(const nlohmann::json& j, Detector_list_detectors_inner& o);
protected:
int64_t m_Id;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -66,7 +66,7 @@ bool Detector_selection::operator!=(const Detector_selection& rhs) const
void to_json(nlohmann::json& j, const Detector_selection& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["id"] = o.m_Id;
}

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -63,8 +63,8 @@ public:
int64_t getId() const;
void setId(int64_t const value);
friend void to_json(nlohmann::json& j, const Detector_selection& o);
friend void from_json(const nlohmann::json& j, Detector_selection& o);
friend void to_json(nlohmann::json& j, const Detector_selection& o);
friend void from_json(const nlohmann::json& j, Detector_selection& o);
protected:
int64_t m_Id;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -220,7 +220,7 @@ bool Detector_settings::operator!=(const Detector_settings& rhs) const
void to_json(nlohmann::json& j, const Detector_settings& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["frame_time_us"] = o.m_Frame_time_us;
if(o.countTimeUsIsSet())
j["count_time_us"] = o.m_Count_time_us;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -147,8 +147,8 @@ public:
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);
friend void to_json(nlohmann::json& j, const Detector_settings& o);
friend void from_json(const nlohmann::json& j, Detector_settings& o);
protected:
int64_t m_Frame_time_us;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -126,7 +126,7 @@ bool Detector_status::operator!=(const Detector_status& rhs) const
void to_json(nlohmann::json& j, const Detector_status& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["state"] = o.m_State;
j["powerchip"] = o.m_Powerchip;
j["server_version"] = o.m_Server_version;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -90,8 +90,8 @@ public:
std::vector<int64_t> getHighVoltageV() const;
void setHighVoltageV(std::vector<int64_t> const value);
friend void to_json(nlohmann::json& j, const Detector_status& o);
friend void from_json(const nlohmann::json& j, Detector_status& o);
friend void to_json(nlohmann::json& j, const Detector_status& o);
friend void from_json(const nlohmann::json& j, Detector_status& o);
protected:
std::string m_State;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -70,7 +70,7 @@ bool Error_message::operator!=(const Error_message& rhs) const
void to_json(nlohmann::json& j, const Error_message& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["msg"] = o.m_Msg;
j["reason"] = o.m_Reason;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -69,8 +69,8 @@ public:
std::string getReason() const;
void setReason(std::string const& value);
friend void to_json(nlohmann::json& j, const Error_message& o);
friend void from_json(const nlohmann::json& j, Error_message& o);
friend void to_json(nlohmann::json& j, const Error_message& o);
friend void from_json(const nlohmann::json& j, Error_message& o);
protected:
std::string m_Msg;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -185,7 +185,7 @@ bool Measurement_statistics::operator!=(const Measurement_statistics& rhs) const
void to_json(nlohmann::json& j, const Measurement_statistics& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
if(o.filePrefixIsSet())
j["file_prefix"] = o.m_File_prefix;
if(o.runNumberIsSet())

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -185,8 +185,8 @@ public:
bool unitCellIsSet() const;
void unsetUnit_cell();
friend void to_json(nlohmann::json& j, const Measurement_statistics& o);
friend void from_json(const nlohmann::json& j, Measurement_statistics& o);
friend void to_json(nlohmann::json& j, const Measurement_statistics& o);
friend void from_json(const nlohmann::json& j, Measurement_statistics& o);
protected:
std::string m_File_prefix;
bool m_File_prefixIsSet;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -114,7 +114,7 @@ bool Plot::operator!=(const Plot& rhs) const
void to_json(nlohmann::json& j, const Plot& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["title"] = o.m_Title;
j["x"] = o.m_x;
j["y"] = o.m_y;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -75,8 +75,8 @@ public:
std::vector<float> getY() const;
void setY(std::vector<float> const value);
friend void to_json(nlohmann::json& j, const Plot& o);
friend void from_json(const nlohmann::json& j, Plot& o);
friend void to_json(nlohmann::json& j, const Plot& o);
friend void from_json(const nlohmann::json& j, Plot& o);
protected:
std::string m_Title;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -91,7 +91,7 @@ bool Plots::operator!=(const Plots& rhs) const
void to_json(nlohmann::json& j, const Plots& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
if(o.titleIsSet())
j["title"] = o.m_Title;
j["plot"] = o.m_Plot;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -73,8 +73,8 @@ public:
std::vector<org::openapitools::server::model::Plot> getPlot() const;
void setPlot(std::vector<org::openapitools::server::model::Plot> const& value);
friend void to_json(nlohmann::json& j, const Plots& o);
friend void from_json(const nlohmann::json& j, Plots& o);
friend void to_json(nlohmann::json& j, const Plots& o);
friend void from_json(const nlohmann::json& j, Plots& o);
protected:
std::string m_Title;
bool m_TitleIsSet;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -153,7 +153,7 @@ bool Preview_settings::operator!=(const Preview_settings& rhs) const
void to_json(nlohmann::json& j, const Preview_settings& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["saturation"] = o.m_Saturation;
if(o.showSpotsIsSet())
j["show_spots"] = o.m_Show_spots;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -105,8 +105,8 @@ public:
bool resolutionRingIsSet() const;
void unsetResolution_ring();
friend void to_json(nlohmann::json& j, const Preview_settings& o);
friend void from_json(const nlohmann::json& j, Preview_settings& o);
friend void to_json(nlohmann::json& j, const Preview_settings& o);
friend void from_json(const nlohmann::json& j, Preview_settings& o);
protected:
int64_t m_Saturation;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -102,7 +102,7 @@ bool Rad_int_settings::operator!=(const Rad_int_settings& rhs) const
void to_json(nlohmann::json& j, const Rad_int_settings& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
if(o.polarizationFactorIsSet())
j["polarization_factor"] = o.m_Polarization_factor;
j["solid_angle_corr"] = o.m_Solid_angle_corr;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -85,8 +85,8 @@ public:
float getQSpacing() const;
void setQSpacing(float const value);
friend void to_json(nlohmann::json& j, const Rad_int_settings& o);
friend void from_json(const nlohmann::json& j, Rad_int_settings& o);
friend void to_json(nlohmann::json& j, const Rad_int_settings& o);
friend void from_json(const nlohmann::json& j, Rad_int_settings& o);
protected:
float m_Polarization_factor;
bool m_Polarization_factorIsSet;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -152,7 +152,7 @@ bool Roi_box::operator!=(const Roi_box& rhs) const
void to_json(nlohmann::json& j, const Roi_box& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["name"] = o.m_Name;
j["min_x_pxl"] = o.m_Min_x_pxl;
j["max_x_pxl"] = o.m_Max_x_pxl;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -84,8 +84,8 @@ public:
int64_t getMaxYPxl() const;
void setMaxYPxl(int64_t const value);
friend void to_json(nlohmann::json& j, const Roi_box& o);
friend void from_json(const nlohmann::json& j, Roi_box& o);
friend void to_json(nlohmann::json& j, const Roi_box& o);
friend void from_json(const nlohmann::json& j, Roi_box& o);
protected:
std::string m_Name;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -92,7 +92,7 @@ bool Roi_box_list::operator!=(const Roi_box_list& rhs) const
void to_json(nlohmann::json& j, const Roi_box_list& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
if(o.roisIsSet() || !o.m_Rois.empty())
j["rois"] = o.m_Rois;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -67,8 +67,8 @@ public:
bool roisIsSet() const;
void unsetRois();
friend void to_json(nlohmann::json& j, const Roi_box_list& o);
friend void from_json(const nlohmann::json& j, Roi_box_list& o);
friend void to_json(nlohmann::json& j, const Roi_box_list& o);
friend void from_json(const nlohmann::json& j, Roi_box_list& o);
protected:
std::vector<org::openapitools::server::model::Roi_box> m_Rois;
bool m_RoisIsSet;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -106,7 +106,7 @@ bool Roi_circle::operator!=(const Roi_circle& rhs) const
void to_json(nlohmann::json& j, const Roi_circle& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["name"] = o.m_Name;
j["center_x_pxl"] = o.m_Center_x_pxl;
j["center_y_pxl"] = o.m_Center_y_pxl;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -79,8 +79,8 @@ public:
float getRadiusPxl() const;
void setRadiusPxl(float const value);
friend void to_json(nlohmann::json& j, const Roi_circle& o);
friend void from_json(const nlohmann::json& j, Roi_circle& o);
friend void to_json(nlohmann::json& j, const Roi_circle& o);
friend void from_json(const nlohmann::json& j, Roi_circle& o);
protected:
std::string m_Name;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -91,7 +91,7 @@ bool Roi_circle_list::operator!=(const Roi_circle_list& rhs) const
void to_json(nlohmann::json& j, const Roi_circle_list& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["rois"] = o.m_Rois;
}

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -65,8 +65,8 @@ public:
std::vector<org::openapitools::server::model::Roi_circle> getRois() const;
void setRois(std::vector<org::openapitools::server::model::Roi_circle> const& value);
friend void to_json(nlohmann::json& j, const Roi_circle_list& o);
friend void from_json(const nlohmann::json& j, Roi_circle_list& o);
friend void to_json(nlohmann::json& j, const Roi_circle_list& o);
friend void from_json(const nlohmann::json& j, Roi_circle_list& o);
protected:
std::vector<org::openapitools::server::model::Roi_circle> m_Rois;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -125,7 +125,7 @@ bool Rotation_axis::operator!=(const Rotation_axis& rhs) const
void to_json(nlohmann::json& j, const Rotation_axis& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
if(o.nameIsSet())
j["name"] = o.m_Name;
j["step"] = o.m_Step;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -86,8 +86,8 @@ public:
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);
friend void to_json(nlohmann::json& j, const Rotation_axis& o);
friend void from_json(const nlohmann::json& j, Rotation_axis& o);
protected:
std::string m_Name;
bool m_NameIsSet;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -197,7 +197,7 @@ bool Spot_finding_settings::operator!=(const Spot_finding_settings& rhs) const
void to_json(nlohmann::json& j, const Spot_finding_settings& o)
{
j = nlohmann::json();
j = nlohmann::json::object();
j["enable"] = o.m_Enable;
j["indexing"] = o.m_Indexing;
if(o.filterPowderRingsIsSet())

View File

@@ -2,7 +2,7 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.0_rc.11
* The version of the OpenAPI document: 1.0.0-rc.12
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -117,8 +117,8 @@ public:
float getIndexingTolerance() const;
void setIndexingTolerance(float const value);
friend void to_json(nlohmann::json& j, const Spot_finding_settings& o);
friend void from_json(const nlohmann::json& j, Spot_finding_settings& o);
friend void to_json(nlohmann::json& j, const Spot_finding_settings& o);
friend void from_json(const nlohmann::json& j, Spot_finding_settings& o);
protected:
bool m_Enable;

View File

@@ -2,7 +2,7 @@ openapi: 3.0.3
info:
title: Jungfraujoch
description: Jungfraujoch Broker Web API
version: 1.0.0_rc.11
version: 1.0.0-rc.12
contact:
email: filip.leonarski@psi.ch
components:
@@ -198,6 +198,16 @@ components:
description: |
Name of group owning the data (e.g. p-group or proposal number).
Transferred over CBOR stream, though not saved in HDF5 file.
poisson_compression:
type: integer
format: int64
minimum: 0
maximum: 16
description: |
Enable lossy compression of pixel values that preserves Poisson statistics.
Requires to provide a numerical factor SQ.
Pixel value P will be transformed to round(sqrt(P) * SQ), with rounding to the closest integer.
Compression is turned off if the value is missing or it is set to zero.
unit_cell:
type: object
description: Units of angstrom and degree

File diff suppressed because one or more lines are too long

View File

@@ -299,14 +299,14 @@ int64_t DatasetSettings::GetImagesPerFile() const {
return images_per_file;
}
DatasetSettings &DatasetSettings::DataReductionFactorSerialMX(float input) {
DatasetSettings &DatasetSettings::LossyCompressionSerialMX(float input) {
check_min("Data reduction factor for serial MX", input, 0.0);
check_max("Data reduction factor for serial MX", input, 1.0);
data_reduction_factor_serialmx = input;
return *this;
}
float DatasetSettings::GetDataReductionFactorSerialMX() const {
float DatasetSettings::GetLossyCompressionSerialMX() const {
return data_reduction_factor_serialmx;
}
@@ -355,3 +355,18 @@ DatasetSettings &DatasetSettings::ImageTime(const std::optional<std::chrono::mic
image_time = input;
return *this;
}
DatasetSettings &DatasetSettings::LossyCompressionPoisson(std::optional<int64_t> input) {
if (!input || (input == 0))
compression_poisson_factor = {};
else {
check_min("Poisson compression factor", input.value(), 1);
check_max("Poisson compression factor", input.value(), 16);
compression_poisson_factor = input;
}
return *this;
}
std::optional<int64_t> DatasetSettings::GetLossyCompressionPoisson() const {
return compression_poisson_factor;
}

View File

@@ -51,6 +51,7 @@ class DatasetSettings {
std::optional<uint64_t> run_number;
std::optional<std::string> run_name;
std::string group;
std::optional<int64_t> compression_poisson_factor;
public:
DatasetSettings();
@@ -75,12 +76,14 @@ public:
DatasetSettings& PhotonEnergyMultiplayer(float input);
DatasetSettings& FPGAOutputMode(FPGAPixelOutput input);
DatasetSettings& ImagesPerFile(int64_t input);
DatasetSettings& DataReductionFactorSerialMX(float input);
DatasetSettings& RunNumber(const std::optional<uint64_t> &run_number);
DatasetSettings& RunName(const std::optional<std::string> &input);
DatasetSettings& ExperimentGroup(const std::string &group);
DatasetSettings& ImageTime(const std::optional<std::chrono::microseconds> input);
DatasetSettings& LossyCompressionSerialMX(float input);
DatasetSettings& LossyCompressionPoisson(std::optional<int64_t> input);
std::optional<float> GetAttenuatorTransmission() const;
std::optional<float> GetTotalFlux() const;
std::optional<GoniometerAxis> GetGoniometer() const;
@@ -106,12 +109,14 @@ public:
int64_t GetNumTriggers() const;
int64_t GetImageNumPerTrigger() const;
int64_t GetImagesPerFile() const;
float GetDataReductionFactorSerialMX() const;
std::optional<uint64_t> GetRunNumber() const;
std::optional<std::string> GetRunName() const;
std::string GetExperimentGroup() const;
std::optional<std::chrono::microseconds> GetImageTime() const;
float GetLossyCompressionSerialMX() const;
std::optional<int64_t> GetLossyCompressionPoisson() const;
};
#endif //JUNGFRAUJOCH_DATASETSETTINGS_H

View File

@@ -761,7 +761,7 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
for (const auto &[x, y]: roi_mask.GetROINameMap())
message.roi_names.emplace_back(x);
message.data_reduction_factor_serialmx = GetDataReductionFactorSerialMX();
message.data_reduction_factor_serialmx = GetLossyCompressionSerialMX();
message.experiment_group = dataset.GetExperimentGroup();
message.jfjoch_release = jfjoch_version();
message.detector_serial_number = detector.GetSerialNumber();
@@ -1205,12 +1205,21 @@ int64_t DiffractionExperiment::GetSendBufferLocationSize() const {
return GetMaxCompressedSize() + 1024 * 1024;
}
float DiffractionExperiment::GetDataReductionFactorSerialMX() const {
return dataset.GetDataReductionFactorSerialMX();
float DiffractionExperiment::GetLossyCompressionSerialMX() const {
return dataset.GetLossyCompressionSerialMX();
}
DiffractionExperiment &DiffractionExperiment::DataReductionFactorSerialMX(float input) {
dataset.DataReductionFactorSerialMX(input);
DiffractionExperiment &DiffractionExperiment::LossyCompressionSerialMX(float input) {
dataset.LossyCompressionSerialMX(input);
return *this;
}
std::optional<int64_t> DiffractionExperiment::GetLossyCompressionPoisson() const {
return dataset.GetLossyCompressionPoisson();
}
DiffractionExperiment &DiffractionExperiment::LossyCompressionPoisson(std::optional<int64_t> input) {
dataset.LossyCompressionPoisson(input);
return *this;
}

View File

@@ -171,7 +171,8 @@ public:
DiffractionExperiment& FPGAOutputMode(FPGAPixelOutput input);
DiffractionExperiment& MaxSpotCount(int64_t input);
DiffractionExperiment& ImagesPerFile(int64_t input);
DiffractionExperiment& DataReductionFactorSerialMX(float input);
DiffractionExperiment& LossyCompressionSerialMX(float input);
DiffractionExperiment& LossyCompressionPoisson(std::optional<int64_t> input);
DiffractionExperiment& ImportDatasetSettings(const DatasetSettings& input);
DatasetSettings GetDatasetSettings() const;
@@ -324,7 +325,8 @@ public:
void ExportROIMap(uint16_t *v, size_t module_number) const;
int64_t GetImagesPerFile() const;
float GetDataReductionFactorSerialMX() const;
float GetLossyCompressionSerialMX() const;
std::optional<int64_t> GetLossyCompressionPoisson() const;
std::string GetExperimentGroup() const;
};

View File

@@ -12,8 +12,6 @@ ELSE()
MESSAGE(STATUS "Xilinx HLS compiler not found")
ENDIF()
INCLUDE_DIRECTORIES(include)
ADD_SUBDIRECTORY(hls)
ADD_SUBDIRECTORY(pcie_driver)
ADD_SUBDIRECTORY(host_library)

View File

@@ -75,7 +75,9 @@
`define ADDR_NSTORAGE_CELLS 16'h021C
`define ADDR_NSUMMATION 16'h0220
`define ADDR_DATA_SOURCE 16'h0224
`define ADDR_SQRTMULT 16'h0224
`define ADDR_DATA_SOURCE 16'h0300
module action_config
#(parameter C_S_AXI_ADDR_WIDTH = 16,
@@ -114,6 +116,7 @@ module action_config
output reg [4:0] nmodules ,
output reg [3:0] nstorage_cells ,
output reg [7:0] nsummation ,
output reg [7:0] sqrtmult ,
output reg [1:0] data_source ,
output wire [31:0] hbm_size_bytes ,
@@ -366,6 +369,9 @@ always @(posedge clk) begin
`ADDR_NSUMMATION: begin
rdata <= nsummation;
end
`ADDR_SQRTMULT: begin
rdata <= sqrtmult;
end
`ADDR_DATA_SOURCE: begin
rdata <= data_source;
end
@@ -639,6 +645,15 @@ always @(posedge clk) begin
end
end
always @(posedge clk) begin
if (!resetn)
sqrtmult <= 0;
else if (reg_data_collection_idle) begin
if (w_hs && waddr == `ADDR_SQRTMULT)
sqrtmult <= (s_axi_WDATA[7:0] & wmask[7:0]) | (sqrtmult & !wmask[7:0]);
end
end
always @(posedge clk) begin
if (!resetn)
data_source <= 0;

View File

@@ -31,11 +31,15 @@ ADD_LIBRARY( JFJochHLSSimulation STATIC
spot_finder_mask.cpp
save_to_hbm_data.cpp
eiger_reorder.cpp
roi_calc.cpp)
roi_calc.cpp
pixel_sqrt.cpp
HLSDevice.cpp
HLSDevice.h)
TARGET_INCLUDE_DIRECTORIES(JFJochHLSSimulation PUBLIC ../include)
TARGET_LINK_LIBRARIES(JFJochHLSSimulation JFJochCommon)
TARGET_COMPILE_DEFINITIONS(JFJochHLSSimulation PUBLIC -DJFJOCH_HLS_NOSYNTH)
TARGET_INCLUDE_DIRECTORIES(JFJochHLSSimulation PUBLIC ../include)
ADD_EXECUTABLE(frame_summation_tb frame_summation_tb.cpp)
TARGET_LINK_LIBRARIES(frame_summation_tb JFJochHLSSimulation)
@@ -54,55 +58,69 @@ TARGET_LINK_LIBRARIES(adu_histo_tb JFJochHLSSimulation)
IF(VIVADO_HLS)
IF(NOT HLS_SOLUTION_NAME)
SET(HLS_SOLUTION_NAME base1)
ENDIF()
GET_FILENAME_COMPONENT(VITIS_HLS_DIR ${VIVADO_HLS} DIRECTORY)
FIND_FILE(HLS_MATH_H hls_math.h HINT ${VITIS_HLS_DIR}/../include)
IF (HLS_MATH_H)
GET_FILENAME_COMPONENT(VITIS_HLS_INCLUDE_DIR ${HLS_MATH_H} DIRECTORY)
MESSAGE(STATUS "Xilinx HLS headers included")
SET (HLS_IPS "")
#TARGET_INCLUDE_DIRECTORIES(JFJochHLSSimulation PUBLIC ${VITIS_HLS_INCLUDE_DIR})
#TARGET_COMPILE_DEFINITIONS(JFJochHLSSimulation PUBLIC JFJOCH_USE_HLS_HEADERS)
ELSE()
MESSAGE(WARNING "Xilinx HLS headers missing")
#TARGET_INCLUDE_DIRECTORIES(JFJochHLSSimulation PUBLIC ../include)
ENDIF()
FUNCTION( MAKE_HLS_MODULE FUNCTION_NAME SRC_FILE TB_FILE)
ADD_CUSTOM_COMMAND(OUTPUT psi_ch_hls_${FUNCTION_NAME}_1_0.zip
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 ../pcie_driver/jfjoch_fpga.h)
SET (HLS_IPS ${HLS_IPS} psi_ch_hls_${FUNCTION_NAME}_1_0.zip PARENT_SCOPE)
ENDFUNCTION(MAKE_HLS_MODULE)
IF(NOT HLS_SOLUTION_NAME)
SET(HLS_SOLUTION_NAME base1)
ENDIF()
MAKE_HLS_MODULE(data_collection_fsm data_collection_fsm.cpp "")
MAKE_HLS_MODULE(timer_host timer.cpp "")
MAKE_HLS_MODULE(jf_conversion jf_conversion.cpp "")
MAKE_HLS_MODULE(load_calibration load_calibration.cpp "")
MAKE_HLS_MODULE(host_writer host_writer.cpp "")
MAKE_HLS_MODULE(icmp icmp.cpp "")
MAKE_HLS_MODULE(ipv4 ipv4.cpp "")
MAKE_HLS_MODULE(ethernet ethernet.cpp "")
MAKE_HLS_MODULE(arp arp.cpp "")
MAKE_HLS_MODULE(udp udp.cpp "")
MAKE_HLS_MODULE(sls_detector sls_detector.cpp "")
MAKE_HLS_MODULE(frame_generator frame_generator.cpp "")
MAKE_HLS_MODULE(stream_merge stream_merge.cpp "")
MAKE_HLS_MODULE(load_from_hbm load_from_hbm.cpp "")
MAKE_HLS_MODULE(save_to_hbm save_to_hbm.cpp "")
MAKE_HLS_MODULE(save_to_hbm_data save_to_hbm_data.cpp "")
MAKE_HLS_MODULE(mask_missing mask_missing.cpp "")
MAKE_HLS_MODULE(integration integration.cpp integration_tb.cpp)
MAKE_HLS_MODULE(spot_finder spot_finder.cpp spot_finder_tb.cpp)
MAKE_HLS_MODULE(axis_broadcast axis_broadcast.cpp "")
MAKE_HLS_MODULE(axis_64_to_512 axis_helpers.cpp "")
MAKE_HLS_MODULE(axis_32_to_512 axis_helpers.cpp "")
MAKE_HLS_MODULE(adu_histo adu_histo.cpp adu_histo_tb.cpp)
MAKE_HLS_MODULE(pedestal pedestal.cpp "")
MAKE_HLS_MODULE(frame_summation frame_summation.cpp frame_summation_tb_2.cpp)
MAKE_HLS_MODULE(frame_summation_reorder_compl frame_summation_reorder_compl.cpp "")
MAKE_HLS_MODULE(stream_24bit_conv stream_24bit_conv.cpp stream_24bit_conv_tb.cpp)
MAKE_HLS_MODULE(spot_finder_mask spot_finder_mask.cpp "")
MAKE_HLS_MODULE(spot_finder_merge spot_finder_merge.cpp "")
MAKE_HLS_MODULE(spot_finder_connectivity spot_finder_connectivity.cpp "")
MAKE_HLS_MODULE(eiger_reorder eiger_reorder.cpp "")
MAKE_HLS_MODULE(roi_calc roi_calc.cpp "")
SET (HLS_IPS "")
SET (HLS_IPS ${HLS_IPS} PARENT_SCOPE)
ADD_CUSTOM_TARGET(hls DEPENDS ${HLS_IPS})
FUNCTION( MAKE_HLS_MODULE FUNCTION_NAME SRC_FILE TB_FILE)
ADD_CUSTOM_COMMAND(OUTPUT psi_ch_hls_${FUNCTION_NAME}_1_0.zip
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 ../pcie_driver/jfjoch_fpga.h)
SET (HLS_IPS ${HLS_IPS} psi_ch_hls_${FUNCTION_NAME}_1_0.zip PARENT_SCOPE)
ENDFUNCTION(MAKE_HLS_MODULE)
MAKE_HLS_MODULE(data_collection_fsm data_collection_fsm.cpp "")
MAKE_HLS_MODULE(timer_host timer.cpp "")
MAKE_HLS_MODULE(jf_conversion jf_conversion.cpp "")
MAKE_HLS_MODULE(load_calibration load_calibration.cpp "")
MAKE_HLS_MODULE(host_writer host_writer.cpp "")
MAKE_HLS_MODULE(pixel_sqrt pixel_sqrt.cpp pixel_sqrt_tb.cpp)
MAKE_HLS_MODULE(icmp icmp.cpp "")
MAKE_HLS_MODULE(ipv4 ipv4.cpp "")
MAKE_HLS_MODULE(ethernet ethernet.cpp "")
MAKE_HLS_MODULE(arp arp.cpp "")
MAKE_HLS_MODULE(udp udp.cpp "")
MAKE_HLS_MODULE(sls_detector sls_detector.cpp "")
MAKE_HLS_MODULE(frame_generator frame_generator.cpp "")
MAKE_HLS_MODULE(stream_merge stream_merge.cpp "")
MAKE_HLS_MODULE(load_from_hbm load_from_hbm.cpp "")
MAKE_HLS_MODULE(save_to_hbm save_to_hbm.cpp "")
MAKE_HLS_MODULE(save_to_hbm_data save_to_hbm_data.cpp "")
MAKE_HLS_MODULE(mask_missing mask_missing.cpp "")
MAKE_HLS_MODULE(integration integration.cpp integration_tb.cpp)
MAKE_HLS_MODULE(spot_finder spot_finder.cpp spot_finder_tb.cpp)
MAKE_HLS_MODULE(axis_broadcast axis_broadcast.cpp "")
MAKE_HLS_MODULE(axis_64_to_512 axis_helpers.cpp "")
MAKE_HLS_MODULE(axis_32_to_512 axis_helpers.cpp "")
MAKE_HLS_MODULE(adu_histo adu_histo.cpp adu_histo_tb.cpp)
MAKE_HLS_MODULE(pedestal pedestal.cpp "")
MAKE_HLS_MODULE(frame_summation frame_summation.cpp frame_summation_tb_2.cpp)
MAKE_HLS_MODULE(frame_summation_reorder_compl frame_summation_reorder_compl.cpp "")
MAKE_HLS_MODULE(stream_24bit_conv stream_24bit_conv.cpp stream_24bit_conv_tb.cpp)
MAKE_HLS_MODULE(spot_finder_mask spot_finder_mask.cpp "")
MAKE_HLS_MODULE(spot_finder_merge spot_finder_merge.cpp "")
MAKE_HLS_MODULE(spot_finder_connectivity spot_finder_connectivity.cpp "")
MAKE_HLS_MODULE(eiger_reorder eiger_reorder.cpp "")
MAKE_HLS_MODULE(roi_calc roi_calc.cpp "")
SET (HLS_IPS ${HLS_IPS} PARENT_SCOPE)
ADD_CUSTOM_TARGET(hls DEPENDS ${HLS_IPS})
ENDIF()

791
fpga/hls/HLSDevice.cpp Normal file
View File

@@ -0,0 +1,791 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include <future>
#include <bitset>
#include <arpa/inet.h>
#include "HLSDevice.h"
#include "hls_jfjoch.h"
#include "datamover_model.h"
#include "../../jungfrau/sls_packet.h"
#include "../../common/Logger.h"
#include "../../common/JFJochException.h"
struct HLSDeviceImpl {
AXI_STREAM din_eth;
AXI_STREAM din_frame_generator;
AXI_STREAM dout_eth;
constexpr static const size_t hbm_if_count = 32;
constexpr static const size_t hbm_if_size = 32 * 1024 * 1024LU;
ap_uint<2> data_source = STREAM_MERGE_SRC_NETWORK;
std::vector<ap_uint<256>> hbm;
hls::stream<ap_uint<32> > work_request_stream;
hls::stream<ap_uint<32> > completion_stream;
Datamover<512> datamover_in;
Datamover<512> datamover_out;
Datamover<256> datamover_in_hbm_0;
Datamover<256> datamover_in_hbm_1;
Datamover<256, 16> datamover_out_hbm_0;
Datamover<256, 16> datamover_out_hbm_1;
ap_uint<1> run_data_collection;
ap_uint<1> cancel_data_collection;
volatile ap_uint<1> host_writer_idle;
HLSDeviceImpl()
: hbm(hbm_if_size / 32 * hbm_if_count),
datamover_in(Direction::Input, nullptr),
datamover_out(Direction::Output, nullptr),
datamover_out_hbm_0(Direction::Output, (char *) hbm.data()),
datamover_out_hbm_1(Direction::Output, (char *) hbm.data()),
datamover_in_hbm_0(Direction::Input, (char *) hbm.data()),
datamover_in_hbm_1(Direction::Input, (char *) hbm.data()) {}
};
uint16_t checksum(const uint16_t *addr, size_t count) {
/* Compute Internet Checksum for "count" bytes
* beginning at location "addr".
*/
long sum = 0;
for (int i = 0; i < count / 2; i++)
sum += addr[i];
/* Add left-over byte, if any */
if (count % 2 == 1)
sum += ((uint8_t *) addr)[count / 2];
/* Fold 32-bit sum to 16 bits */
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
return ~sum;
}
HLSDevice::HLSDevice(std::vector<DeviceOutput *> &buffer_device) : idle(true), dma_address_table(65536) {
impl_ = std::make_unique<HLSDeviceImpl>();
auto in_mem_location32 = (uint32_t *) dma_address_table.data();
for (int i = 0; i < buffer_device.size(); i++) {
in_mem_location32[2 * i ] = ((uint64_t) buffer_device[i]) & UINT32_MAX;
in_mem_location32[2 * i + 1] = ((uint64_t) buffer_device[i]) >> 32;
}
}
HLSDevice::~HLSDevice() {
if (action_thread.joinable())
action_thread.join();
impl_.reset();
}
void HLSDevice::CreateFinalPacket(const DiffractionExperiment& experiment) {
CreateJFPacket(experiment, UINT64_MAX, 0, 0, nullptr, false);
}
void HLSDevice::SendPacket(char *buffer, int len, uint8_t user) {
auto obuff = (ap_uint<512> *)buffer;
for (int i = 0; i < (len + 63) / 64; i++) {
packet_512_t packet_in;
if (i == (len + 63) / 64 - 1) packet_in.last = 1;
else packet_in.last = 0;
packet_in.keep = 0xFFFFFFFFFFFFFFFF;
packet_in.user = user;
packet_in.data = obuff[i];
impl_->din_eth.write(packet_in);
}
}
void HLSDevice::CreateJFPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, int8_t adjust_axis, uint8_t user) {
char buff[256*64];
memset(buff, 0, 256*64);
auto packet = (jf_raw_packet *)buff;
packet->ether_type = htons(0x0800);
packet->sour_mac[0] = 0x00; // module 0
uint64_t tmp_mac = mac_addr;
for (int i = 0; i < 6; i++)
packet->dest_mac[i] = (tmp_mac >> (8*i)) % 256;
uint32_t half_module = 2 * module_number | ((eth_packet >= 64) ? 1 : 0);
packet->ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet->ipv4_header_total_length = htons(8268); // Big endian in IP header!
packet->ipv4_header_dest_ip = ipv4_addr;
packet->ipv4_header_sour_ip = experiment.GetSrcIPv4Address(0, half_module);
packet->ipv4_header_ttl_protocol = htons(0x0011);
packet->ipv4_header_checksum = checksum( (uint16_t *) &packet->ipv4_header_h, 20); // checksum is already in network order
packet->udp_dest_port = htons(234); // port doesn't matter
packet->udp_sour_port = htons(0xDFAC);
packet->udp_length = htons(8248);
// JF headers are little endian
packet->jf.detectortype = SLS_DETECTOR_TYPE_JUNGFRAU;
packet->jf.timestamp = 0xABCDEF0000FEDCBAL;
packet->jf.bunchid = 0x1234567898765431L;
packet->jf.row = half_module;
packet->jf.column = 0;
packet->jf.framenum = frame_number;
packet->jf.packetnum = eth_packet % 64;
if (data != nullptr) {
for (int i = 0; i < 4096; i++)
packet->jf.data[i] = data[i];
}
packet->udp_checksum = htons(checksum( (uint16_t *) (buff+42), 8192+48));
SendPacket(buff, (130+adjust_axis)*64, user);
}
void HLSDevice::CreateJFPackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
uint32_t module_number, const uint16_t *data) {
for (uint64_t i = 0; i < frames; i++) {
for (int j = 0; j < 128; j++)
CreateJFPacket(experiment, frame_number_0 + i, j, module_number, data + (i * 128 + j) * 4096, 0, 0);
}
}
void HLSDevice::CreateEIGERPacket(const DiffractionExperiment &experiment, uint64_t frame_number,
uint32_t eth_packet, uint32_t module_number, uint32_t col, uint32_t row,
const uint16_t *data) {
char buff[256*64];
memset(buff, 0, 256*64);
auto packet = (eiger_raw_packet *)buff;
packet->ether_type = htons(0x0800);
packet->sour_mac[0] = 0x00; // module 0
uint64_t tmp_mac = mac_addr;
for (int i = 0; i < 6; i++)
packet->dest_mac[i] = (tmp_mac >> (8*i)) % 256;
packet->ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet->ipv4_header_total_length = htons(4172); // Big endian in IP header!
packet->ipv4_header_dest_ip = ipv4_addr;
packet->ipv4_header_sour_ip = experiment.GetSrcIPv4Address(0, 0);
packet->ipv4_header_ttl_protocol = htons(0x0011);
packet->ipv4_header_checksum = checksum( (uint16_t *) &packet->ipv4_header_h, 20); // checksum is already in network order
packet->udp_dest_port = htons(234); // ignored
packet->udp_sour_port = htons(0xDFAC);
packet->udp_length = htons(4152);
// JF headers are little endian
packet->eiger.detectortype = SLS_DETECTOR_TYPE_EIGER;
packet->eiger.timestamp = 0xABCDEF0000FEDCBAL;
packet->eiger.bunchid = 0x1234567898765431L;
packet->eiger.row = (2 * module_number) | (row % 2);
packet->eiger.column = col % 2;
packet->eiger.framenum = frame_number;
packet->eiger.packetnum = eth_packet % 64;
if (data != nullptr) {
for (int i = 0; i < 2048; i++)
packet->eiger.data[i] = data[i];
}
packet->udp_checksum = htons(checksum( (uint16_t *) (buff+42), 4096+48));
SendPacket(buff, 66*64, 0);
}
void HLSDevice::HW_ReadActionRegister(DataCollectionConfig *job) {
memcpy(job, &cfg, sizeof(DataCollectionConfig));
}
void HLSDevice::HW_WriteActionRegister(const DataCollectionConfig *job) {
memcpy(&cfg, job, sizeof(DataCollectionConfig));
}
void HLSDevice::FPGA_StartAction(const DiffractionExperiment &experiment) {
if (action_thread.joinable())
action_thread.join();
run_counter += 1;
impl_->run_data_collection = 1;
impl_->cancel_data_collection = 0;
idle = false;
while (!impl_->din_frame_generator.empty())
impl_->din_frame_generator.read();
impl_->datamover_out.ClearCompletedDescriptors();
action_thread = std::thread(&HLSDevice::HLSMainThread, this );
}
void HLSDevice::FrameGeneratorFuture(FrameGeneratorConfig config) {
frame_generator(impl_->din_frame_generator,
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm_if_size,
mac_addr,
ipv4_addr,
impl_->cancel_data_collection,
config);
}
void HLSDevice::HW_RunInternalGenerator(const FrameGeneratorConfig &config) {
frame_generator_future = std::async(std::launch::async, &HLSDevice::FrameGeneratorFuture, this, config);
}
void HLSDevice::FPGA_EndAction() {
if (action_thread.joinable())
action_thread.join();
}
bool HLSDevice::HW_ReadMailbox(uint32_t *values) {
std::unique_lock<std::mutex> ul(completion_mutex);
ap_uint<32> tmp;
bool ret = impl_->completion_stream.read_nb(tmp);
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) && (data_collection_id != DATA_COLLECTION_ID_PURGE)) {
completion_count++;
while (completion_count * DMA_DESCRIPTORS_PER_MODULE > impl_->datamover_out.GetCompletedDescriptors())
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
return ret;
}
void HLSDevice::Cancel() {
impl_->cancel_data_collection = 1;
}
bool HLSDevice::HW_IsIdle() const {
return idle && impl_->datamover_out.IsIdle();
}
bool HLSDevice::HW_SendWorkRequest(uint32_t handle) {
impl_->work_request_stream.write(handle);
return true;
}
inline uint32_t float2uint(float f) {
float_uint32 fu;
fu.f = f;
return fu.u;
}
void HLSDevice::HLSMainThread() {
ap_uint<1> clear_counters = 0;
uint64_t packets_processed;
std::vector<std::thread> hls_cores;
STREAM_512 ip1, udp1, udp2, icmp1, arp1;
STREAM_512 network0;
STREAM_768 stream_768_0;
STREAM_768 stream_768_1;
STREAM_768 stream_768_2;
STREAM_768 stream_768_3;
STREAM_768 stream_768_4;
STREAM_768 stream_768_5;
STREAM_768 stream_768_6;
STREAM_512 data_0;
hls::stream<ap_axiu<512, 1, 1, 1>, 2> data_1;
hls::stream<ap_axiu<512, 1, 1, 1>, 2> data_2;
STREAM_512 data_3;
STREAM_512 data_4;
STREAM_512 data_5;
STREAM_512 data_6;
STREAM_512 data_7;
STREAM_512 data_8;
STREAM_512 data_9;
STREAM_512 data_10;
STREAM_512 data_12;
STREAM_512 data_13;
hls::stream<axis_addr> addr0;
hls::stream<axis_addr> addr1;
hls::stream<axis_addr> addr2;
hls::stream<axis_addr> addr3;
hls::stream<axis_completion> axi_compl[12];
hls::stream<ap_uint<16>> hbm_handles;
hls::stream<ap_uint<512>> adu_histo_result;
hls::stream<ap_axiu<64,1,1,1>> integration_result_0;
hls::stream<ap_uint<512>> integration_result_1;
hls::stream<ap_axiu<32,1,1,1>> spot_finder_result_0;
hls::stream<ap_axiu<32,1,1,1>> spot_finder_result_1;
hls::stream<ap_uint<32>> spot_finder_conn_0;
hls::stream<ap_axiu<32,1,1,1>> spot_finder_result_2;
hls::stream<ap_uint<512>> spot_finder_result_3;
hls::stream<ap_uint<32>> spot_finder_mask_0;
hls::stream<ap_uint<256>> roi_calc_result_0;
hls::stream<ap_uint<UDP_METADATA_STREAM_WIDTH> > udp_metadata;
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;
volatile bool done = false;
volatile bool udp_done = false; // done AND udp_idle
volatile bool sls_done = false; // done AND sls_idle
// Sent gratuitous ARP message
arp(arp1, impl_->dout_eth, mac_addr, ipv4_addr, 1, 1);
Logger logger_hls("HLS");
volatile rcv_state_t state = RCV_INIT;
// Start data collection
data_collection_fsm(data_0, data_1,
addr0, addr1,
impl_->run_data_collection,
impl_->cancel_data_collection,
idle_data_collection,
cfg.mode,
float2uint(cfg.energy_kev),
cfg.nframes,
cfg.nmodules,
cfg.nstorage_cells,
cfg.nsummation ,
cfg.sqrtmult, state);
impl_->run_data_collection = 0;
data_collection_fsm(data_0, data_1,
addr0, addr1,
impl_->run_data_collection,
impl_->cancel_data_collection,
idle_data_collection,
cfg.mode,
float2uint(cfg.energy_kev),
cfg.nframes,
cfg.nmodules,
cfg.nstorage_cells,
cfg.nsummation,
cfg.sqrtmult,
state);
hls_cores.emplace_back([&] {
while (!udp_done) {
if (impl_->din_eth.empty() && impl_->din_frame_generator.empty())
std::this_thread::sleep_for(std::chrono::microseconds(10));
else
stream_merge(impl_->din_eth, impl_->din_frame_generator, network0, impl_->data_source);
}
logger_hls.Info("Stream_merge done");
});
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");
});
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");
});
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, data_0, addr0, sls_packets, udp_eth_err, udp_len_err, current_pulse_id,
clear_counters, sls_idle);
}
sls_done = true;
logger_hls.Info("sls_detector done");
});
// 1. Parse incoming UDP packets
hls_cores.emplace_back([&] {
while ((state != RCV_WAIT_FOR_START) || (idle_data_collection.read() == 0) || (!data_0.empty())) {
data_collection_fsm(data_0, data_1,
addr0, addr1,
impl_->run_data_collection,
impl_->cancel_data_collection,
idle_data_collection,
cfg.mode,
float2uint(cfg.energy_kev),
cfg.nframes,
cfg.nmodules,
cfg.nstorage_cells,
cfg.nsummation,
cfg.sqrtmult,
state);
}
done = true;
logger_hls.Info("data collection done");
});
// 2. Cache images in HBM
hls_cores.emplace_back([&] { save_to_hbm(addr1, axi_compl[0], hbm_handles,
impl_->datamover_out_hbm_0.GetCtrlStream(),
impl_->datamover_out_hbm_1.GetCtrlStream(),
save_to_hbm_idle,
impl_->hbm_if_size);});
hls_cores.emplace_back([&] { save_to_hbm_data(data_1,
data_3,
impl_->datamover_out_hbm_0.GetDataStream(),
impl_->datamover_out_hbm_1.GetDataStream());});
hls_cores.emplace_back([&] {frame_summation_reorder_compl(data_3, data_4, axi_compl[0], axi_compl[1]);});
hls_cores.emplace_back([&] { load_from_hbm(data_4, data_5, axi_compl[1], axi_compl[2], hbm_handles,
impl_->datamover_in_hbm_0.GetDataStream(), impl_->datamover_in_hbm_1.GetDataStream(),
impl_->datamover_in_hbm_0.GetCtrlStream(), impl_->datamover_in_hbm_1.GetCtrlStream(),
load_to_hbm_idle, impl_->hbm_if_size);});
hls_cores.emplace_back([&] { pedestal(data_5, data_6, axi_compl[2], axi_compl[3],
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm_if_size);});
// 3. Calculate histogram of ADU values
hls_cores.emplace_back([&] { adu_histo(data_6, data_7, adu_histo_result, axi_compl[3], axi_compl[4]);});
// 4. Mask missing pixels
hls_cores.emplace_back([&] { mask_missing(data_7, data_8, axi_compl[4], axi_compl[5]);});
// 5. Handle EIGER packets properly
hls_cores.emplace_back([&] { eiger_reorder(data_8, data_9, axi_compl[5], axi_compl[6]);});
// 6. Apply pedestal & gain corrections
hls_cores.emplace_back([&] { jf_conversion(data_9, stream_768_0,
axi_compl[6], axi_compl[7],
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm_if_size); });
// 7. Frame summation
hls_cores.emplace_back([&] { frame_summation(stream_768_0, stream_768_1, axi_compl[7], axi_compl[8], frame_summation_idle);});
// 8. Integration of pixels
hls_cores.emplace_back([&] { integration(stream_768_1, stream_768_2, integration_result_0, axi_compl[8], axi_compl[9],
impl_->hbm.data(), impl_->hbm.data(), impl_->hbm.data(), impl_->hbm.data(), integration_idle, impl_->hbm_if_size);});
hls_cores.emplace_back([&] { axis_64_to_512(integration_result_0, integration_result_1);});
// 9. Spot finding
ap_uint<32> tmp_snr_threshold = float2uint(spot_finder_parameters.snr_threshold);
ap_uint<32> min_d = float2uint(spot_finder_parameters.min_d);
ap_uint<32> max_d = float2uint(spot_finder_parameters.max_d);
ap_int<32> tmp_count_threshold = spot_finder_parameters.count_threshold;
ap_uint<32> min_pix_per_spot = spot_finder_parameters.min_pix_per_spot;
hls_cores.emplace_back([&] {
spot_finder_mask(stream_768_2,
stream_768_3,
spot_finder_mask_0,
axi_compl[9],
axi_compl[10],
impl_->hbm.data(),
impl_->hbm.data(),
min_d,
max_d,
impl_->hbm_if_size);
logger_hls.Info("spot_finder_mask done");
});
hls_cores.emplace_back([&] {
spot_finder(stream_768_3, spot_finder_mask_0, stream_768_4, spot_finder_result_0, tmp_count_threshold, tmp_snr_threshold);
logger_hls.Info("spot_finder done");
});
hls_cores.emplace_back([&] {
spot_finder_connectivity(spot_finder_result_0,
spot_finder_result_1,
spot_finder_conn_0);
logger_hls.Info("spot_finder_connectivity done");
});
hls_cores.emplace_back([&] {
spot_finder_merge(spot_finder_result_1,
spot_finder_conn_0,
spot_finder_result_2,
min_pix_per_spot);
logger_hls.Info("spot_finder_merge done");
});
hls_cores.emplace_back([&] {
axis_32_to_512(spot_finder_result_2, spot_finder_result_3);
logger_hls.Info("axis_32_to_512 done");
});
// 10. ROI calculation
hls_cores.emplace_back([&] {
roi_calc(stream_768_4,
stream_768_5,
roi_calc_result_0,
axi_compl[10],
axi_compl[11],
impl_->hbm.data(),
impl_->hbm.data(),
impl_->hbm_if_size);
logger_hls.Info("roi_calc done");
});
// 11. Pixel sq root
hls_cores.emplace_back([&] {
pixel_sqrt(stream_768_5,
stream_768_6);
logger_hls.Info("pixel_sqrt done");
});
// 12. Reduce/extend 24-bit stream
hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_6, data_12, stream_conv_idle);});
// 13. Prepare data to write to host memory
hls_cores.emplace_back([&] {
ap_uint<3> state;
host_writer(data_12, adu_histo_result, integration_result_1, spot_finder_result_3, roi_calc_result_0,
axi_compl[11], impl_->datamover_out.GetDataStream(),
impl_->datamover_out.GetCtrlStream(), impl_->work_request_stream, impl_->completion_stream,
dma_address_table.data(), packets_processed, impl_->host_writer_idle, impl_->cancel_data_collection, state);
logger_hls.Info("host_writer done");
});
for (auto &i : hls_cores)
i.join();
if (frame_generator_future.valid())
frame_generator_future.get();
// reset static counter
arp(arp1, impl_->dout_eth, mac_addr, ipv4_addr, 0, 1);
try {
while (!impl_->din_eth.empty())
impl_->din_eth.read();
if (!addr1.empty())
throw std::runtime_error("Addr1 queue not empty");
if (!addr2.empty())
throw std::runtime_error("Addr2 queue not empty");
if (!addr3.empty())
throw std::runtime_error("Addr3 queue not empty");
if (!data_1.empty())
throw std::runtime_error("data_1 queue not empty");
if (!data_2.empty())
throw std::runtime_error("data_2 queue not empty");
if (!data_3.empty())
throw std::runtime_error("data_3 queue not empty");
if (!data_4.empty())
throw std::runtime_error("data_4 queue not empty");
if (!data_5.empty())
throw std::runtime_error("data_5 queue not empty");
if (!data_7.empty())
throw std::runtime_error("data_7 queue not empty");
if (!data_8.empty())
throw std::runtime_error("data_8 queue not empty");
if (!data_9.empty())
throw std::runtime_error("data_9 queue not empty");
if (!data_10.empty())
throw std::runtime_error("data_10 queue not empty");
if (!data_12.empty())
throw std::runtime_error("data_12 queue not empty");
if (!data_13.empty())
throw std::runtime_error("data_13 queue not empty");
for (auto &c: axi_compl) {
if (!c.empty())
throw std::runtime_error("Compl queue not empty");
}
if (!stream_768_0.empty())
throw std::runtime_error("stream_768_0 queue not empty");
if (!stream_768_1.empty())
throw std::runtime_error("stream_768_1 queue not empty");
if (!stream_768_2.empty())
throw std::runtime_error("stream_768_2 queue not empty");
if (!stream_768_3.empty())
throw std::runtime_error("stream_768_3 queue not empty");
if (!stream_768_4.empty())
throw std::runtime_error("stream_768_4 queue not empty");
if (!hbm_handles.empty())
throw std::runtime_error("Handles queue not empty");
if (!integration_result_0.empty())
throw std::runtime_error("Integration result queue not empty");
if (!integration_result_1.empty())
throw std::runtime_error("Integration result queue not empty");
if (!impl_->datamover_in.GetDataStream().empty())
throw std::runtime_error("Datamover queue is not empty");
while (!impl_->datamover_out.IsIdle())
std::this_thread::sleep_for(std::chrono::milliseconds(100));
} catch (const std::runtime_error &e) {
logger_hls.ErrorException(e);
throw e;
}
idle = true;
}
DataCollectionStatus HLSDevice::GetDataCollectionStatus() const {
DataCollectionStatus status{};
union {
uint64_t u64;
double d;
} pulse_id_conv;
pulse_id_conv.u64 = current_pulse_id;
status.ctrl_reg = ap_uint<1>(impl_->host_writer_idle) ? (1 << 4) : 0;
status.max_modules = MAX_MODULES_FPGA;
status.hbm_size_bytes = impl_->hbm_if_size;
status.run_counter = run_counter;
status.current_pulseid = pulse_id_conv.d;
status.packets_udp = udp_packets;
status.packets_eth = eth_packets;
status.packets_sls = sls_packets;
return status;
}
void HLSDevice::HW_LoadCalibration(const LoadCalibrationConfig &config) {
int ret = load_calibration(impl_->hbm.data(), impl_->hbm.data(),
config,
impl_->hbm_if_size,
impl_->datamover_in.GetCtrlStream(),
impl_->datamover_in.GetDataStream(),
dma_address_table.data());
if (ret)
throw JFJochException(JFJochExceptionCategory::AcquisitionDeviceError,
"Error in loading calibration " + std::to_string(ret));
if (!impl_->datamover_in.GetDataStream().empty())
throw std::runtime_error("Datamover queue is not empty");
}
void HLSDevice::HW_SetSpotFinderParameters(const SpotFinderParameters &params) {
spot_finder_parameters = params;
}
void HLSDevice::HW_SetDataSource(uint32_t val) {
impl_->data_source = val;
}
uint32_t HLSDevice::HW_GetDataSource() {
return impl_->data_source;
}
void HLSDevice::CreateXfelBunchIDPacket(double pulse_id, uint32_t event_code) {
union {
uint64_t u64;
double d;
} pulse_id_conv;
pulse_id_conv.d = pulse_id;
bunchid_raw_packet packet{};
packet.ether_type = htons(0x0800);
for (int i = 0; i < 6; i++)
packet.dest_mac[i] = 0xFF;
packet.ipv4_header_h = htons(0x4500); // Big endian in IP header!
packet.ipv4_header_total_length = htons(sizeof(bunchid_payload) + 8 + 20); // Big endian in IP header!
packet.ipv4_header_dest_ip = UINT32_MAX;
packet.ipv4_header_ttl_protocol = htons(0x0011);
packet.ipv4_header_checksum = checksum( (uint16_t *) &packet.ipv4_header_h, 20); // checksum is already in network order
packet.udp_length = htons(sizeof(bunchid_payload) + 8);
packet.payload.magicn[0] = BUNCHID_MAGICN;
packet.payload.magicn[1] = BUNCHID_MAGICN;
packet.payload.magicn[2] = BUNCHID_MAGICN;
packet.payload.bunchid_msb[0] = (pulse_id_conv.u64 >> 32) & UINT32_MAX;
packet.payload.bunchid_msb[1] = (pulse_id_conv.u64 >> 32) & UINT32_MAX;
packet.payload.bunchid_lsb[0] = pulse_id_conv.u64 & UINT32_MAX;
packet.payload.bunchid_lsb[1] = pulse_id_conv.u64 & UINT32_MAX;
packet.payload.montrig = event_code;
SendPacket((char *) &packet, sizeof(bunchid_raw_packet));
}

75
fpga/hls/HLSDevice.h Normal file
View File

@@ -0,0 +1,75 @@
// Copyright (2019-2024) Paul Scherrer Institute
#ifndef JFJOCH_HLSDEVICE_H
#define JFJOCH_HLSDEVICE_H
#include <future>
#include "../../common/DiffractionExperiment.h"
#include "../pcie_driver/jfjoch_fpga.h"
class HLSDeviceImpl;
class HLSDevice {
// Hide all HLS simulation structures here
std::unique_ptr<HLSDeviceImpl> impl_;
std::mutex completion_mutex;
uint32_t completion_count;
std::thread action_thread;
std::future<void> frame_generator_future;
std::vector<uint64_t> dma_address_table;
uint64_t eth_packets = 0;
uint64_t icmp_packets = 0;
uint64_t udp_packets = 0;
uint64_t sls_packets = 0;
uint32_t udp_len_err = 0;
uint32_t udp_eth_err = 0;
uint64_t current_pulse_id = 0;
uint32_t run_counter = 0;
DataCollectionConfig cfg;
SpotFinderParameters spot_finder_parameters;
const uint64_t mac_addr = 0xCCAA11223344;
const uint32_t ipv4_addr = 0x0132010A;
volatile bool idle;
void FrameGeneratorFuture(FrameGeneratorConfig config);
void HLSMainThread();
public:
explicit HLSDevice(std::vector<DeviceOutput *> &device_buffer);
~HLSDevice();
void SendPacket(char *buffer, int len, uint8_t user = 0);
void CreateJFPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, const uint16_t *data, int8_t adjust_axis = 0, uint8_t user = 0);
void CreateJFPackets(const DiffractionExperiment& experiment, uint64_t frame_number_0, uint64_t frames,
uint32_t module_number, const uint16_t *data);
void CreateEIGERPacket(const DiffractionExperiment& experiment, uint64_t frame_number, uint32_t eth_packet,
uint32_t module_number, uint32_t col, uint32_t row,
const uint16_t *data);
void CreateFinalPacket(const DiffractionExperiment& experiment);
void CreateXfelBunchIDPacket(double bunchid, uint32_t event_code);
DataCollectionStatus GetDataCollectionStatus() const ;
void Cancel() ;
void HW_ReadActionRegister(DataCollectionConfig *job);
void HW_WriteActionRegister(const DataCollectionConfig *job);
void FPGA_StartAction(const DiffractionExperiment &experiment);
void FPGA_EndAction();
bool HW_IsIdle() const;
bool HW_ReadMailbox(uint32_t *values);
bool HW_SendWorkRequest(uint32_t handle);
void HW_LoadCalibration(const LoadCalibrationConfig &config);
void HW_SetSpotFinderParameters(const SpotFinderParameters &params);
uint32_t HW_GetDataSource();
void HW_SetDataSource(uint32_t val);
void HW_RunInternalGenerator(const FrameGeneratorConfig &config) ;
};
#endif //JFJOCH_HLSDEVICE_H

View File

@@ -36,9 +36,9 @@ int main() {
for (int i = 0; i < nframes * RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 2; i++)
output.read();
if (adu_result.size() != nframes * (ADU_HISTO_BIN_COUNT / 16))
if (adu_result.size() != nframes * (ADU_HISTO_BIN_COUNT / 16 + 1))
ret = 1;
for (int i = 0; i < nframes * (ADU_HISTO_BIN_COUNT / 16); i++)
for (int i = 0; i < nframes * (ADU_HISTO_BIN_COUNT / 16 + 1); i++)
adu_result.read();
if (compl_out.size() != nframes + 1)

View File

@@ -16,6 +16,7 @@ void data_collection_fsm(AXI_STREAM &eth_in,
ap_uint<5> nmodules,
ap_uint<4> nstorage_cells,
ap_uint<8> nsummation,
ap_uint<8> sqrtmult,
volatile rcv_state_t &data_collection_state) {
#pragma HLS INTERFACE ap_ctrl_none port=return
@@ -33,6 +34,7 @@ void data_collection_fsm(AXI_STREAM &eth_in,
#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=sqrtmult
#pragma HLS INTERFACE ap_none register port=data_collection_state
#pragma HLS PIPELINE II=1 style=flp
@@ -78,6 +80,7 @@ void data_collection_fsm(AXI_STREAM &eth_in,
ACT_REG_NMODULES(packet_out.data) = nmodules;
ACT_REG_NSTORAGE_CELLS(packet_out.data) = nstorage_cells + 1;
ACT_REG_NSUMMATION(packet_out.data) = nsummation;
ACT_REG_SQRTMULT(packet_out.data) = sqrtmult;
packet_out.user = 0;
packet_out.last = 1;

View File

@@ -10,17 +10,23 @@
#include <cstring>
#include <hls_burst_maxi.h>
#ifndef __SYNTHESIS__
#define ap_wait()
#endif
#ifndef JFJOCH_HLS_NOSYNTH
#include <ap_axi_sdata.h>
#include <hls_stream.h>
#include <hls_math.h>
#else
#define ap_wait()
#include "parallel_stream.h"
#include <cmath>
namespace hls {
inline bool isfinite(float f) {return std::isfinite(f);}
// inline float sqrt(float f) {return std::sqrt(f); }
template <class T> float sqrt(const T &f) {return std::round(std::sqrt(f.to_float())); }
}
#endif
@@ -61,7 +67,8 @@ typedef hls::stream<packet_768_t> STREAM_768;
#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
#define ACT_REG_NSUMMATION(x) ((x)(167, 160)) // 7 bit (0..255)
#define ACT_REG_NSUMMATION(x) ((x)(167, 160)) // 8 bit (0..255)
#define ACT_REG_SQRTMULT(x) ((x)(175, 168)) // 8 bit (0..255)
struct axis_datamover_ctrl {
ap_uint<40+64> data;
@@ -330,6 +337,7 @@ void data_collection_fsm(AXI_STREAM &eth_in,
ap_uint<5> nmodules,
ap_uint<4> nstorage_cells,
ap_uint<8> nsummation,
ap_uint<8> sqrootmult,
volatile rcv_state_t &state);
void host_writer(STREAM_512 &data_in,
@@ -444,4 +452,7 @@ void roi_calc(STREAM_768 &data_in,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes);
void pixel_sqrt(STREAM_768 &data_in,
STREAM_768 &data_out);
#endif

47
fpga/hls/pixel_sqrt.cpp Normal file
View File

@@ -0,0 +1,47 @@
// Copyright (2019-2023) Paul Scherrer Institute
#include "hls_jfjoch.h"
void pixel_sqrt(STREAM_768 &data_in,
STREAM_768 &data_out) {
#pragma HLS INTERFACE register both axis port=data_in
#pragma HLS INTERFACE register both axis port=data_out
#pragma HLS INTERFACE ap_ctrl_none port=return
packet_768_t packet_in;
{
#pragma HLS PROTOCOL fixed
data_in >> packet_in;
ap_wait();
data_out << packet_in;
ap_wait();
}
ap_uint<32> data_collection_mode = ACT_REG_MODE(packet_in.data);
ap_uint<1> apply_sqroot = ((data_collection_mode & MODE_SQROOT) ? 1 : 0);
ap_uint<9> sqrtmult = ACT_REG_SQRTMULT(packet_in.data) * ACT_REG_SQRTMULT(packet_in.data);
data_in >> packet_in;
while (!packet_in.user) {
#pragma HLS PIPELINE II=1
if (apply_sqroot) {
ap_int<24> pixel[32];
unpack32(packet_in.data, pixel);
for (int i = 0; i < 32; i++) {
ap_uint<32> tmp = pixel[i] * sqrtmult;
if ((pixel[i] == INT24_MAX) || (pixel[i] == INT24_MIN)) {
pixel[i] = pixel[i];
} else if (pixel[i] < 0)
pixel[i] = 0;
else
pixel[i] = hls::sqrt(tmp);
}
packet_in.data = pack32(pixel);
}
data_out << packet_in;
data_in >> packet_in;
}
data_out << packet_in;
}

View File

@@ -0,0 +1,65 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include "hls_jfjoch.h"
int main() {
bool all_good = true;
std::vector<uint16_t> sqrtmult_values = {1,2,4,8,16};
for (int i = 0; i < sqrtmult_values.size(); i++) {
uint16_t sqrtmult = sqrtmult_values[i];
STREAM_768 input;
STREAM_768 output;
packet_768_t packet_in;
packet_in.user = 0;
packet_in.data = 0;
ACT_REG_SQRTMULT(packet_in.data) = sqrtmult;
ACT_REG_MODE(packet_in.data) = MODE_SQROOT;
input << packet_in;
ap_int<24> values_in[32], values_out[32];
for (int i = 0; i < 30; i++)
values_in[i] = i;
values_in[30] = INT24_MAX;
values_in[31] = INT24_MIN;
packet_in.data = pack32(values_in);
input << packet_in;
input << packet_768_t{.user = 1};
pixel_sqrt(input, output);
output.read();
packet_768_t packet_out = output.read();
output.read();
unpack32(packet_out.data, values_out);
for (int i = 0; i < 32; i++) {
double value_expected = std::round(std::sqrt(values_in[i].to_float()) * sqrtmult);
if (values_in[i] == INT24_MAX)
value_expected = INT24_MAX;
if (values_in[i] == INT24_MIN)
value_expected = INT24_MIN;
if (values_out[i] != value_expected) {
all_good = false;
std::cerr << "Value " << i << " expected: " << value_expected << " calculated " << values_out[i] << " sqrtmult " << sqrtmult << std::endl;
}
}
}
if (all_good)
return 0;
else
return 1;
}

View File

@@ -45,9 +45,10 @@ int main() {
for (int i = 0; i < nframes * RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 2; i++)
output.read();
if (strong_pixel.size() != nframes * (RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 2) + 1)
if (strong_pixel.size() != nframes * (RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 16) + 1) {
ret = 1;
for (int i = 0; i < nframes * (RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 2) + 1; i++)
}
for (int i = 0; i < nframes * (RAW_MODULE_SIZE * sizeof(uint16_t) / 64 + 16) + 1; i++)
strong_pixel.read();
if (ret != 0) {

View File

@@ -3,5 +3,66 @@
#include "hls_jfjoch.h"
int main() {
bool all_good = true;
STREAM_768 input;
STREAM_512 output;
packet_768_t packet_in;
packet_in.user = 0;
packet_in.data = 0;
ACT_REG_MODE(packet_in.data) = MODE_32BIT;
input << packet_in;
ap_int<24> values_in[32];
ap_int<32> values_out[32];
for (int i = 0; i < 30; i++)
values_in[i] = i;
values_in[30] = INT24_MAX;
values_in[31] = INT24_MIN;
packet_in.data = pack32(values_in);
input << packet_in;
input << packet_768_t{.user = 1};
volatile ap_uint<1> idle;
stream_24bit_conv(input, output, idle);
if (output.size() != 4) {
std::cerr << "Wrong output size" << std::endl;
return 1;
}
output.read();
packet_512_t packet_out_1 = output.read();
packet_512_t packet_out_2 = output.read();
output.read();
ap_uint<1024> packet_out = (packet_out_2.data, packet_out_1.data);
unpack32(packet_out, values_out);
for (int i = 0; i < 32; i++) {
int32_t value_expected = values_in[i];
if (values_in[i] == INT24_MAX)
value_expected = INT32_MAX;
if (values_in[i] == INT24_MIN)
value_expected = INT32_MIN;
if (values_out[i] != value_expected) {
all_good = false;
std::cerr << "Value " << i << " expected: " << value_expected << " calculated " << values_out[i] << std::endl;
}
}
if (all_good)
return 0;
else
return 1;
}

View File

@@ -95,7 +95,7 @@
#define ADDR_ONE_OVER_ENERGY 0x0214
#define ADDR_NFRAMES 0x0218
#define ADDR_NSTORAGE_CELLS 0x021C
#define ADDR_DATA_SOURCE 0x0224
#define ADDR_DATA_SOURCE 0x0300
#define ADDR_SPOT_FINDER_THRESHOLD 0x0100
#define ADDR_SPOT_FINDER_SNR 0x0104

View File

@@ -27,7 +27,7 @@ typedef __u64 uint64_t;
#define GAIN_G2_MULTIPLIER (-1)
#define JFJOCH_FPGA_MAGIC 0x52324158
#define JFJOCH_FPGA_RELEASE 0x0056
#define JFJOCH_FPGA_RELEASE 0x0057
#define JFJOCH_FPGA_VARIANT_100G 0
#define JFJOCH_FPGA_VARIANT_8x10G 1
@@ -35,6 +35,7 @@ typedef __u64 uint64_t;
#define MODE_CONV 0x0001L
#define MODE_32BIT 0x0002L
#define MODE_UNSIGNED 0x0004L
#define MODE_SQROOT 0x0008L
#define MODE_PEDESTAL_G0 0x0010L
#define MODE_PEDESTAL_G1 0x0020L
#define MODE_PEDESTAL_G2 0x0040L
@@ -106,6 +107,7 @@ struct DataCollectionConfig {
uint32_t nframes; // Number of frames for data collection
uint32_t nstorage_cells; // Number of storage cells minus one (0 = 1SC, 1 = 2SC, ..., 15 = 16SC)
uint32_t nsummation; // Summation of frames minus one (0 = no summation, 1 = 2 frames, 2 = 3 frames, ..., 255 = 256 frames)
uint32_t sqrtmult; // Multiplication factor (minus one) of pixel value BEFORE taking square root function - should be square of the coeff used in other work
};
struct DataCollectionStatus {

View File

@@ -249,6 +249,12 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
CONFIG.FIFO_DEPTH {512} \
] $axis_data_fifo_10
# Create instance: axis_data_fifo_11, and set properties
set axis_data_fifo_11 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_11 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {512} \
] $axis_data_fifo_11
# Create instance: axis_data_spot_finder_mask_0, and set properties
set axis_data_spot_finder_mask_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_spot_finder_mask_0 ]
set_property -dict [ list \
@@ -343,6 +349,9 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
# Create instance: pedestal_0, and set properties
set pedestal_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:pedestal:1.0 pedestal_0 ]
# Create instance: pixel_sqrt_0, and set properties
set pixel_sqrt_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:pixel_sqrt:1.0 pixel_sqrt_0 ]
# Create instance: roi_calc_0, and set properties
set roi_calc_0 [ create_bd_cell -type ip -vlnv psi.ch:hls:roi_calc:1.0 roi_calc_0 ]
@@ -414,7 +423,8 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
connect_bd_intf_net -intf_net axis_compl_fifo_6_M_AXIS [get_bd_intf_pins axis_compl_fifo_6/M_AXIS] [get_bd_intf_pins spot_finder_mask_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_compl_fifo_7_M_AXIS [get_bd_intf_pins axis_compl_fifo_7/M_AXIS] [get_bd_intf_pins roi_calc_0/s_axis_completion]
connect_bd_intf_net -intf_net axis_data_fifo_0_M_AXIS [get_bd_intf_pins axis_data_fifo_0/M_AXIS] [get_bd_intf_pins pedestal_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_10_M_AXIS [get_bd_intf_pins axis_data_fifo_10/M_AXIS] [get_bd_intf_pins stream_24bit_conv_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_10_M_AXIS [get_bd_intf_pins axis_data_fifo_10/M_AXIS] [get_bd_intf_pins pixel_sqrt_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_11_M_AXIS [get_bd_intf_pins axis_data_fifo_11/M_AXIS] [get_bd_intf_pins stream_24bit_conv_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_1_M_AXIS [get_bd_intf_pins adu_histo_0/data_in] [get_bd_intf_pins axis_data_fifo_1/M_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_2_M_AXIS [get_bd_intf_pins axis_data_fifo_2/M_AXIS] [get_bd_intf_pins mask_missing_0/data_in]
connect_bd_intf_net -intf_net axis_data_fifo_3_M_AXIS [get_bd_intf_pins axis_data_fifo_3/M_AXIS] [get_bd_intf_pins eiger_reorder_0/data_in]
@@ -460,6 +470,7 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
connect_bd_intf_net -intf_net pedestal_0_m_axi_d_hbm_p5 [get_bd_intf_pins pedestal_0/m_axi_d_hbm_p5] [get_bd_intf_pins smartconnect_5/S00_AXI]
connect_bd_intf_net -intf_net pedestal_0_m_axi_d_hbm_p5_w [get_bd_intf_pins pedestal_0/m_axi_d_hbm_p5_w] [get_bd_intf_pins smartconnect_5/S01_AXI]
connect_bd_intf_net -intf_net pedestal_0_m_axis_completion [get_bd_intf_pins axis_compl_fifo_0/S_AXIS] [get_bd_intf_pins pedestal_0/m_axis_completion]
connect_bd_intf_net -intf_net pixel_sqrt_0_data_out [get_bd_intf_pins axis_data_fifo_11/S_AXIS] [get_bd_intf_pins pixel_sqrt_0/data_out]
connect_bd_intf_net -intf_net roi_calc_0_data_out [get_bd_intf_pins axis_data_fifo_10/S_AXIS] [get_bd_intf_pins roi_calc_0/data_out]
connect_bd_intf_net -intf_net roi_calc_0_m_axis_completion [get_bd_intf_pins m_axis_completion] [get_bd_intf_pins roi_calc_0/m_axis_completion]
connect_bd_intf_net -intf_net roi_calc_0_roi_out [get_bd_intf_pins axis_roi_calc_result_fifo_0/S_AXIS] [get_bd_intf_pins roi_calc_0/roi_out]
@@ -483,10 +494,10 @@ proc create_hier_cell_image_processing { parentCell nameHier } {
connect_bd_intf_net -intf_net stream_24bit_conv_0_data_out [get_bd_intf_pins axis_register_slice_data_3/S_AXIS] [get_bd_intf_pins stream_24bit_conv_0/data_out]
# Create port connections
connect_bd_net -net ap_rst_n_1 [get_bd_pins ap_rst_n] [get_bd_pins adu_histo_0/ap_rst_n] [get_bd_pins axis_32_to_512_0/ap_rst_n] [get_bd_pins axis_64_to_512_0/ap_rst_n] [get_bd_pins eiger_reorder_0/ap_rst_n] [get_bd_pins frame_summation_0/ap_rst_n] [get_bd_pins integration_0/ap_rst_n] [get_bd_pins jf_conversion_0/ap_rst_n] [get_bd_pins mask_missing_0/ap_rst_n] [get_bd_pins pedestal_0/ap_rst_n] [get_bd_pins roi_calc_0/ap_rst_n] [get_bd_pins spot_finder_0/ap_rst_n] [get_bd_pins spot_finder_connecti_0/ap_rst_n] [get_bd_pins spot_finder_mask_0/ap_rst_n] [get_bd_pins spot_finder_merge_0/ap_rst_n] [get_bd_pins stream_24bit_conv_0/ap_rst_n]
connect_bd_net -net ap_rst_n_1 [get_bd_pins ap_rst_n] [get_bd_pins adu_histo_0/ap_rst_n] [get_bd_pins axis_32_to_512_0/ap_rst_n] [get_bd_pins axis_64_to_512_0/ap_rst_n] [get_bd_pins eiger_reorder_0/ap_rst_n] [get_bd_pins frame_summation_0/ap_rst_n] [get_bd_pins integration_0/ap_rst_n] [get_bd_pins jf_conversion_0/ap_rst_n] [get_bd_pins mask_missing_0/ap_rst_n] [get_bd_pins pedestal_0/ap_rst_n] [get_bd_pins pixel_sqrt_0/ap_rst_n] [get_bd_pins roi_calc_0/ap_rst_n] [get_bd_pins spot_finder_0/ap_rst_n] [get_bd_pins spot_finder_connecti_0/ap_rst_n] [get_bd_pins spot_finder_mask_0/ap_rst_n] [get_bd_pins spot_finder_merge_0/ap_rst_n] [get_bd_pins stream_24bit_conv_0/ap_rst_n]
connect_bd_net -net ap_start_1 [get_bd_pins frame_summation_0/ap_start] [get_bd_pins integration_0/ap_start] [get_bd_pins one/dout] [get_bd_pins spot_finder_0/ap_start] [get_bd_pins stream_24bit_conv_0/ap_start]
connect_bd_net -net axi_clk_1 [get_bd_pins axi_clk] [get_bd_pins adu_histo_0/ap_clk] [get_bd_pins axis_32_to_512_0/ap_clk] [get_bd_pins axis_64_to_512_0/ap_clk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_compl_fifo_2/s_axis_aclk] [get_bd_pins axis_compl_fifo_3/s_axis_aclk] [get_bd_pins axis_compl_fifo_4/s_axis_aclk] [get_bd_pins axis_compl_fifo_5/s_axis_aclk] [get_bd_pins axis_compl_fifo_6/s_axis_aclk] [get_bd_pins axis_compl_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_0/s_axis_aclk] [get_bd_pins axis_data_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_10/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_data_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_6/s_axis_aclk] [get_bd_pins axis_data_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_8/s_axis_aclk] [get_bd_pins axis_data_fifo_9/s_axis_aclk] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_1/s_axis_aclk] [get_bd_pins axis_register_slice_data_1/aclk] [get_bd_pins axis_register_slice_data_2/aclk] [get_bd_pins axis_register_slice_data_3/aclk] [get_bd_pins axis_roi_calc_result_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_3/s_axis_aclk] [get_bd_pins eiger_reorder_0/ap_clk] [get_bd_pins frame_summation_0/ap_clk] [get_bd_pins integration_0/ap_clk] [get_bd_pins jf_conversion_0/ap_clk] [get_bd_pins mask_missing_0/ap_clk] [get_bd_pins pedestal_0/ap_clk] [get_bd_pins roi_calc_0/ap_clk] [get_bd_pins smartconnect_0/aclk] [get_bd_pins smartconnect_1/aclk] [get_bd_pins smartconnect_2/aclk] [get_bd_pins smartconnect_3/aclk] [get_bd_pins smartconnect_4/aclk] [get_bd_pins smartconnect_5/aclk] [get_bd_pins spot_finder_0/ap_clk] [get_bd_pins spot_finder_connecti_0/ap_clk] [get_bd_pins spot_finder_mask_0/ap_clk] [get_bd_pins spot_finder_merge_0/ap_clk] [get_bd_pins stream_24bit_conv_0/ap_clk]
connect_bd_net -net axi_rst_n_1 [get_bd_pins axi_rst_n] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_compl_fifo_2/s_axis_aresetn] [get_bd_pins axis_compl_fifo_3/s_axis_aresetn] [get_bd_pins axis_compl_fifo_4/s_axis_aresetn] [get_bd_pins axis_compl_fifo_5/s_axis_aresetn] [get_bd_pins axis_compl_fifo_6/s_axis_aresetn] [get_bd_pins axis_compl_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_10/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_4/s_axis_aresetn] [get_bd_pins axis_data_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_6/s_axis_aresetn] [get_bd_pins axis_data_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_8/s_axis_aresetn] [get_bd_pins axis_data_fifo_9/s_axis_aresetn] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_1/s_axis_aresetn] [get_bd_pins axis_register_slice_data_1/aresetn] [get_bd_pins axis_register_slice_data_2/aresetn] [get_bd_pins axis_register_slice_data_3/aresetn] [get_bd_pins axis_roi_calc_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_3/s_axis_aresetn] [get_bd_pins smartconnect_0/aresetn] [get_bd_pins smartconnect_1/aresetn] [get_bd_pins smartconnect_2/aresetn] [get_bd_pins smartconnect_3/aresetn] [get_bd_pins smartconnect_4/aresetn] [get_bd_pins smartconnect_5/aresetn]
connect_bd_net -net axi_clk_1 [get_bd_pins axi_clk] [get_bd_pins adu_histo_0/ap_clk] [get_bd_pins axis_32_to_512_0/ap_clk] [get_bd_pins axis_64_to_512_0/ap_clk] [get_bd_pins axis_compl_fifo_0/s_axis_aclk] [get_bd_pins axis_compl_fifo_1/s_axis_aclk] [get_bd_pins axis_compl_fifo_2/s_axis_aclk] [get_bd_pins axis_compl_fifo_3/s_axis_aclk] [get_bd_pins axis_compl_fifo_4/s_axis_aclk] [get_bd_pins axis_compl_fifo_5/s_axis_aclk] [get_bd_pins axis_compl_fifo_6/s_axis_aclk] [get_bd_pins axis_compl_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_0/s_axis_aclk] [get_bd_pins axis_data_fifo_1/s_axis_aclk] [get_bd_pins axis_data_fifo_10/s_axis_aclk] [get_bd_pins axis_data_fifo_11/s_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] [get_bd_pins axis_data_fifo_4/s_axis_aclk] [get_bd_pins axis_data_fifo_5/s_axis_aclk] [get_bd_pins axis_data_fifo_6/s_axis_aclk] [get_bd_pins axis_data_fifo_7/s_axis_aclk] [get_bd_pins axis_data_fifo_8/s_axis_aclk] [get_bd_pins axis_data_fifo_9/s_axis_aclk] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_0/s_axis_aclk] [get_bd_pins axis_integration_result_fifo_1/s_axis_aclk] [get_bd_pins axis_register_slice_data_1/aclk] [get_bd_pins axis_register_slice_data_2/aclk] [get_bd_pins axis_register_slice_data_3/aclk] [get_bd_pins axis_roi_calc_result_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aclk] [get_bd_pins axis_spot_finder_fifo_3/s_axis_aclk] [get_bd_pins eiger_reorder_0/ap_clk] [get_bd_pins frame_summation_0/ap_clk] [get_bd_pins integration_0/ap_clk] [get_bd_pins jf_conversion_0/ap_clk] [get_bd_pins mask_missing_0/ap_clk] [get_bd_pins pedestal_0/ap_clk] [get_bd_pins pixel_sqrt_0/ap_clk] [get_bd_pins roi_calc_0/ap_clk] [get_bd_pins smartconnect_0/aclk] [get_bd_pins smartconnect_1/aclk] [get_bd_pins smartconnect_2/aclk] [get_bd_pins smartconnect_3/aclk] [get_bd_pins smartconnect_4/aclk] [get_bd_pins smartconnect_5/aclk] [get_bd_pins spot_finder_0/ap_clk] [get_bd_pins spot_finder_connecti_0/ap_clk] [get_bd_pins spot_finder_mask_0/ap_clk] [get_bd_pins spot_finder_merge_0/ap_clk] [get_bd_pins stream_24bit_conv_0/ap_clk]
connect_bd_net -net axi_rst_n_1 [get_bd_pins axi_rst_n] [get_bd_pins axis_compl_fifo_0/s_axis_aresetn] [get_bd_pins axis_compl_fifo_1/s_axis_aresetn] [get_bd_pins axis_compl_fifo_2/s_axis_aresetn] [get_bd_pins axis_compl_fifo_3/s_axis_aresetn] [get_bd_pins axis_compl_fifo_4/s_axis_aresetn] [get_bd_pins axis_compl_fifo_5/s_axis_aresetn] [get_bd_pins axis_compl_fifo_6/s_axis_aresetn] [get_bd_pins axis_compl_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins axis_data_fifo_10/s_axis_aresetn] [get_bd_pins axis_data_fifo_11/s_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins axis_data_fifo_4/s_axis_aresetn] [get_bd_pins axis_data_fifo_5/s_axis_aresetn] [get_bd_pins axis_data_fifo_6/s_axis_aresetn] [get_bd_pins axis_data_fifo_7/s_axis_aresetn] [get_bd_pins axis_data_fifo_8/s_axis_aresetn] [get_bd_pins axis_data_fifo_9/s_axis_aresetn] [get_bd_pins axis_data_spot_finder_mask_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_integration_result_fifo_1/s_axis_aresetn] [get_bd_pins axis_register_slice_data_1/aresetn] [get_bd_pins axis_register_slice_data_2/aresetn] [get_bd_pins axis_register_slice_data_3/aresetn] [get_bd_pins axis_roi_calc_result_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_conn_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_0/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_1/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_2/s_axis_aresetn] [get_bd_pins axis_spot_finder_fifo_3/s_axis_aresetn] [get_bd_pins smartconnect_0/aresetn] [get_bd_pins smartconnect_1/aresetn] [get_bd_pins smartconnect_2/aresetn] [get_bd_pins smartconnect_3/aresetn] [get_bd_pins smartconnect_4/aresetn] [get_bd_pins smartconnect_5/aresetn]
connect_bd_net -net axis_data_fifo_6_almost_empty [get_bd_pins proc_fifo_empty] [get_bd_pins axis_data_fifo_7/almost_empty]
connect_bd_net -net axis_data_fifo_6_almost_full [get_bd_pins proc_fifo_full] [get_bd_pins axis_data_fifo_7/almost_full]
connect_bd_net -net frame_summation_0_idle [get_bd_pins frame_summation_idle] [get_bd_pins frame_summation_0/idle]

View File

@@ -495,6 +495,7 @@ proc create_hier_cell_jungfraujoch { parentCell nameHier } {
connect_bd_net -net action_config_0_nmodules [get_bd_pins action_config_0/nmodules] [get_bd_pins data_collection_fsm_0/nmodules]
connect_bd_net -net action_config_0_nstorage_cells [get_bd_pins action_config_0/nstorage_cells] [get_bd_pins data_collection_fsm_0/nstorage_cells]
connect_bd_net -net action_config_0_nsummation [get_bd_pins action_config_0/nsummation] [get_bd_pins data_collection_fsm_0/nsummation]
connect_bd_net -net action_config_0_sqrtmult [get_bd_pins action_config_0/sqrtmult] [get_bd_pins data_collection_fsm_0/sqrtmult]
connect_bd_net -net action_config_0_spot_finder_count_threshold [get_bd_pins action_config_0/spot_finder_count_threshold] [get_bd_pins image_processing/in_count_threshold]
connect_bd_net -net action_config_0_spot_finder_d_max [get_bd_pins action_config_0/spot_finder_d_max] [get_bd_pins image_processing/in_max_d_value]
connect_bd_net -net action_config_0_spot_finder_d_min [get_bd_pins action_config_0/spot_finder_d_min] [get_bd_pins image_processing/in_min_d_value]

View File

@@ -7,7 +7,9 @@ set_top $env(HLS_TOP_FUNCTION)
add_files $env(SRC_DIR)/$env(HLS_FILE)
if { [info exists ::env(HLS_TB_FILE)] } {
add_files -tb $env(SRC_DIR)/$env(HLS_TB_FILE)
if {$env(HLS_TB_FILE) != ""} {
add_files -tb $env(SRC_DIR)/$env(HLS_TB_FILE)
}
}
open_solution solution1
@@ -19,6 +21,12 @@ create_clock -period 3.2 -name default
config_interface -m_axi_addr64=true
config_schedule -enable_dsp_full_reg=true
if { [info exists ::env(HLS_TB_FILE)] } {
if {$env(HLS_TB_FILE) != ""} {
csim_design
}
}
csynth_design
config_export -vendor {psi.ch} -version 1.0 -ipname $env(HLS_TOP_FUNCTION) -format ip_catalog -rtl verilog

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
"@mui/icons-material": "^5.10.6",
"@mui/material": "^5.10.6",
"@mui/x-data-grid": "^5.17.14",
"@redocly/cli": "^1.12.2",
"@redocly/cli": "^1.17.1",
"@types/jest": "^29.2.4",
"@types/node": "^18.11.13",
"@types/react": "^18.0.26",
@@ -24,9 +24,11 @@
"typescript": "^4.9.4"
},
"scripts": {
"start": "REACT_APP_VERSION=$(git rev-parse --short HEAD) PORT=8000 react-scripts start",
"build": "REACT_APP_VERSION=$(git rev-parse --short HEAD) react-scripts build",
"start": "REACT_APP_VERSION=$(cat ../VERSION |sed s/_/-/) PORT=8000 react-scripts start",
"build": "REACT_APP_VERSION=$(cat ../VERSION |sed s/_/-/) react-scripts build",
"redocly": "redocly build-docs ../broker/jfjoch_api.yaml --output=build/openapi.html",
"redocly4broker": "redocly build-docs ../broker/jfjoch_api.yaml --output=../broker/redoc-static.html",
"redocly4writer": "redocly build-docs ../writer/writer_api.yaml --output=../writer/redoc-static.html",
"test": "react-scripts test",
"eject": "react-scripts eject",
"openapi": "./node_modules/openapi-typescript-codegen/bin/index.js -i ../broker/jfjoch_api.yaml --output ./src/openapi"

View File

@@ -144,7 +144,7 @@ class App extends Component<MyProps, MyState> {
href="mailto:filip.leonarski@psi.ch">Filip Leonarski</a> <br/>
For more information see <a href="https://doi.org/10.1107/S1600577522010268"><i>J. Synchrotron
Rad.</i> (2023). <b>30</b>, 227234</a> <br/>
Build: {process.env.REACT_APP_VERSION}&nbsp;&nbsp;&nbsp;
Version: {process.env.REACT_APP_VERSION}&nbsp;&nbsp;&nbsp;
<a href="/frontend/openapi.html">API reference</a></center>
<br/>
</ThemeProvider>

View File

@@ -21,7 +21,7 @@ export type OpenAPIConfig = {
export const OpenAPI: OpenAPIConfig = {
BASE: '',
VERSION: '1.0.1',
VERSION: '1.0.0-rc.12',
WITH_CREDENTIALS: false,
CREDENTIALS: 'include',
TOKEN: undefined,

View File

@@ -19,13 +19,14 @@ export type dataset_settings = {
*/
ntrigger?: number;
/**
* FPGA frame summation. For summation above two 32-bit pixel format will be used, unless explicitly specified.
* Frame summation factor applies only to conversion mode (assumed as 1 for raw data).
* Image time.
* If not provided (or zero value) the frame time is assumed as default.
* Image time must be multiple of frame time; max value is 256 * frame_time.
* In XFEL mode: summation happens for frames collected with multiple triggers.
* Ignored for storage cells (assumed as 1).
* Ignored for storage cells and if raw data are saved.
*
*/
summation?: number;
image_time_us?: number;
/**
* /entry/detector/beam_center_x in NXmx
* Beam center in X direction [pixels]
@@ -62,7 +63,7 @@ export type dataset_settings = {
* Sample name
*
*/
sample_name: string;
sample_name?: string;
/**
* FPGA output data type
*/
@@ -82,13 +83,13 @@ export type dataset_settings = {
transmission?: number;
goniometer?: rotation_axis;
/**
* Header appendix, added as user_data to start message
* Header appendix, added as user_data/user to start message (can be any valid JSON)
*/
header_appendix?: string;
header_appendix?: any;
/**
* Image appendix, added as user_data to image message
* Image appendix, added as user_data to image message (can be any valid JSON)
*/
image_appendix?: string;
image_appendix?: any;
/**
* For JUNGFRAU conversion it is possible to multiply incident energy by a given factor to get fractional/multiplied particle counts
*/
@@ -108,12 +109,28 @@ export type dataset_settings = {
*
*/
run_number?: number;
/**
* Unique ID of run.
* Transferred over CBOR stream as "unique series ID", though not saved in HDF5 file.
* It is highly recommended to keep this name unique for each data collection during experimental series.
* If not provided, the name will be automatically generated as number + colon + file_prefix.
*
*/
run_name?: string;
/**
* Name of group owning the data (e.g. p-group or proposal number).
* Transferred over CBOR stream, though not saved in HDF5 file.
*
*/
experiment_group?: string;
/**
* Enable lossy compression of pixel values that preserves Poisson statistics.
* Requires to provide a numerical factor SQ.
* Pixel value P will be transformed to round(sqrt(P) * SQ), with rounding to the closest integer.
* Compression is turned off if the value is missing or it is set to zero.
*
*/
poisson_compression?: number;
/**
* Units of angstrom and degree
*/

View File

@@ -100,18 +100,27 @@ export class DefaultService {
* Block execution of external script till initialization, data collection or pedestal is finished.
* Running this command does not affect (cancel) running data collection, it is only to ensure synchronous execution of other software.
*
* To not block web server for a long period of time, the procedure is provided with a timeout of 5 seconds.
* To not block web server for a indefinite period of time, the procedure is provided with a timeout.
* Extending timeout is possible, but requires to ensure safety that client will not close the connection and retry the connection.
*
* @param timeout Timeout in seconds (0 == immediate response)
* @returns any Detector in `Idle` state, another data collection can start immediately
* @throws ApiError
*/
public static postWaitTillDone(): CancelablePromise<any> {
public static postWaitTillDone(
timeout: number = 60,
): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'POST',
url: '/wait_till_done',
query: {
'timeout': timeout,
},
errors: {
400: `Timeout parameter out of bounds`,
500: `Error within Jungfraujoch code - see output message.`,
504: `5 second timeout reached, need to restart operation`,
502: `Detector is inactive mode`,
504: `Timeout reached, need to restart operation`,
},
});
}
@@ -957,4 +966,15 @@ export class DefaultService {
});
}
/**
* @returns string Release number of Jungfraujoch
* @throws ApiError
*/
public static getVersion(): CancelablePromise<string> {
return __request(OpenAPI, {
method: 'GET',
url: '/version',
});
}
}

View File

@@ -10,16 +10,17 @@ AzimuthalIntegration::AzimuthalIntegration(const DiffractionExperiment& experime
corrections(experiment.GetPixelsNum(), 1.0),
nbins(mapping.GetBinNumber()),
sum(mapping.GetBinNumber(), 0),
sum2(mapping.GetBinNumber(), 0),
count(mapping.GetBinNumber(), 0)
{
auto mapping_raw = mapping.GetPixelToBinMappingRaw();
RawToConvertedGeometry(experiment, pixel_to_bin.data(), mapping_raw.data());
auto &bin_to_q = mapping.GetBinToQ();
std::vector<float> corrections_raw(experiment.GetModulesNum() * RAW_MODULE_SIZE);
for (int i = 0; i < experiment.GetModulesNum(); i++)
CalcAzIntCorrRawCoord(corrections_raw.data() + i * RAW_MODULE_SIZE, experiment, i);
solid_angle_corr.resize(mapping.GetBinNumber());
for (int i = 0; i < mapping.GetBinNumber(); i++)
solid_angle_corr[i] = 1.0 / CalcAzIntSolidAngleCorr(experiment, bin_to_q[i]);
RawToConvertedGeometry(experiment, corrections.data(), corrections_raw.data());
}
void AzimuthalIntegration::Process(const int16_t *data, size_t npixel) {
@@ -29,9 +30,10 @@ void AzimuthalIntegration::Process(const int16_t *data, size_t npixel) {
for (int i = 0; i < npixel; i++) {
auto bin = pixel_to_bin[i];
auto value = data[i];
if ((value > INT16_MIN + 4) && (value < INT16_MAX - 4) && (bin < nbins)) {
auto value = data[i] * corrections[i];
if ((data[i] > INT16_MIN + 4) && (data[i] < INT16_MAX - 4) && (bin < nbins)) {
sum[bin] += value;
sum2[bin] += value * value;
count[bin] += 1;
}
}
@@ -42,7 +44,7 @@ void AzimuthalIntegration::GetResult(std::vector<double> &result) const {
for (int i = 0; i < nbins; i++) {
if (count[i] > 0)
result[i] = static_cast<double>(sum[i]) / static_cast<double>(count[i]) * solid_angle_corr[i];
result[i] = sum[i] / count[i];
else
result[i] = 0;
}

View File

@@ -13,9 +13,9 @@
class AzimuthalIntegration {
std::vector<uint16_t> pixel_to_bin;
std::vector<float> corrections;
std::vector<float> solid_angle_corr;
const uint16_t nbins;
std::vector<int64_t> sum;
std::vector<double> sum;
std::vector<double> sum2;
std::vector<int64_t> count;
public:
AzimuthalIntegration(const DiffractionExperiment& experiment, const AzimuthalIntegrationMapping& mapping);

View File

@@ -28,4 +28,4 @@ bool LossyFilter::ApplyFilter(DataMessage &message) {
}
LossyFilter::LossyFilter(const DiffractionExperiment &x)
: p (x.GetDataReductionFactorSerialMX()){}
: p (x.GetLossyCompressionSerialMX()){}

View File

@@ -20,6 +20,7 @@ void print_usage(Logger &logger) {
logger.Info(" -N<num> number of image processing threads");
logger.Info(" -P<txt> NUMA Policy (none|n2g2|n8g4|n8g4_hbm), none is default");
logger.Info(" -B<num> size of send buffer in MiB (default 2048)");
logger.Info(" -q<num> Use Poisson lossy compression, with square root of counts");
}
int main(int argc, char **argv) {
@@ -39,6 +40,7 @@ int main(int argc, char **argv) {
DetectorType detector_type = DetectorType::JUNGFRAU;
bool hls_simulation = false;
size_t send_buffer_size_MiB = 2048;
std::optional<int64_t> lossy_compression_poisson;
if (argc == 1) {
print_usage(logger);
@@ -46,7 +48,7 @@ int main(int argc, char **argv) {
}
int opt;
while ((opt = getopt(argc, argv, "s:i:m:N:P:vRIS:EHB:")) != -1) {
while ((opt = getopt(argc, argv, "s:i:m:N:P:vRIS:EHB:q:")) != -1) {
switch (opt) {
case 'i':
nimages = atol(optarg);
@@ -84,6 +86,9 @@ int main(int argc, char **argv) {
case 'B':
send_buffer_size_MiB = atol(optarg);
break;
case 'q':
lossy_compression_poisson = atol(optarg);
break;
default: /* '?' */
print_usage(logger);
exit(EXIT_FAILURE);
@@ -106,6 +111,7 @@ int main(int argc, char **argv) {
x.MaskModuleEdges(false).MaskChipEdges(false).BeamX_pxl(x.GetXPixelsNum()/ 2.0).BeamY_pxl(x.GetYPixelsNum()/ 2.0).DetectorDistance_mm(100);
x.Compression(CompressionAlgorithm::BSHUF_LZ4).DataStreams(nstreams);
x.SetUnitCell(UnitCell{.a = 79, .b = 79, .c = 37, .alpha = 90.0, .beta = 90.0, .gamma = 90.0});
x.LossyCompressionPoisson(lossy_compression_poisson);
if (force_32bit)
x.FPGAOutputMode(FPGAPixelOutput::Int32);

View File

@@ -37,6 +37,7 @@ ADD_EXECUTABLE(jfjoch_test
SendBufferTest.cpp
PixelMaskTest.cpp
RegressionTest.cpp
FPGAHLSModulesTest.cpp
)
target_link_libraries(jfjoch_test Catch2WithMain JFJochBroker JFJochReceiver JFJochWriter JFJochImageAnalysis JFJochCommon JFJochHLSSimulation JFJochPreview)

View File

@@ -0,0 +1,212 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include <catch2/catch_all.hpp>
#include <random>
#include "../fpga/hls/hls_jfjoch.h"
TEST_CASE("HLS_DataCollectionFSM","[OpenCAPI]") {
DataCollectionConfig act_reg;
STREAM_512 raw0;
STREAM_512 raw1;
hls::stream<axis_addr> addr0;
hls::stream<axis_addr> addr1;
ap_uint<1> run_data_collection = 0;
ap_uint<1> cancel_data_collection = 0;
ap_uint<1> idle_data_collection;
uint32_t save_data_collection_counter;
act_reg.mode = MODE_CONV;
// state = WAIT_FOR_START
volatile rcv_state_t state;
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 1);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_WAIT_FOR_START);
run_data_collection = 1;
// state = WAIT_FOR_START
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_WAIT_FOR_START_LOW);
// state = WAIT_FOR_START_LOW
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_WAIT_FOR_START_LOW);
// state = WAIT_FOR_START_LOW
run_data_collection = 0;
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_START);
// state = START
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(raw1.size() == 1);
REQUIRE( state == RCV_INIT);
// state = INIT
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(raw1.size() == 1);
REQUIRE( state == RCV_INIT);
// state = INIT
cancel_data_collection = 1;
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(raw1.size() == 1);
// state = LAST
REQUIRE( state == RCV_LAST);
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.size() == 1);
REQUIRE(raw1.size() == 2);
REQUIRE( state == RCV_WAIT_FOR_START);
// state = WAIT_FOR_START
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
act_reg.sqrtmult,
state);
REQUIRE( state == RCV_WAIT_FOR_START);
REQUIRE(idle_data_collection == 1);
REQUIRE(addr1.size() == 1);
REQUIRE(raw1.size() == 2);
auto packet = raw1.read();
REQUIRE(packet.last == 1);
REQUIRE(packet.dest == 0);
packet = raw1.read();
REQUIRE(packet.last);
REQUIRE(packet.dest == 0);
auto addr = addr1.read();
REQUIRE(addr.last);
}

View File

@@ -29,9 +29,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
@@ -67,8 +64,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_custom_frame", "[FPGA][Ful
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * nframes * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < nframes; image++) {
@@ -106,9 +101,6 @@ TEST_CASE("HLS_C_Simulation_check_raw", "[FPGA][Full]") {
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
uint64_t diffs = 0;
@@ -142,8 +134,6 @@ TEST_CASE("HLS_C_Simulation_check_cancel", "[FPGA][Full]") {
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == 0);
}
@@ -167,9 +157,6 @@ TEST_CASE("HLS_C_Simulation_check_cancel_conversion", "[FPGA][Full]") {
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == 0);
}
@@ -235,9 +222,6 @@ TEST_CASE("HLS_C_Simulation_check_lost_frame_raw", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == JUNGFRAU_PACKET_SIZE_BYTES);
REQUIRE(test.GetDeviceOutput(0,0)->pixels[0] == 0);
@@ -267,8 +251,6 @@ TEST_CASE("HLS_C_Simulation_check_lost_frame_conversion", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == JUNGFRAU_PACKET_SIZE_BYTES);
@@ -324,9 +306,6 @@ TEST_CASE("HLS_C_Simulation_check_single_packet", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == 15 * JUNGFRAU_PACKET_SIZE_BYTES);
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels, data, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
@@ -383,8 +362,6 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), test.GetDeviceOutput(0,0)->pixels);
@@ -434,8 +411,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_HG0", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), test.GetDeviceOutput(0,0)->pixels);
@@ -464,8 +440,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_HG0", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), test.GetDeviceOutput(0,0)->pixels);
@@ -515,8 +490,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_fixedG1", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), test.GetDeviceOutput(0,0)->pixels);
@@ -565,8 +539,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_I32", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), (int32_t *) test.GetDeviceOutput(0,0)->pixels);
@@ -619,8 +592,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_sum4", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * nsummation * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), (int32_t *) test.GetDeviceOutput(0,0)->pixels);
@@ -670,8 +642,108 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_U16", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), (uint16_t *) test.GetDeviceOutput(0,0)->pixels);
REQUIRE(mean_error < 0.5);
}
}
TEST_CASE("HLS_C_Simulation_check_conversion_poisson_full_range", "[FPGA][Full]") {
// This test is not 100% representable!
// At the moment it is not possible to include "hls_math.h" in jfjoch_test
// So hls::sqrt is actually implemented as round(sqrt())
// This can be only handled by HLS test bench
Logger logger("HLS_C_Simulation_check_poisson_full_range");
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
data[i] = i % UINT16_MAX;
}
const uint16_t nmodules = 1;
for (int sqrtmult: {1, 2,4,8}) {
DiffractionExperiment x((DetectorGeometry(nmodules)));
x.Mode(DetectorMode::Raw).FPGAOutputMode(FPGAPixelOutput::Int16);
HLSSimulatedDevice test(0, 64);
x.NumTriggers(1).ImagesPerTrigger(1).LossyCompressionPoisson(sqrtmult);
test.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto data_signed = (int16_t *) data.data();
uint64_t diff = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
uint64_t expected_value = 0;
if (data_signed[i] == INT16_MAX)
expected_value = INT16_MAX;
else if (data_signed[i] == INT16_MIN)
expected_value = INT16_MIN;
else if (data_signed[i] >= 0)
expected_value = std::lround(std::sqrt(data_signed[i]) * sqrtmult);
if (expected_value != test.GetDeviceOutput(0, 0)->pixels[i])
diff++;
}
REQUIRE(diff == 0);
}
}
TEST_CASE("HLS_C_Simulation_check_convert_full_range_poisson", "[FPGA][Full]") {
Logger logger("HLS_C_Simulation_check_convert_full_range_poisson");
std::vector<uint16_t> data(RAW_MODULE_SIZE);
std::vector<double> gain(3 * RAW_MODULE_SIZE);
JFModulePedestal pedestal_g0(0), pedestal_g1(14500), pedestal_g2(14500);
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
data[i] = i % UINT16_MAX;
}
std::vector<double> energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7};
const uint16_t nmodules = 1;
DiffractionExperiment x((DetectorGeometry(nmodules)));
x.LossyCompressionPoisson(2);
x.Mode(DetectorMode::Conversion);
HLSSimulatedDevice test(0, 64);
auto gain_from_file = GainCalibrationFromTestFile();
for (const auto energy : energy_values) {
logger.Info("Trying with {} keV", energy);
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PhotonEnergy_keV(energy).FPGAOutputMode(FPGAPixelOutput::Uint16);
REQUIRE(x.GetPhotonEnergy_keV() == Catch::Approx(energy));
JFCalibration c_in(x);
c_in.Pedestal(0,0) = pedestal_g0;
c_in.Pedestal(0,1) = pedestal_g1;
c_in.Pedestal(0,2) = pedestal_g2;
for (int i = 0; i < x.GetModulesNum(); i++)
c_in.GainCalibration(i) = gain_from_file;
test.InitializeCalibration(x, c_in);
test.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckConversion(x, c_in, data.data(), (uint16_t *) test.GetDeviceOutput(0,0)->pixels);
@@ -704,8 +776,6 @@ TEST_CASE("HLS_C_Simulation_no_conversion_U16", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto output = (uint16_t *) test.GetDeviceOutput(0, 0)->pixels;
@@ -740,8 +810,6 @@ TEST_CASE("HLS_C_Simulation_no_conversion_U32", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto output = (uint32_t *) test.GetDeviceOutput(0, 0)->pixels;
@@ -778,8 +846,6 @@ TEST_CASE("HLS_C_Simulation_no_conversion_I32", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto data16_signed = (int16_t *) data.data();
@@ -840,8 +906,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_convert_full_range", "[FPG
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == nmodules * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -895,8 +959,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_convert_full_range_adu_his
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == nmodules * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -958,8 +1020,6 @@ TEST_CASE("HLS_C_Simulation_check_2_trigger_convert", "[FPGA][Full]") {
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE(test.Counters().GetCurrFrameNumber(0) == 0);
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived()== 128 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -997,8 +1057,6 @@ TEST_CASE("HLS_C_Simulation_check_detect_last_frame", "[FPGA][Full]") {
REQUIRE(test.Counters().IsAcquisitionFinished());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
}
TEST_CASE("HLS_C_Simulation_check_wrong_packet_size", "[FPGA][Full]") {
@@ -1042,202 +1100,6 @@ TEST_CASE("HLS_C_Simulation_check_wrong_packet_size", "[FPGA][Full]") {
REQUIRE(test.GetBytesReceived() == 6 * JUNGFRAU_PACKET_SIZE_BYTES);
}
TEST_CASE("HLS_DataCollectionFSM","[OpenCAPI]") {
DataCollectionConfig act_reg;
STREAM_512 raw0;
STREAM_512 raw1;
hls::stream<axis_addr> addr0;
hls::stream<axis_addr> addr1;
ap_uint<1> run_data_collection = 0;
ap_uint<1> cancel_data_collection = 0;
ap_uint<1> idle_data_collection;
uint32_t save_data_collection_counter;
act_reg.mode = MODE_CONV;
// state = WAIT_FOR_START
volatile rcv_state_t state;
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 1);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_WAIT_FOR_START);
run_data_collection = 1;
// state = WAIT_FOR_START
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_WAIT_FOR_START_LOW);
// state = WAIT_FOR_START_LOW
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_WAIT_FOR_START_LOW);
// state = WAIT_FOR_START_LOW
run_data_collection = 0;
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.empty());
REQUIRE(raw1.empty());
REQUIRE( state == RCV_START);
// state = START
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(raw1.size() == 1);
REQUIRE( state == RCV_INIT);
// state = INIT
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(raw1.size() == 1);
REQUIRE( state == RCV_INIT);
// state = INIT
cancel_data_collection = 1;
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(raw1.size() == 1);
// state = LAST
REQUIRE( state == RCV_LAST);
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE(idle_data_collection == 0);
REQUIRE(addr1.size() == 1);
REQUIRE(raw1.size() == 2);
REQUIRE( state == RCV_WAIT_FOR_START);
// state = WAIT_FOR_START
data_collection_fsm(raw0, raw1,
addr0, addr1,
run_data_collection,
cancel_data_collection,
idle_data_collection,
act_reg.mode,
act_reg.energy_kev,
act_reg.nframes,
act_reg.nmodules,
act_reg.nstorage_cells,
act_reg.nsummation,
state);
REQUIRE( state == RCV_WAIT_FOR_START);
REQUIRE(idle_data_collection == 1);
REQUIRE(addr1.size() == 1);
REQUIRE(raw1.size() == 2);
auto packet = raw1.read();
REQUIRE(packet.last == 1);
REQUIRE(packet.dest == 0);
packet = raw1.read();
REQUIRE(packet.last);
REQUIRE(packet.dest == 0);
auto addr = addr1.read();
REQUIRE(addr.last);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_15_storage_cell_convert_G0", "[FPGA][Full]") {
const uint16_t nmodules = 2;
@@ -1279,8 +1141,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_15_storage_cell_convert_G0
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == ntrigger * nmodules * nstoragecells * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -1330,8 +1190,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_8_storage_cell_convert_G0"
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == ntrigger * nmodules * nstoragecells * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -1380,8 +1238,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_16_storage_cell_convert_G0
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == ntrigger * nmodules * nstoragecells * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -1427,8 +1283,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_storage_cell_convert_G1",
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == 32*128*JUNGFRAU_PACKET_SIZE_BYTES);
@@ -1469,8 +1323,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_integration", "[FPGA][Full
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
@@ -1538,8 +1390,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_count_threshol
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
@@ -1600,8 +1450,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_mask", "[FPGA]
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
@@ -1658,8 +1506,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_min_pix_per_sp
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
@@ -1717,8 +1563,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_d_min_max", "[
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
@@ -1775,8 +1619,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_snr_threshold"
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
@@ -1815,8 +1657,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_32bit", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * nframes * JUNGFRAU_PACKET_SIZE_BYTES);
auto test_frame_unsigned = (uint16_t *) test_frame.data();
@@ -1866,8 +1706,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_summation", "[FPGA][Full]"
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * nframes * nsummation * JUNGFRAU_PACKET_SIZE_BYTES);
auto test_frame_signed = (int16_t *) test_frame.data();
@@ -1942,8 +1780,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_pedestal", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == NFRAMES_PEDESTAL_CHECK * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -1995,8 +1832,6 @@ TEST_CASE("HLS_C_Simulation_count_sat_and_err_pixels", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
@@ -2022,8 +1857,6 @@ TEST_CASE("HLS_C_Simulation_check_bunchid", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == 0);
REQUIRE(test.GetDataCollectionStatus().current_pulseid == bunchid);
@@ -2062,8 +1895,6 @@ TEST_CASE("HLS_C_Simulation_check_raw_eiger", "[FPGA][Full]") {
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE_NOTHROW(test.OutputStream().read());
REQUIRE(test.OutputStream().size() == 0);
REQUIRE(test.GetBytesReceived() == 256 * 4096);
@@ -2100,8 +1931,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_eiger", "[FPGA][Full]") {
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
@@ -2160,8 +1989,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_roi_calc", "[FPGA][Full]")
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nimages * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
@@ -2203,8 +2030,6 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_4_images", "[FPGA][Full]")
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {

View File

@@ -5,7 +5,8 @@
#include <netinet/ip_icmp.h>
#include <net/if_arp.h>
#include "../acquisition_device/HLSSimulatedDevice.h"
#include "../fpga/hls/hls_jfjoch.h"
#include "../jungfrau/sls_packet.h"
// ARP packet - from if_arp.h
#pragma pack(push)
@@ -29,22 +30,14 @@ struct RAW_ARP_Packet
#pragma pack(pop)
TEST_CASE("HLS_Network_ARP_Gratuitous") {
HLSSimulatedDevice device(0, 64);
const uint16_t nmodules = 4;
DiffractionExperiment x((DetectorGeometry(nmodules)));
AXI_STREAM arp_in;
AXI_STREAM arp_out;
auto gain_from_file = GainCalibrationFromTestFile();
device.CreateFinalPacket(x);
device.StartAction(x);
device.WaitForActionComplete();
arp(arp_in, arp_out, 0x1, 0x1, 1, 1);
packet_512_t network_packet;
device.OutputStream().read(network_packet);
REQUIRE(arp_out.read_nb(network_packet));
auto arp_packet = (RAW_ARP_Packet *) &network_packet.data;
for (int i = 0; i < 6; i++) {

View File

@@ -57,6 +57,18 @@ template <class T> double CheckConversion(const DiffractionExperiment &experimen
experiment.IsUsingGainHG0());
conversion.ConvertFP(conversion_ref.data(), raw);
if (experiment.GetLossyCompressionPoisson()) {
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
if (((int64_t)conversion_ref[i] == experiment.GetOverflow())
|| ((int64_t)conversion_ref[i] == experiment.GetUnderflow()));
else if (conversion_ref[i] < 0.0)
conversion_ref[i] = 0.0;
else {
conversion_ref[i] = std::round(experiment.GetLossyCompressionPoisson().value() *
std::sqrt(conversion_ref[i]));
}
}
}
return Compare(converted, conversion_ref, RAW_MODULE_SIZE);
}
@@ -97,6 +109,21 @@ template <class T> double CheckConversionWithGeomTransform(const DiffractionExpe
raw + m * RAW_MODULE_SIZE);
}
}
if (experiment.GetLossyCompressionPoisson()) {
for (int i = 0; i < experiment.GetModulesNum() * RAW_MODULE_SIZE; i++) {
auto old = conversion_ref[i];
if (((int64_t)conversion_ref[i] == experiment.GetOverflow())
|| ((int64_t)conversion_ref[i] == experiment.GetUnderflow()));
else if (conversion_ref[i] < 0.0)
conversion_ref[i] = 0.0;
else {
conversion_ref[i] = std::round(experiment.GetLossyCompressionPoisson().value() *
std::sqrt(conversion_ref[i]));
}
}
}
RawToConvertedGeometryAdjustMultipixels(experiment, conversion_ref_transformed.data(), conversion_ref.data() );
return Compare(converted, conversion_ref_transformed, experiment.GetPixelsNum());

View File

@@ -64,6 +64,35 @@ TEST_CASE("JFJochReceiverTest_Conversion", "[JFJochReceiver]") {
REQUIRE(!output.status.cancelled);
}
TEST_CASE("JFJochReceiverTest_Conversion_Poisson", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Conversion_Poisson");
DiffractionExperiment x(DetectorGeometry(2));
const uint16_t nthreads = 4;
x.Mode(DetectorMode::Conversion);
x.PedestalG0Frames(0).NumTriggers(1).UseInternalPacketGenerator(true)
.ImagesPerTrigger(32).ImagesPerFile(10).PhotonEnergy_keV(12.4).Compression(
CompressionAlgorithm::BSHUF_ZSTD);
x.LossyCompressionPoisson(1);
AcquisitionDeviceGroup aq_devices;
for (int i = 0; i < x.GetDataStreamsNum(); i++) {
std::unique_ptr<HLSSimulatedDevice> test = std::make_unique<HLSSimulatedDevice>(i, 64);
aq_devices.Add(std::move(test));
}
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
REQUIRE(!output.status.cancelled);
}
TEST_CASE("JFJochReceiverTest_Conversion_FixedGainG1", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_Conversion");

View File

@@ -11,6 +11,9 @@ TARGET_LINK_LIBRARIES(jfjoch_writer_test JFJochReceiver JFJochWriter ImagePushe
ADD_EXECUTABLE(jfjoch_spot_finding_test jfjoch_spot_finding_test.cpp)
TARGET_LINK_LIBRARIES(jfjoch_spot_finding_test JFJochReceiver JFJochWriter ImagePusher JFJochCommon)
ADD_EXECUTABLE(jfjoch_az_int_test jfjoch_az_int_test.cpp)
TARGET_LINK_LIBRARIES(jfjoch_az_int_test JFJochImageAnalysis)
ADD_EXECUTABLE(gain_file_statistics gain_file_statistics.cpp)
TARGET_LINK_LIBRARIES(gain_file_statistics JFJochCommon)

View File

@@ -0,0 +1,54 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include <iostream>
#include <chrono>
#include <future>
#include "../image_analysis/AzimuthalIntegrationMapping.h"
#include "../image_analysis/AzimuthalIntegration.h"
#include "../common/RawToConvertedGeometry.h"
#include "../common/Logger.h"
int main() {
Logger logger("azimuthal_gpu_test");
DiffractionExperiment experiment(DetectorGeometry(18, 3, 8, 36));
experiment.BeamX_pxl(1090).BeamY_pxl(1136).DetectorDistance_mm(75).PhotonEnergy_keV(WVL_1A_IN_KEV);
experiment.QSpacingForAzimInt_recipA(0.02);
AzimuthalIntegrationMapping map(experiment);
std::cout << map.GetBinNumber() << std::endl;
auto map_raw = map.GetPixelToBinMappingRaw();
std::vector<uint16_t> map_conv(experiment.GetPixelsNum());
RawToConvertedGeometry(experiment, map_conv.data(), map_raw.data());
std::vector<double> sum(map.GetBinNumber());
std::vector<double> sum2(map.GetBinNumber());
std::vector<uint32_t> count(map.GetBinNumber());
std::vector<int16_t> image(experiment.GetPixelsNum(), 5);
std::vector<float> coeff(experiment.GetPixelsNum(), 1.0);
auto const iterations = 1000;
auto const threads = 16;
std::vector<std::future<void>> futures;
auto start_time = std::chrono::system_clock::now();
for (int j = 0; j < threads; j++) {
futures.emplace_back(std::async(std::launch::async, [&] {
AzimuthalIntegration azim(experiment, map);
for (int i = 0; i < iterations; i++)
azim.Process(image.data(), experiment.GetPixelsNum());
}));
}
for (auto &f: futures)
f.get();
auto end_time = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
logger.Info("Performance {:.2f} us", elapsed.count() / static_cast<double>(iterations * threads));
}

View File

@@ -123,7 +123,7 @@ int parse_options(DiffractionExperiment& experiment,
settings.indexing_tolerance = atof(optarg);
break;
case 'l':
experiment.DataReductionFactorSerialMX(atof(optarg));
experiment.LossyCompressionSerialMX(atof(optarg));
break;
case 'r':
settings.filter_spots_powder_ring = true;
@@ -198,8 +198,8 @@ int main(int argc, char **argv) {
logger.Info("Detector distance {} mm", x.GetDetectorDistance_mm());
logger.Info("Energy {} keV", x.GetPhotonEnergyForConversion_keV());
logger.Info("Output file prefix {}", x.GetFilePrefix());
if (x.GetDataReductionFactorSerialMX() != 1.0)
logger.Info("MX reduction factor {:0.2f}", x.GetDataReductionFactorSerialMX());
if (x.GetLossyCompressionSerialMX() != 1.0)
logger.Info("MX reduction factor {:0.2f}", x.GetLossyCompressionSerialMX());
if (settings.indexing)
logger.Info("Indexing tolerance {:0.4f}", settings.indexing_tolerance);

29
update_openapi.sh Normal file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
#
# Copyright (2019-2024) Paul Scherrer Institute
#
#wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.2.0/openapi-generator-cli-7.2.0.jar -O openapi-generator-cli.jar
VERSION=$(<VERSION)
VERSION_SEM=${VERSION//_/-}
echo $VERSION_SEM
SRC=' version:.*'
DST=" version: $VERSION_SEM"
sed -i -e "s/$SRC/$DST/" broker/jfjoch_api.yaml
sed -i -e "s/$SRC/$DST/" writer/writer_api.yaml
java -jar openapi-generator-cli.jar generate -i broker/jfjoch_api.yaml -o broker/gen -g cpp-pistache-server
java -jar openapi-generator-cli.jar generate -i writer/writer_api.yaml -o writer/gen -g cpp-pistache-server
sed -i s/org::openapitools::server::model::nlohmann/nlohmann/g broker/gen/model/Dataset_settings.h
sed -i s/org::openapitools::server::model::nlohmann/nlohmann/g broker/gen/model/Dataset_settings.cpp
cd frontend_ui
npm install
npm run openapi
npm run redocly4broker

39
writer/gen/api/ApiBase.h Normal file
View File

@@ -0,0 +1,39 @@
/**
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0-rc.12
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* ApiBase.h
*
* Generalization of the Api classes
*/
#ifndef ApiBase_H_
#define ApiBase_H_
#include <pistache/router.h>
#include <memory>
namespace org::openapitools::server::api
{
class ApiBase {
public:
explicit ApiBase(const std::shared_ptr<Pistache::Rest::Router>& rtr) : router(rtr) {};
virtual ~ApiBase() = default;
virtual void init() = 0;
protected:
const std::shared_ptr<Pistache::Rest::Router> router;
};
} // namespace org::openapitools::server::api
#endif /* ApiBase_H_ */

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0.rc_11
* The version of the OpenAPI document: 1.0.0-rc.12
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -22,7 +22,7 @@ using namespace org::openapitools::server::model;
const std::string DefaultApi::base = "";
DefaultApi::DefaultApi(const std::shared_ptr<Pistache::Rest::Router>& rtr)
: router(rtr)
: ApiBase(rtr)
{
}

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0.rc_11
* The version of the OpenAPI document: 1.0.0-rc.12
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -19,6 +19,8 @@
#define DefaultApi_H_
#include "ApiBase.h"
#include <pistache/http.h>
#include <pistache/router.h>
#include <pistache/http_headers.h>
@@ -32,11 +34,11 @@
namespace org::openapitools::server::api
{
class DefaultApi {
class DefaultApi : public ApiBase {
public:
explicit DefaultApi(const std::shared_ptr<Pistache::Rest::Router>& rtr);
virtual ~DefaultApi() = default;
void init();
~DefaultApi() override = default;
void init() override;
static const std::string base;
@@ -48,8 +50,6 @@ private:
void version_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void default_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
const std::shared_ptr<Pistache::Rest::Router> router;
/// <summary>
/// Helper function to handle unexpected Exceptions during Parameter parsing and validation.
/// May be overridden to return custom error formats. This is called inside a catch block.

Some files were not shown because too many files have changed in this diff Show More