JFJochReceiverPlots: Safer code
This commit is contained in:
@@ -189,56 +189,3 @@ MultiLinePlot StatusVector::GetMaxPlot(int64_t bin_size, float x_start, float x_
|
||||
ret.AddPlot(GetMaxPerBin(bin_size, x_start, x_incr, fill_value));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void StatusMultiVector::Clear(size_t reserve) {
|
||||
std::unique_lock ul(m);
|
||||
if (reserve > 0)
|
||||
r = reserve;
|
||||
status.clear();
|
||||
}
|
||||
|
||||
void StatusMultiVector::AddElement(const std::string &s, uint32_t id, float val) {
|
||||
std::unique_lock ul(m);
|
||||
if (!status.contains(s)) {
|
||||
status[s] = std::make_unique<StatusVector>();
|
||||
status[s]->Clear(r);
|
||||
}
|
||||
status[s]->AddElement(id, val);
|
||||
}
|
||||
|
||||
void StatusMultiVector::AddElement(const std::string &s, uint32_t id, std::optional<float> val) {
|
||||
// no need to lock, as AddElement(string, u32, T) has lock already
|
||||
if (val.has_value())
|
||||
AddElement(s, id, val.value());
|
||||
}
|
||||
|
||||
MultiLinePlotStruct StatusMultiVector::GetMeanPerBin(const std::string &in_key, int64_t bin_size, float x_start,
|
||||
float x_incr,
|
||||
const std::optional<float> &fill_value) const {
|
||||
MultiLinePlotStruct ret{};
|
||||
for (const auto &[key, value]: status) {
|
||||
if (key == in_key) {
|
||||
ret = value->GetMeanPerBin(bin_size, x_start, x_incr, fill_value);
|
||||
ret.title = key;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
MultiLinePlot StatusMultiVector::GetMeanPlot(int64_t bin_size, float x_start, float x_incr,
|
||||
const std::optional<float> &fill_value) const {
|
||||
MultiLinePlot ret;
|
||||
for (const auto &[key, value]: status) {
|
||||
auto tmp = value->GetMeanPerBin(bin_size, x_start, x_incr, fill_value);
|
||||
tmp.title = key;
|
||||
ret.AddPlot(tmp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<float> StatusMultiVector::ExportArray(const std::string &s) const {
|
||||
auto iter = status.find(s);
|
||||
if (iter == status.end() || !iter->second)
|
||||
return {};
|
||||
return iter->second->ExportArray();
|
||||
}
|
||||
|
||||
@@ -41,20 +41,4 @@ public:
|
||||
const std::optional<float> &fill_value = {}) const;
|
||||
};
|
||||
|
||||
class StatusMultiVector {
|
||||
std::mutex m;
|
||||
std::map<std::string, std::unique_ptr<StatusVector>> status;
|
||||
size_t r = 0;
|
||||
public:
|
||||
void Clear(size_t reserve = 0);
|
||||
void AddElement(const std::string& s, uint32_t id, float val);
|
||||
void AddElement(const std::string& s, uint32_t id, std::optional<float> val);
|
||||
|
||||
[[nodiscard]] MultiLinePlotStruct GetMeanPerBin(const std::string& in_key, int64_t bin_size, float x_start, float x_incr,
|
||||
const std::optional<float> &fill_value = {}) const;
|
||||
[[nodiscard]] MultiLinePlot GetMeanPlot(int64_t bin_size, float x_start, float x_incr,
|
||||
const std::optional<float> &fill_value = {}) const;
|
||||
[[nodiscard]] std::vector<float> ExportArray(const std::string& s) const;
|
||||
};
|
||||
|
||||
#endif //JUNGFRAUJOCH_STATUSVECTOR_H
|
||||
|
||||
@@ -3,6 +3,44 @@
|
||||
|
||||
#include "JFJochReceiverPlots.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
MultiLinePlot JFJochReceiverPlots::GetROIPlot(PlotType type, int64_t nbins, float start, float incr,
|
||||
const std::optional<float> &fill_value) const {
|
||||
MultiLinePlot ret;
|
||||
|
||||
std::shared_lock sl(roi_m);
|
||||
for (const auto &[key, roi] : roi_status) {
|
||||
MultiLinePlotStruct plot;
|
||||
switch (type) {
|
||||
case PlotType::ROISum:
|
||||
plot = roi.sum.GetMeanPerBin(nbins, start, incr, fill_value);
|
||||
break;
|
||||
case PlotType::ROIMaxCount:
|
||||
plot = roi.max_count.GetMeanPerBin(nbins, start, incr, fill_value);
|
||||
break;
|
||||
case PlotType::ROIPixels:
|
||||
plot = roi.pixels.GetMeanPerBin(nbins, start, incr, fill_value);
|
||||
break;
|
||||
case PlotType::ROIMean:
|
||||
plot = roi.mean.GetMeanPerBin(nbins, start, incr, fill_value);
|
||||
break;
|
||||
case PlotType::ROIWeightedX:
|
||||
plot = roi.x.GetMeanPerBin(nbins, start, incr, fill_value);
|
||||
break;
|
||||
case PlotType::ROIWeightedY:
|
||||
plot = roi.y.GetMeanPerBin(nbins, start, incr, fill_value);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
plot.title = key;
|
||||
ret.AddPlot(plot);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JFJochReceiverPlots::Setup(const DiffractionExperiment &experiment, const AzimuthalIntegration &mapping) {
|
||||
std::unique_lock ul(m);
|
||||
|
||||
@@ -14,13 +52,14 @@ void JFJochReceiverPlots::Setup(const DiffractionExperiment &experiment, const A
|
||||
default_binning = experiment.GetDefaultPlotBinning();
|
||||
|
||||
size_t r = experiment.GetImageNum();
|
||||
|
||||
// Reset all status vectors
|
||||
xfel_pulse_id.Clear();
|
||||
xfel_event_code.Clear();
|
||||
if (experiment.IsPulsedSource()) {
|
||||
xfel_pulse_id.reserve(r);
|
||||
xfel_event_code.reserve(r);
|
||||
}
|
||||
xfel_event_code.Clear();
|
||||
bkg_estimate.Clear(r);
|
||||
spot_count.Clear(r);
|
||||
spot_count_low_res.Clear(r);
|
||||
@@ -28,20 +67,33 @@ void JFJochReceiverPlots::Setup(const DiffractionExperiment &experiment, const A
|
||||
spot_count_ice.Clear(r);
|
||||
|
||||
indexing_solution.Clear(r);
|
||||
indexing_unit_cell_angle.Clear(r);
|
||||
indexing_unit_cell_len.Clear(r);
|
||||
indexing_uc_a.Clear(r);
|
||||
indexing_uc_b.Clear(r);
|
||||
indexing_uc_c.Clear(r);
|
||||
indexing_uc_alpha.Clear(r);
|
||||
indexing_uc_beta.Clear(r);
|
||||
indexing_uc_gamma.Clear(r);
|
||||
error_pixels.Clear(r);
|
||||
saturated_pixels.Clear(r);
|
||||
strong_pixels.Clear(r);
|
||||
receiver_delay.Clear(r);
|
||||
receiver_free_send_buf.Clear(r);
|
||||
image_collection_efficiency.Clear(r);
|
||||
roi_sum.Clear(r);
|
||||
roi_max_count.Clear(r);
|
||||
roi_pixels.Clear(r);
|
||||
roi_x.Clear(r);
|
||||
roi_y.Clear(r);
|
||||
roi_mean.Clear(r);
|
||||
|
||||
{
|
||||
std::unique_lock roi_lock(roi_m);
|
||||
roi_status.clear();
|
||||
for (const auto &[name, _id] : experiment.ROI().GetROINameMap()) {
|
||||
auto &entry = roi_status[name];
|
||||
entry.sum.Clear(r);
|
||||
entry.max_count.Clear(r);
|
||||
entry.pixels.Clear(r);
|
||||
entry.x.Clear(r);
|
||||
entry.y.Clear(r);
|
||||
entry.mean.Clear(r);
|
||||
}
|
||||
}
|
||||
|
||||
packets_received.Clear(r);
|
||||
max_value.Clear(r);
|
||||
resolution_estimate.Clear(r);
|
||||
@@ -77,12 +129,12 @@ void JFJochReceiverPlots::Add(const DataMessage &msg, const AzimuthalIntegration
|
||||
processing_time.AddElement(msg.number, msg.processing_time_s);
|
||||
|
||||
if (msg.indexing_unit_cell) {
|
||||
indexing_unit_cell_len.AddElement("a", msg.number, msg.indexing_unit_cell->a);
|
||||
indexing_unit_cell_len.AddElement("b", msg.number, msg.indexing_unit_cell->b);
|
||||
indexing_unit_cell_len.AddElement("c", msg.number, msg.indexing_unit_cell->c);
|
||||
indexing_unit_cell_angle.AddElement("alpha", msg.number, msg.indexing_unit_cell->alpha);
|
||||
indexing_unit_cell_angle.AddElement("beta", msg.number, msg.indexing_unit_cell->beta);
|
||||
indexing_unit_cell_angle.AddElement("gamma", msg.number, msg.indexing_unit_cell->gamma);
|
||||
indexing_uc_a.AddElement(msg.number, msg.indexing_unit_cell->a);
|
||||
indexing_uc_b.AddElement(msg.number, msg.indexing_unit_cell->b);
|
||||
indexing_uc_c.AddElement(msg.number, msg.indexing_unit_cell->c);
|
||||
indexing_uc_alpha.AddElement(msg.number, msg.indexing_unit_cell->alpha);
|
||||
indexing_uc_beta.AddElement(msg.number, msg.indexing_unit_cell->beta);
|
||||
indexing_uc_gamma.AddElement(msg.number, msg.indexing_unit_cell->gamma);
|
||||
}
|
||||
|
||||
beam_center_x.AddElement(msg.number, msg.beam_corr_x);
|
||||
@@ -104,12 +156,22 @@ void JFJochReceiverPlots::Add(const DataMessage &msg, const AzimuthalIntegration
|
||||
}
|
||||
|
||||
for (const auto &[key, value] : msg.roi) {
|
||||
roi_sum.AddElement(key, msg.number, value.sum);
|
||||
roi_mean.AddElement(key, msg.number, static_cast<double>(value.sum) / static_cast<double>(value.pixels));
|
||||
roi_max_count.AddElement(key, msg.number, value.max_count);
|
||||
roi_pixels.AddElement(key, msg.number, value.pixels);
|
||||
roi_x.AddElement(key, msg.number, static_cast<double>(value.x_weighted) / static_cast<double>(value.sum));
|
||||
roi_y.AddElement(key, msg.number, static_cast<double>(value.y_weighted) / static_cast<double>(value.sum));
|
||||
if (value.pixels == 0)
|
||||
continue;
|
||||
|
||||
std::shared_lock sl(roi_m);
|
||||
auto it = roi_status.find(key);
|
||||
if (it == roi_status.end())
|
||||
continue; // ROI not configured in setup -> ignore
|
||||
|
||||
it->second.sum.AddElement(msg.number, value.sum);
|
||||
it->second.mean.AddElement(msg.number, static_cast<double>(value.sum) / static_cast<double>(value.pixels));
|
||||
it->second.max_count.AddElement(msg.number, value.max_count);
|
||||
it->second.pixels.AddElement(msg.number, value.pixels);
|
||||
if (value.sum > 0) {
|
||||
it->second.x.AddElement(msg.number, static_cast<double>(value.x_weighted) / static_cast<double>(value.sum));
|
||||
it->second.y.AddElement(msg.number, static_cast<double>(value.y_weighted) / static_cast<double>(value.sum));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +182,7 @@ void JFJochReceiverPlots::AddEmptyImage(const DataMessage &msg) {
|
||||
MultiLinePlot JFJochReceiverPlots::GetPlots(const PlotRequest &request) {
|
||||
MultiLinePlot ret;
|
||||
MultiLinePlotUnits units = MultiLinePlotUnits::ImageNumber;
|
||||
int64_t nbins;
|
||||
int64_t nbins = 1;
|
||||
|
||||
std::optional<GridScanSettings> local_grid_scan;
|
||||
float start = 0.0;
|
||||
@@ -137,6 +199,7 @@ MultiLinePlot JFJochReceiverPlots::GetPlots(const PlotRequest &request) {
|
||||
nbins = default_binning;
|
||||
if (request.binning > 0)
|
||||
nbins = request.binning;
|
||||
nbins = std::max<int64_t>(1, nbins);
|
||||
|
||||
if (request.experimental_coord && goniometer) {
|
||||
start = goniometer->GetStart_deg();
|
||||
@@ -211,22 +274,12 @@ MultiLinePlot JFJochReceiverPlots::GetPlots(const PlotRequest &request) {
|
||||
ret = strong_pixels.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::ROISum:
|
||||
ret = roi_sum.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::ROIMaxCount:
|
||||
ret = roi_max_count.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::ROIPixels:
|
||||
ret = roi_pixels.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::ROIMean:
|
||||
ret = roi_mean.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::ROIWeightedX:
|
||||
ret = roi_x.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::ROIWeightedY:
|
||||
ret = roi_y.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
ret = GetROIPlot(request.type, nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::AzInt:
|
||||
ret = GetAzIntProfilePlot(false, request.azint_unit);
|
||||
@@ -234,18 +287,36 @@ MultiLinePlot JFJochReceiverPlots::GetPlots(const PlotRequest &request) {
|
||||
case PlotType::AzInt1D:
|
||||
ret = GetAzIntProfilePlot(true, request.azint_unit);
|
||||
break;
|
||||
case PlotType::IndexingUnitCellLength:
|
||||
ret = indexing_unit_cell_len.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
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);
|
||||
auto c = indexing_uc_c.GetMeanPerBin(nbins, start, incr, request.fill_value);
|
||||
a.title = "a";
|
||||
b.title = "b";
|
||||
c.title = "c";
|
||||
ret.AddPlot(a);
|
||||
ret.AddPlot(b);
|
||||
ret.AddPlot(c);
|
||||
break;
|
||||
case PlotType::IndexingUnitCellAngle:
|
||||
ret = indexing_unit_cell_angle.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
}
|
||||
case PlotType::IndexingUnitCellAngle: {
|
||||
auto alpha = indexing_uc_alpha.GetMeanPerBin(nbins, start, incr, request.fill_value);
|
||||
auto beta = indexing_uc_beta.GetMeanPerBin(nbins, start, incr, request.fill_value);
|
||||
auto gamma = indexing_uc_gamma.GetMeanPerBin(nbins, start, incr, request.fill_value);
|
||||
alpha.title = "alpha";
|
||||
beta.title = "beta";
|
||||
gamma.title = "gamma";
|
||||
ret.AddPlot(alpha);
|
||||
ret.AddPlot(beta);
|
||||
ret.AddPlot(gamma);
|
||||
break;
|
||||
}
|
||||
case PlotType::PacketsReceived:
|
||||
ret = packets_received.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
case PlotType::MaxValue:
|
||||
ret = max_value.GetMaxPlot(nbins, start, incr, request.fill_value);
|
||||
break; // doesn't make sense to give mean here
|
||||
break;
|
||||
case PlotType::PixelSum:
|
||||
ret = pixel_sum.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
@@ -259,7 +330,6 @@ MultiLinePlot JFJochReceiverPlots::GetPlots(const PlotRequest &request) {
|
||||
ret = beam_center_y.GetMeanPlot(nbins, start, incr, request.fill_value);
|
||||
break;
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -367,23 +437,41 @@ void JFJochReceiverPlots::GetPlotRaw(std::vector<float> &v, PlotType type, const
|
||||
v = strong_pixels.ExportArray();
|
||||
break;
|
||||
case PlotType::ROISum:
|
||||
v = roi_sum.ExportArray(roi);
|
||||
break;
|
||||
case PlotType::ROIMaxCount:
|
||||
v = roi_max_count.ExportArray(roi);
|
||||
break;
|
||||
case PlotType::ROIPixels:
|
||||
v = roi_pixels.ExportArray(roi);
|
||||
break;
|
||||
case PlotType::ROIMean:
|
||||
v = roi_mean.ExportArray(roi);
|
||||
break;
|
||||
case PlotType::ROIWeightedX:
|
||||
v = roi_x.ExportArray(roi);
|
||||
break;
|
||||
case PlotType::ROIWeightedY:
|
||||
v = roi_y.ExportArray(roi);
|
||||
case PlotType::ROIWeightedY: {
|
||||
std::shared_lock sl(roi_m);
|
||||
auto it = roi_status.find(roi);
|
||||
if (it == roi_status.end()) {
|
||||
v.clear();
|
||||
break;
|
||||
}
|
||||
switch (type) {
|
||||
case PlotType::ROISum:
|
||||
v = it->second.sum.ExportArray();
|
||||
break;
|
||||
case PlotType::ROIMaxCount:
|
||||
v = it->second.max_count.ExportArray();
|
||||
break;
|
||||
case PlotType::ROIPixels:
|
||||
v = it->second.pixels.ExportArray();
|
||||
break;
|
||||
case PlotType::ROIMean:
|
||||
v = it->second.mean.ExportArray();
|
||||
break;
|
||||
case PlotType::ROIWeightedX:
|
||||
v = it->second.x.ExportArray();
|
||||
break;
|
||||
case PlotType::ROIWeightedY:
|
||||
v = it->second.y.ExportArray();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PlotType::AzInt: {
|
||||
std::unique_lock ul(m);
|
||||
if (az_int_profile)
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#ifndef JUNGFRAUJOCH_JFJOCHRECEIVERPLOTS_H
|
||||
#define JUNGFRAUJOCH_JFJOCHRECEIVERPLOTS_H
|
||||
|
||||
#include <map>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
|
||||
#include "../common/StatusVector.h"
|
||||
#include "../common/Histogram.h"
|
||||
#include "../common/ADUHistogram.h"
|
||||
@@ -31,8 +35,12 @@ class JFJochReceiverPlots {
|
||||
StatusVector spot_count_ice;
|
||||
|
||||
StatusVector indexing_solution;
|
||||
StatusMultiVector indexing_unit_cell_len;
|
||||
StatusMultiVector indexing_unit_cell_angle;
|
||||
StatusVector indexing_uc_a;
|
||||
StatusVector indexing_uc_b;
|
||||
StatusVector indexing_uc_c;
|
||||
StatusVector indexing_uc_alpha;
|
||||
StatusVector indexing_uc_beta;
|
||||
StatusVector indexing_uc_gamma;
|
||||
StatusVector error_pixels;
|
||||
StatusVector saturated_pixels;
|
||||
StatusVector strong_pixels;
|
||||
@@ -42,12 +50,18 @@ class JFJochReceiverPlots {
|
||||
StatusVector packets_received;
|
||||
StatusVector max_value;
|
||||
StatusVector resolution_estimate;
|
||||
StatusMultiVector roi_sum;
|
||||
StatusMultiVector roi_max_count;
|
||||
StatusMultiVector roi_pixels;
|
||||
StatusMultiVector roi_x;
|
||||
StatusMultiVector roi_y;
|
||||
StatusMultiVector roi_mean;
|
||||
|
||||
struct ROIStatus {
|
||||
StatusVector sum;
|
||||
StatusVector max_count;
|
||||
StatusVector pixels;
|
||||
StatusVector x;
|
||||
StatusVector y;
|
||||
StatusVector mean;
|
||||
};
|
||||
mutable std::shared_mutex roi_m;
|
||||
std::map<std::string, ROIStatus> roi_status;
|
||||
|
||||
StatusVector indexing_time;
|
||||
StatusVector profile_radius;
|
||||
StatusVector mosaicity_deg;
|
||||
@@ -58,6 +72,9 @@ class JFJochReceiverPlots {
|
||||
StatusVector beam_center_y;
|
||||
|
||||
StatusVector processing_time;
|
||||
|
||||
MultiLinePlot GetROIPlot(PlotType type, int64_t nbins, float start, float incr,
|
||||
const std::optional<float> &fill_value) const;
|
||||
public:
|
||||
void Setup(const DiffractionExperiment& experiment, const AzimuthalIntegration& mapping);
|
||||
|
||||
@@ -77,5 +94,4 @@ public:
|
||||
void GetPlotRaw(std::vector<float> &v, PlotType type, const std::string &roi);
|
||||
};
|
||||
|
||||
|
||||
#endif //JUNGFRAUJOCH_JFJOCHRECEIVERPLOTS_H
|
||||
|
||||
@@ -272,28 +272,6 @@ TEST_CASE("StatusVector_Plot_NoBinning","[StatusVector]") {
|
||||
REQUIRE(plot_out.GetPlots()[0].y[0] == Catch::Approx(11));
|
||||
}
|
||||
|
||||
TEST_CASE("StatusMultiVector","[StatusMultiVector]") {
|
||||
StatusMultiVector status_vector;
|
||||
status_vector.AddElement("plot1", 0, 4);
|
||||
status_vector.AddElement("plot1", 1, 3);
|
||||
status_vector.AddElement("plot2", 0, 5);
|
||||
status_vector.AddElement("plot2", 1, 4);
|
||||
|
||||
auto ret = status_vector.GetMeanPlot(1, 3.0, 5.0);
|
||||
REQUIRE(ret.GetPlots().size() == 2);
|
||||
REQUIRE(ret.GetPlots()[0].title == "plot1");
|
||||
REQUIRE(ret.GetPlots()[0].x.size() == 2);
|
||||
REQUIRE(ret.GetPlots()[0].y.size() == 2);
|
||||
REQUIRE(ret.GetPlots()[0].x[0] == 3.0 + 5.0 * 0.0f);
|
||||
REQUIRE(ret.GetPlots()[0].y[1] == 3.0f);
|
||||
|
||||
REQUIRE(ret.GetPlots()[1].title == "plot2");
|
||||
REQUIRE(ret.GetPlots()[1].x.size() == 2);
|
||||
REQUIRE(ret.GetPlots()[1].y.size() == 2);
|
||||
REQUIRE(ret.GetPlots()[1].x[1] == 3.0 + 5.0 * 1.0f);
|
||||
REQUIRE(ret.GetPlots()[1].y[1] == 4.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("StatusVector_Clear","[StatusVector]") {
|
||||
StatusVector status_vector;
|
||||
status_vector.AddElement(5, 800);
|
||||
|
||||
Reference in New Issue
Block a user