From 30c80cb58d38a4d2ac1bb46a96c7fd45a68a1493 Mon Sep 17 00:00:00 2001 From: Mikhail Svechnikov <svechnikovmv@gmail.com> Date: Wed, 13 Dec 2023 19:34:31 +0100 Subject: [PATCH] MaskUnitsConverter is back --- GUI/Model/Mask/MaskUnitsConverter.cpp | 118 ++++++++++++++++++++++++++ GUI/Model/Mask/MaskUnitsConverter.h | 50 +++++++++++ 2 files changed, 168 insertions(+) create mode 100644 GUI/Model/Mask/MaskUnitsConverter.cpp create mode 100644 GUI/Model/Mask/MaskUnitsConverter.h diff --git a/GUI/Model/Mask/MaskUnitsConverter.cpp b/GUI/Model/Mask/MaskUnitsConverter.cpp new file mode 100644 index 00000000000..6ff5bb85b2b --- /dev/null +++ b/GUI/Model/Mask/MaskUnitsConverter.cpp @@ -0,0 +1,118 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Model/Data/MaskUnitsConverter.cpp +//! @brief Implements class MaskUnitsConverter +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "GUI/Model/Mask/MaskUnitsConverter.h" +#include "Base/Axis/FrameUtil.h" +#include "Device/Data/Datafield.h" +#include "GUI/Model/Data/Data2DItem.h" +#include "GUI/Model/Mask/MaskItems.h" +#include "GUI/Model/Mask/ProjectionContainerItem.h" + +MaskUnitsConverter::MaskUnitsConverter() + : m_data(nullptr) + , m_direction(UNDEFINED) +{ +} + +//! Converts all masks on board of IntensityDataItem into bin-fraction coordinates. + +void MaskUnitsConverter::convertToNbins(Data2DItem* intensityData) +{ + m_direction = TO_NBINS; + convertIntensityDataItem(intensityData); +} + +//! Converts all masks on board of IntensityDataItem from bin-fraction coordinates to coordinates +//! of axes currently defined in Datafield. + +void MaskUnitsConverter::convertFromNbins(Data2DItem* intensityData) +{ + m_direction = FROM_NBINS; + convertIntensityDataItem(intensityData); +} + +//! Converts all masks on board of IntensityDataItem from/to bin-fraction coordinates + +void MaskUnitsConverter::convertIntensityDataItem(Data2DItem* intensityData) +{ + if (!intensityData || !intensityData->c_field()) + return; + + m_data = intensityData->c_field(); + + if (intensityData->maskContainerItem()) + for (auto* maskItem : intensityData->maskContainerItem()->maskItems()) + convertMask(maskItem); + + if (intensityData->projectionContainerItem()) + for (auto* maskItem : intensityData->projectionContainerItem()->maskItems()) + convertMask(maskItem); +} + +//! Converts single mask from/to bin-fraction coordinates + +void MaskUnitsConverter::convertMask(MaskItem* maskItem) +{ + if (auto* rectItem = dynamic_cast<RectangleItem*>(maskItem)) { + rectItem->setXLow(convert(rectItem->xLow(), Axis::X)); + rectItem->setYLow(convert(rectItem->yLow(), Axis::Y)); + rectItem->setXUp(convert(rectItem->xUp(), Axis::X)); + rectItem->setYUp(convert(rectItem->yUp(), Axis::Y)); + } else if (auto* poly = dynamic_cast<PolygonItem*>(maskItem)) { + for (PolygonPointItem* pointItem : poly->points()) { + pointItem->setPosX(convert(pointItem->posX(), Axis::X)); + pointItem->setPosY(convert(pointItem->posY(), Axis::Y)); + } + } else if (auto* vlineItem = dynamic_cast<VerticalLineItem*>(maskItem)) { + vlineItem->setPosX(convert(vlineItem->posX(), Axis::X)); + } else if (auto* hlineItem = dynamic_cast<HorizontalLineItem*>(maskItem)) { + hlineItem->setPosY(convert(hlineItem->posY(), Axis::Y)); + } else if (auto* ellItem = dynamic_cast<EllipseItem*>(maskItem)) { + double xc = ellItem->xCenter(); + double yc = ellItem->yCenter(); + double xR = ellItem->xRadius(); + double yR = ellItem->yRadius(); + + double x2 = xc + xR; + double y2 = yc + yR; + + if (m_direction == TO_NBINS) { + FrameUtil::coordinatesToBinf(xc, yc, m_data->frame()); + FrameUtil::coordinatesToBinf(x2, y2, m_data->frame()); + } else { + FrameUtil::coordinatesFromBinf(xc, yc, m_data->frame()); + FrameUtil::coordinatesFromBinf(x2, y2, m_data->frame()); + } + ellItem->setXCenter(xc); + ellItem->setYCenter(yc); + ellItem->setXRadius(x2 - xc); + ellItem->setYRadius(y2 - yc); + } +} + +//! Convert value of axis from/to bin-fraction coordinates. + +double MaskUnitsConverter::convert(double value, Axis axis) +{ + auto axis_index = static_cast<size_t>(axis); + + ASSERT(m_data); + ASSERT(axis_index == 0 || axis_index == 1); + + if (m_direction == TO_NBINS) + return FrameUtil::coordinateToBinf(value, m_data->axis(axis_index)); + if (m_direction == FROM_NBINS) + return FrameUtil::coordinateFromBinf(value, m_data->axis(axis_index)); + ASSERT(false); +} diff --git a/GUI/Model/Mask/MaskUnitsConverter.h b/GUI/Model/Mask/MaskUnitsConverter.h new file mode 100644 index 00000000000..12d2fd6008f --- /dev/null +++ b/GUI/Model/Mask/MaskUnitsConverter.h @@ -0,0 +1,50 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Model/Data/MaskUnitsConverter.h +//! @brief Defines class MaskUnitsConverter +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#ifndef BORNAGAIN_GUI_MODEL_DATA_MASKUNITSCONVERTER_H +#define BORNAGAIN_GUI_MODEL_DATA_MASKUNITSCONVERTER_H + +class Data2DItem; +class Datafield; +class MaskItem; + +//! The MaskUnitsConverter converts coordinates of all masks from one units to anoter. +//! I.e. masks in 'mm' into masks in 'deg'. This is done in two steps. +//! On first step masks are converted from native coordinates (as given by axes of Datafield) +//! into bin-fraction coordinates. +//! On second step masks are converted from bin-fraction coordinates into current axes of +//! Datafield. + +class MaskUnitsConverter { +public: + enum EConvertionDirection { TO_NBINS, FROM_NBINS, UNDEFINED }; + + MaskUnitsConverter(); + + void convertToNbins(Data2DItem* intensityData); + void convertFromNbins(Data2DItem* intensityData); + +private: + enum class Axis { X, Y }; + + void convertIntensityDataItem(Data2DItem* intensityData); + void convertMask(MaskItem* maskItem); + + double convert(double value, Axis axis); + + const Datafield* m_data; + EConvertionDirection m_direction; +}; + +#endif // BORNAGAIN_GUI_MODEL_DATA_MASKUNITSCONVERTER_H -- GitLab