Skip to content
Snippets Groups Projects
ParameterTreeUtils.cpp 6.66 KiB
Newer Older
//  ************************************************************************************************
Pospelov, Gennady's avatar
Pospelov, Gennady committed
//
//  BornAgain: simulate and fit reflection and scattering
Pospelov, Gennady's avatar
Pospelov, Gennady committed
//
//! @file      GUI/Model/Job/ParameterTreeUtils.cpp
//! @brief     Implements ParameterTreeUtils namespace
Pospelov, Gennady's avatar
Pospelov, Gennady committed
//!
//! @homepage  http://www.bornagainproject.org
Pospelov, Gennady's avatar
Pospelov, Gennady committed
//! @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)
Pospelov, Gennady's avatar
Pospelov, Gennady committed
//
//  ************************************************************************************************
Pospelov, Gennady's avatar
Pospelov, Gennady committed

#include "GUI/Model/Job/ParameterTreeUtils.h"
#include "GUI/Model/Fit/ParameterTreeItems.h"
#include "GUI/Model/Group/GroupItem.h"
Wuttke, Joachim's avatar
Wuttke, Joachim committed
#include "GUI/Model/Group/PropertyItem.h"
#include "GUI/Model/Instrument/InstrumentItems.h"
#include "GUI/Model/Job/JobItem.h"
#include "GUI/Model/Material/MaterialItem.h"
#include "GUI/Model/Sample/InterferenceItems.h"
#include "GUI/Model/Sample/Lattice2DItems.h"
#include "GUI/Model/Sample/MultiLayerItem.h"
#include "GUI/Model/Sample/ParticleCoreShellItem.h"
#include "GUI/Model/Sample/ParticleItem.h"
#include "GUI/Model/Sample/ParticleLayoutItem.h"
#include "GUI/Model/Session/ModelPath.h"
#include "GUI/Model/Types/VectorDescriptor.h"
#include "GUI/Util/Error.h"
#include <boost/polymorphic_cast.hpp>
using boost::polymorphic_downcast;

namespace {
void handleItem(ParameterContainerItem* container, SessionItem* tree, SessionItem* source,
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    if (tree->hasModelType<ParameterLabelItem>())
        tree->setDisplayName(source->itemName());

    else if (tree->hasModelType<ParameterItem>()) {
David Li's avatar
David Li committed
        tree->setDisplayName(source->itemName());
        const double sourceValue = source->value().toDouble();
        tree->setValue(QVariant(sourceValue));
        auto* parItem = polymorphic_downcast<ParameterItem*>(tree);
        parItem->linkToSessionItem(source);
        if (recreateBackupValues)
            container->setBackupValue(parItem->link(), sourceValue);
David Li's avatar
David Li committed
        return;
David Li's avatar
David Li committed
        return;
    for (SessionItem* child : source->children()) {

        // later in handleItems the position of a shell particle has to be ignored.
        if (auto* c = dynamic_cast<ParticleCoreShellItem*>(child))
            if (c->shell())
                c->shell()->positionItem()->setEnabled(false);

        // later in handleItems the rotation of an interference may have to be ignored.
        if (auto* c = dynamic_cast<Interference2DAbstractLatticeItem*>(child))
            if (c->latticeType().currentItem())
                c->latticeType().currentItem()->enableRotationAngle(!c->xiIntegration());

David Li's avatar
David Li committed
        if (child->isVisible() && child->isEnabled()) {
            if (child->hasModelType<PropertyItem>()) {
David Li's avatar
David Li committed
                if (child->value().type() == QVariant::Double) {
                    auto* branch = tree->model()->insertItem<ParameterItem>(tree);
                    handleItem(container, branch, child, recreateBackupValues);
            } else if (child->hasModelType<GroupItem>()) {
                SessionItem* currentItem = dynamic_cast<GroupItem*>(child)->currentItem();
                if (currentItem && currentItem->numberOfChildren() > 0) {
                    auto* branch = tree->model()->insertItem<ParameterLabelItem>(tree);
                    handleItem(container, branch, currentItem, recreateBackupValues);
David Li's avatar
David Li committed
            } else {
                auto* branch = tree->model()->insertItem<ParameterLabelItem>(tree);
                handleItem(container, branch, child, recreateBackupValues);
//! Populates ParameterContainer with ParameterItem's corresponding to all properties found
//! in a source item.

void populateParameterContainer(ParameterContainerItem* container, SessionItem* source,
    auto* sourceLabel = container->model()->insertItem<ParameterLabelItem>(container);
    handleItem(container, sourceLabel, source, recreateBackupValues);
void GUI::Model::ParameterTreeUtils::createParameterTree(JobItem* jobItem,
                                                         bool recreateBackupValues)
    auto* container = jobItem->parameterContainerItem();
    if (!container)
        container = jobItem->createParameterContainerItem();
    // add the job's materials
    auto* materialTopLabel = container->model()->insertItem<ParameterLabelItem>(container);
    materialTopLabel->setDisplayName("Materials");
    for (auto* material : jobItem->materialItems().materialItems()) {
        auto* materialLabel = container->model()->insertItem<ParameterLabelItem>(container);
        materialLabel->setDisplayName(material->materialName());

        DoubleDescriptors descriptors;
        if (material->hasRefractiveIndex())
            descriptors << material->delta() << material->beta();
        else
            descriptors << material->sldRe() << material->sldIm();

        // TODO: remove when specular instrument is ready for magnetization
        if (!jobItem->isSpecularJob())
            descriptors << material->magnetizationVector().x << material->magnetizationVector().y
                        << material->magnetizationVector().z;

Wuttke, Joachim's avatar
Wuttke, Joachim committed
        for (const auto& d : descriptors) {
            auto* materialValue = materialLabel->model()->insertItem<ParameterItem>(materialLabel);
            materialValue->setDisplayName(d.label);
            materialValue->setValue(QVariant(d.get()));
Matthias Puchner's avatar
Matthias Puchner committed
            materialValue->linkToDescriptor(d);
            if (recreateBackupValues)
                container->setBackupValue(materialValue->link(), d.get());
        }
    }
    // add sample.
    // #baMigration To ignore thickness/roughness, they are disabled. This has to be changed after
    // SessionModel migration. Compare also to handling in
    // LayerForm::updateLayerPositionDependentElements()
    // dto. for totalDensity of particle layout
    for (auto* layer : jobItem->sampleItem()->layers()) {
        const bool isFirstLayer = jobItem->sampleItem()->layers().first() == layer;
        const bool isLastLayer = jobItem->sampleItem()->layers().last() == layer;

        layer->setRoughnessEnabled(!isFirstLayer);
        layer->setThicknessEnabled(!isFirstLayer && !isLastLayer);

        for (auto* layout : layer->layouts())
            layout->enableDensity(!layout->totalDensityIsDefinedByInterference());
    populateParameterContainer(container, jobItem->sampleItem(), recreateBackupValues);
    populateParameterContainer(container, jobItem->instrumentItem(), recreateBackupValues);