Files
Jungfraujoch/receiver/ImageMetadata.cpp
2025-04-14 11:52:06 +02:00

122 lines
4.8 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "ImageMetadata.h"
#include <cmath>
inline uint64_t convert_pulse_id(double pulse_id) {
if (!std::isfinite(pulse_id))
return UINT64_MAX;
double integer_part;
double fractional_part = std::modf(pulse_id, &integer_part);
if (fractional_part != 0.0)
return UINT64_MAX;
return static_cast<uint64_t>(integer_part);
}
ImageMetadata::ImageMetadata(const DiffractionExperiment &experiment)
: pulsed_source(experiment.IsPulsedSource()), geom(experiment.GetDetectorSetup().GetGeometry()) {
roi_map_name = experiment.ROI().GetROINameMap();
for (const auto &[x,y]: roi_map_name)
rois[x] = ROIMessage{.max_count = INT64_MIN};
}
void ImageMetadata::Process(const DeviceOutput *output) {
std::unique_lock ul(m);
auto moduleNum = output->module_statistics.module_number;
uint64_t module_pulse_id = convert_pulse_id(output->module_statistics.pulse_id);
if (!first_module_loaded) {
xfel_pulse_id = module_pulse_id;
jf_info = output->module_statistics.debug;
storage_cell = (jf_info >> 8) & 0xF;
xfel_event_code = (jf_info >> 16) & UINT8_MAX;
timestamp = output->module_statistics.timestamp;
exptime = output->module_statistics.exptime;
max_value = INT64_MIN;
min_value = INT64_MAX;
first_module_loaded = true;
} else {
if (pulsed_source && (module_pulse_id != xfel_pulse_id)) {
metadata_consistent = false;
xfel_pulse_id = UINT64_MAX; // mark clearly inconsistent frames
}
}
saturated_pixels += output->module_statistics.saturated_pixels;
error_pixels += output->module_statistics.err_pixels;
strong_pixels += output->spot_finding_result.strong_pixel_count;
packets_collected += output->module_statistics.packet_count;
image_sum += output->module_statistics.pixel_sum;
if (output->module_statistics.max_value > max_value)
max_value = output->module_statistics.max_value;
if (output->module_statistics.min_value < min_value)
min_value = output->module_statistics.min_value;
for (const auto &[key, val]: roi_map_name) {
rois[key].sum += output->roi_counts[val].sum;
rois[key].sum_square += output->roi_counts[val].sum2;
rois[key].pixels += output->roi_counts[val].good_pixels;
int64_t x_weighted = output->roi_counts[val].sum_x_weighted
* static_cast<int64_t>(geom.GetFastDirection(moduleNum).x)
+ output->roi_counts[val].sum_y_weighted
* static_cast<int64_t>(geom.GetSlowDirection(moduleNum).x)
+ geom.GetX0(moduleNum)
* output->roi_counts[val].sum;
int64_t y_weighted = output->roi_counts[val].sum_x_weighted
* static_cast<int64_t>(geom.GetFastDirection(moduleNum).y)
+ output->roi_counts[val].sum_y_weighted
* static_cast<int64_t>(geom.GetSlowDirection(moduleNum).y)
+ geom.GetY0(moduleNum)
* output->roi_counts[val].sum;
rois[key].x_weighted += x_weighted;
rois[key].y_weighted += y_weighted;
if (output->roi_counts[val].max_value > rois[key].max_count)
rois[key].max_count = output->roi_counts[val].max_value;
}
}
bool ImageMetadata::IsBunchIDConsistent() const {
return metadata_consistent;
}
void ImageMetadata::Export(DataMessage &message, uint64_t packets_expected_per_image) const {
std::unique_lock ul(m);
if (pulsed_source) {
message.xfel_pulse_id = xfel_pulse_id;
message.xfel_event_code = xfel_event_code;
}
message.jf_info = jf_info;
message.storage_cell = storage_cell;
message.timestamp = timestamp;
message.timestamp_base = 10*1000*1000;
message.exptime = exptime;
message.exptime_base = 10*1000*1000;
message.saturated_pixel_count = saturated_pixels;
message.error_pixel_count = error_pixels;
message.strong_pixel_count = strong_pixels;
message.packets_received = packets_collected;
message.packets_expected = packets_expected_per_image;
if (min_value != INT64_MAX)
message.min_viable_pixel_value = min_value;
if (max_value != INT64_MIN)
message.max_viable_pixel_value = max_value;
if ((packets_collected > 0) && (packets_expected_per_image > 0))
message.image_collection_efficiency = static_cast<double>(packets_collected)
/ static_cast<double>(packets_expected_per_image);
else
message.image_collection_efficiency = 0.0f;
message.roi = rois;
}