diff --git a/GUI/Model/Sample/InterferenceItemCatalog.cpp b/GUI/Model/Sample/InterferenceItemCatalog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..997fc24f8c77f8161431aa588ba0287e1aa9bd11 --- /dev/null +++ b/GUI/Model/Sample/InterferenceItemCatalog.cpp @@ -0,0 +1,104 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Model/Sample/InterferenceItemCatalog.cpp +//! @brief Implements class InterferenceItemCatalog +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "GUI/Model/Sample/InterferenceItemCatalog.h" +#include "GUI/Model/Sample/InterferenceItems.h" + +InterferenceItem* InterferenceItemCatalog::create(Type type) +{ + switch (type) { + case Type::None: + return nullptr; + case Type::RadialParaCrystalRadial: + return new InterferenceRadialParaCrystalItem(); + case Type::ParaCrystal2D: + return new Interference2DParaCrystalItem(); + case Type::Lattice1D: + return new Interference1DLatticeItem(); + case Type::Lattice2D: + return new Interference2DLatticeItem(); + case Type::FiniteLattice2D: + return new InterferenceFinite2DLatticeItem(); + case Type::HardDisk: + return new InterferenceHardDiskItem(); + default: + ASSERT(false); + } +} + +QVector<InterferenceItemCatalog::Type> InterferenceItemCatalog::types() +{ + return {Type::None, Type::RadialParaCrystalRadial, Type::Lattice1D, + Type::Lattice2D, Type::FiniteLattice2D, Type::ParaCrystal2D, + Type::HardDisk}; +} + +InterferenceItemCatalog::UiInfo InterferenceItemCatalog::uiInfo(Type type) +{ + auto createUiInfo = [](const QString& menuEntry, const QString& iconPath, + const QString& description) { + UiInfo info; + info.menuEntry = menuEntry; + info.iconPath = iconPath; + info.description = description; + return info; + }; + + switch (type) { + case Type::None: + return createUiInfo("None", "", ""); + case Type::RadialParaCrystalRadial: + return createUiInfo("Radial paracrystal", + ":/SampleDesignerToolbox/images/ParaCrystal1D.png", + "Interference function of radial paracrystal"); + case Type::ParaCrystal2D: + return createUiInfo("2D paracrystal", ":/SampleDesignerToolbox/images/ParaCrystal2D.png", + "Interference function of two-dimensional paracrystal"); + case Type::Lattice1D: + return createUiInfo("1D lattice", ":/SampleDesignerToolbox/images/Lattice1D.png", + "Interference function of 1D lattice"); + case Type::Lattice2D: + return createUiInfo("2D lattice", ":/SampleDesignerToolbox/images/Lattice2D.png", + "Interference function of 2D lattice"); + case Type::FiniteLattice2D: + return createUiInfo("Finite 2D lattice", + ":/SampleDesignerToolbox/images/Lattice2DFinite.png", + "Interference function of finite 2D lattice"); + case Type::HardDisk: + return createUiInfo("Hard disk Percus-Yevick", + ":/SampleDesignerToolbox/images/Lattice2D.png", + "Interference function for hard disk Percus-Yevick"); + default: + ASSERT(false); + } +} + +InterferenceItemCatalog::Type InterferenceItemCatalog::type(InterferenceItem* item) +{ + if (!item) + return Type::None; + +#define CHECK(itfClass, type) \ + if (dynamic_cast<itfClass*>(item)) \ + return Type::type + + CHECK(InterferenceRadialParaCrystalItem, RadialParaCrystalRadial); + CHECK(Interference2DParaCrystalItem, ParaCrystal2D); + CHECK(Interference1DLatticeItem, Lattice1D); + CHECK(Interference2DLatticeItem, Lattice2D); + CHECK(InterferenceFinite2DLatticeItem, FiniteLattice2D); + CHECK(InterferenceHardDiskItem, HardDisk); +#undef CHECK + ASSERT(false); +} diff --git a/GUI/Model/Sample/InterferenceItemCatalog.h b/GUI/Model/Sample/InterferenceItemCatalog.h new file mode 100644 index 0000000000000000000000000000000000000000..e5b7a85e56d3876bf50b5a157f6109ea64c0bc10 --- /dev/null +++ b/GUI/Model/Sample/InterferenceItemCatalog.h @@ -0,0 +1,62 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Model/Sample/InterferenceItemCatalog.h +//! @brief Defines class InterferenceItemCatalog +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#ifndef BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMCATALOG_H +#define BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMCATALOG_H + +#include <QString> + +class InterferenceItem; + +class InterferenceItemCatalog { +public: + using CatalogedType = InterferenceItem; + + // Do not change the numbering! It is serialized! + enum class Type : uint8_t { + None = 0, + RadialParaCrystalRadial = 1, + ParaCrystal2D = 2, + Lattice1D = 3, + Lattice2D = 4, + FiniteLattice2D = 5, + HardDisk = 6 + }; + + struct UiInfo { + QString menuEntry; + QString description; + QString iconPath; + }; + + + //! Creates the item of the given type. + //! + //! If type is "None", a nullptr is returned. + static InterferenceItem* create(Type type); + + //! Available types of interference items. + //! + //! Contains also type "None". + //! This list is sorted as expected in the UI (e.g. in combo box) + static QVector<Type> types(); + + //! UiInfo on the given type. + static UiInfo uiInfo(Type t); + + //! Returns the enum type of the given item. + static Type type(InterferenceItem* item); +}; + +#endif // BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMCATALOG_H diff --git a/GUI/Model/Sample/InterferenceItems.cpp b/GUI/Model/Sample/InterferenceItems.cpp index c9f3e65a3b797adb6cb29f51f7cc973c93068fa0..0b446a09149824f9f47a5ed84736f1ea9146ccb8 100644 --- a/GUI/Model/Sample/InterferenceItems.cpp +++ b/GUI/Model/Sample/InterferenceItems.cpp @@ -7,132 +7,109 @@ //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @copyright Forschungszentrum Jülich GmbH 2021 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ #include "GUI/Model/Sample/InterferenceItems.h" #include "Base/Const/Units.h" +#include "GUI/Model/Sample/FTDecayFunctionItemCatalogs.h" #include "GUI/Model/Sample/FTDecayFunctionItems.h" +#include "GUI/Model/Sample/FTDistributionItemCatalogs.h" #include "GUI/Model/Sample/FTDistributionItems.h" +#include "GUI/Model/Sample/Lattice2DItemCatalog.h" #include "GUI/Model/Sample/Lattice2DItems.h" #include "GUI/Model/Types/UIntDescriptor.h" #include "Sample/Aggregate/Interferences.h" -// TODO (when back compatibility will be broken again) -// Make Interference1DLatticeItem::P_DECAY_FUNCTION and -// Interference2DLatticeItem::P_DECAY_FUNCTION rely on same constant - -InterferenceItem::~InterferenceItem() = default; - -DoubleDescriptor InterferenceItem::positionVariance() const +InterferenceItem::InterferenceItem() { - DoubleDescriptor d(getItem(P_POSITION_VARIANCE), Unit::nanometerPower2); - d.tooltip = "Variance of the position in each dimension"; - return d; + m_positionVariance.init("PositionVariance", "Variance of the position in each dimension", 0.0, + Unit::nanometerPower2, "PositionVariance"); } -InterferenceItem::InterferenceItem(const QString& modelType) : SessionItem(modelType) +DoubleDescriptor InterferenceItem::positionVariance() const { - addProperty(P_POSITION_VARIANCE, 0.0) - ->setToolTip("Variance of the position in each dimension (nm^2)"); + return m_positionVariance; } // --------------------------------------------------------------------------------------------- // -Interference1DLatticeItem::Interference1DLatticeItem() : InterferenceItem(M_TYPE) +Interference1DLatticeItem::Interference1DLatticeItem() { - addProperty(P_LENGTH, 20.0 * Units::nm)->setToolTip("Lattice length in nanometers"); - addProperty(P_ROTATION_ANGLE, 0.0) - ->setToolTip("Rotation of lattice with respect to x-axis of reference \n" - "frame (beam direction) in degrees "); - - GroupInfo info; - info.add<FTDecayFunction1DCauchyItem>(); - info.add<FTDecayFunction1DGaussItem>(); - info.add<FTDecayFunction1DTriangleItem>(); - info.add<FTDecayFunction1DVoigtItem>(); - info.setDefaultType<FTDecayFunction1DCauchyItem>(); - addGroupProperty(P_DECAY_FUNCTION, info) - ->setToolTip("One-dimensional decay function (finite size effects)"); + m_length.init("Length", "Lattice length", 20.0, Unit::nanometer, "Length"); + m_rotationAngle.init( + "Xi", "Rotation of lattice with respect to x-axis of reference frame (beam direction)", 0.0, + Unit::degree, "xi"); + m_decayFunction.init<FTDecayFunction1DItemCatalog>( + "Decay Function", "One-dimensional decay function (finite size effects)", "decay"); } std::unique_ptr<IInterference> Interference1DLatticeItem::createInterference() const { - auto result = std::make_unique<Interference1DLattice>( - getItemValue(P_LENGTH).toDouble(), - Units::deg2rad(getItemValue(P_ROTATION_ANGLE).toDouble())); - auto* pdfItem = dynamic_cast<FTDecayFunction1DItem*>( - getGroupItem(Interference1DLatticeItem::P_DECAY_FUNCTION)); - result->setDecayFunction(*pdfItem->createFTDecayFunction()); + auto result = + std::make_unique<Interference1DLattice>(m_length, Units::deg2rad(m_rotationAngle)); + result->setDecayFunction(*m_decayFunction->createFTDecayFunction()); result->setPositionVariance(positionVariance()); return std::unique_ptr<IInterference>(result.release()); } DoubleDescriptor Interference1DLatticeItem::length() const { - DoubleDescriptor d(getItem(P_LENGTH), Unit::nanometer); - d.tooltip = "Lattice length"; - return d; + return m_length; } DoubleDescriptor Interference1DLatticeItem::rotationAngle() const { - DoubleDescriptor d(getItem(P_ROTATION_ANGLE), Unit::degree); - d.tooltip = "Rotation of lattice with respect to x-axis of reference frame (beam direction)"; - return d; + return m_rotationAngle; +} + +void Interference1DLatticeItem::setDecayFunction(FTDecayFunction1DItem* p) +{ + m_decayFunction.set(p); } SelectionDescriptor<FTDecayFunction1DItem*> Interference1DLatticeItem::decayFunction() const { - return SelectionDescriptor<FTDecayFunction1DItem*>(item<GroupItem>(P_DECAY_FUNCTION)); + return m_decayFunction; } // --------------------------------------------------------------------------------------------- // SelectionDescriptor<Lattice2DItem*> Interference2DAbstractLatticeItem::latticeType() const { - return SelectionDescriptor<Lattice2DItem*>(item<GroupItem>(P_LATTICE_TYPE)); + return m_latticeType; } -bool Interference2DAbstractLatticeItem::xiIntegration() const +void Interference2DAbstractLatticeItem::setLatticeType(Lattice2DItem* p) { - return getItemValue(P_XI_INTEGRATION).toBool(); + m_latticeType.set(p); } -void Interference2DAbstractLatticeItem::setXiIntegration(bool xi_integration) +bool Interference2DAbstractLatticeItem::xiIntegration() const { - setItemValue(P_XI_INTEGRATION, xi_integration); + return m_xiIntegration; } -Interference2DAbstractLatticeItem::Interference2DAbstractLatticeItem(const QString& modelType, - bool xi_integration) - : InterferenceItem(modelType) +void Interference2DAbstractLatticeItem::setXiIntegration(bool xiIntegration) { - GroupInfo info; - info.add<BasicLattice2DItem>(); - info.add<SquareLattice2DItem>(); - info.add<HexagonalLattice2DItem>(); - info.setDefaultType<HexagonalLattice2DItem>(); - addGroupProperty(P_LATTICE_TYPE, info)->setToolTip("Type of lattice"); + m_xiIntegration = xiIntegration; +} - addProperty(P_XI_INTEGRATION, xi_integration) - ->setToolTip("Enables/disables averaging over the lattice rotation angle."); +Interference2DAbstractLatticeItem::Interference2DAbstractLatticeItem(bool xiIntegration) + : m_xiIntegration(xiIntegration) +{ + m_latticeType.init<Lattice2DItemCatalog>("Lattice type", "", "latticeType"); + m_latticeType.set(new HexagonalLattice2DItem()); } // --------------------------------------------------------------------------------------------- // -Interference2DLatticeItem::Interference2DLatticeItem() - : Interference2DAbstractLatticeItem(M_TYPE, false) +Interference2DLatticeItem::Interference2DLatticeItem() : Interference2DAbstractLatticeItem(false) { - GroupInfo info; - info.add<FTDecayFunction2DCauchyItem>(); - info.add<FTDecayFunction2DGaussItem>(); - info.add<FTDecayFunction2DVoigtItem>(); - info.setDefaultType<FTDecayFunction2DCauchyItem>(); - addGroupProperty(P_DECAY_FUNCTION, info) - ->setToolTip("Two-dimensional decay function (finite size effects)"); + m_decayFunction.init<FTDecayFunction2DItemCatalog>( + "Decay Function", "Two-dimensional decay function (finite size effects)", "decay"); } std::unique_ptr<IInterference> Interference2DLatticeItem::createInterference() const @@ -141,8 +118,7 @@ std::unique_ptr<IInterference> Interference2DLatticeItem::createInterference() c std::unique_ptr<Interference2DLattice> result( new Interference2DLattice(*latticeItem->createLattice())); - auto& pdfItem = groupItem<FTDecayFunction2DItem>(P_DECAY_FUNCTION); - result->setDecayFunction(*pdfItem.createFTDecayFunction()); + result->setDecayFunction(*m_decayFunction->createFTDecayFunction()); result->setIntegrationOverXi(xiIntegration()); result->setPositionVariance(positionVariance()); @@ -151,36 +127,24 @@ std::unique_ptr<IInterference> Interference2DLatticeItem::createInterference() c SelectionDescriptor<FTDecayFunction2DItem*> Interference2DLatticeItem::decayFunction() const { - return SelectionDescriptor<FTDecayFunction2DItem*>(item<GroupItem>(P_DECAY_FUNCTION)); + return m_decayFunction; } // --------------------------------------------------------------------------------------------- // Interference2DParaCrystalItem::Interference2DParaCrystalItem() - : Interference2DAbstractLatticeItem(M_TYPE, true) + : Interference2DAbstractLatticeItem(true) { - latticeType().currentItem()->latticeRotationAngleItem()->setEnabled(false); - - addProperty(P_DAMPING_LENGTH, 0.0) - ->setToolTip("The damping (coherence) length of the paracrystal in nanometers"); - - addProperty(P_DOMAIN_SIZE1, 20.0 * Units::micrometer) - ->setToolTip("Size of the coherent domain along the first basis vector in nanometers"); - addProperty(P_DOMAIN_SIZE2, 20.0 * Units::micrometer) - ->setToolTip("Size of the coherent domain along the second basis vector in nanometers"); - - GroupInfo info; - info.add<FTDistribution2DCauchyItem>(); - info.add<FTDistribution2DGaussItem>(); - info.add<FTDistribution2DGateItem>(); - info.add<FTDistribution2DConeItem>(); - info.add<FTDistribution2DVoigtItem>(); - info.setDefaultType<FTDistribution2DCauchyItem>(); - - addGroupProperty(P_PDF1, info) - ->setToolTip("Probability distribution in first lattice direction"); - addGroupProperty(P_PDF2, info) - ->setToolTip("Probability distribution in second lattice direction"); + m_dampingLength.init("Damping length", "The damping (coherence) length of the paracrystal", 0.0, + Unit::nanometer, "dampingLen"); + m_domainSize1.init("Domain size 1", "Size of the coherent domain along the first basis vector", + 20000.0, Unit::nanometer, "size1"); + m_domainSize2.init("Domain size 2", "Size of the coherent domain along the second basis vector", + 20000.0, Unit::nanometer, "size2"); + m_pdf1.init<FTDistribution2DItemCatalog>( + "PDF 1", "Probability distribution in first lattice direction", "pdf1"); + m_pdf2.init<FTDistribution2DItemCatalog>( + "PDF 2", "Probability distribution in second lattice direction", "pdf2"); } std::unique_ptr<IInterference> Interference2DParaCrystalItem::createInterference() const @@ -190,84 +154,83 @@ std::unique_ptr<IInterference> Interference2DParaCrystalItem::createInterference std::unique_ptr<Interference2DParaCrystal> result( new Interference2DParaCrystal(*latticeItem->createLattice(), 0, 0, 0)); - result->setDampingLength(getItemValue(P_DAMPING_LENGTH).toDouble()); - result->setDomainSizes(getItemValue(P_DOMAIN_SIZE1).toDouble(), - getItemValue(P_DOMAIN_SIZE2).toDouble()); + result->setDampingLength(m_dampingLength); + result->setDomainSizes(m_domainSize1, m_domainSize2); result->setIntegrationOverXi(xiIntegration()); - - auto& pdf1Item = groupItem<FTDistribution2DItem>(Interference2DParaCrystalItem::P_PDF1); - auto& pdf2Item = groupItem<FTDistribution2DItem>(Interference2DParaCrystalItem::P_PDF2); - result->setProbabilityDistributions(*pdf1Item.createFTDistribution(), - *pdf2Item.createFTDistribution()); - + result->setProbabilityDistributions(*m_pdf1->createFTDistribution(), + *m_pdf2->createFTDistribution()); result->setPositionVariance(positionVariance()); return std::unique_ptr<IInterference>(result.release()); } DoubleDescriptor Interference2DParaCrystalItem::dampingLength() const { - DoubleDescriptor d(getItem(P_DAMPING_LENGTH), Unit::nanometer); - d.tooltip = "The damping (coherence) length of the paracrystal"; - return d; + return m_dampingLength; } -void Interference2DParaCrystalItem::setDampingLength(const double damping_length) +void Interference2DParaCrystalItem::setDampingLength(double dampingLength) { - setItemValue(P_DAMPING_LENGTH, damping_length); + m_dampingLength.set(dampingLength); } DoubleDescriptor Interference2DParaCrystalItem::domainSize1() const { - DoubleDescriptor d(getItem(P_DOMAIN_SIZE1), Unit::nanometer); - d.tooltip = "Size of the coherent domain along the first basis vector"; - return d; + return m_domainSize1; } -void Interference2DParaCrystalItem::setDomainSize1(const double domain_size1) +void Interference2DParaCrystalItem::setDomainSize1(const double size) { - setItemValue(P_DOMAIN_SIZE1, domain_size1); + m_domainSize1.set(size); } DoubleDescriptor Interference2DParaCrystalItem::domainSize2() const { - DoubleDescriptor d(getItem(P_DOMAIN_SIZE2), Unit::nanometer); - d.tooltip = "Size of the coherent domain along the second basis vector"; - return d; + return m_domainSize2; } -void Interference2DParaCrystalItem::setDomainSize2(const double domain_size2) +void Interference2DParaCrystalItem::setDomainSize2(const double size) { - setItemValue(P_DOMAIN_SIZE2, domain_size2); + m_domainSize2.set(size); } SelectionDescriptor<FTDistribution2DItem*> Interference2DParaCrystalItem::probabilityDistribution1() const { - return SelectionDescriptor<FTDistribution2DItem*>(item<GroupItem>(P_PDF1)); + return m_pdf1; +} + +void Interference2DParaCrystalItem::setPDF1Type(FTDistribution2DItem* p) +{ + m_pdf1.set(p); } SelectionDescriptor<FTDistribution2DItem*> Interference2DParaCrystalItem::probabilityDistribution2() const { - return SelectionDescriptor<FTDistribution2DItem*>(item<GroupItem>(P_PDF2)); + return m_pdf2; +} + +void Interference2DParaCrystalItem::setPDF2Type(FTDistribution2DItem* p) +{ + m_pdf2.set(p); } // --------------------------------------------------------------------------------------------- // InterferenceFinite2DLatticeItem::InterferenceFinite2DLatticeItem() - : Interference2DAbstractLatticeItem(M_TYPE, false) + : Interference2DAbstractLatticeItem(false) { - addProperty(P_DOMAIN_SIZE_1, 100u)->setToolTip("Domain size 1 in number of unit cells"); - addProperty(P_DOMAIN_SIZE_2, 100u)->setToolTip("Domain size 2 in number of unit cells"); + m_domainSize1.init("Domain size 1", "Domain size 1 in number of unit cells", 100, + Unit::unitless, "size1"); + m_domainSize2.init("Domain size 2", "Domain size 2 in number of unit cells", 100, + Unit::unitless, "size2"); } std::unique_ptr<IInterference> InterferenceFinite2DLatticeItem::createInterference() const { Lattice2DItem* latticeItem = latticeType().currentItem(); - auto size_1 = getItemValue(P_DOMAIN_SIZE_1).toUInt(); - auto size_2 = getItemValue(P_DOMAIN_SIZE_2).toUInt(); - std::unique_ptr<InterferenceFinite2DLattice> result( - new InterferenceFinite2DLattice(*latticeItem->createLattice(), size_1, size_2)); + std::unique_ptr<InterferenceFinite2DLattice> result(new InterferenceFinite2DLattice( + *latticeItem->createLattice(), m_domainSize1, m_domainSize2)); result->setIntegrationOverXi(xiIntegration()); result->setPositionVariance(positionVariance()); @@ -277,122 +240,104 @@ std::unique_ptr<IInterference> InterferenceFinite2DLatticeItem::createInterferen UIntDescriptor InterferenceFinite2DLatticeItem::domainSize1() { - return UIntDescriptor(getItem(P_DOMAIN_SIZE_1), Unit::unitless); + return m_domainSize1; } -void InterferenceFinite2DLatticeItem::setDomainSize1(const unsigned int domain_size1) +void InterferenceFinite2DLatticeItem::setDomainSize1(const unsigned int size) { - setItemValue(P_DOMAIN_SIZE_1, domain_size1); + m_domainSize1.set(size); } UIntDescriptor InterferenceFinite2DLatticeItem::domainSize2() { - return UIntDescriptor(getItem(P_DOMAIN_SIZE_2), Unit::unitless); + return m_domainSize2; } -void InterferenceFinite2DLatticeItem::setDomainSize2(const unsigned int domain_size2) +void InterferenceFinite2DLatticeItem::setDomainSize2(const unsigned int size) { - setItemValue(P_DOMAIN_SIZE_2, domain_size2); + m_domainSize2.set(size); } // --------------------------------------------------------------------------------------------- // -InterferenceHardDiskItem::InterferenceHardDiskItem() : InterferenceItem(M_TYPE) +InterferenceHardDiskItem::InterferenceHardDiskItem() { - addProperty(P_RADIUS, 5.0 * Units::nm)->setToolTip("Hard disk radius in nanometers"); - addProperty(P_DENSITY, 0.002)->setToolTip("Particle density in particles per square nanometer"); + m_radius.init("Radius", "Hard disk radius", 5.0, Unit::nanometer, "radius"); + m_density.init("Total particle density", "Particle density in particles per area", 0.002, + Unit::nanometerPowerMinus2, "density"); } std::unique_ptr<IInterference> InterferenceHardDiskItem::createInterference() const { - auto result = std::make_unique<InterferenceHardDisk>(getItemValue(P_RADIUS).toDouble(), - getItemValue(P_DENSITY).toDouble()); + auto result = std::make_unique<InterferenceHardDisk>(m_radius, m_density); result->setPositionVariance(positionVariance()); return std::unique_ptr<IInterference>(result.release()); } DoubleDescriptor InterferenceHardDiskItem::density() const { - DoubleDescriptor d(getItem(P_DENSITY), Unit::nanometerPowerMinus2); - d.tooltip = "Particle density in particles per area"; - return d; + return m_density; } DoubleDescriptor InterferenceHardDiskItem::radius() const { - DoubleDescriptor d(getItem(P_RADIUS), Unit::nanometer); - d.tooltip = "Hard disk radius"; - return d; + return m_radius; } // --------------------------------------------------------------------------------------------- // -InterferenceRadialParaCrystalItem::InterferenceRadialParaCrystalItem() : InterferenceItem(M_TYPE) -{ - addProperty(P_PEAK_DISTANCE, 20.0 * Units::nm) - ->setToolTip("Average distance to the next neighbor in nanometers"); - addProperty(P_DAMPING_LENGTH, 1000.0 * Units::nm) - ->setToolTip("The damping (coherence) length of the paracrystal " - "in nanometers"); - addProperty(P_DOMAIN_SIZE, 0.0) - ->setToolTip("Size of coherence domain along the lattice main axis " - "in nanometers"); - addProperty(P_KAPPA, 0.0) - ->setToolTip("Size spacing coupling parameter of the Size Spacing " - "Correlation Approximation"); - - GroupInfo info; - info.add<FTDistribution1DCauchyItem>(); - info.add<FTDistribution1DGaussItem>(); - info.add<FTDistribution1DGateItem>(); - info.add<FTDistribution1DTriangleItem>(); - info.add<FTDistribution1DCosineItem>(); - info.add<FTDistribution1DVoigtItem>(); - info.setDefaultType<FTDistribution1DCauchyItem>(); - addGroupProperty(P_PDF, info)->setToolTip("One-dimensional probability distribution"); +InterferenceRadialParaCrystalItem::InterferenceRadialParaCrystalItem() +{ + m_peakDistance.init("Peak distance", "Average distance to the next neighbor", 20.0, + Unit::nanometer, "peak"); + m_dampingLength.init("Damping length", "The damping (coherence) length of the paracrystal", + 1000.0, Unit::nanometer, "dampingLen"); + m_domainSize.init("Domain size", "Size of coherence domain along the lattice main axis", 0.0, + Unit::nanometer, "size"); + m_kappa.init("SizeSpaceCoupling", + "Size spacing coupling parameter of the Size Spacing Correlation Approximation", + 0.0, Unit::unitless, "kappa"); + m_pdf.init<FTDistribution1DItemCatalog>("PDF", "One-dimensional probability distribution", + "pdf"); } std::unique_ptr<IInterference> InterferenceRadialParaCrystalItem::createInterference() const { - auto result = std::make_unique<InterferenceRadialParaCrystal>( - getItemValue(P_PEAK_DISTANCE).toDouble(), getItemValue(P_DAMPING_LENGTH).toDouble()); - result->setDomainSize(getItemValue(P_DOMAIN_SIZE).toDouble()); - result->setKappa(getItemValue(P_KAPPA).toDouble()); - - auto& pdfItem = groupItem<FTDistribution1DItem>(P_PDF); - result->setProbabilityDistribution(*pdfItem.createFTDistribution()); + auto result = std::make_unique<InterferenceRadialParaCrystal>(m_peakDistance, m_dampingLength); + result->setDomainSize(m_domainSize); + result->setKappa(m_kappa); + result->setProbabilityDistribution(*m_pdf->createFTDistribution()); result->setPositionVariance(positionVariance()); return std::unique_ptr<IInterference>(result.release()); } DoubleDescriptor InterferenceRadialParaCrystalItem::peakDistance() const { - DoubleDescriptor d(getItem(P_PEAK_DISTANCE), Unit::nanometer); - d.tooltip = "Average distance to the next neighbor"; - return d; + return m_peakDistance; } DoubleDescriptor InterferenceRadialParaCrystalItem::dampingLength() const { - DoubleDescriptor d(getItem(P_DAMPING_LENGTH), Unit::nanometer); - d.tooltip = "The damping (coherence) length of the paracrystal"; - return d; + return m_dampingLength; } DoubleDescriptor InterferenceRadialParaCrystalItem::domainSize() const { - DoubleDescriptor d(getItem(P_DOMAIN_SIZE), Unit::nanometer); - d.tooltip = "Size of coherence domain along the lattice main axis"; - return d; + return m_domainSize; } DoubleDescriptor InterferenceRadialParaCrystalItem::kappa() const { - return DoubleDescriptor(getItem(P_KAPPA), Unit::unitless); + return m_kappa; } SelectionDescriptor<FTDistribution1DItem*> InterferenceRadialParaCrystalItem::probabilityDistribution() const { - return SelectionDescriptor<FTDistribution1DItem*>(item<GroupItem>(P_PDF)); + return m_pdf; +} + +void InterferenceRadialParaCrystalItem::setPDFType(FTDistribution1DItem* p) +{ + m_pdf.set(p); } diff --git a/GUI/Model/Sample/InterferenceItems.h b/GUI/Model/Sample/InterferenceItems.h index d62a7721718ff4f8ec452b4ab177df7170f14ebf..63408ba65daf042ea3decae445a349b4b1afd288 100644 --- a/GUI/Model/Sample/InterferenceItems.h +++ b/GUI/Model/Sample/InterferenceItems.h @@ -7,7 +7,7 @@ //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @copyright Forschungszentrum Jülich GmbH 2021 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ @@ -15,8 +15,9 @@ #ifndef BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMS_H #define BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMS_H -#include "GUI/Model/Group/SelectionDescriptor.h" -#include "GUI/Model/Session/SessionItem.h" +#include "GUI/Model/Types/DoubleProperty.h" +#include "GUI/Model/Types/SelectionProperty.h" +#include "GUI/Model/Types/UIntProperty.h" class FTDecayFunction1DItem; class FTDecayFunction2DItem; @@ -24,109 +25,95 @@ class FTDistribution1DItem; class FTDistribution2DItem; class IInterference; class Lattice2DItem; -class DoubleDescriptor; -class UIntDescriptor; - -class InterferenceItem : public SessionItem { -private: - static constexpr auto P_POSITION_VARIANCE{"PositionVariance"}; +class InterferenceItem { public: - ~InterferenceItem() override; + virtual ~InterferenceItem() = default; virtual std::unique_ptr<IInterference> createInterference() const = 0; DoubleDescriptor positionVariance() const; protected: - explicit InterferenceItem(const QString& modelType); -}; + InterferenceItem(); -class Interference1DLatticeItem : public InterferenceItem { private: - static constexpr auto P_LENGTH{"Length"}; - static constexpr auto P_ROTATION_ANGLE{"Xi"}; - static constexpr auto P_DECAY_FUNCTION{"Decay Function"}; + DoubleProperty m_positionVariance; +}; +class Interference1DLatticeItem : public InterferenceItem { public: - static constexpr auto M_TYPE{"Interference1DLattice"}; - Interference1DLatticeItem(); + std::unique_ptr<IInterference> createInterference() const override; DoubleDescriptor length() const; DoubleDescriptor rotationAngle() const; - template <typename T> T* setDecayFunctionType(); + void setDecayFunction(FTDecayFunction1DItem* p); SelectionDescriptor<FTDecayFunction1DItem*> decayFunction() const; -}; -class Interference2DAbstractLatticeItem : public InterferenceItem { private: - static constexpr auto P_LATTICE_TYPE{"LatticeType"}; - static constexpr auto P_XI_INTEGRATION{"Integration_over_xi"}; + DoubleProperty m_length; + DoubleProperty m_rotationAngle; + SelectionProperty<FTDecayFunction1DItem*> m_decayFunction; +}; +class Interference2DAbstractLatticeItem : public InterferenceItem { public: SelectionDescriptor<Lattice2DItem*> latticeType() const; - template <typename T> T* setLatticeType(); + void setLatticeType(Lattice2DItem* p); bool xiIntegration() const; - void setXiIntegration(bool xi_integration); + void setXiIntegration(bool xiIntegration); protected: - explicit Interference2DAbstractLatticeItem(const QString& modelType, bool xi_integration); + explicit Interference2DAbstractLatticeItem(bool xiIntegration); + + bool m_xiIntegration; // #baMigration serialize + SelectionProperty<Lattice2DItem*> m_latticeType; }; class Interference2DLatticeItem : public Interference2DAbstractLatticeItem { -private: - static constexpr auto P_DECAY_FUNCTION{"Decay Function"}; - public: - static constexpr auto M_TYPE{"Interference2DLattice"}; - Interference2DLatticeItem(); std::unique_ptr<IInterference> createInterference() const override; template <typename T> T* setDecayFunctionType(); SelectionDescriptor<FTDecayFunction2DItem*> decayFunction() const; + +protected: + SelectionProperty<FTDecayFunction2DItem*> m_decayFunction; }; class Interference2DParaCrystalItem : public Interference2DAbstractLatticeItem { -private: - static constexpr auto P_DAMPING_LENGTH{"DampingLength"}; - static constexpr auto P_DOMAIN_SIZE1{"DomainSize1"}; - static constexpr auto P_DOMAIN_SIZE2{"DomainSize2"}; - static constexpr auto P_PDF1{"PDF #1"}; - static constexpr auto P_PDF2{"PDF #2"}; - public: - static constexpr auto M_TYPE{"Interference2DParaCrystal"}; - Interference2DParaCrystalItem(); std::unique_ptr<IInterference> createInterference() const override; DoubleDescriptor dampingLength() const; - void setDampingLength(double damping_length); + void setDampingLength(double dampingLength); DoubleDescriptor domainSize1() const; - void setDomainSize1(double domain_size1); + void setDomainSize1(double size); DoubleDescriptor domainSize2() const; - void setDomainSize2(double domain_size2); + void setDomainSize2(double size); SelectionDescriptor<FTDistribution2DItem*> probabilityDistribution1() const; - template <typename T> T* setPDF1Type(); + void setPDF1Type(FTDistribution2DItem* p); SelectionDescriptor<FTDistribution2DItem*> probabilityDistribution2() const; - template <typename T> T* setPDF2Type(); -}; + void setPDF2Type(FTDistribution2DItem* p); -class InterferenceFinite2DLatticeItem : public Interference2DAbstractLatticeItem { private: - static constexpr auto P_DOMAIN_SIZE_1{"Domain_size_1"}; - static constexpr auto P_DOMAIN_SIZE_2{"Domain_size_2"}; + DoubleProperty m_dampingLength; + DoubleProperty m_domainSize1; + DoubleProperty m_domainSize2; + SelectionProperty<FTDistribution2DItem*> m_pdf1; + SelectionProperty<FTDistribution2DItem*> m_pdf2; +}; +class InterferenceFinite2DLatticeItem : public Interference2DAbstractLatticeItem { public: - static constexpr auto M_TYPE{"InterferenceFinite2DLattice"}; - InterferenceFinite2DLatticeItem(); std::unique_ptr<IInterference> createInterference() const override; @@ -134,34 +121,27 @@ public: void setDomainSize1(unsigned int domain_size1); UIntDescriptor domainSize2(); void setDomainSize2(unsigned int domain_size2); -}; -class InterferenceHardDiskItem : public InterferenceItem { private: - static constexpr auto P_RADIUS{"Radius"}; - static constexpr auto P_DENSITY{"TotalParticleDensity"}; + UIntProperty m_domainSize1; + UIntProperty m_domainSize2; +}; +class InterferenceHardDiskItem : public InterferenceItem { public: - static constexpr auto M_TYPE{"InterferenceHardDisk"}; - InterferenceHardDiskItem(); std::unique_ptr<IInterference> createInterference() const override; DoubleDescriptor radius() const; DoubleDescriptor density() const; -}; -class InterferenceRadialParaCrystalItem : public InterferenceItem { private: - static constexpr auto P_PEAK_DISTANCE{"PeakDistance"}; - static constexpr auto P_DAMPING_LENGTH{"DampingLength"}; - static constexpr auto P_DOMAIN_SIZE{"DomainSize"}; - static constexpr auto P_KAPPA{"SizeSpaceCoupling"}; - static constexpr auto P_PDF{"PDF"}; + DoubleProperty m_radius; + DoubleProperty m_density; +}; +class InterferenceRadialParaCrystalItem : public InterferenceItem { public: - static constexpr auto M_TYPE{"InterferenceRadialParaCrystal"}; - InterferenceRadialParaCrystalItem(); std::unique_ptr<IInterference> createInterference() const override; @@ -170,55 +150,14 @@ public: DoubleDescriptor domainSize() const; DoubleDescriptor kappa() const; SelectionDescriptor<FTDistribution1DItem*> probabilityDistribution() const; - template <typename T> T* setPDFType(); -}; - -template <typename T> T* Interference1DLatticeItem::setDecayFunctionType() -{ - static_assert(std::is_base_of<FTDecayFunction1DItem, T>::value, - "Class must be derived from FTDecayFunction1DItem"); + void setPDFType(FTDistribution1DItem* p); - return setGroupPropertyType<T>(P_DECAY_FUNCTION); -} - -template <typename T> T* Interference2DAbstractLatticeItem::setLatticeType() -{ - static_assert(std::is_base_of<Lattice2DItem, T>::value, - "Class must be derived from Lattice2DItem"); - - return setGroupPropertyType<T>(P_LATTICE_TYPE); -} - -template <typename T> T* Interference2DLatticeItem::setDecayFunctionType() -{ - static_assert(std::is_base_of<FTDecayFunction2DItem, T>::value, - "Class must be derived from FTDecayFunction2DItem"); - - return setGroupPropertyType<T>(P_DECAY_FUNCTION); -} - -template <typename T> T* Interference2DParaCrystalItem::setPDF1Type() -{ - static_assert(std::is_base_of<FTDistribution2DItem, T>::value, - "Class must be derived from FTDistribution2DItem"); - - return setGroupPropertyType<T>(P_PDF1); -} - -template <typename T> T* Interference2DParaCrystalItem::setPDF2Type() -{ - static_assert(std::is_base_of<FTDistribution2DItem, T>::value, - "Class must be derived from FTDistribution2DItem"); - - return setGroupPropertyType<T>(P_PDF2); -} - -template <typename T> T* InterferenceRadialParaCrystalItem::setPDFType() -{ - static_assert(std::is_base_of<FTDistribution1DItem, T>::value, - "Class must be derived from FTDistribution1DItem"); - - return setGroupPropertyType<T>(P_PDF); -} +private: + DoubleProperty m_peakDistance; + DoubleProperty m_dampingLength; + DoubleProperty m_domainSize; + DoubleProperty m_kappa; + SelectionProperty<FTDistribution1DItem*> m_pdf; +}; #endif // BORNAGAIN_GUI_MODEL_SAMPLE_INTERFERENCEITEMS_H