Compare commits
8 Commits
1.0.0_rc.1
...
1.0.0-rc.1
| Author | SHA1 | Date | |
|---|---|---|---|
| e1045ee3b6 | |||
| 3e5ed2e9f9 | |||
| 3a08733872 | |||
| 00be0bb224 | |||
| c4fc178f7a | |||
| 6b5fddf2b7 | |||
| 2b9ce9a26e | |||
| 3035d9e144 |
@@ -104,6 +104,7 @@ build:x86:rpm:
|
||||
- cd build
|
||||
- source /opt/rh/gcc-toolset-12/enable
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
- make update_version
|
||||
- make frontend
|
||||
- make -j48 package
|
||||
- mv *.rpm ..
|
||||
@@ -251,6 +252,7 @@ synthesis:vivado_pcie_100g:
|
||||
- fpga/pcie_driver/jfjoch_fpga.h
|
||||
tags:
|
||||
- vivado
|
||||
retry: 1
|
||||
artifacts:
|
||||
paths:
|
||||
- "jfjoch_fpga_pcie_100g.mcs"
|
||||
@@ -284,6 +286,7 @@ synthesis:vivado_pcie_8x10g:
|
||||
allow_failure: true
|
||||
tags:
|
||||
- vivado
|
||||
retry: 1
|
||||
artifacts:
|
||||
paths:
|
||||
- "jfjoch_fpga_pcie_8x10g.mcs"
|
||||
@@ -313,8 +316,9 @@ release:
|
||||
- build:x86:driver
|
||||
- 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=`head -n1 VERSION`
|
||||
- export PACKAGE_VERSION=${PACKAGE_VERSION_SEM//-/_}
|
||||
- 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"'
|
||||
@@ -323,7 +327,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\"}"
|
||||
|
||||
@@ -131,13 +131,17 @@ 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(update_version
|
||||
COMMAND bash update_version.sh
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/
|
||||
DESTINATION /usr/src/jfjoch-1.0.0
|
||||
DESTINATION /usr/src/jfjoch-${JFJOCH_VERSION}
|
||||
COMPONENT driver-dkms
|
||||
FILES_MATCHING PATTERN "dkms.conf")
|
||||
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/
|
||||
DESTINATION /usr/src/jfjoch-1.0.0/src
|
||||
DESTINATION /usr/src/jfjoch-${JFJOCH_VERSION}/src
|
||||
COMPONENT driver-dkms
|
||||
FILES_MATCHING PATTERN "*.c" PATTERN "*.h" PATTERN "Makefile")
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ¶ms) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -475,8 +477,21 @@ void JFJochBrokerHttp::status_get(Pistache::Http::ResponseWriter &response) {
|
||||
ProcessOutput(Convert(state_machine.GetStatus()), response);
|
||||
}
|
||||
|
||||
void JFJochBrokerHttp::wait_till_done_post(Pistache::Http::ResponseWriter &response) {
|
||||
auto state = state_machine.WaitTillMeasurementDone(std::chrono::seconds(5));
|
||||
|
||||
|
||||
void JFJochBrokerHttp::wait_till_done_post(const std::optional<int32_t> &timeout,
|
||||
Pistache::Http::ResponseWriter &response) {
|
||||
JFJochState state;
|
||||
if (!timeout)
|
||||
state = state_machine.WaitTillMeasurementDone(std::chrono::minutes(1));
|
||||
else if ((timeout.value() > 3600) || (timeout.value() < 0)) {
|
||||
response.send(Pistache::Http::Code::Bad_Request);
|
||||
return;
|
||||
} else if (timeout.value() == 0)
|
||||
state = state_machine.GetState();
|
||||
else
|
||||
state = state_machine.WaitTillMeasurementDone(std::chrono::seconds(timeout.value()));
|
||||
|
||||
switch (state) {
|
||||
case JFJochState::Idle:
|
||||
response.send(Pistache::Http::Code::Ok);
|
||||
|
||||
@@ -90,7 +90,7 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi {
|
||||
|
||||
void status_get(Pistache::Http::ResponseWriter &response) override;
|
||||
|
||||
void wait_till_done_post(Pistache::Http::ResponseWriter &response) override;
|
||||
void wait_till_done_post(const std::optional<int32_t> &timeoutMs, Pistache::Http::ResponseWriter &response) override;
|
||||
void trigger_post(Pistache::Http::ResponseWriter &response) override;
|
||||
void pedestal_post(Pistache::Http::ResponseWriter &response) override;
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "JFJochBrokerParser.h"
|
||||
#include "../common/NetworkAddressConvert.h"
|
||||
#include "../frame_serialize/ZMQStream2Pusher.h"
|
||||
#include "../frame_serialize/DumpCBORToFilePusher.h"
|
||||
|
||||
inline bool CHECK_ARRAY(const nlohmann::json &j, const std::string& tag) {
|
||||
if (j.contains(tag)) {
|
||||
@@ -183,6 +185,7 @@ inline int64_t TimeToUs(const std::string &unit) {
|
||||
|
||||
inline std::chrono::microseconds GET_TIME(const nlohmann::json &j, const std::string& tag) {
|
||||
if (j.contains(tag)) {
|
||||
// If no units provided for time, this is always microsecond
|
||||
if (j[tag].is_number())
|
||||
return std::chrono::microseconds (std::lround(j[tag].get<double>() * 1000.0 * 1000.0));
|
||||
else if (j[tag].is_string()) {
|
||||
@@ -300,6 +303,35 @@ void ParseDetectorSetup(const nlohmann::json &j, const std::string& tag, JFJochB
|
||||
throw JFJochException(JFJochExceptionCategory::JSON, "Detector setup not found");
|
||||
}
|
||||
|
||||
void ParseImagePusher(const nlohmann::json &input, std::unique_ptr<ImagePusher> &image_pusher) {
|
||||
std::string pusher_type = ParseString(input, "stream_type", "zmq");
|
||||
if (pusher_type == "zmq") {
|
||||
int32_t zmq_send_watermark = ParseInt32(input, "zmq_send_watermark", 100);
|
||||
int32_t zmq_send_buffer_size = ParseInt32(input, "zmq_send_buffer_size", -1);
|
||||
|
||||
auto tmp = std::make_unique<ZMQStream2Pusher>(ParseStringArray(input, "zmq_image_addr"),
|
||||
zmq_send_watermark,
|
||||
zmq_send_buffer_size);
|
||||
|
||||
std::string preview_addr = ParseString(input, "zmq_preview_addr", "");
|
||||
if (!preview_addr.empty())
|
||||
tmp->PreviewSocket(preview_addr);
|
||||
|
||||
if (input.contains("zmq_preview_period"))
|
||||
tmp->PreviewCounterPeriod(GET_TIME(input, "zmq_preview_period"));
|
||||
|
||||
std::string writer_notification_addr = ParseString(input, "zmq_writer_notification_addr", "");
|
||||
if (!writer_notification_addr.empty())
|
||||
tmp->WriterNotificationSocket(writer_notification_addr);
|
||||
|
||||
image_pusher = std::move(tmp);
|
||||
} else if (pusher_type == "dump_cbor") {
|
||||
image_pusher = std::make_unique<DumpCBORToFilePusher>();
|
||||
} else
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"stream_type allowed: zmq (default), dump_cbor");
|
||||
}
|
||||
|
||||
void ParseFacilityConfiguration(const nlohmann::json &input, const std::string& tag, DiffractionExperiment &experiment) {
|
||||
if (CHECK_OBJECT(input, tag)) {
|
||||
auto j = input[tag];
|
||||
@@ -328,12 +360,11 @@ void ParseFacilityConfiguration(const nlohmann::json &input, const std::string&
|
||||
experiment.PedestalG1Frames(GET_I64(j, "pedestal_g1_frames"));
|
||||
if (j.contains("pedestal_g2_frames"))
|
||||
experiment.PedestalG2Frames(GET_I64(j, "pedestal_g2_frames"));
|
||||
if (j.contains("detector_trigger_delay_us"))
|
||||
experiment.DetectorDelay(GET_TIME(j, "detector_trigger_delay_us"));
|
||||
if (j.contains("detector_trigger_delay"))
|
||||
experiment.DetectorDelay(GET_TIME(j, "detector_trigger_delay"));
|
||||
|
||||
experiment.FrameTime(GET_TIME(j, "frame_time"), GET_TIME(j, "count_time"));
|
||||
|
||||
experiment.FrameTime(GET_TIME(j, "frame_time_us"), GET_TIME(j, "count_time_us"));
|
||||
if (j.contains("preview_period_us"))
|
||||
experiment.PreviewPeriod(GET_TIME(j, "preview_period_us"));
|
||||
experiment.UseInternalPacketGenerator(GET_BOOL(j, "internal_frame_generator", false));
|
||||
if (experiment.IsUsingInternalPacketGen())
|
||||
experiment.ConversionOnFPGA(false);
|
||||
|
||||
@@ -14,6 +14,7 @@ DetectorGeometry ParseDetectorGeometry(const nlohmann::json &j);
|
||||
DetectorSetup ParseDetectorSetup(const nlohmann::json &j);
|
||||
void ParseDetectorSetup(const nlohmann::json &j, const std::string& tag, JFJochBrokerHttp& broker);
|
||||
void ParseFacilityConfiguration(const nlohmann::json &j, const std::string& tag, DiffractionExperiment &experiment);
|
||||
void ParseImagePusher(const nlohmann::json &j, std::unique_ptr<ImagePusher> &image_pusher);
|
||||
|
||||
void ParseAcquisitionDeviceGroup(const nlohmann::json &input, const std::string& tag, AcquisitionDeviceGroup &aq_devices);
|
||||
std::vector<std::string> ParseStringArray(const nlohmann::json &input, const std::string& tag);
|
||||
|
||||
@@ -340,12 +340,6 @@ void JFJochStateMachine::Start(const DatasetSettings& settings) {
|
||||
}
|
||||
}
|
||||
|
||||
void JFJochStateMachine::WaitTillMeasurementDone() {
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
|
||||
c.wait(ul, [&] { return !IsRunning(); });
|
||||
}
|
||||
|
||||
void JFJochStateMachine::MeasurementThread() {
|
||||
try {
|
||||
auto tmp_output = services.Stop();
|
||||
@@ -659,6 +653,14 @@ bool JFJochStateMachine::IsRunning() const {
|
||||
}
|
||||
}
|
||||
|
||||
JFJochState JFJochStateMachine::WaitTillMeasurementDone() {
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
|
||||
c.wait(ul, [&] { return !IsRunning(); });
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
JFJochState JFJochStateMachine::WaitTillMeasurementDone(std::chrono::milliseconds timeout) {
|
||||
std::unique_lock<std::mutex> ul(m);
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
void Pedestal();
|
||||
void Deactivate();
|
||||
void Start(const DatasetSettings& settings);
|
||||
void WaitTillMeasurementDone();
|
||||
JFJochState WaitTillMeasurementDone();
|
||||
JFJochState WaitTillMeasurementDone(std::chrono::milliseconds timeout);
|
||||
void Trigger();
|
||||
|
||||
|
||||
39
broker/gen/api/ApiBase.h
Normal file
39
broker/gen/api/ApiBase.h
Normal 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_ */
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1275,12 +1275,22 @@ void DefaultApi::version_get_handler(const Pistache::Rest::Request &, Pistache::
|
||||
}
|
||||
|
||||
}
|
||||
void DefaultApi::wait_till_done_post_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
|
||||
void DefaultApi::wait_till_done_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
|
||||
try {
|
||||
|
||||
|
||||
// Getting the query params
|
||||
auto timeoutQuery = request.query().get("timeout");
|
||||
std::optional<int32_t> timeout;
|
||||
if(timeoutQuery.has_value()){
|
||||
int32_t valueQuery_instance;
|
||||
if(fromStringValue(timeoutQuery.value(), valueQuery_instance)){
|
||||
timeout = valueQuery_instance;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this->wait_till_done_post(response);
|
||||
this->wait_till_done_post(timeout, response);
|
||||
} catch (Pistache::Http::HttpError &e) {
|
||||
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
|
||||
return;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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.
|
||||
@@ -479,9 +480,10 @@ private:
|
||||
/// Wait for acquisition done
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// 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 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.
|
||||
/// </remarks>
|
||||
virtual void wait_till_done_post(Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <param name="timeout">Timeout in seconds (0 == immediate response) (optional, default to 60)</param>
|
||||
virtual void wait_till_done_post(const std::optional<int32_t> &timeout, Pistache::Http::ResponseWriter &response) = 0;
|
||||
/// <summary>
|
||||
/// Return XFEL event codes for the current data acquisition
|
||||
/// </summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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).
|
||||
@@ -38,6 +38,7 @@ Dataset_settings::Dataset_settings()
|
||||
m_Space_group_number = 0L;
|
||||
m_Space_group_numberIsSet = false;
|
||||
m_Sample_name = "";
|
||||
m_Sample_nameIsSet = false;
|
||||
m_Fpga_output = "auto";
|
||||
m_Fpga_outputIsSet = false;
|
||||
m_Compression = "bslz4";
|
||||
@@ -59,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;
|
||||
|
||||
}
|
||||
@@ -256,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;
|
||||
}
|
||||
|
||||
@@ -295,8 +317,8 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
|
||||
|
||||
((!spaceGroupNumberIsSet() && !rhs.spaceGroupNumberIsSet()) || (spaceGroupNumberIsSet() && rhs.spaceGroupNumberIsSet() && getSpaceGroupNumber() == rhs.getSpaceGroupNumber())) &&
|
||||
|
||||
(getSampleName() == rhs.getSampleName())
|
||||
&&
|
||||
|
||||
((!sampleNameIsSet() && !rhs.sampleNameIsSet()) || (sampleNameIsSet() && rhs.sampleNameIsSet() && getSampleName() == rhs.getSampleName())) &&
|
||||
|
||||
|
||||
((!fpgaOutputIsSet() && !rhs.fpgaOutputIsSet()) || (fpgaOutputIsSet() && rhs.fpgaOutputIsSet() && getFpgaOutput() == rhs.getFpgaOutput())) &&
|
||||
@@ -335,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()))
|
||||
|
||||
;
|
||||
@@ -347,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())
|
||||
@@ -364,7 +389,8 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
|
||||
j["images_per_file"] = o.m_Images_per_file;
|
||||
if(o.spaceGroupNumberIsSet())
|
||||
j["space_group_number"] = o.m_Space_group_number;
|
||||
j["sample_name"] = o.m_Sample_name;
|
||||
if(o.sampleNameIsSet())
|
||||
j["sample_name"] = o.m_Sample_name;
|
||||
if(o.fpgaOutputIsSet())
|
||||
j["fpga_output"] = o.m_Fpga_output;
|
||||
if(o.compressionIsSet())
|
||||
@@ -389,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;
|
||||
|
||||
@@ -430,7 +458,11 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
|
||||
j.at("space_group_number").get_to(o.m_Space_group_number);
|
||||
o.m_Space_group_numberIsSet = true;
|
||||
}
|
||||
j.at("sample_name").get_to(o.m_Sample_name);
|
||||
if(j.find("sample_name") != j.end())
|
||||
{
|
||||
j.at("sample_name").get_to(o.m_Sample_name);
|
||||
o.m_Sample_nameIsSet = true;
|
||||
}
|
||||
if(j.find("fpga_output") != j.end())
|
||||
{
|
||||
j.at("fpga_output").get_to(o.m_Fpga_output);
|
||||
@@ -491,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);
|
||||
@@ -640,6 +677,15 @@ std::string Dataset_settings::getSampleName() const
|
||||
void Dataset_settings::setSampleName(std::string const& value)
|
||||
{
|
||||
m_Sample_name = value;
|
||||
m_Sample_nameIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::sampleNameIsSet() const
|
||||
{
|
||||
return m_Sample_nameIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetSample_name()
|
||||
{
|
||||
m_Sample_nameIsSet = false;
|
||||
}
|
||||
std::string Dataset_settings::getFpgaOutput() const
|
||||
{
|
||||
@@ -845,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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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).
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
bool ntriggerIsSet() const;
|
||||
void unsetNtrigger();
|
||||
/// <summary>
|
||||
/// Image time. If not provided (or zero value) the frame time is assumed as default. For JUNGFRAU, image time must be multiple of frame time, up to 256 * frame_time. In XFEL mode: summation happens for frames collected with multiple triggers. Ignored for storage cells and if raw data are saved.
|
||||
/// 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 and if raw data are saved.
|
||||
/// </summary>
|
||||
int64_t getImageTimeUs() const;
|
||||
void setImageTimeUs(int64_t const value);
|
||||
@@ -128,6 +128,8 @@ public:
|
||||
/// </summary>
|
||||
std::string getSampleName() const;
|
||||
void setSampleName(std::string const& value);
|
||||
bool sampleNameIsSet() const;
|
||||
void unsetSample_name();
|
||||
/// <summary>
|
||||
/// FPGA output data type
|
||||
/// </summary>
|
||||
@@ -213,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;
|
||||
@@ -220,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;
|
||||
@@ -244,7 +253,7 @@ protected:
|
||||
int64_t m_Space_group_number;
|
||||
bool m_Space_group_numberIsSet;
|
||||
std::string m_Sample_name;
|
||||
|
||||
bool m_Sample_nameIsSet;
|
||||
std::string m_Fpga_output;
|
||||
bool m_Fpga_outputIsSet;
|
||||
std::string m_Compression;
|
||||
@@ -269,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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Jungfraujoch
|
||||
* Jungfraujoch Broker Web API
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0_rc.10
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ openapi: 3.0.3
|
||||
info:
|
||||
title: Jungfraujoch
|
||||
description: Jungfraujoch Broker Web API
|
||||
version: 1.0.0_rc.10
|
||||
version: 1.0.0-rc.12
|
||||
contact:
|
||||
email: filip.leonarski@psi.ch
|
||||
components:
|
||||
@@ -45,7 +45,6 @@ components:
|
||||
- beam_y_pxl
|
||||
- detector_distance_mm
|
||||
- incident_energy_keV
|
||||
- sample_name
|
||||
properties:
|
||||
images_per_trigger:
|
||||
type: integer
|
||||
@@ -117,6 +116,7 @@ components:
|
||||
maximum: 194
|
||||
sample_name:
|
||||
type: string
|
||||
default: ""
|
||||
description: |
|
||||
/entry/sample/name in NXmx
|
||||
Sample name
|
||||
@@ -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
|
||||
@@ -853,22 +863,37 @@ paths:
|
||||
/wait_till_done:
|
||||
post:
|
||||
summary: Wait for acquisition done
|
||||
parameters:
|
||||
- in: query
|
||||
name: timeout
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 60
|
||||
minimum: 0
|
||||
maximum: 3600
|
||||
description: Timeout in seconds (0 == immediate response)
|
||||
description: |
|
||||
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.
|
||||
responses:
|
||||
"200":
|
||||
description: Detector in `Idle` state, another data collection can start immediately
|
||||
"400":
|
||||
description: Timeout parameter out of bounds
|
||||
"500":
|
||||
description: Error within Jungfraujoch code - see output message.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/error_message'
|
||||
"502":
|
||||
description: Detector is inactive mode
|
||||
"504":
|
||||
description: 5 second timeout reached, need to restart operation
|
||||
description: Timeout reached, need to restart operation
|
||||
|
||||
/trigger:
|
||||
post:
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "JFJochBrokerHttp.h"
|
||||
|
||||
#include "JFJochBrokerParser.h"
|
||||
#include "../frame_serialize/ZMQStream2Pusher.h"
|
||||
#include "../frame_serialize/DumpCBORToFilePusher.h"
|
||||
|
||||
static Pistache::Http::Endpoint *httpEndpoint;
|
||||
|
||||
@@ -81,25 +79,7 @@ int main (int argc, char **argv) {
|
||||
if (aq_devices.size() > 0) {
|
||||
experiment.DataStreams(aq_devices.size());
|
||||
|
||||
std::string pusher_type = ParseString(input, "stream_type", "zmq");
|
||||
if (pusher_type == "zmq") {
|
||||
int32_t zmq_send_watermark = ParseInt32(input, "zmq_send_watermark", 100);
|
||||
int32_t zmq_send_buffer_size = ParseInt32(input, "zmq_send_buffer_size", -1);
|
||||
|
||||
auto tmp = std::make_unique<ZMQStream2Pusher>(ParseStringArray(input, "zmq_image_addr"),
|
||||
zmq_send_watermark,
|
||||
zmq_send_buffer_size);
|
||||
|
||||
std::string preview_addr = ParseString(input, "zmq_preview_addr", "");
|
||||
if (!preview_addr.empty())
|
||||
tmp->PreviewSocket(preview_addr);
|
||||
|
||||
image_pusher = std::move(tmp);
|
||||
} else if (pusher_type == "dump_cbor") {
|
||||
image_pusher = std::make_unique<DumpCBORToFilePusher>();
|
||||
} else
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"stream_type allowed: zmq (default), dump_cbor");
|
||||
ParseImagePusher(input, image_pusher);
|
||||
|
||||
int32_t send_buffer_size_MiB = ParseInt32(input, "send_buffer_size_MiB", 2048);
|
||||
receiver = std::make_unique<JFJochReceiverService>(aq_devices, logger, *image_pusher, send_buffer_size_MiB);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ class DiffractionExperiment {
|
||||
int64_t max_spot_count;
|
||||
|
||||
int64_t summation;
|
||||
|
||||
std::string detector_update_zmq_addr;
|
||||
public:
|
||||
// Public methods are atomic
|
||||
DiffractionExperiment();
|
||||
@@ -169,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;
|
||||
@@ -322,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;
|
||||
};
|
||||
|
||||
|
||||
@@ -65,14 +65,14 @@ void DetectorWrapper::Initialize(const DiffractionExperiment& experiment,
|
||||
det.setSourceUDPIP(sls::IpAddr(cfg.ipv4_src_addr_1), {i});
|
||||
det.setSourceUDPMAC(sls::MacAddr(BASE_DETECTOR_MAC + i * 2), {i});
|
||||
|
||||
det.setDestinationUDPPort(cfg.udp_dest_port_1, i);
|
||||
det.setDestinationUDPPort(cfg.udp_dest_port_1 + 2 * i, i);
|
||||
det.setDestinationUDPIP(sls::IpAddr(cfg.ipv4_dest_addr_1), {i});
|
||||
det.setDestinationUDPMAC(sls::MacAddr(cfg.mac_addr_dest_1), {i});
|
||||
|
||||
if (experiment.GetUDPInterfaceCount() == 2) {
|
||||
det.setSourceUDPIP2(sls::IpAddr(cfg.ipv4_src_addr_2), {i});
|
||||
det.setSourceUDPMAC2(sls::MacAddr(BASE_DETECTOR_MAC + i * 2 + 1), {i});
|
||||
det.setDestinationUDPPort2(cfg.udp_dest_port_2, i);
|
||||
det.setDestinationUDPPort2(cfg.udp_dest_port_2 + 2 * i + 1, i);
|
||||
det.setDestinationUDPIP2(sls::IpAddr(cfg.ipv4_dest_addr_2), {i});
|
||||
det.setDestinationUDPMAC2(sls::MacAddr(cfg.mac_addr_dest_2), {i});
|
||||
}
|
||||
@@ -100,8 +100,8 @@ void DetectorWrapper::Initialize(const DiffractionExperiment& experiment,
|
||||
|
||||
auto &cfg = mod_cfg[i];
|
||||
|
||||
det.setDestinationUDPPort(cfg.udp_dest_port_1, 2 * i);
|
||||
det.setDestinationUDPPort2(cfg.udp_dest_port_1, 2 * i + 1);
|
||||
det.setDestinationUDPPort(cfg.udp_dest_port_1 + 2 * i, 2 * i);
|
||||
det.setDestinationUDPPort2(cfg.udp_dest_port_1 + 2 * i + 1, 2 * i + 1);
|
||||
det.setSourceUDPIP(sls::IpAddr(cfg.ipv4_src_addr_1), {2 * i, 2 * i + 1});
|
||||
det.setDestinationUDPIP(sls::IpAddr(cfg.ipv4_dest_addr_1), {2 * i, 2 * i + 1});
|
||||
det.setDestinationUDPMAC(sls::MacAddr(cfg.mac_addr_dest_1), {2 * i, 2 * i + 1});
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
"pedestal_g0_frames": 2000,
|
||||
"pedestal_g1_frames": 300,
|
||||
"pedestal_g2_frames": 300,
|
||||
"frame_time_us": "500 us",
|
||||
"count_time_us": "480 us",
|
||||
"preview_period_us": "1 s",
|
||||
"frame_time": "500 us",
|
||||
"count_time": "480 us",
|
||||
"detector_ipv4": "10.10.85.0"
|
||||
},
|
||||
"frontend_directory":"/home/jungfrau/nextgendcu/frontend/build",
|
||||
"numa_policy": "n2g2",
|
||||
"zmq_preview_period": "1 s",
|
||||
"zmq_image_addr": ["tcp://0.0.0.0:5500", "tcp://0.0.0.0:5501", "tcp://0.0.0.0:5502", "tcp://0.0.0.0:5503"],
|
||||
"receiver_threads": 64,
|
||||
"receiver": {
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
"pedestal_g0_frames": 2000,
|
||||
"pedestal_g1_frames": 300,
|
||||
"pedestal_g2_frames": 300,
|
||||
"frame_time_us": "10 ms",
|
||||
"count_time_us": "10 us",
|
||||
"preview_period_us": "1 s",
|
||||
"frame_time": "10 ms",
|
||||
"count_time": "10 us",
|
||||
"detector_ipv4": "10.3.30.155",
|
||||
"pulsed_source": true
|
||||
},
|
||||
"frontend_directory":"/home/jungfrau/nextgendcu/frontend/build",
|
||||
"numa_policy": "n2g4",
|
||||
"zmq_image_addr": ["tcp://0.0.0.0:5500"],
|
||||
"zmq_preview_period": "1 s",
|
||||
|
||||
"receiver_threads": 64,
|
||||
"receiver": {
|
||||
"type": "pcie",
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
"pedestal_g0_frames": 0,
|
||||
"pedestal_g1_frames": 0,
|
||||
"pedestal_g2_frames": 0,
|
||||
"frame_time_us": "1000 us",
|
||||
"count_time_us": "980 us",
|
||||
"preview_period_us": "1 s",
|
||||
"frame_time": "1000 us",
|
||||
"count_time": "980 us",
|
||||
"detector_ipv4": "10.10.85.20",
|
||||
"internal_frame_generator": true
|
||||
},
|
||||
@@ -20,6 +19,9 @@
|
||||
},
|
||||
"frontend_directory": "../../frontend_ui/build/",
|
||||
"zmq_image_addr": ["tcp://0.0.0.0:5500"],
|
||||
"zmq_preview_addr": "tcp://0.0.0.0:5501",
|
||||
"zmq_preview_period": "1 s",
|
||||
"zmq_writer_notification_addr": "ipc://*",
|
||||
"detectors": [
|
||||
{
|
||||
"standard_geometry": {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
791
fpga/hls/HLSDevice.cpp
Normal 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 ¶ms) {
|
||||
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
75
fpga/hls/HLSDevice.h
Normal 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 ¶ms);
|
||||
uint32_t HW_GetDataSource();
|
||||
void HW_SetDataSource(uint32_t val);
|
||||
void HW_RunInternalGenerator(const FrameGeneratorConfig &config) ;
|
||||
};
|
||||
|
||||
|
||||
#endif //JFJOCH_HLSDEVICE_H
|
||||
@@ -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)
|
||||
|
||||
@@ -16,6 +16,7 @@ void data_collection_fsm(AXI_STREAM ð_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 ð_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 ð_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;
|
||||
|
||||
@@ -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 ð_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
47
fpga/hls/pixel_sqrt.cpp
Normal 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;
|
||||
}
|
||||
65
fpga/hls/pixel_sqrt_tb.cpp
Normal file
65
fpga/hls/pixel_sqrt_tb.cpp
Normal 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;
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
PACKAGE_NAME=jfjoch
|
||||
PACKAGE_VERSION=1.0.0
|
||||
PACKAGE_VERSION=1.0.0-rc.12
|
||||
|
||||
DEST_MODULE_LOCATION=/extra
|
||||
BUILT_MODULE_NAME=jfjoch
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
MODULE_AUTHOR("Filip Leonarski; Paul Scherrer Institute");
|
||||
MODULE_DESCRIPTION("Jungfraujoch device module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("1.0.0");
|
||||
MODULE_VERSION("1.0.0-rc.12");
|
||||
|
||||
#define XDMA_GEN4_x8 (0x9048)
|
||||
#define XDMA_GEN3_x16 (0x903F)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Taken from https://schneide.blog/2015/08/10/packaging-kernel-modulesdrivers-using-dkms/
|
||||
|
||||
VERSION="1.0.0"
|
||||
VERSION=1.0.0-rc.12
|
||||
|
||||
occurrences=`/usr/sbin/dkms status | grep jfjoch | grep ${VERSION} | wc -l`
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Taken from https://schneide.blog/2015/08/10/packaging-kernel-modulesdrivers-using-dkms/
|
||||
|
||||
VERSION="1.0.0"
|
||||
VERSION=1.0.0-rc.12
|
||||
|
||||
/usr/sbin/dkms remove -m jfjoch -v ${VERSION} --all
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -92,7 +92,7 @@ if {$WNSPLACE > -0.3000} {
|
||||
puts " ***** Final WNS: $WNSROUTE ps *****"
|
||||
puts ""
|
||||
|
||||
if {$WNSROUTE >= -0.050} {
|
||||
if {$WNSROUTE >= 0} {
|
||||
write_bitstream -force -file ${bitstream_name} >> bitstream.log
|
||||
if {$part eq {xcu55c-fsvh2892-2L-e}} {
|
||||
write_cfgmem -force -size 128 -format mcs -interface SPIx4 -loadbit "up 0x01002000 ${bitstream_name}.bit" ${bitstream_name} >> cfgmem.log
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -659,7 +659,10 @@ namespace {
|
||||
message.experiment_group = j["experiment_group"];
|
||||
if (j.contains("jfjoch_release"))
|
||||
message.jfjoch_release = j["jfjoch_release"];
|
||||
|
||||
if (j.contains("socket_number"))
|
||||
message.socket_number = j["socket_number"];
|
||||
if (j.contains("writer_notification_zmq_addr"))
|
||||
message.writer_notification_zmq_addr = j["writer_notification_zmq_addr"];
|
||||
} catch (const std::exception &e) {
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError,
|
||||
"Cannot parse user_data as valid JSON " + std::string(e.what()));
|
||||
|
||||
@@ -321,9 +321,13 @@ inline void CBOR_ENC_START_USER_DATA(CborEncoder& encoder, const char* key,
|
||||
j["write_master_file"] = message.write_master_file.value();
|
||||
if (message.data_reduction_factor_serialmx)
|
||||
j["data_reduction_factor_serialmx"] = message.data_reduction_factor_serialmx.value();
|
||||
if (message.experiment_group)
|
||||
j["experiment_group"] = message.experiment_group.value();
|
||||
j["experiment_group"] = message.experiment_group;
|
||||
j["jfjoch_release"] = message.jfjoch_release;
|
||||
if (message.socket_number)
|
||||
j["socket_number"] = message.socket_number.value();
|
||||
|
||||
j["writer_notification_zmq_addr"] = message.writer_notification_zmq_addr;
|
||||
|
||||
auto str = j.dump();
|
||||
|
||||
CBOR_ENC(encoder, key, str);
|
||||
|
||||
@@ -21,6 +21,7 @@ ADD_LIBRARY(ImagePusher STATIC
|
||||
ImagePusher.cpp ImagePusher.h
|
||||
TestImagePusher.cpp TestImagePusher.h
|
||||
ZMQStream2Pusher.cpp ZMQStream2Pusher.h
|
||||
ZMQWriterNotificationPuller.cpp ZMQWriterNotificationPuller.h
|
||||
DumpCBORToFilePusher.cpp
|
||||
DumpCBORToFilePusher.h)
|
||||
|
||||
|
||||
@@ -15,3 +15,9 @@ void PrepareCBORImage(DataMessage& message,
|
||||
message.image.algorithm = experiment.GetCompressionAlgorithm();
|
||||
message.image.channel = "default";
|
||||
}
|
||||
|
||||
void ImagePusher::Finalize() {}
|
||||
|
||||
std::string ImagePusher::GetWriterNotificationSocketAddress() const {
|
||||
return "socket1234";
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "CBORStream2Serializer.h"
|
||||
#include "JFJochMessages.h"
|
||||
#include "../common/ZeroCopyReturnValue.h"
|
||||
#include "../common/Logger.h"
|
||||
|
||||
void PrepareCBORImage(DataMessage& message,
|
||||
const DiffractionExperiment &experiment,
|
||||
@@ -24,6 +25,9 @@ public:
|
||||
virtual void SendImage(const uint8_t *image_data, size_t image_size, int64_t image_number,
|
||||
ZeroCopyReturnValue *z) = 0;
|
||||
virtual bool SendCalibration(const CompressedImage& message) = 0;
|
||||
virtual void Finalize(); // Ensure that all streams are closed, can throw exception
|
||||
virtual std::string GetWriterNotificationSocketAddress() const;
|
||||
virtual ~ImagePusher() = default;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@ struct StartMessage {
|
||||
std::string detector_serial_number;
|
||||
std::string run_name;
|
||||
uint64_t run_number;
|
||||
|
||||
std::vector<std::string> gain_file_names;
|
||||
|
||||
std::vector<std::string> roi_names;
|
||||
@@ -175,9 +176,12 @@ struct StartMessage {
|
||||
nlohmann::json user_data;
|
||||
|
||||
std::optional<float> data_reduction_factor_serialmx;
|
||||
std::optional<std::string> experiment_group;
|
||||
std::string experiment_group;
|
||||
|
||||
std::string jfjoch_release;
|
||||
|
||||
std::optional<uint64_t> socket_number; // This is number of socket in ZeroMQ
|
||||
std::string writer_notification_zmq_addr; // Socket to inform detector on writer done
|
||||
};
|
||||
|
||||
struct EndMessage {
|
||||
|
||||
@@ -13,58 +13,60 @@ There are minor differences at the moment:
|
||||
|
||||
## Start message
|
||||
|
||||
| Field name | Type | Description | Present in DECTRIS format |
|
||||
|---------------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
|
||||
| type | String | value "start" | X |
|
||||
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
|
||||
| detector_distance | float | Detector distance \[m\] | |
|
||||
| detector_translation | float | Detector translation vector \[m\] | X |
|
||||
| beam_center_x | float | Beam center in X direction \[pixels\] | X |
|
||||
| beam_center_y | float | Beam center in Y direction \[pixels\] | X |
|
||||
| number_of_images | uint64 | Number of images in the series | X |
|
||||
| image_size_x | uint64 | Image width \[pixels\] | X |
|
||||
| image_size_y | uint64 | Image height \[pixels\] | X |
|
||||
| incident_energy | float | X-ray energy \[eV\] | X |
|
||||
| incident_wavelength | float | X-ray wavelength \[Angstrom\] | X |
|
||||
| frame_time | float | Frame time, if multiple frames per trigger \[s\] | X |
|
||||
| count_time | float | Exposure time \[s\] | X |
|
||||
| saturation_value | int64 | Maximum valid sample value | X |
|
||||
| error_value | int64 | Value used in images to describe pixels that are in error state or missing | |
|
||||
| pixel_size_x | float | Pixel width \[m\] | X |
|
||||
| pixel_size_y | float | Pixel height \[m\] | X |
|
||||
| sensor_thickness | float | Sensor thickness \[m\] | X |
|
||||
| sensor_material | string | Sensor material | X |
|
||||
| arm_data | data | Approximate date of arming | X |
|
||||
| pixel_mask_enabled | bool | Pixel mask applied on images | X |
|
||||
| detector_description | string | Name of the detector | X |
|
||||
| series_unique_id | string | Unique text ID of the series (run_name parameter) | X |
|
||||
| series_id | uint64 | Unique numeric ID of the series (run_number parameter) | X |
|
||||
| goniometer | Map | See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) - only one axis is supported | X |
|
||||
| pixel_mask | Map(string -> Image) | Pixel mask - multiple in case of storage cells | X |
|
||||
| channels | Array(string) | List of image channels | X |
|
||||
| max_spot_count | uint64 | Maximum number of spots identified in spot finding | |
|
||||
| storage_cell_number | uint64 | Number of storage cells used by JUNGFRAU | |
|
||||
| image_dtype | string | Pixel bit type (e.g. uint16) | X |
|
||||
| unit_cell | Array(6 * float) (optional) | Unit cell of the system: a, b, c \[angstrom\] and alpha, beta, gamma \[degree\] | |
|
||||
| az_int_bin_number | uint64 | Number of azimuthal integration bins | |
|
||||
| az_int_bin_to_q | Array(float) | Q value for each azimuthal integration bin \[angstrom^-1\] | |
|
||||
| summation | uint64 | Factor of frame summation | |
|
||||
| user_data | string | JSON serialized to string that can contain the following fields: | X |
|
||||
| - user | any valid JSON | Value of header_appendix provided at collection start to Jungfraujoch | |
|
||||
| - source_name | string | Facility name | |
|
||||
| - source_name_short | string | Facility name (short) | |
|
||||
| - source_type | string (optional) | Type of X-ray source (use NXsource/type values, for example "Synchrotron X-ray Source" or "Free-Electron Laser") | |
|
||||
| - instrument_name | string | Instrument name | |
|
||||
| - instrument_name_short | string | Instrument name (short) | |
|
||||
| - attenuator_transmission | float (optional) | Attenuator transmission \[\] | |
|
||||
| - total_flux | float (optional) | Total flux \[ph/s\] | |
|
||||
| - data_file_count | uint64 | Number of used data files | |
|
||||
| - file_prefix | string | File prefix | |
|
||||
| - sample_name | string | Name of the sample | |
|
||||
| - rotation_axis | Array(float) | Rotation axis vector (array of size 3) | |
|
||||
| - space_group_number | uint64 | Space group number | |
|
||||
| - write_master_file | bool | With multiple sockets, it selects which socket will provide master file | |
|
||||
| - experiment_group | string | ID of instrument user, e.g., p-group (SLS/SwissFEL) or proposal number | |
|
||||
| Field name | Type | Description | Present in DECTRIS format |
|
||||
|--------------------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
|
||||
| type | String | value "start" | X |
|
||||
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
|
||||
| detector_distance | float | Detector distance \[m\] | |
|
||||
| detector_translation | float | Detector translation vector \[m\] | X |
|
||||
| beam_center_x | float | Beam center in X direction \[pixels\] | X |
|
||||
| beam_center_y | float | Beam center in Y direction \[pixels\] | X |
|
||||
| number_of_images | uint64 | Number of images in the series | X |
|
||||
| image_size_x | uint64 | Image width \[pixels\] | X |
|
||||
| image_size_y | uint64 | Image height \[pixels\] | X |
|
||||
| incident_energy | float | X-ray energy \[eV\] | X |
|
||||
| incident_wavelength | float | X-ray wavelength \[Angstrom\] | X |
|
||||
| frame_time | float | Frame time, if multiple frames per trigger \[s\] | X |
|
||||
| count_time | float | Exposure time \[s\] | X |
|
||||
| saturation_value | int64 | Maximum valid sample value | X |
|
||||
| error_value | int64 | Value used in images to describe pixels that are in error state or missing | |
|
||||
| pixel_size_x | float | Pixel width \[m\] | X |
|
||||
| pixel_size_y | float | Pixel height \[m\] | X |
|
||||
| sensor_thickness | float | Sensor thickness \[m\] | X |
|
||||
| sensor_material | string | Sensor material | X |
|
||||
| arm_data | data | Approximate date of arming | X |
|
||||
| pixel_mask_enabled | bool | Pixel mask applied on images | X |
|
||||
| detector_description | string | Name of the detector | X |
|
||||
| series_unique_id | string | Unique text ID of the series (run_name parameter) | X |
|
||||
| series_id | uint64 | Unique numeric ID of the series (run_number parameter) | X |
|
||||
| goniometer | Map | See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) - only one axis is supported | X |
|
||||
| pixel_mask | Map(string -> Image) | Pixel mask - multiple in case of storage cells | X |
|
||||
| channels | Array(string) | List of image channels | X |
|
||||
| max_spot_count | uint64 | Maximum number of spots identified in spot finding | |
|
||||
| storage_cell_number | uint64 | Number of storage cells used by JUNGFRAU | |
|
||||
| image_dtype | string | Pixel bit type (e.g. uint16) | X |
|
||||
| unit_cell | Array(6 * float) (optional) | Unit cell of the system: a, b, c \[angstrom\] and alpha, beta, gamma \[degree\] | |
|
||||
| az_int_bin_number | uint64 | Number of azimuthal integration bins | |
|
||||
| az_int_bin_to_q | Array(float) | Q value for each azimuthal integration bin \[angstrom^-1\] | |
|
||||
| summation | uint64 | Factor of frame summation | |
|
||||
| user_data | string | JSON serialized to string that can contain the following fields: | X |
|
||||
| - user | any valid JSON | Value of header_appendix provided at collection start to Jungfraujoch | |
|
||||
| - source_name | string | Facility name | |
|
||||
| - source_name_short | string | Facility name (short) | |
|
||||
| - source_type | string (optional) | Type of X-ray source (use NXsource/type values, for example "Synchrotron X-ray Source" or "Free-Electron Laser") | |
|
||||
| - instrument_name | string | Instrument name | |
|
||||
| - instrument_name_short | string | Instrument name (short) | |
|
||||
| - attenuator_transmission | float (optional) | Attenuator transmission \[\] | |
|
||||
| - total_flux | float (optional) | Total flux \[ph/s\] | |
|
||||
| - data_file_count | uint64 | Number of used data files | |
|
||||
| - file_prefix | string | File prefix | |
|
||||
| - sample_name | string | Name of the sample | |
|
||||
| - rotation_axis | Array(float) | Rotation axis vector (array of size 3) | |
|
||||
| - space_group_number | uint64 | Space group number | |
|
||||
| - write_master_file | bool | With multiple sockets, it selects which socket will provide master file | |
|
||||
| - writer_notification_zmq_addr | string | ZeroMQ address to inform `jfjoch_broker` about writers that finished operation | |
|
||||
| - socket_number | uint64 | Number of ZeroMQ socket (on `jfjoch_broker` side) used for transmission | |
|
||||
| - experiment_group | string | ID of instrument user, e.g., p-group (SLS/SwissFEL) or proposal number | |
|
||||
|
||||
See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) for definition of Image as MultiDimArray with optional compression.
|
||||
|
||||
|
||||
@@ -55,17 +55,17 @@ void ZMQStream2Pusher::StartDataCollection(StartMessage& message) {
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Images per file cannot be zero or negative");
|
||||
images_per_file = message.images_per_file;
|
||||
run_number = message.run_number;
|
||||
run_name = message.run_name;
|
||||
|
||||
serializer.SerializeSequenceStart(message);
|
||||
|
||||
for (auto &s: socket) {
|
||||
if (!s->Send(serialization_buffer.data(), serializer.GetBufferSize(), true))
|
||||
throw JFJochException(JFJochExceptionCategory::ZeroMQ, "Timeout on pushing start message on addr "
|
||||
+ s->GetEndpointName());
|
||||
if (message.write_master_file) {
|
||||
for (int i = 0; i < socket.size(); i++) {
|
||||
message.socket_number = i;
|
||||
if (i > 0)
|
||||
message.write_master_file = false;
|
||||
serializer.SerializeSequenceStart(message);
|
||||
}
|
||||
serializer.SerializeSequenceStart(message);
|
||||
if (!socket[i]->Send(serialization_buffer.data(), serializer.GetBufferSize(), true))
|
||||
throw JFJochException(JFJochExceptionCategory::ZeroMQ, "Timeout on pushing start message on addr "
|
||||
+ socket[i]->GetEndpointName());
|
||||
}
|
||||
|
||||
if (preview_socket)
|
||||
@@ -115,3 +115,36 @@ std::string ZMQStream2Pusher::GetPreviewAddress() {
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
void ZMQStream2Pusher::Finalize() {
|
||||
if (writer_notification_socket) {
|
||||
for (int i = 0; i < socket.size(); i++) {
|
||||
auto n = writer_notification_socket->Receive(run_number, run_name);
|
||||
if (!n)
|
||||
throw JFJochException(JFJochExceptionCategory::FileWriteError, "No notification received from writer");
|
||||
else if (n->socket_number >= socket.size())
|
||||
throw JFJochException(JFJochExceptionCategory::FileWriteError, "Wrong socket number provided in the message");
|
||||
else if (!n->ok)
|
||||
throw JFJochException(JFJochExceptionCategory::FileWriteError, "Writer (socket "
|
||||
+ socket[n->socket_number]->GetEndpointName()
|
||||
+ ") finished with error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ZMQStream2Pusher::GetWriterNotificationSocketAddress() const {
|
||||
if (writer_notification_socket)
|
||||
return writer_notification_socket->GetEndpointName();
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
ZMQStream2Pusher &ZMQStream2Pusher::WriterNotificationSocket(const std::string &addr) {
|
||||
writer_notification_socket = std::make_unique<ZMQWriterNotificationPuller>(addr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZMQStream2Pusher &ZMQStream2Pusher::PreviewCounterPeriod(std::chrono::microseconds input) {
|
||||
preview_counter.Period(input);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user