Skip to content
Snippets Groups Projects
Commit 8f9c3a56 authored by Matthias Puchner's avatar Matthias Puchner
Browse files

free ParticleLayoutItem from SessionItem

parent d59914e1
No related branches found
No related tags found
1 merge request!570remove SessionModel/Item from SampleModel and all related items
......@@ -7,56 +7,60 @@
//!
//! @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/ParticleLayoutItem.h"
#include "GUI/Model/Sample/InterferenceItemCatalog.h"
#include "GUI/Model/Sample/InterferenceItems.h"
#include "GUI/Model/Sample/Lattice2DItems.h"
#include "GUI/Model/Sample/MesoCrystalItem.h"
#include "GUI/Model/Sample/ParticleCompositionItem.h"
#include "GUI/Model/Sample/ParticleCoreShellItem.h"
#include "GUI/Model/Sample/ParticleItem.h"
#include "GUI/Model/Types/DoubleDescriptor.h"
#include "GUI/Model/Session/SessionXML.h"
ParticleLayoutItem::ParticleLayoutItem() : SessionItem(M_TYPE)
using namespace GUI::Session::XML;
namespace {
namespace Tags {
const QString Interference("Interference");
const QString Particle("Particle");
const QString Type("Type");
} // namespace Tags
} // namespace
ParticleLayoutItem::ParticleLayoutItem()
{
setToolTip("A layout of particles");
addProperty(P_TOTAL_DENSITY, 0.01);
getItem(P_TOTAL_DENSITY)->setDecimals(10);
addProperty(P_WEIGHT, 1.0);
registerTag(T_PARTICLES, 0, -1,
{ParticleItem::M_TYPE, ParticleCoreShellItem::M_TYPE,
ParticleCompositionItem::M_TYPE, MesoCrystalItem::M_TYPE});
setDefaultTag(T_PARTICLES);
registerTag(T_INTERFERENCE, 0, 1,
{Interference1DLatticeItem::M_TYPE, Interference2DLatticeItem::M_TYPE,
Interference2DParaCrystalItem::M_TYPE, InterferenceFinite2DLatticeItem::M_TYPE,
InterferenceHardDiskItem::M_TYPE, InterferenceRadialParaCrystalItem::M_TYPE});
m_ownDensity.init("Total particle density",
"Number of particles per area (particle surface density).\n "
"Should be defined for disordered and 1d-ordered particle collections.",
0.01, Unit::nanometerPowerMinus2, 10, RealLimits::nonnegative(), "density");
m_weight.init("Weight",
"Weight of this particle layout.\nShould be used when multiple layouts define "
"different domains in the sample.",
1.0, Unit::unitless, "weight");
m_interference.init<InterferenceItemCatalog>("Interference function", "", "interference");
}
DoubleDescriptor ParticleLayoutItem::ownDensity() const
{
DoubleDescriptor d(getItem(P_TOTAL_DENSITY), Unit::nanometerPowerMinus2);
d.tooltip = "Number of particles per area (particle surface density).\n "
"Should be defined for disordered and 1d-ordered particle collections.";
return d;
return m_ownDensity;
}
double ParticleLayoutItem::totalDensity() const
{
if (!totalDensityIsDefinedByInterference())
return ownDensity();
return m_ownDensity;
const auto* interferenceItem = getItem(T_INTERFERENCE);
ASSERT(interferenceItem);
ASSERT(m_interference.get());
if (const auto* interLatticeItem =
dynamic_cast<const Interference2DAbstractLatticeItem*>(interferenceItem)) {
dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.get())) {
Lattice2DItem* latticeItem = interLatticeItem->latticeType().currentItem();
try {
const double area = latticeItem->unitCellArea();
......@@ -66,7 +70,7 @@ double ParticleLayoutItem::totalDensity() const
return 0.0;
}
} else if (const auto* interHDItem =
dynamic_cast<const InterferenceHardDiskItem*>(interferenceItem))
dynamic_cast<const InterferenceHardDiskItem*>(m_interference.get()))
return interHDItem->density();
else {
ASSERT(false);
......@@ -76,97 +80,74 @@ double ParticleLayoutItem::totalDensity() const
DoubleDescriptor ParticleLayoutItem::weight() const
{
DoubleDescriptor d(getItem(P_WEIGHT), Unit::unitless);
d.tooltip = "Weight of this particle layout.\n"
"Should be used when multiple layouts define different domains in the sample.";
return d;
return m_weight;
}
QVector<ItemWithParticles*> ParticleLayoutItem::particles() const
{
return items<ItemWithParticles>(T_PARTICLES);
return m_particles;
}
void ParticleLayoutItem::addParticle(ItemWithParticles* particle)
{
model()->moveItem(particle, this, -1, T_PARTICLES);
m_particles << particle;
}
void ParticleLayoutItem::removeParticle(ItemWithParticles* particle)
{
model()->removeItem(particle);
m_particles.removeAll(particle);
delete particle;
}
QVector<ItemWithParticles*> ParticleLayoutItem::containedItemsWithParticles() const
{
QVector<ItemWithParticles*> result;
for (auto* p : particles())
for (auto* p : m_particles)
result << p << p->containedItemsWithParticles();
return result;
}
SelectionDescriptor<InterferenceItem*> ParticleLayoutItem::interference() const
{
SelectionDescriptor<InterferenceItem*> d;
// we need a special filling for this selection descriptor (not just from a GroupItem), since
// the interference is stored in a child, which can be present or not.
static QVector<QPair<QString, QString>> map;
// initialize if not done so far
if (map.isEmpty()) {
map << qMakePair(QString("None"), QString(""));
for (const auto& modelType : ItemCatalog::interferenceFunctionTypes())
map << qMakePair(ItemCatalog::instance().uiInfo(modelType).menuEntry, modelType);
}
d.label = "Interference function";
for (auto [title, type] : map)
d.options << title;
d.currentItem = [=] { return dynamic_cast<InterferenceItem*>(getItem(T_INTERFERENCE)); };
d.currentIndexSetter = [=](int current) {
if (auto* item = getItem(T_INTERFERENCE))
model()->removeItem(item);
if (current > 0)
model()->insertNewItem(map[current].second, const_cast<ParticleLayoutItem*>(this), -1,
T_INTERFERENCE);
};
d.currentIndexGetter = [=]() {
if (auto* item = dynamic_cast<InterferenceItem*>(getItem(T_INTERFERENCE)))
for (int i = 1; i < map.size(); i++)
if (map[i].second == item->modelType())
return i;
return 0;
};
return d;
return m_interference;
}
void ParticleLayoutItem::setInterference(InterferenceItem* interference)
{
model()->moveItem(interference, this, -1, T_INTERFERENCE);
m_interference.set(interference);
}
void ParticleLayoutItem::removeInterference()
{
if (auto* item = getItem(T_INTERFERENCE))
model()->removeItem(item);
m_interference.set(nullptr);
}
void ParticleLayoutItem::enableDensity(bool b)
bool ParticleLayoutItem::totalDensityIsDefinedByInterference() const
{
getItem(P_TOTAL_DENSITY)->setEnabled(b);
return dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.get())
|| dynamic_cast<const InterferenceHardDiskItem*>(m_interference.get());
}
bool ParticleLayoutItem::totalDensityIsDefinedByInterference() const
void ParticleLayoutItem::writeContentTo(QXmlStreamWriter* writer) const
{
writeAttribute(writer, GUI::Session::XML::Version, int(1));
writeUid(writer, m_uid);
writeDescriptors(writer, {ownDensity(), weight()});
if (m_interference.get()) {
writer->writeStartElement(Tags::Interference);
// writeAttribute(writer, Tags::Type, persistentName(m_interference));
// m_interference->writeContentTo(writer); // #baMigration ++ implement
writer->writeEndElement();
}
for (auto* particle : m_particles) {
writer->writeStartElement(Tags::Particle);
// particle->writeContentTo(writer);// #baMigration ++ implement
writer->writeEndElement();
}
}
void ParticleLayoutItem::readContentFrom(QXmlStreamReader* reader)
{
const auto* interferenceItem = getItem(T_INTERFERENCE);
return dynamic_cast<const Interference2DAbstractLatticeItem*>(interferenceItem)
|| dynamic_cast<const InterferenceHardDiskItem*>(interferenceItem);
// #baMigration ++ implement
}
......@@ -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,23 +15,19 @@
#ifndef BORNAGAIN_GUI_MODEL_SAMPLE_PARTICLELAYOUTITEM_H
#define BORNAGAIN_GUI_MODEL_SAMPLE_PARTICLELAYOUTITEM_H
#include "GUI/Model/Group/SelectionDescriptor.h"
#include "GUI/Model/Session/SessionModel.h"
#include "GUI/Model/Sample/InterferenceItems.h"
#include "GUI/Model/Types/DoubleProperty.h"
#include "GUI/Model/Types/SelectionProperty.h"
#include <QUuid>
#include <memory>
class InterferenceItem;
class ItemWithParticles;
class DoubleDescriptor;
class BA_CORE_API_ ParticleLayoutItem : public SessionItem {
private:
static constexpr auto P_TOTAL_DENSITY{"TotalParticleDensity"};
static constexpr auto P_WEIGHT{"Weight"};
static constexpr auto T_PARTICLES{"Particle Tag"};
static constexpr auto T_INTERFERENCE{"Interference Tag"};
class ItemWithParticles;
class QXmlStreamReader;
class QXmlStreamWriter;
class ParticleLayoutItem {
public:
static constexpr auto M_TYPE{"ParticleLayout"};
ParticleLayoutItem();
//! The density value which belonging only to the layout.
......@@ -63,26 +59,24 @@ public:
QVector<ItemWithParticles*> containedItemsWithParticles() const;
SelectionDescriptor<InterferenceItem*> interference() const;
template <typename T> T* createInterference();
void setInterference(InterferenceItem* interference);
void removeInterference();
// #baMigration Use only while not migrated from SessionModel!
void enableDensity(bool b);
//! Returns whether total density is defined by the currently selected interference.
//!
//! Two dimensional interference calculates density automatically; in these cases the "own"
//! total density value should not be edited but set by the one from the interference.
bool totalDensityIsDefinedByInterference() const;
};
template <typename T> T* ParticleLayoutItem::createInterference()
{
static_assert(std::is_base_of<InterferenceItem, T>::value,
"Class must be derived from InterferenceFunciontItem");
void writeContentTo(QXmlStreamWriter* writer) const;
void readContentFrom(QXmlStreamReader* reader);
return model()->insertItem<T>(this, -1, T_INTERFERENCE);
}
private:
QUuid m_uid = QUuid::createUuid(); // #baMigration necessary?
DoubleProperty m_ownDensity;
DoubleProperty m_weight;
SelectionProperty<InterferenceItem*> m_interference;
QVector<ItemWithParticles*> m_particles;
};
#endif // BORNAGAIN_GUI_MODEL_SAMPLE_PARTICLELAYOUTITEM_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment