jfjoch_writer: Save integrated reflection count

This commit is contained in:
2026-04-28 19:54:00 +02:00
parent 97a5899b73
commit 83fff25724
18 changed files with 35 additions and 6 deletions
+2
View File
@@ -882,6 +882,8 @@ PlotType ConvertPlotType(const std::optional<std::string>& input) {
if (input == "processing_time") return PlotType::ImageProcessingTime;
if (input == "beam_center_x") return PlotType::RefinementBeamX;
if (input == "beam_center_y") return PlotType::RefinementBeamY;
if (input == "integrated_reflections") return PlotType::IntegratedReflections;
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Plot type not recognized");
}
+1
View File
@@ -115,6 +115,7 @@ components:
- processing_time
- beam_center_x
- beam_center_y
- integrated_reflections
roi:
in: query
name: roi
File diff suppressed because one or more lines are too long
+2
View File
@@ -120,6 +120,8 @@ struct DataMessage {
std::vector<uint64_t> adu_histogram;
std::optional<int64_t> integrated_reflections;
uint64_t timestamp;
uint32_t timestamp_base;
+1 -1
View File
@@ -15,7 +15,7 @@ enum class PlotType {
IndexingUnitCellAngle, ErrorPixels, SaturatedPixels, ImageCollectionEfficiency, ReceiverDelay, ReceiverFreeSendBuf,
ROISum, ROIMean, ROIMaxCount, ROIPixels, ROIWeightedX, ROIWeightedY, PacketsReceived, MaxValue,
ResolutionEstimate, ProfileRadius, Mosaicity, BFactor, PixelSum, StrongPixels,
RefinementBeamX, RefinementBeamY, ImageProcessingTime,
RefinementBeamX, RefinementBeamY, ImageProcessingTime, IntegratedReflections
};
enum class PlotAzintUnit {
+1
View File
@@ -159,6 +159,7 @@ See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/s
| indexing_unit_cell | object | Indexing result unit cell: a, b, c \[angstrom\] and alpha, beta, gamma \[degree\]; present only if indexed | | X |
| | | Unit cell is redundant to lattice - yet to simplify downstream programs to analyze results, both are provided | | |
| profile_radius | float | Profile radius of the image - describes distance of observed reflections from the Ewald sphere \[Angstrom^-1\] | | |
| integrated_reflections | int64 | Count of integrated reflections | | |
| mosaicity | float | Angular range of spots in image from a rotation scan \[degree\] | | |
| b_factor | float | Estimated B-factor (Angstrom^2) | | |
| compression_time | float | Time spent on compression/decompressing image \[s\] | | |
@@ -699,6 +699,8 @@ namespace {
message.mosaicity_deg = GetCBORFloat(value);
else if (key == "b_factor")
message.b_factor = GetCBORFloat(value);
else if (key == "integrated_reflections")
message.integrated_reflections = GetCBORInt(value);
else if (key == "indexing_unit_cell")
message.indexing_unit_cell = ProcessUnitCellElement(value);
else if (key == "lattice_type")
@@ -702,6 +702,7 @@ void CBORStream2Serializer::SerializeImageInternal(CborEncoder &mapEncoder, cons
CBOR_ENC(mapEncoder, "indexing_lattice", message.indexing_lattice->GetVector());
CBOR_ENC(mapEncoder, "profile_radius", message.profile_radius);
CBOR_ENC(mapEncoder, "mosaicity", message.mosaicity_deg);
CBOR_ENC(mapEncoder, "integrated_reflections", message.integrated_reflections);
CBOR_ENC(mapEncoder, "b_factor", message.b_factor);
CBOR_ENC(mapEncoder, "indexing_time", message.indexing_time_s);
CBOR_ENC(mapEncoder, "processing_time", message.processing_time_s);
@@ -47,6 +47,8 @@ function AxisTypeY(plot: plot_type) : string | ReactNode {
switch (plot) {
case plot_type.IMAGE_COLLECTION_EFFICIENCY:
return "Efficiency";
case plot_type.INTEGRATED_REFLECTIONS:
return "Reflection count";
case plot_type.SPOT_COUNT:
case plot_type.SPOT_COUNT_LOW_RES:
case plot_type.SPOT_COUNT_INDEXED:
@@ -77,6 +77,7 @@ class DataProcessingPlots extends Component<MyProps, MyState> {
<MenuItem value={plot_type.B_FACTOR}>Wilson B-factor</MenuItem>
<MenuItem value={plot_type.BEAM_CENTER_X}>Beam center X (post-indexing geometry refinement)</MenuItem>
<MenuItem value={plot_type.BEAM_CENTER_Y}>Beam center Y (post-indexing geometry refinement)</MenuItem>
<MenuItem value={plot_type.INTEGRATED_REFLECTIONS}>Integrated reflections</MenuItem>
<MenuItem value={plot_type.IMAGE_COLLECTION_EFFICIENCY}>Image collection efficiency</MenuItem>
<MenuItem value={plot_type.PROCESSING_TIME}> Processing time</MenuItem>
<MenuItem value={plot_type.RECEIVER_DELAY}>Receiver delay (internal debugging)</MenuItem>
+1
View File
@@ -39,4 +39,5 @@ export enum plot_type {
PROCESSING_TIME = 'processing_time',
BEAM_CENTER_X = 'beam_center_x',
BEAM_CENTER_Y = 'beam_center_y',
INTEGRATED_REFLECTIONS = 'integrated_reflections',
}
@@ -1031,7 +1031,7 @@ export class DefaultService {
* @throws ApiError
*/
public static getPreviewPlot(
type: 'bkg_estimate' | 'azint' | 'azint_1d' | 'spot_count' | 'spot_count_low_res' | 'spot_count_indexed' | 'spot_count_ice' | 'indexing_rate' | 'indexing_unit_cell_length' | 'indexing_unit_cell_angle' | 'profile_radius' | 'mosaicity' | 'b_factor' | 'error_pixels' | 'saturated_pixels' | 'image_collection_efficiency' | 'receiver_delay' | 'receiver_free_send_buf' | 'strong_pixels' | 'roi_sum' | 'roi_mean' | 'roi_max_count' | 'roi_pixels' | 'roi_weighted_x' | 'roi_weighted_y' | 'packets_received' | 'max_pixel_value' | 'resolution_estimate' | 'pixel_sum' | 'processing_time' | 'beam_center_x' | 'beam_center_y',
type: 'bkg_estimate' | 'azint' | 'azint_1d' | 'spot_count' | 'spot_count_low_res' | 'spot_count_indexed' | 'spot_count_ice' | 'indexing_rate' | 'indexing_unit_cell_length' | 'indexing_unit_cell_angle' | 'profile_radius' | 'mosaicity' | 'b_factor' | 'error_pixels' | 'saturated_pixels' | 'image_collection_efficiency' | 'receiver_delay' | 'receiver_free_send_buf' | 'strong_pixels' | 'roi_sum' | 'roi_mean' | 'roi_max_count' | 'roi_pixels' | 'roi_weighted_x' | 'roi_weighted_y' | 'packets_received' | 'max_pixel_value' | 'resolution_estimate' | 'pixel_sum' | 'processing_time' | 'beam_center_x' | 'beam_center_y' | 'integrated_reflections',
binning: number = 1,
fill?: number,
experimentalCoord: boolean = false,
@@ -1064,7 +1064,7 @@ export class DefaultService {
* @throws ApiError
*/
public static getPreviewPlotBin(
type: 'bkg_estimate' | 'azint' | 'azint_1d' | 'spot_count' | 'spot_count_low_res' | 'spot_count_indexed' | 'spot_count_ice' | 'indexing_rate' | 'indexing_unit_cell_length' | 'indexing_unit_cell_angle' | 'profile_radius' | 'mosaicity' | 'b_factor' | 'error_pixels' | 'saturated_pixels' | 'image_collection_efficiency' | 'receiver_delay' | 'receiver_free_send_buf' | 'strong_pixels' | 'roi_sum' | 'roi_mean' | 'roi_max_count' | 'roi_pixels' | 'roi_weighted_x' | 'roi_weighted_y' | 'packets_received' | 'max_pixel_value' | 'resolution_estimate' | 'pixel_sum' | 'processing_time' | 'beam_center_x' | 'beam_center_y',
type: 'bkg_estimate' | 'azint' | 'azint_1d' | 'spot_count' | 'spot_count_low_res' | 'spot_count_indexed' | 'spot_count_ice' | 'indexing_rate' | 'indexing_unit_cell_length' | 'indexing_unit_cell_angle' | 'profile_radius' | 'mosaicity' | 'b_factor' | 'error_pixels' | 'saturated_pixels' | 'image_collection_efficiency' | 'receiver_delay' | 'receiver_free_send_buf' | 'strong_pixels' | 'roi_sum' | 'roi_mean' | 'roi_max_count' | 'roi_pixels' | 'roi_weighted_x' | 'roi_weighted_y' | 'packets_received' | 'max_pixel_value' | 'resolution_estimate' | 'pixel_sum' | 'processing_time' | 'beam_center_x' | 'beam_center_y' | 'integrated_reflections',
roi?: string,
): CancelablePromise<Blob> {
return __request(OpenAPI, {
+1
View File
@@ -205,6 +205,7 @@ void IndexAndRefine::QuickPredictAndIntegrate(DataMessage &msg,
auto integration_start_time = std::chrono::steady_clock::now();
auto refl_ret = BraggIntegrate2D(outcome.experiment, image, prediction.GetReflections(), nrefl, msg.number);
msg.integrated_reflections = refl_ret.size();
constexpr size_t kMaxReflections = 10000;
if (refl_ret.size() > kMaxReflections) {
+4
View File
@@ -587,6 +587,7 @@ bool JFJochHDF5Reader::LoadImage_i(std::shared_ptr<JFJochReaderDataset> &dataset
{(hsize_t) image_id, 0},
{1, spot_count}
);
auto geom = dataset->experiment.GetDiffractionGeometry();
for (int i = 0; i < spot_count; i++) {
@@ -629,6 +630,9 @@ bool JFJochHDF5Reader::LoadImage_i(std::shared_ptr<JFJochReaderDataset> &dataset
GenerateSpotPlot(message, 1.5);
}
if (source_file->Exists("/entry/MX/integratedReflections"))
message.integrated_reflections = source_file->ReadElement<float>("/entry/MX/integratedReflections", image_id);
if (!dataset->az_int_bin_to_q.empty()) {
if (dataset->azimuthal_bins == 0)
message.az_int_profile = source_file->ReadOptVector<float>(
+5
View File
@@ -105,6 +105,7 @@ void JFJochReceiverPlots::Setup(const DiffractionExperiment &experiment, const A
beam_center_x.Clear(r);
beam_center_y.Clear(r);
pixel_sum.Clear(r);
integrated_reflections.Clear(r);
refinement_time.Clear(r);
spot_finding_time.Clear(r);
@@ -129,6 +130,7 @@ void JFJochReceiverPlots::Add(const DataMessage &msg, const AzimuthalIntegration
saturated_pixels.AddElement(msg.number, msg.saturated_pixel_count);
pixel_sum.AddElement(msg.number, msg.pixel_sum);
strong_pixels.AddElement(msg.number, msg.strong_pixel_count);
integrated_reflections.AddElement(msg.number, msg.integrated_reflections);
packets_received.AddElement(msg.number, msg.packets_received);
image_collection_efficiency.AddElement(msg.number, msg.image_collection_efficiency);
@@ -314,6 +316,9 @@ MultiLinePlot JFJochReceiverPlots::GetPlots(const PlotRequest &request) {
case PlotType::AzInt1D:
ret = GetAzIntProfilePlot(true, request.azint_unit);
break;
case PlotType::IntegratedReflections:
ret = integrated_reflections.GetMeanPlot(nbins, start, incr, request.fill_value);
break;
case PlotType::IndexingUnitCellLength: {
auto a = indexing_uc_a.GetMeanPerBin(nbins, start, incr, request.fill_value);
auto b = indexing_uc_b.GetMeanPerBin(nbins, start, incr, request.fill_value);
+1
View File
@@ -65,6 +65,7 @@ class JFJochReceiverPlots {
StatusVector packets_received;
StatusVector max_value;
StatusVector resolution_estimate;
StatusVector integrated_reflections;
// StatusVector objects are fully thread-safe (protected by internal mutex)
// It is OK to have concurrent access to StatusVector
+4
View File
@@ -93,6 +93,7 @@ void HDF5DataFilePluginMX::OpenFile(HDF5File &data_file, const DataMessage &msg,
spot_count_ice.reserve(images_per_file);
spot_count_indexed.reserve(images_per_file);
spot_count_low_res.reserve(images_per_file);
integrated_reflections.reserve(images_per_file);
}
void HDF5DataFilePluginMX::Write(const DataMessage &msg, uint64_t image_number) {
@@ -151,6 +152,7 @@ void HDF5DataFilePluginMX::Write(const DataMessage &msg, uint64_t image_number)
beam_corr_x[image_number] = msg.beam_corr_x.value_or(NAN);
beam_corr_y[image_number] = msg.beam_corr_y.value_or(NAN);
spot_count_indexed[image_number] = msg.spot_count_indexed.value_or(0);
integrated_reflections[image_number] = msg.integrated_reflections.value_or(0);
if (msg.indexing_lattice) {
auto tmp = msg.indexing_lattice->GetVector();
@@ -228,4 +230,6 @@ void HDF5DataFilePluginMX::WriteFinal(HDF5File &data_file) {
data_file.SaveVector("/entry/MX/bravais_lattice", bravais_lattice.vec());
if (!resolution_estimate.empty())
data_file.SaveVector("/entry/MX/resolutionEstimate", resolution_estimate.vec())->Units("Angstrom");
if (!integrated_reflections.empty())
data_file.SaveVector("/entry/MX/integratedReflections", integrated_reflections.vec());
}
+1
View File
@@ -50,6 +50,7 @@ class HDF5DataFilePluginMX : public HDF5DataFilePlugin {
AutoIncrVector<uint32_t> niggli_class;
AutoIncrVector<std::string> bravais_lattice;
AutoIncrVector<int64_t> integrated_reflections;
public:
explicit HDF5DataFilePluginMX(const StartMessage& msg);