Files
Jungfraujoch/common/GridPlot.cpp
2025-05-28 18:49:27 +02:00

86 lines
2.6 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "GridPlot.h"
#include "JFJochException.h"
#include <cmath>
#include <algorithm>
GridPlot::GridPlot(const MultiLinePlotStruct &p, const GridScanSettings &settings,
float in_fill_value)
: width(settings.GetGridSizeX_step()),
height(settings.GetGridSizeY_step()),
step_x_um(settings.GetGridStepX_um()),
step_y_um(settings.GetGridStepY_um()),
fill_value(in_fill_value) {
if (width == 0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Cannot add plots to empty MultiGridPlot");
val = settings.Rearrange(p.y, fill_value);
}
const std::vector<float> &GridPlot::GetPlot() const {
return val;
}
int64_t GridPlot::GetWidth() const {
return width;
}
int64_t GridPlot::GetHeight() const {
return height;
}
float GridPlot::GetStepX_um() const {
return step_x_um;
}
float GridPlot::GetStepY_um() const {
return step_y_um;
}
CompressedImage GridPlot::GetImage(std::vector<rgb> &buffer, const GridPlotImageRequest &request) const {
ColorScale c;
c.Select(request.scale);
float scaled_step_x_um = step_x_um / request.base_unit;
float scaled_step_y_um = step_y_um / request.base_unit;
size_t image_x = std::floor(width * scaled_step_x_um);
size_t image_y = std::floor(height * scaled_step_y_um);
float max = -std::numeric_limits<float>::infinity();
float min = std::numeric_limits<float>::infinity();
if (!request.bg || !request.fg) {
for (const auto &i: val) {
if (i > max && (i != fill_value))
max = i;
if (i < min && (i != fill_value))
min = i;
}
}
float fg = request.fg.value_or(max);
float bg = request.bg.value_or(min);
buffer.resize(image_x * image_y);
for (int y = 0; y < image_y; y++) {
size_t elem_y = std::lround(y / scaled_step_y_um);
if (elem_y >= height)
elem_y = height - 1;
for (int x = 0; x < image_x; x++) {
size_t elem_x = std::lround(x / scaled_step_x_um);
if (elem_x >= width)
elem_x = width - 1;
float v = val.at(elem_y * width + elem_x);
if (v == fill_value)
buffer[y * image_x + x] = c.Apply(ColorScaleSpecial::Gap);
else
buffer[y * image_x + x] = c.Apply(v, bg, fg);
}
}
return {buffer, image_x, image_y};
}