Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • c.trageser/bornagain
  • mlz/bornagain
2 results
Show changes
Commits on Source (17)
Showing
with 277 additions and 31 deletions
......@@ -81,7 +81,7 @@ native_Debian_clang:
- cd build
- cmake .. -DCMAKE_CXX_COMPILER_LAUNCHER=ccache #-DWERROR=ON
- make -j6
- xvfb-run ctest -j6 --output-on-failure
- xvfb-run -a ctest -j6 --output-on-failure
- make package_source
artifacts:
paths:
......
......@@ -27,9 +27,8 @@ GUI::Model::DomainObjectBuilder::buildMultiLayer(const MultiLayerItem& multilaye
auto P_multilayer = GUI::Transform::ToDomain::createMultiLayer(multilayer_item);
for (LayerItem* child : multilayer_item.childrenOfType<LayerItem>()) {
auto P_layer = buildLayer(*child);
auto roughnessItem = child->roughness();
ASSERT(roughnessItem);
auto P_roughness = GUI::Transform::ToDomain::createLayerRoughness(*roughnessItem);
const auto roughness = child->roughness().currentItem();
auto P_roughness = GUI::Transform::ToDomain::createLayerRoughness(roughness);
if (P_layer) {
if (P_roughness)
P_multilayer->addLayerWithTopRoughness(*P_layer, *P_roughness);
......
......@@ -14,6 +14,7 @@
#include "GUI/Models/InterferenceItems.h"
#include "Base/Const/Units.h"
#include "GUI/Models/ComboProperty.h"
#include "GUI/Models/DoubleDescriptor.h"
#include "GUI/Models/FTDecayFunctionItems.h"
#include "GUI/Models/FTDistributionItems.h"
......@@ -86,6 +87,11 @@ DoubleDescriptor Interference1DLatticeItem::rotationAngle() const
return d;
}
SelectionDescriptor<FTDecayFunction1DItem*> Interference1DLatticeItem::decayFunction() const
{
return SelectionDescriptor<FTDecayFunction1DItem*>(item<GroupItem>(P_DECAY_FUNCTION));
}
// --------------------------------------------------------------------------------------------- //
Lattice2DItem* Interference2DAbstractLatticeItem::latticeType() const
......@@ -424,3 +430,9 @@ DoubleDescriptor InterferenceRadialParaCrystalItem::kappa() const
{
return DoubleDescriptor(getItem(P_KAPPA), Unit::unitless);
}
SelectionDescriptor<FTDistribution1DItem*>
InterferenceRadialParaCrystalItem::probabilityDistribution() const
{
return SelectionDescriptor<FTDistribution1DItem*>(item<GroupItem>(P_PDF));
}
......@@ -15,6 +15,7 @@
#ifndef BORNAGAIN_GUI_MODELS_INTERFERENCEITEMS_H
#define BORNAGAIN_GUI_MODELS_INTERFERENCEITEMS_H
#include "GUI/Models/SelectionDescriptor.h"
#include "GUI/Models/SessionGraphicsItem.h"
class FTDecayFunction1DItem;
......@@ -55,6 +56,7 @@ public:
DoubleDescriptor rotationAngle() const;
template <typename T> T* setDecayFunctionType();
SelectionDescriptor<FTDecayFunction1DItem*> decayFunction() const;
};
class Interference2DAbstractLatticeItem : public InterferenceItem {
......@@ -167,7 +169,7 @@ public:
DoubleDescriptor dampingLength() const;
DoubleDescriptor domainSize() const;
DoubleDescriptor kappa() const;
SelectionDescriptor<FTDistribution1DItem*> probabilityDistribution() const;
template <typename T> T* setPDFType();
};
......
......@@ -60,6 +60,12 @@ void ItemWithParticles::setTransformation(RotationItem* transformation)
model()->moveItem(transformation, this, -1, T_TRANSFORMATION);
}
RotationItem* ItemWithParticles::rotationItem() const
{
auto* transformationItem = dynamic_cast<TransformationItem*>(getItem(T_TRANSFORMATION));
return transformationItem ? transformationItem->rotationItem() : nullptr;
}
bool ItemWithParticles::isTransformationTagName(const QString& name)
{
return name == T_TRANSFORMATION;
......@@ -67,8 +73,49 @@ bool ItemWithParticles::isTransformationTagName(const QString& name)
Transform3D ItemWithParticles::rotation() const
{
const auto item = dynamic_cast<TransformationItem*>(getItem(T_TRANSFORMATION));
return item ? item->rotationItem()->rotation() : Transform3D();
const auto item = rotationItem();
return item ? item->rotation() : Transform3D();
}
SelectionDescriptor<RotationItem*> ItemWithParticles::rotationMethod()
{
SelectionDescriptor<RotationItem*> d;
// we need a special filling for this selection descriptor (not just from a GroupItem), since
// the rotation is stored in a TransformationItem instance, which can be present or not.
static QVector<QPair<QString, QString>> map = {{"None", ""},
{"X axis Rotation", XRotationItem::M_TYPE},
{"Y axis Rotation", YRotationItem::M_TYPE},
{"Z axis Rotation", ZRotationItem::M_TYPE},
{"Euler Rotation", EulerRotationItem::M_TYPE}};
d.label = "Rotation";
for (auto [title, type] : map)
d.options << title;
d.currentItem = [=]() -> RotationItem* { return rotationItem(); };
d.setCurrentIndex = [=](int current) {
if (auto item = getItem(T_TRANSFORMATION))
model()->removeItem(item);
if (current > 0)
createTransformationItem()->setRotationType(map[current].second);
};
d.currentIndex = [=]() {
auto item = rotationItem();
if (item == nullptr)
return 0;
for (int i = 1; i < map.size(); i++)
if (map[i].second == item->modelType())
return i;
return 0;
};
return d;
}
ItemWithParticles::ItemWithParticles(const QString& model_type, const QString& abundance_tooltip,
......
......@@ -16,6 +16,7 @@
#define BORNAGAIN_GUI_MODELS_ITEMWITHPARTICLES_H
#include "Base/Vector/Vectors3D.h"
#include "GUI/Models/SelectionDescriptor.h"
#include "GUI/Models/SessionGraphicsItem.h"
class RotationItem;
......@@ -45,6 +46,9 @@ public:
//! Returns identity transformation if no rotation is defined at all
Transform3D rotation() const;
//! Returns selection descriptor for rotation methods.
SelectionDescriptor<RotationItem*> rotationMethod();
protected:
ItemWithParticles(const QString& model_type, const QString& abundance_tooltip,
const QString& position_tooltip);
......@@ -53,6 +57,10 @@ protected:
private:
virtual bool isShellParticle() const;
//! Convenience method to return a rotation item from the contained transformation item.
//! nullptr, if no transformation item defined.
RotationItem* rotationItem() const;
};
#endif // BORNAGAIN_GUI_MODELS_ITEMWITHPARTICLES_H
......@@ -19,8 +19,11 @@
#include "GUI/Models/MaterialItemUtils.h"
#include "GUI/Models/MultiLayerItem.h"
#include "GUI/Models/ParticleLayoutItem.h"
#include "GUI/Models/SelectionDescriptor.h"
#include "GUI/Models/UIntDescriptor.h"
using std::function;
namespace {
const QString layer_nslices_tooltip = "Number of horizontal slices.\n"
"Used for Average Layer Material calculations \n"
......@@ -76,9 +79,24 @@ bool LayerItem::isThicknessPropertyName(const QString& name)
return name == P_THICKNESS;
}
SessionItem* LayerItem::roughness() const
void LayerItem::setThicknessEnabled(bool enabled)
{
return getGroupItem(P_ROUGHNESS);
getItem(P_THICKNESS)->setEnabled(enabled);
}
SelectionDescriptor<std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*>>
LayerItem::roughness()
{
SelectionDescriptor<std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*>> d(
item<GroupItem>(P_ROUGHNESS));
d.currentItem = [=]() -> std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*> {
if (auto r = dynamic_cast<LayerBasicRoughnessItem*>(getGroupItem(P_ROUGHNESS)))
return {r};
return {dynamic_cast<LayerZeroRoughnessItem*>(getGroupItem(P_ROUGHNESS))};
};
return d;
}
SessionItem* LayerItem::roughnessItem() const
......@@ -86,12 +104,16 @@ SessionItem* LayerItem::roughnessItem() const
return getItem(P_ROUGHNESS);
}
void LayerItem::setRoughnessEnabled(bool enabled)
{
getItem(P_ROUGHNESS)->setEnabled(enabled);
}
UIntDescriptor LayerItem::numSlices() const
{
return UIntDescriptor(getItem(P_NSLICES), Unit::unitless);
}
QVector<ParticleLayoutItem*> LayerItem::layouts() const
{
return items<ParticleLayoutItem>(T_LAYOUTS);
......
......@@ -16,6 +16,8 @@
#define BORNAGAIN_GUI_MODELS_LAYERITEM_H
#include "GUI/Models/ItemWithMaterial.h"
#include "GUI/Models/SelectionDescriptor.h"
#include <variant>
class LayerZeroRoughnessItem;
class LayerBasicRoughnessItem;
......@@ -37,13 +39,14 @@ public:
QVector<ItemWithMaterial*> itemsWithMaterial();
SessionItem* thicknessItem() const;
DoubleDescriptor thickness() const;
static bool isThicknessPropertyName(const QString& name);
void setThicknessEnabled(bool enabled);
template <typename T> T* setRoughnessType();
SessionItem* roughness() const;
SessionItem* roughnessItem() const;
SelectionDescriptor<std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*>>
roughness();
void setRoughnessEnabled(bool enabled);
UIntDescriptor numSlices() const;
......@@ -52,6 +55,14 @@ public:
private:
void updateAppearance(SessionItem* new_parent);
// -- Only for testing
friend class TestMultiLayerItem_test_twoLayerSystem_Test;
friend class TestMultiLayerItem_test_threeLayerSystem_Test;
friend class TestMultiLayerItem_test_movingMiddleLayerOnTop_Test;
friend class TestModelUtils_test_iterateIf_Test;
SessionItem* thicknessItem() const;
SessionItem* roughnessItem() const;
};
template <typename T> T* LayerItem::setRoughnessType()
......
......@@ -125,6 +125,11 @@ std::unique_ptr<IFormFactor> MesoCrystalItem::getOuterShape() const
return ff_item.createFormFactor();
}
SelectionDescriptor<FormFactorItem*> MesoCrystalItem::outerShape()
{
return SelectionDescriptor<FormFactorItem*>(item<GroupItem>(P_OUTER_SHAPE));
}
ItemWithParticles* MesoCrystalItem::basisParticle() const
{
return dynamic_cast<ItemWithParticles*>(getItem(T_BASIS_PARTICLE));
......
......@@ -17,6 +17,7 @@
#include "Base/Vector/Vectors3D.h"
#include "GUI/Models/ItemWithParticles.h"
#include "GUI/Models/SelectionDescriptor.h"
#include "Sample/Lattice/Lattice3D.h"
class FormFactorItem;
......@@ -46,6 +47,9 @@ public:
std::unique_ptr<IFormFactor> getOuterShape() const;
template <typename T> T* setOuterShapeType();
SelectionDescriptor<FormFactorItem*> outerShape();
ItemWithParticles* basisParticle() const;
void setVectorA(const R3& vector_a);
......
......@@ -120,16 +120,12 @@ void MultiLayerItem::updateLayers()
{
QVector<LayerItem*> list = childrenOfType<LayerItem>();
for (auto it = list.begin(); it != list.end(); ++it) {
if (it == list.begin())
(*it)->roughnessItem()->setEnabled(false);
else
(*it)->roughnessItem()->setEnabled(true);
(*it)->setRoughnessEnabled(it != list.begin());
if (it == list.begin() || it == (list.end() - 1)) {
(*it)->thicknessItem()->setEnabled(false);
(*it)->setThicknessEnabled(false);
(*it)->thickness().set(0.0);
} else {
(*it)->thicknessItem()->setEnabled(true);
}
} else
(*it)->setThicknessEnabled(true);
}
}
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/Models/SelectionDescriptor.h
//! @brief Defines class SelectionDescriptor
//!
//! @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_MODELS_SELECTIONDESCRIPTOR_H
#define BORNAGAIN_GUI_MODELS_SELECTIONDESCRIPTOR_H
#include "GUI/Models/ComboProperty.h"
#include "GUI/Models/GroupItem.h"
#include <QString>
#include <QStringList>
#include <functional>
using std::function;
//! Describes a selection (various possibilities and the current one).
//!
//! Usually a selection is presented as a combo box.
//! Right now with SessionModel still in place, in most cases a selection changes the current item
//! of a group item, i.e. it changes the class of a certain child item (e.g.
//! XRotationItem*/YRotationItem*/...).
//!
//! The template parameter defines the type of the current item. This can be a pointer to a common
//! base class (like RotationItem*), but it also can be a std::variant<...>, which is useful if
//! no dedicated common base class exists (like for the roughness items LayerZeroRoughnessItem and
//! LayerBasicRoughnessItem).
//!
//! By using this class, the underlying data scheme is hidden from the user of the data. This e.g.
//! eases SessionItem migration. The underlying implementation can be a GroupItem, a simple pointer
//! member, a std::variant or any other construction to define a selection.
template <typename T> class SelectionDescriptor {
public:
SelectionDescriptor() = default;
//! Initialize the members by means of a GroupItem.
//!
//! currentItem can only be initialized if the template parameter is a pointer (like
//! RotationItem*). If it is e.g. a std::variant<>, the currentItem has to be initialized by the
//! caller. Only for easier migration. Should be removed after SessionItem refactoring.
explicit SelectionDescriptor(GroupItem* item)
{
label = item->displayName();
options = item->value().value<ComboProperty>().getValues();
setCurrentIndex = [=](int index) {
ComboProperty comboProperty = item->value().value<ComboProperty>();
if (comboProperty.currentIndex() != index) {
comboProperty.setCurrentIndex(index);
item->setValue(QVariant::fromValue<ComboProperty>(comboProperty));
}
};
currentIndex = [=] { return item->value().value<ComboProperty>().currentIndex(); };
if constexpr (std::is_pointer<T>::value)
currentItem = [=] { return dynamic_cast<T>(item->currentItem()); };
}
QString label; //!< A label text (short, no trailing colon)
QString tooltip; //!< Tooltip text
QStringList options; //!< List of options, usually presented as combo entries
function<void(int)> setCurrentIndex; //!< Function to set currently selected option
function<int()> currentIndex; //!< Function to get currently selected option
function<T()> currentItem; //!< Function to get currently selected item
};
#endif // BORNAGAIN_GUI_MODELS_SELECTIONDESCRIPTOR_H
......@@ -81,14 +81,13 @@ std::unique_ptr<Layer> GUI::Transform::ToDomain::createLayer(const LayerItem& it
return P_layer;
}
std::unique_ptr<LayerRoughness>
GUI::Transform::ToDomain::createLayerRoughness(const SessionItem& roughnessItem)
std::unique_ptr<LayerRoughness> GUI::Transform::ToDomain::createLayerRoughness(
const std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*>& roughness)
{
if (roughnessItem.modelType() == LayerZeroRoughnessItem::M_TYPE)
if (std::holds_alternative<LayerZeroRoughnessItem*>(roughness))
return nullptr;
if (roughnessItem.modelType() == LayerBasicRoughnessItem::M_TYPE) {
const LayerBasicRoughnessItem& basicRoughnessItem =
dynamic_cast<const LayerBasicRoughnessItem&>(roughnessItem);
if (std::holds_alternative<LayerBasicRoughnessItem*>(roughness)) {
const auto& basicRoughnessItem = *std::get<LayerBasicRoughnessItem*>(roughness);
return std::make_unique<LayerRoughness>(basicRoughnessItem.sigma(),
basicRoughnessItem.hurst(),
basicRoughnessItem.lateralCorrelationLength());
......
......@@ -25,6 +25,7 @@
#include "Sample/Multilayer/MultiLayer.h"
#include "Sample/Particle/IParticle.h"
#include <memory>
#include <variant>
class AlphaScan;
class BeamDistributionItem;
......@@ -39,13 +40,16 @@ class MultiLayerItem;
class ParticleLayoutItem;
class SessionItem;
class ISimulation;
class LayerZeroRoughnessItem;
class LayerBasicRoughnessItem;
namespace GUI::Transform::ToDomain {
std::unique_ptr<Material> createDomainMaterial(const ItemWithMaterial& item);
std::unique_ptr<IParticle> createIParticle(const SessionItem& item);
std::unique_ptr<Layer> createLayer(const LayerItem& item);
std::unique_ptr<LayerRoughness> createLayerRoughness(const SessionItem& item);
std::unique_ptr<LayerRoughness> createLayerRoughness(
const std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*>& roughness);
std::unique_ptr<MultiLayer> createMultiLayer(const MultiLayerItem& item);
std::unique_ptr<ParticleLayout> createParticleLayout(const ParticleLayoutItem& item);
......
......@@ -34,3 +34,8 @@ RotationItem* TransformationItem::rotationItem() const
{
return dynamic_cast<RotationItem*>(getGroupItem(P_ROT));
}
void TransformationItem::setRotationType(const QString& modelType)
{
setGroupProperty(P_ROT, modelType);
}
......@@ -30,6 +30,7 @@ public:
RotationItem* rotationItem() const;
template <typename T> T* setRotationType();
void setRotationType(const QString& modelType);
};
......
......@@ -60,7 +60,7 @@ JobListView::JobListView(JobModel* jobs, QWidget* parent, Qt::WindowFlags f) : Q
addAction(m_runAction);
m_cancelAction = new QAction("Stop", this);
m_cancelAction->setIcon(QIcon(":/images/hand-right.svg"));
m_cancelAction->setIcon(QIcon(":/images/stop.svg"));
m_cancelAction->setToolTip("Stop currently selected jobs");
connect(m_cancelAction, &QAction::triggered, this, &JobListView::onCancel);
addAction(m_cancelAction);
......
......@@ -52,6 +52,7 @@
<file>images/shape-square-plus.svg</file>
<file>images/content-copy.svg</file>
<file>images/play.svg</file>
<file>images/stop.svg</file>
<file>images/alpha-f-box.svg</file>
<file>images/dock-right.svg</file>
<file>images/content-save-outline.svg</file>
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="stop.svg"
id="svg4"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.1">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
inkscape:current-layer="svg4"
inkscape:window-maximized="1"
inkscape:window-y="0"
inkscape:window-x="0"
inkscape:cy="12"
inkscape:cx="12"
inkscape:zoom="47.791667"
showgrid="false"
id="namedview6"
inkscape:window-height="1363"
inkscape:window-width="2500"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#838686;fill-opacity:1"
id="path2"
d="M5,5V19H19V5Z" />
</svg>
......@@ -14,13 +14,13 @@ TEST_F(TestLayerRoughnessItems, test_LayerRoughnessToDomain)
roughnessItem.hurst().set(20.0);
roughnessItem.lateralCorrelationLength().set(30.0);
auto P_roughness = GUI::Transform::ToDomain::createLayerRoughness(roughnessItem);
auto P_roughness = GUI::Transform::ToDomain::createLayerRoughness(&roughnessItem);
EXPECT_EQ(P_roughness->getSigma(), roughnessItem.sigma());
EXPECT_EQ(P_roughness->getHurstParameter(), roughnessItem.hurst());
EXPECT_EQ(P_roughness->getLatteralCorrLength(), roughnessItem.lateralCorrelationLength());
LayerZeroRoughnessItem zeroRoughnessItem;
EXPECT_TRUE(GUI::Transform::ToDomain::createLayerRoughness(zeroRoughnessItem) == nullptr);
EXPECT_TRUE(GUI::Transform::ToDomain::createLayerRoughness(&zeroRoughnessItem) == nullptr);
}
TEST_F(TestLayerRoughnessItems, test_LayerRoughnessFromDomain)
......