86 lines
2.6 KiB
C++
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};
|
|
}
|