diff --git a/GUI/Models/DetectorItems.cpp b/GUI/Models/DetectorItems.cpp index cfac4d17331f14e64bcacd84c693812fbcd8fef2..1c9adc359028772fe2f36661e7f49395cd996dab 100644 --- a/GUI/Models/DetectorItems.cpp +++ b/GUI/Models/DetectorItems.cpp @@ -77,11 +77,6 @@ void DetectorItem::importMasks(const MaskContainerItem* maskContainer) model()->copyItem(maskContainer, this, T_MASKS); } -SessionItem* DetectorItem::setResolutionFunctionType(const QString& model_type) -{ - return setGroupProperty(P_RESOLUTION_FUNCTION, model_type); -} - SessionItem* DetectorItem::resolutionFunctionItem() const { return getItem(P_RESOLUTION_FUNCTION); @@ -145,12 +140,14 @@ void DetectorItem::update_resolution_function_tooltips() { auto& resfuncItem = groupItem<ResolutionFunctionItem>(DetectorItem::P_RESOLUTION_FUNCTION); - if (resfuncItem.modelType() == "ResolutionFunction2DGaussian") { + if (resfuncItem.modelType() == ResolutionFunction2DGaussianItem::M_TYPE) { QString units = modelType() == SphericalDetectorItem::M_TYPE ? "deg" : "mm"; - resfuncItem.getItem(ResolutionFunction2DGaussianItem::P_SIGMA_X) + ResolutionFunction2DGaussianItem& resfuncGaussItem = + dynamic_cast<ResolutionFunction2DGaussianItem&>(resfuncItem); + resfuncGaussItem.sigmaXItem() ->setToolTip("Resolution along horizontal axis (in " + units + ")"); - resfuncItem.getItem(ResolutionFunction2DGaussianItem::P_SIGMA_Y) + resfuncGaussItem.sigmaYItem() ->setToolTip("Resolution along vertical axis (in " + units + ")"); } } diff --git a/GUI/Models/DetectorItems.h b/GUI/Models/DetectorItems.h index 6dd1935fc52bfb4de1f6beaa13bf8f05fd0cd9e3..0888aad64956d9698bce875177d45dd80ce4e7ad 100644 --- a/GUI/Models/DetectorItems.h +++ b/GUI/Models/DetectorItems.h @@ -22,6 +22,7 @@ class MaskContainerItem; class IDetector2D; class IResolutionFunction2D; class DetectorItem; +class ResolutionFunctionItem; class BA_CORE_API_ DetectorItem : public SessionItem { private: @@ -56,7 +57,7 @@ public: void importMasks(const MaskContainerItem* maskContainer); - SessionItem* setResolutionFunctionType(const QString& model_type); + template <typename T> T* setResolutionFunctionType(); SessionItem* resolutionFunctionItem() const; void setAnalyserDirection(const kvector_t& directorion); @@ -83,4 +84,13 @@ protected: void addMasksToDomain(IDetector2D* detector) const; }; +template <typename T> +T* DetectorItem::setResolutionFunctionType() +{ + static_assert(std::is_base_of<ResolutionFunctionItem,T>::value, + "Class must be derived from ResolutionFunctionItem"); + + return setGroupPropertyType<T>(P_RESOLUTION_FUNCTION); +} + #endif // BORNAGAIN_GUI_MODELS_DETECTORITEMS_H diff --git a/GUI/Models/GroupInfoCatalog.cpp b/GUI/Models/GroupInfoCatalog.cpp index 45e6ad9fe2c8a5023e5aa81e2313bd70ab6888d5..bc388ad4c86ff08ea20ae4d4378d2c6e56edecf1 100644 --- a/GUI/Models/GroupInfoCatalog.cpp +++ b/GUI/Models/GroupInfoCatalog.cpp @@ -22,6 +22,7 @@ #include "GUI/Models/PointwiseAxisItem.h" #include "GUI/Models/RealLimitsItems.h" #include "GUI/Models/RectangularDetectorItem.h" +#include "GUI/Models/ResolutionFunctionItems.h" #include "GUI/Models/SphericalDetectorItem.h" GroupInfoCatalog::GroupInfoCatalog() @@ -149,9 +150,9 @@ GroupInfoCatalog::GroupInfoCatalog() addInfo(info); info = GroupInfo("Resolution function group"); - info.add("ResolutionFunctionNone", "None"); - info.add("ResolutionFunction2DGaussian", "2D Gaussian"); - info.setDefaultType("ResolutionFunctionNone"); + info.add(ResolutionFunctionNoneItem::M_TYPE, "None"); + info.add(ResolutionFunction2DGaussianItem::M_TYPE, "2D Gaussian"); + info.setDefaultType(ResolutionFunctionNoneItem::M_TYPE); addInfo(info); info = GroupInfo("Minimizer library group"); diff --git a/GUI/Models/ItemCatalog.cpp b/GUI/Models/ItemCatalog.cpp index 74b43559c4b01099a55ba26ff80b3cc01127fedf..fa64e9c8d4cb1235714efad540264ad78865f6b0 100644 --- a/GUI/Models/ItemCatalog.cpp +++ b/GUI/Models/ItemCatalog.cpp @@ -192,8 +192,8 @@ ItemCatalog::ItemCatalog() addItem<SpecularBeamInclinationItem>(); addItem<SpecularBeamWavelengthItem>(); - add("ResolutionFunctionNone", create_new<ResolutionFunctionNoneItem>); - add("ResolutionFunction2DGaussian", create_new<ResolutionFunction2DGaussianItem>); + addItem<ResolutionFunctionNoneItem>(); + addItem<ResolutionFunction2DGaussianItem>(); add("MaskContainer", create_new<MaskContainerItem>); add("RectangleMask", create_new<RectangleItem>); diff --git a/GUI/Models/ResolutionFunctionItems.cpp b/GUI/Models/ResolutionFunctionItems.cpp index bf47edc53a365fda67060651e020c83337d12209..9f21de7b42c60ead1d70b4159219a28ea1f4fdb6 100644 --- a/GUI/Models/ResolutionFunctionItems.cpp +++ b/GUI/Models/ResolutionFunctionItems.cpp @@ -19,8 +19,10 @@ ResolutionFunctionItem::ResolutionFunctionItem(const QString& name) : SessionIte /* --------------------------------------------------------------------------------------------- */ +const QString ResolutionFunctionNoneItem::M_TYPE = "ResolutionFunctionNone"; + ResolutionFunctionNoneItem::ResolutionFunctionNoneItem() - : ResolutionFunctionItem("ResolutionFunctionNone") + : ResolutionFunctionItem(M_TYPE) { } @@ -32,11 +34,13 @@ ResolutionFunctionNoneItem::createResolutionFunction(double) const /* --------------------------------------------------------------------------------------------- */ -const QString ResolutionFunction2DGaussianItem::P_SIGMA_X = QString::fromStdString("SigmaX"); -const QString ResolutionFunction2DGaussianItem::P_SIGMA_Y = QString::fromStdString("SigmaY"); +const QString ResolutionFunction2DGaussianItem::P_SIGMA_X = "SigmaX"; +const QString ResolutionFunction2DGaussianItem::P_SIGMA_Y = "SigmaY"; + +const QString ResolutionFunction2DGaussianItem::M_TYPE = "ResolutionFunction2DGaussian"; ResolutionFunction2DGaussianItem::ResolutionFunction2DGaussianItem() - : ResolutionFunctionItem("ResolutionFunction2DGaussian") + : ResolutionFunctionItem(M_TYPE) { addProperty(P_SIGMA_X, 0.02) ->setLimits(RealLimits::lowerLimited(0.0)) @@ -54,3 +58,23 @@ ResolutionFunction2DGaussianItem::createResolutionFunction(double scale) const return std::make_unique<ResolutionFunction2DGaussian>( scale * getItemValue(P_SIGMA_X).toDouble(), scale * getItemValue(P_SIGMA_Y).toDouble()); } + +SessionItem* ResolutionFunction2DGaussianItem::sigmaXItem() const +{ + return getItem(P_SIGMA_X); +} + +void ResolutionFunction2DGaussianItem::setSigmaXValue(const double sigma_x) +{ + setItemValue(P_SIGMA_X, sigma_x); +} + +SessionItem* ResolutionFunction2DGaussianItem::sigmaYItem() const +{ + return getItem(P_SIGMA_Y); +} + +void ResolutionFunction2DGaussianItem::setSigmaYValue(const double sigma_y) +{ + setItemValue(P_SIGMA_Y, sigma_y); +} diff --git a/GUI/Models/ResolutionFunctionItems.h b/GUI/Models/ResolutionFunctionItems.h index 9c2d60564bdccd0f8aca7240482f3801167e6212..64031cf352a84075a8456b1a71503e53d025b633 100644 --- a/GUI/Models/ResolutionFunctionItems.h +++ b/GUI/Models/ResolutionFunctionItems.h @@ -22,8 +22,10 @@ class IResolutionFunction2D; class BA_CORE_API_ ResolutionFunctionItem : public SessionItem { -public: +protected: explicit ResolutionFunctionItem(const QString& name); + +public: virtual ~ResolutionFunctionItem() {} virtual std::unique_ptr<IResolutionFunction2D> @@ -33,17 +35,28 @@ public: class BA_CORE_API_ ResolutionFunctionNoneItem : public ResolutionFunctionItem { public: + static const QString M_TYPE; + ResolutionFunctionNoneItem(); std::unique_ptr<IResolutionFunction2D> createResolutionFunction(double scale = 1.0) const; }; class BA_CORE_API_ ResolutionFunction2DGaussianItem : public ResolutionFunctionItem { - -public: +private: static const QString P_SIGMA_X; static const QString P_SIGMA_Y; + +public: + static const QString M_TYPE; + ResolutionFunction2DGaussianItem(); std::unique_ptr<IResolutionFunction2D> createResolutionFunction(double scale = 1.0) const; + + SessionItem* sigmaXItem() const; + void setSigmaXValue(double sigma_x); + + SessionItem* sigmaYItem() const; + void setSigmaYValue(double sigma_y); }; #endif // BORNAGAIN_GUI_MODELS_RESOLUTIONFUNCTIONITEMS_H diff --git a/GUI/Models/TransformFromDomain.cpp b/GUI/Models/TransformFromDomain.cpp index e8373ed47aee4ad6ffeb56b261fabacec5c2ef72..5773f66a4f11337add578cd899662741d7f399ec 100644 --- a/GUI/Models/TransformFromDomain.cpp +++ b/GUI/Models/TransformFromDomain.cpp @@ -320,15 +320,13 @@ void TransformFromDomain::setDetectorResolution(DetectorItem* detector_item, if (auto p_convfunc = dynamic_cast<const ConvolutionDetectorResolution*>(p_resfunc)) { if (auto resfunc = dynamic_cast<const ResolutionFunction2DGaussian*>( p_convfunc->getResolutionFunction2D())) { - SessionItem* item = detector_item->setResolutionFunctionType - ("ResolutionFunction2DGaussian"); + ResolutionFunction2DGaussianItem* item = + detector_item->setResolutionFunctionType<ResolutionFunction2DGaussianItem>(); double scale(1.0); if (detector_item->modelType() == SphericalDetectorItem::M_TYPE) scale = 1. / Units::deg; - item->setItemValue(ResolutionFunction2DGaussianItem::P_SIGMA_X, - scale * resfunc->getSigmaX()); - item->setItemValue(ResolutionFunction2DGaussianItem::P_SIGMA_Y, - scale * resfunc->getSigmaY()); + item->setSigmaXValue(scale * resfunc->getSigmaX()); + item->setSigmaYValue(scale * resfunc->getSigmaY()); } else { throw Error("TransformFromDomain::setDetectorResolution() -> Error. " "Unknown detector resolution function"); diff --git a/Tests/UnitTests/GUI/TestDetectorItems.cpp b/Tests/UnitTests/GUI/TestDetectorItems.cpp index 587a763033f9c3066944b7b362df4268ce522a85..29268fafd3ad7de86066699390fd73c1654ec15b 100644 --- a/Tests/UnitTests/GUI/TestDetectorItems.cpp +++ b/Tests/UnitTests/GUI/TestDetectorItems.cpp @@ -6,6 +6,7 @@ #include "GUI/Models/InstrumentItems.h" #include "GUI/Models/InstrumentModel.h" #include "GUI/Models/RectangularDetectorItem.h" +#include "GUI/Models/ResolutionFunctionItems.h" #include "Tests/GTestWrapper/google_test.h" class TestDetectorItems : public ::testing::Test { @@ -35,7 +36,7 @@ TEST_F(TestDetectorItems, test_resolutionFunction) DetectorItem* detectorItem = instrument->detectorItem(); - detectorItem->setResolutionFunctionType("ResolutionFunction2DGaussian"); + detectorItem->setResolutionFunctionType<ResolutionFunction2DGaussianItem>(); auto detector = detectorItem->createDetector(); auto convol =