diff --git a/GUI/Model/Data/ApplicationModels.cpp b/GUI/Model/Data/ApplicationModels.cpp index 767adc2483c07bdac56b462b18a669e0d4133389..aaaf1338c91561c249a1d605972aa6f61f81af3e 100644 --- a/GUI/Model/Data/ApplicationModels.cpp +++ b/GUI/Model/Data/ApplicationModels.cpp @@ -13,7 +13,6 @@ // ************************************************************************************************ #include "GUI/Model/Data/ApplicationModels.h" -#include "GUI/Model/Data/DocumentModel.h" #include "GUI/Model/Data/RealDataModel.h" #include "GUI/Model/Instrument/InstrumentModel.h" #include "GUI/Model/Job/JobModel.h" @@ -25,7 +24,6 @@ ApplicationModels::ApplicationModels(QObject* parent) : QObject(parent) - , m_documentModel(nullptr) , m_materialModel(nullptr) , m_instrumentModel(nullptr) , m_sampleModel(nullptr) @@ -33,14 +31,12 @@ ApplicationModels::ApplicationModels(QObject* parent) , m_jobModel(nullptr) { //! creates and initializes models, order is important - m_documentModel = new DocumentModel(this); m_materialModel = new MaterialModel(this); m_sampleModel = new SampleModel(this); m_instrumentModel = new InstrumentModel(this); m_realDataModel = new RealDataModel(this); m_jobModel = new JobModel(this); - connectModel(m_documentModel); connectModel(m_materialModel); connectModel(m_sampleModel); connectModel(m_instrumentModel); @@ -52,11 +48,6 @@ ApplicationModels::ApplicationModels(QObject* parent) ApplicationModels::~ApplicationModels() = default; -DocumentModel* ApplicationModels::documentModel() const -{ - return m_documentModel; -} - MaterialModel* ApplicationModels::materialModel() const { return m_materialModel; @@ -85,9 +76,6 @@ JobModel* ApplicationModels::jobModel() const //! reset all models to initial state void ApplicationModels::resetModels() { - m_documentModel->clear(); - m_documentModel->insertItem<SimulationOptionsItem>(); - m_materialModel->clear(); m_materialModel->addRefractiveMaterial("Default", 1e-3, 1e-5); m_materialModel->addRefractiveMaterial("Vacuum", 0.0, 0.0); @@ -112,6 +100,11 @@ void ApplicationModels::readFrom(QXmlStreamReader* reader, MessageService* messa { try { for (auto* model : modelList()) { + if (reader->name().toString() == "DocumentModel") { + reader->skipCurrentElement(); + break; + } + if (model->getModelTag() == reader->name()) { model->readFrom(reader, messageService); break; @@ -128,7 +121,6 @@ void ApplicationModels::readFrom(QXmlStreamReader* reader, MessageService* messa QList<SessionModel*> ApplicationModels::modelList() { QList<SessionModel*> result; - result.append(m_documentModel); result.append(m_materialModel); result.append(m_instrumentModel); result.append(m_sampleModel); diff --git a/GUI/Model/Data/ApplicationModels.h b/GUI/Model/Data/ApplicationModels.h index 765a37afcbe361a71ab4bf6d52606efefaa896bf..500878004c388283e94dbb82740d7c2f2c3612dc 100644 --- a/GUI/Model/Data/ApplicationModels.h +++ b/GUI/Model/Data/ApplicationModels.h @@ -33,7 +33,6 @@ public: explicit ApplicationModels(QObject* parent = nullptr); ~ApplicationModels() override; - DocumentModel* documentModel() const; MaterialModel* materialModel() const; InstrumentModel* instrumentModel() const; SampleModel* sampleModel() const; diff --git a/GUI/Model/Data/DocumentModel.cpp b/GUI/Model/Data/DocumentModel.cpp deleted file mode 100644 index 7242015754ed82bbb9ede95cbb47a13dd1e32fc4..0000000000000000000000000000000000000000 --- a/GUI/Model/Data/DocumentModel.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/Model/Data/DocumentModel.cpp -//! @brief Implements class DocumentModel -//! -//! @homepage http://www.bornagainproject.org -//! @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) -// -// ************************************************************************************************ - -#include "GUI/Model/Data/DocumentModel.h" -#include "GUI/Model/Session/SimulationOptionsItem.h" - -DocumentModel::DocumentModel(QObject* parent) - : SessionModel(GUI::Session::XML::DocumentModelTag, parent) -{ - setObjectName(GUI::Session::XML::DocumentModelTag); -} - -SimulationOptionsItem* DocumentModel::simulationOptionsItem() -{ - return topItem<SimulationOptionsItem>(); -} diff --git a/GUI/Model/Data/DocumentModel.h b/GUI/Model/Data/DocumentModel.h deleted file mode 100644 index c8b2afb0328a602d05bb12d688be2c0529a85372..0000000000000000000000000000000000000000 --- a/GUI/Model/Data/DocumentModel.h +++ /dev/null @@ -1,34 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/Model/Data/DocumentModel.h -//! @brief Defines class DocumentModel -//! -//! @homepage http://www.bornagainproject.org -//! @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) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI_MODEL_DATA_DOCUMENTMODEL_H -#define BORNAGAIN_GUI_MODEL_DATA_DOCUMENTMODEL_H - -#include "GUI/Model/Session/SessionModel.h" - -class SimulationOptionsItem; - -//! The DocumentModel class is a model with GUI settings related to the opened project. -//! Can be the place to store splitter position, etc. - -class DocumentModel : public SessionModel { - Q_OBJECT - -public: - explicit DocumentModel(QObject* parent = nullptr); - - SimulationOptionsItem* simulationOptionsItem(); -}; - -#endif // BORNAGAIN_GUI_MODEL_DATA_DOCUMENTMODEL_H diff --git a/GUI/Model/From/GUIObjectBuilder.cpp b/GUI/Model/From/GUIObjectBuilder.cpp index 4b27e01397cd5e6a14edab15b319a4564c74d8fb..499ba1ffe608ad0506580e0ba1ca9b39f3b067dd 100644 --- a/GUI/Model/From/GUIObjectBuilder.cpp +++ b/GUI/Model/From/GUIObjectBuilder.cpp @@ -16,11 +16,10 @@ #include "Base/Const/Units.h" #include "Base/Util/Assert.h" #include "Core/Simulation/includeSimulations.h" -#include "GUI/Model/Data/DocumentModel.h" #include "GUI/Model/From/FromDomain.h" +#include "GUI/Model/From/GUIDomainSampleVisitor.h" #include "GUI/Model/Instrument/InstrumentItems.h" #include "GUI/Model/Instrument/InstrumentModel.h" -#include "GUI/Model/From/GUIDomainSampleVisitor.h" #include "GUI/Model/Session/SimulationOptionsItem.h" #include "Resample/Options/SimulationOptions.h" @@ -93,18 +92,15 @@ SessionItem* GUI::Model::ObjectBuilder::populateInstrumentModel(InstrumentModel* ASSERT(0); } -SessionItem* GUI::Model::ObjectBuilder::populateDocumentModel(DocumentModel* p_document_model, - const ISimulation& simulation) +void GUI::Model::ObjectBuilder::populateSimulationOptions(SimulationOptionsItem* item, + const ISimulation& simulation) { - auto* item = p_document_model->insertItem<SimulationOptionsItem>(); - if (simulation.options().isIntegrate()) - item->setUseMonteCarloIntegration(static_cast<int>(simulation.options().getMcPoints())); + item->setUseMonteCarloIntegration( + static_cast<unsigned>(simulation.options().getMcPoints())); else item->setUseAnalytical(); item->setUseAverageMaterials(simulation.options().useAvgMaterials()); item->setIncludeSpecularPeak(simulation.options().includeSpecular()); - - return item; } diff --git a/GUI/Model/From/GUIObjectBuilder.h b/GUI/Model/From/GUIObjectBuilder.h index 877bf3deb767f06619147167392f3ee598ec7944..44cbc403922f5cf904dde5f98fc147a21acf975c 100644 --- a/GUI/Model/From/GUIObjectBuilder.h +++ b/GUI/Model/From/GUIObjectBuilder.h @@ -17,7 +17,7 @@ #include <QString> -class DocumentModel; +class SimulationOptionsItem; class ISimulation; class InstrumentModel; class MaterialModel; @@ -33,7 +33,7 @@ SessionItem* populateInstrumentModel(InstrumentModel* p_instrument_model, const ISimulation& simulation, const QString& instrument_name = ""); -SessionItem* populateDocumentModel(DocumentModel* p_document_model, const ISimulation& simulation); +void populateSimulationOptions(SimulationOptionsItem* item, const ISimulation& simulation); } // namespace GUI::Model::ObjectBuilder diff --git a/GUI/Model/Group/ItemCatalog.cpp b/GUI/Model/Group/ItemCatalog.cpp index bf0b112236cd491062ac8264fe81de9fe49c17f6..9b9a3c560caecbb5502be6ffb828374757307dbc 100644 --- a/GUI/Model/Group/ItemCatalog.cpp +++ b/GUI/Model/Group/ItemCatalog.cpp @@ -309,8 +309,6 @@ ItemCatalog::ItemCatalog() addItem<FitParameterLinkItem>(); addItem<FitSuiteItem>(); - addItem<SimulationOptionsItem>(); - addItem<RealDataItem>(); addItem<MinimizerContainerItem>(); diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp index 0fd79ad1bbf1ee24f461639d32b3f59119b0e11f..0e17b686d37d127f9051a79159c1425c8b94f74b 100644 --- a/GUI/Model/Job/JobItem.cpp +++ b/GUI/Model/Job/JobItem.cpp @@ -28,6 +28,11 @@ #include "GUI/Model/Session/SimulationOptionsItem.h" #include "GUI/Util/Error.h" +namespace { +const QString SimulationOptionsTag("SimulationOptions"); +} // namespace + + JobItem::JobItem() : SessionItem(M_TYPE) { setItemName(M_TYPE); @@ -55,8 +60,6 @@ JobItem::JobItem() : SessionItem(M_TYPE) registerTag(T_DATAVIEW, 1, 1, {Data1DViewItem::M_TYPE}); registerTag(T_PARAMETER_TREE, 0, -1, {ParameterContainerItem::M_TYPE}); - registerTag(T_SIMULATION_OPTIONS, 1, 1, {SimulationOptionsItem::M_TYPE}); - registerTag(T_FIT_SUITE, 1, 1, {FitSuiteItem::M_TYPE}); mapper()->setOnChildPropertyChange([this](SessionItem* item, const QString& name) { @@ -224,12 +227,12 @@ bool JobItem::isProgressPropertyName(const QString& name) bool JobItem::runImmediately() const { - return simulationOptionsItem()->runImmediately(); + return simulationOptionsItem().runImmediately(); } bool JobItem::runInBackground() const { - return simulationOptionsItem()->runInBackground(); + return simulationOptionsItem().runInBackground(); } MultiLayerItem* JobItem::sampleItem() @@ -378,6 +381,22 @@ void JobItem::setPresentationType(const QString& type) setItemValue(P_PRESENTATION_TYPE, type); } +void JobItem::writeNonSessionItems(QXmlStreamWriter* writer) const +{ + writer->writeStartElement(SimulationOptionsTag); + m_simulationOptionsItem.writeContentTo(writer); + writer->writeEndElement(); +} + +void JobItem::readNonSessionItems(QXmlStreamReader* reader) +{ + reader->readNextStartElement(); + if (reader->name() == SimulationOptionsTag) { + m_simulationOptionsItem.readContentFrom(reader); + reader->skipCurrentElement(); + } +} + //! Updates the name of file to store intensity data. void JobItem::updateIntensityDataFileName() @@ -394,18 +413,12 @@ void JobItem::updateIntensityDataFileName() } } -SimulationOptionsItem* JobItem::simulationOptionsItem() -{ - return const_cast<SimulationOptionsItem*>( - static_cast<const JobItem*>(this)->simulationOptionsItem()); -} - -const SimulationOptionsItem* JobItem::simulationOptionsItem() const +const SimulationOptionsItem& JobItem::simulationOptionsItem() const { - return item<const SimulationOptionsItem>(T_SIMULATION_OPTIONS); + return m_simulationOptionsItem; } -SimulationOptionsItem* JobItem::copySimulationOptionsIntoJob(const SimulationOptionsItem* options) +void JobItem::copySimulationOptionsIntoJob(const SimulationOptionsItem& options) { - return model()->copyItem(options, this, T_SIMULATION_OPTIONS); + m_simulationOptionsItem = options; } diff --git a/GUI/Model/Job/JobItem.h b/GUI/Model/Job/JobItem.h index af3cd9677020e021bd5863a7e1d361a0d1a00c7d..16d34064e0ec0db3afcdfa3d88cedf3d44008d44 100644 --- a/GUI/Model/Job/JobItem.h +++ b/GUI/Model/Job/JobItem.h @@ -15,10 +15,12 @@ #ifndef BORNAGAIN_GUI_MODEL_JOB_JOBITEM_H #define BORNAGAIN_GUI_MODEL_JOB_JOBITEM_H +#include "GUI/Model/Job/JobStatus.h" // enum cannot be forward declared #include "GUI/Model/Session/SessionItem.h" - -#include "GUI/Model/Job/JobStatus.h" // enum cannot be forward declared #include "GUI/Model/Session/SessionModel.h" // call to model() from templated fct +#include "GUI/Model/Session/SimulationOptionsItem.h" +#include <QDateTime> +#include <optional> class Data1DViewItem; class DataItem; @@ -34,9 +36,6 @@ class ParameterContainerItem; class RealDataItem; class SimulationOptionsItem; -#include <QDateTime> -#include <optional> - class BA_CORE_API_ JobItem : public SessionItem { private: @@ -57,7 +56,6 @@ private: static constexpr auto T_REALDATA{"Real Data tag"}; static constexpr auto T_DATAVIEW{"Data View tag"}; static constexpr auto T_PARAMETER_TREE{"Parameter tree tag"}; - static constexpr auto T_SIMULATION_OPTIONS{"Simulation options tag"}; static constexpr auto T_FIT_SUITE{"Fit suite tag"}; public: @@ -114,8 +112,8 @@ public: InstrumentItem* instrumentItem() const; InstrumentItem* copyInstrumentIntoJob(const InstrumentItem* instrument); - SimulationOptionsItem* simulationOptionsItem(); - SimulationOptionsItem* copySimulationOptionsIntoJob(const SimulationOptionsItem* options); + const SimulationOptionsItem& simulationOptionsItem() const; + void copySimulationOptionsIntoJob(const SimulationOptionsItem& options); void setResults(const ISimulation* simulation); @@ -148,9 +146,13 @@ public: QString presentationType() const; void setPresentationType(const QString& type); + void writeNonSessionItems(QXmlStreamWriter* writer) const override; + void readNonSessionItems(QXmlStreamReader* reader) override; + private: void updateIntensityDataFileName(); - const SimulationOptionsItem* simulationOptionsItem() const; + + SimulationOptionsItem m_simulationOptionsItem; }; template <typename T> T* JobItem::setDataType() diff --git a/GUI/Model/Job/JobModel.cpp b/GUI/Model/Job/JobModel.cpp index 1d710658abb73594c7acee37c1d08ef4b959dc6b..34c0f14ba4190c7fca2dc30c33f94d8a1e67a220 100644 --- a/GUI/Model/Job/JobModel.cpp +++ b/GUI/Model/Job/JobModel.cpp @@ -69,11 +69,10 @@ JobItem* JobModel::getJobItemForIdentifier(const QString& identifier) //! Main method to add a job JobItem* JobModel::addJob(const MultiLayerItem* multiLayerItem, const InstrumentItem* instrumentItem, const RealDataItem* realDataItem, - const SimulationOptionsItem* optionItem) + const SimulationOptionsItem& optionItem) { ASSERT(multiLayerItem); ASSERT(instrumentItem); - ASSERT(optionItem); auto* jobItem = insertItem<JobItem>(); jobItem->setItemName(generateJobName()); diff --git a/GUI/Model/Job/JobModel.h b/GUI/Model/Job/JobModel.h index b11a3a3d597521793d5a5de8f05437dd80f8e753..62fea049428a533ef028e3a2ae867e0dd65b8a99 100644 --- a/GUI/Model/Job/JobModel.h +++ b/GUI/Model/Job/JobModel.h @@ -36,7 +36,7 @@ public: JobItem* getJobItemForIdentifier(const QString& identifier); JobItem* addJob(const MultiLayerItem* multiLayerItem, const InstrumentItem* instrumentItem, - const RealDataItem* realDataItem, const SimulationOptionsItem* optionItem); + const RealDataItem* realDataItem, const SimulationOptionsItem& optionItem); QVector<JobItem*> jobItems() const; diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp index 03eafdb077435c35edb53daa342ec2294c7657b0..c18aa8d4c37839e4f781a7cf75136d33f1bcf481 100644 --- a/GUI/Model/Project/ProjectDocument.cpp +++ b/GUI/Model/Project/ProjectDocument.cpp @@ -13,11 +13,11 @@ // ************************************************************************************************ #include "GUI/Model/Project/ProjectDocument.h" -#include "GUI/Model/Data/DocumentModel.h" #include "GUI/Model/IO/ProjectUtils.h" #include "GUI/Model/Instrument/LinkInstrumentManager.h" #include "GUI/Model/Job/JobModel.h" #include "GUI/Model/Project/OutputDataIOService.h" +#include "GUI/Model/Session/SimulationOptionsItem.h" #include "GUI/Util/Error.h" #include "GUI/Util/MessageService.h" #include "GUI/Util/Path.h" @@ -34,6 +34,7 @@ const QString BornAgainTag("BornAgain"); const QString BornAgainVersionAttribute("Version"); const QString InfoTag("DocumentInfo"); const QString InfoNameAttribute("ProjectName"); +const QString SimulationOptionsTag("SimulationOptions"); } // namespace @@ -133,9 +134,9 @@ JobModel* ProjectDocument::jobModel() const return m_applicationModels.jobModel(); } -SimulationOptionsItem* ProjectDocument::simulationOptionsItem() const +SimulationOptionsItem* ProjectDocument::simulationOptionsItem() { - return m_applicationModels.documentModel()->simulationOptionsItem(); + return &m_simulationOptionsItem; } LinkInstrumentManager* ProjectDocument::linkInstrumentManager() @@ -318,7 +319,10 @@ ProjectDocument::ReadResult ProjectDocument::readProject(QIODevice* device, while (reader.readNextStartElement()) if (reader.name() == InfoTag) reader.skipCurrentElement(); - else + else if (reader.name() == SimulationOptionsTag) { + m_simulationOptionsItem.readContentFrom(&reader); + reader.skipCurrentElement(); + } else m_applicationModels.readFrom(&reader, &messageService); } } @@ -348,6 +352,10 @@ void ProjectDocument::writeTo(QIODevice* device) writer.writeAttribute(InfoNameAttribute, projectName()); writer.writeEndElement(); // InfoTag + writer.writeStartElement(SimulationOptionsTag); + m_simulationOptionsItem.writeContentTo(&writer); + writer.writeEndElement(); + m_applicationModels.writeTo(&writer); writer.writeEndElement(); // BornAgain tag diff --git a/GUI/Model/Project/ProjectDocument.h b/GUI/Model/Project/ProjectDocument.h index 4ffac40b4b848ef32a5827d9e1efb0746b3e4594..fcac92afdac9cd0fdf9df828365b6b2a4ec129fe 100644 --- a/GUI/Model/Project/ProjectDocument.h +++ b/GUI/Model/Project/ProjectDocument.h @@ -16,6 +16,7 @@ #define BORNAGAIN_GUI_MODEL_PROJECT_PROJECTDOCUMENT_H #include "GUI/Model/Data/ApplicationModels.h" +#include "GUI/Model/Session/SimulationOptionsItem.h" #include <QObject> #include <QVariant> #include <memory> @@ -74,7 +75,7 @@ public: MaterialModel* materialModel() const; RealDataModel* realDataModel() const; JobModel* jobModel() const; - SimulationOptionsItem* simulationOptionsItem() const; + SimulationOptionsItem* simulationOptionsItem(); LinkInstrumentManager* linkInstrumentManager(); @@ -134,6 +135,7 @@ private: bool m_singleInstrumentMode; bool m_singleSampleMode; Functionalities m_functionalities; + SimulationOptionsItem m_simulationOptionsItem; }; Q_DECLARE_OPERATORS_FOR_FLAGS(ProjectDocument::Functionalities) diff --git a/GUI/Model/Session/SessionItem.cpp b/GUI/Model/Session/SessionItem.cpp index f6a8c9d47645a687888c58b39949271f1a59f801..eb8fed9b6a5bb09cf5d29e29ecee48794abf1769 100644 --- a/GUI/Model/Session/SessionItem.cpp +++ b/GUI/Model/Session/SessionItem.cpp @@ -335,9 +335,7 @@ QVariant SessionItem::roleProperty(int role) const bool SessionItem::setRoleProperty(int role, const QVariant& value) { - bool result = m_properties->setData(role, m_translatorForRolePropertySetter - ? m_translatorForRolePropertySetter(role, value) - : value); + bool result = m_properties->setData(role, value); if (result) emitDataChanged(role); return result; @@ -541,10 +539,9 @@ QByteArray SessionItem::serializeBinaryData() const void SessionItem::deserializeBinaryData(const QByteArray&) {} -void SessionItem::setTranslatorForRolePropertySetter(TranslatorForRolePropertySetter translator) -{ - m_translatorForRolePropertySetter = translator; -} +void SessionItem::writeNonSessionItems(QXmlStreamWriter*) const {} + +void SessionItem::readNonSessionItems(QXmlStreamReader*) {} void SessionItem::childDeleted(SessionItem* child) { diff --git a/GUI/Model/Session/SessionItem.h b/GUI/Model/Session/SessionItem.h index e753ce9394f9dd383166dbca41b46bcb0baa9e96..eef243f3d9c0268edab060943191d6da92a3400a 100644 --- a/GUI/Model/Session/SessionItem.h +++ b/GUI/Model/Session/SessionItem.h @@ -207,8 +207,6 @@ private: static constexpr auto P_NAME{"Name"}; public: - using TranslatorForRolePropertySetter = std::function<QVariant(int, const QVariant&)>; - explicit SessionItem(const QString& modelType); virtual ~SessionItem(); SessionModel* model() const; @@ -314,24 +312,8 @@ public: virtual QByteArray serializeBinaryData() const; virtual void deserializeBinaryData(const QByteArray& data); - //! Set a translation function which shall be called when a property is to be set via - //! setRoleProperty. Use this e.g. when the type of a property changed, and it should be - //! readable by legacy XML. Example: Property P_TRUE_OR_FALSE was a ComboProperty ("true", - //! "false") and is now a bool property. To still be able to read legacy XML project files, your - //! code could look like this: - //! - //! \code - //! - //! auto p = addProperty(P_TRUE_OR_FALSE, true); - //! p->->setTranslatorForRolePropertySetter([](int role, const QVariant& value) { - //! if (role == Qt::DisplayRole && value.canConvert<ComboProperty>()) - //! return QVariant(value.value<ComboProperty>().currentIndex() == 0); // 0->"true" - //! return value; - //! }); - //! - //! \endcode - //! - void setTranslatorForRolePropertySetter(TranslatorForRolePropertySetter translator); + virtual void writeNonSessionItems(QXmlStreamWriter* writer) const; + virtual void readNonSessionItems(QXmlStreamReader* reader); private: void childDeleted(SessionItem* child); @@ -347,7 +329,6 @@ private: std::unique_ptr<SessionItemData> m_properties; std::unique_ptr<SessionItemTags> m_tags; std::unique_ptr<ModelMapper> m_mapper; - TranslatorForRolePropertySetter m_translatorForRolePropertySetter; }; template <typename T> T* SessionItem::item(const QString& tag) const diff --git a/GUI/Model/Session/SessionModel.cpp b/GUI/Model/Session/SessionModel.cpp index dad544ad56919f23a71a5acd661c968bf6c578fd..462da433a6f5fb0aafede8b3d28d851891233a73 100644 --- a/GUI/Model/Session/SessionModel.cpp +++ b/GUI/Model/Session/SessionModel.cpp @@ -382,11 +382,9 @@ void SessionModel::readFrom(QXmlStreamReader* reader, MessageService* messageSer endResetModel(); } -void SessionModel::writeTo(QXmlStreamWriter* writer, SessionItem* parent) +void SessionModel::writeTo(QXmlStreamWriter* writer) { - if (!parent) - parent = m_root_item; - GUI::Session::XML::writeTo(writer, parent); + GUI::Session::XML::writeTo(writer, m_root_item); } //! Move given parameterized item to the new_parent at given row. If new_parent is not defined, diff --git a/GUI/Model/Session/SessionModel.h b/GUI/Model/Session/SessionModel.h index 6303ad9ae586d7a2bf55ee00f56a412352ce3abc..8c8b61af6063fb86eb3f68b5970fc5c3b2100c4d 100644 --- a/GUI/Model/Session/SessionModel.h +++ b/GUI/Model/Session/SessionModel.h @@ -99,7 +99,7 @@ public: SessionItem* itemForIndex(const QModelIndex& index) const; virtual void readFrom(QXmlStreamReader* reader, MessageService* messageService = nullptr); - virtual void writeTo(QXmlStreamWriter* writer, SessionItem* parent = nullptr); + virtual void writeTo(QXmlStreamWriter* writer); SessionItem* moveItem(SessionItem* item, SessionItem* new_parent = nullptr, int row = -1, const QString& tag = ""); diff --git a/GUI/Model/Session/SessionXML.cpp b/GUI/Model/Session/SessionXML.cpp index 3947af9a1b38a94597a81f54d32e11fd3a9f982f..4d17697f591bcf7adfb1d044158fbc5a2d43ced9 100644 --- a/GUI/Model/Session/SessionXML.cpp +++ b/GUI/Model/Session/SessionXML.cpp @@ -25,12 +25,6 @@ namespace { -const QString bool_type_name = "bool"; -const QString double_type_name = "double"; -const QString int_type_name = "int"; -const QString uint_type_name = "uint"; -const QString qstring_type_name = "QString"; - void report_error(MessageService* messageService, SessionItem* item, const QString& message) { if (!messageService) @@ -99,48 +93,58 @@ void GUI::Session::XML::writeItemAndChildItems(QXmlStreamWriter* writer, const S writer->writeEndElement(); } + QString nonSessionItemContent; + QXmlStreamWriter nonSessionItemStream(&nonSessionItemContent); + item->writeNonSessionItems(&nonSessionItemStream); + if (!nonSessionItemContent.isEmpty()) { + writer->writeStartElement(GUI::Session::XML::NonSessionItemData); + writer->writeAttribute(GUI::Session::XML::Version, "1"); + item->writeNonSessionItems(writer); + writer->writeEndElement(); + } + if (item->parent()) writer->writeEndElement(); // ItemTag } +void GUI::Session::XML::writeAttribute(QXmlStreamWriter* writer, const QString& attributeName, + const QVariant& variant) +{ + ASSERT(writer); + ASSERT(variant.isValid()); + + if (variant.type() == QVariant::Double) { + writer->writeAttribute(attributeName, QString::number(variant.toDouble(), 'e', 12)); + } else if (variant.type() == QVariant::Int) { + writer->writeAttribute(attributeName, QString::number(variant.toInt())); + } else if (variant.type() == QVariant::UInt) { + writer->writeAttribute(attributeName, QString::number(variant.toUInt())); + } else if (variant.type() == QVariant::Bool) { + writer->writeAttribute(attributeName, QString::number(variant.toBool())); + } else if (variant.type() == QVariant::String) { + writer->writeAttribute(attributeName, variant.toString()); + } else if (variant.type() == QVariant::Color) { + const auto col = variant.value<QColor>(); + const QString tcol = col.isValid() ? col.name(QColor::HexArgb) : ""; + writer->writeAttribute(attributeName, tcol); + } else if (QString(variant.typeName()) == "ComboProperty") { + auto combo = variant.value<ComboProperty>(); + writer->writeAttribute(attributeName, combo.stringOfSelections()); + writer->writeAttribute(GUI::Session::XML::ParameterExtAttribute, combo.stringOfValues()); + + } else + throw Error("GUI::Session::XML::writeVariant: Parameter type not supported " + + QString(variant.typeName())); +} + void GUI::Session::XML::writeVariant(QXmlStreamWriter* writer, QVariant variant, int role) { ASSERT(writer); if (variant.isValid()) { writer->writeStartElement(GUI::Session::XML::ParameterTag); - QString type_name = variant.typeName(); - writer->writeAttribute(GUI::Session::XML::ParameterTypeAttribute, type_name); + writer->writeAttribute(GUI::Session::XML::ParameterTypeAttribute, variant.typeName()); writer->writeAttribute(GUI::Session::XML::ParameterRoleAttribute, QString::number(role)); - - if (type_name == double_type_name) { - writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, - QString::number(variant.toDouble(), 'e', 12)); - } else if (type_name == int_type_name) { - writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, - QString::number(variant.toInt())); - } else if (type_name == uint_type_name) { - writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, - QString::number(variant.toUInt())); - } else if (type_name == bool_type_name) { - writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, - QString::number(variant.toBool())); - } else if (type_name == qstring_type_name) { - writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, variant.toString()); - } else if (type_name == "QColor") { - const auto col = variant.value<QColor>(); - const QString tcol = col.isValid() ? col.name(QColor::HexArgb) : ""; - writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, tcol); - } else if (type_name == "ComboProperty") { - auto combo = variant.value<ComboProperty>(); - writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, - combo.stringOfSelections()); - writer->writeAttribute(GUI::Session::XML::ParameterExtAttribute, - combo.stringOfValues()); - - } else - throw Error("GUI::Session::XML::writeVariant: Parameter type not supported " - + type_name); - + writeAttribute(writer, GUI::Session::XML::ParameterValueAttribute, variant); writer->writeEndElement(); // end ParameterTag } } @@ -206,6 +210,11 @@ void GUI::Session::XML::readItems(QXmlStreamReader* reader, SessionItem* parent, parent->deserializeBinaryData(data); } else throw DeserializationException::tooNew(); + } else if (reader->name() == GUI::Session::XML::NonSessionItemData) { + if (reader->attributes().value(GUI::Session::XML::Version).toInt() == 1) + parent->readNonSessionItems(reader); + else + throw DeserializationException::tooNew(); } } else if (reader->isEndElement()) { if (reader->name() == GUI::Session::XML::ItemTag && parent) @@ -234,23 +243,23 @@ QString GUI::Session::XML::readProperty(QXmlStreamReader* reader, SessionItem* i } QVariant variant; - if (parameter_type == double_type_name) { + if (parameter_type == "double") { double parameter_value = reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toDouble(); variant = parameter_value; - } else if (parameter_type == int_type_name) { + } else if (parameter_type == "int") { int parameter_value = reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toInt(); variant = parameter_value; - } else if (parameter_type == uint_type_name) { + } else if (parameter_type == "uint") { unsigned parameter_value = reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toUInt(); variant = parameter_value; - } else if (parameter_type == bool_type_name) { + } else if (parameter_type == "bool") { bool parameter_value = reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toInt(); variant = parameter_value; - } else if (parameter_type == qstring_type_name) { + } else if (parameter_type == "QString") { QString parameter_value = reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toString(); variant = parameter_value; @@ -305,3 +314,14 @@ QString GUI::Session::XML::readProperty(QXmlStreamReader* reader, SessionItem* i return parameter_name; } + +bool GUI::Session::XML::readBoolAttribute(QXmlStreamReader* reader, const QString& attributeName) +{ + return reader->attributes().value(attributeName).toUInt() != 0; +} + +unsigned GUI::Session::XML::readUIntAttribute(QXmlStreamReader* reader, + const QString& attributeName) +{ + return reader->attributes().value(attributeName).toUInt(); +} diff --git a/GUI/Model/Session/SessionXML.h b/GUI/Model/Session/SessionXML.h index 776c4162f05662d812e9e8b71a72a4978ebdea0b..e97bf7b2d3459bb9b4f778fe59a4f5cd1953a3a2 100644 --- a/GUI/Model/Session/SessionXML.h +++ b/GUI/Model/Session/SessionXML.h @@ -42,6 +42,7 @@ const QString ModelTypeAttribute("ModelType"); const QString DisplayNameAttribute("DisplayName"); const QString ParameterTag("Parameter"); const QString BinaryData("BinaryData"); +const QString NonSessionItemData("NonSessionItemData"); const QString Version("Version"); const QString ParameterNameAttribute("ParName"); const QString ParameterTypeAttribute("ParType"); @@ -54,13 +55,22 @@ const QString ExternalPropertyIdentifierAtt("Identifier"); void writeTo(QXmlStreamWriter* writer, SessionItem* parent); void writeItemAndChildItems(QXmlStreamWriter* writer, const SessionItem* item); + +//! Write the variant as a complete tag, including the given role void writeVariant(QXmlStreamWriter* writer, QVariant variant, int role); +//! Write the variant's value as an attribute +void writeAttribute(QXmlStreamWriter* writer, const QString& attributeName, + const QVariant& variant); + void readItems(QXmlStreamReader* reader, SessionItem* parent, QString topTag = "", MessageService* messageService = nullptr); QString readProperty(QXmlStreamReader* reader, SessionItem* item, MessageService* messageService = nullptr); +bool readBoolAttribute(QXmlStreamReader* reader, const QString& attributeName); +unsigned readUIntAttribute(QXmlStreamReader* reader, const QString& attributeName); + } // namespace GUI::Session::XML #endif // BORNAGAIN_GUI_MODEL_SESSION_SESSIONXML_H diff --git a/GUI/Model/Session/SimulationOptionsItem.cpp b/GUI/Model/Session/SimulationOptionsItem.cpp index ba2bb9f55fb6bb40572b25dea237d4b477927cf0..516f863be28f4c76e7cbdb01e755434d0089ec9a 100644 --- a/GUI/Model/Session/SimulationOptionsItem.cpp +++ b/GUI/Model/Session/SimulationOptionsItem.cpp @@ -13,80 +13,47 @@ // ************************************************************************************************ #include "GUI/Model/Session/SimulationOptionsItem.h" -#include "GUI/Util/ComboProperty.h" +#include "GUI/Model/Session/SessionXML.h" +#include "GUI/Util/DeserializationException.h" +#include <QXmlStreamWriter> #include <thread> -// !! Attention !! Do not change the following texts, despite they are not matching the -// constants! They are used for file loading => keep stable! +namespace { +namespace Tags { +const QString RunImmediately("RunImmediately"); +const QString NumberOfThreads("NumberOfThreads"); +const QString Analytical("Analytical"); +const QString NumberOfMonteCarloPoints("NumberOfMonteCarloPoints"); +const QString UseAverageMaterials("UseAverageMaterials"); +const QString IncludeSpecularPeak("IncludeSpecularPeak"); +} // namespace Tags +} // namespace -SimulationOptionsItem::SimulationOptionsItem() : SessionItem(M_TYPE) -{ - addProperty(P_RUN_IMMEDIATELY, true); - addProperty(P_NTHREADS, static_cast<int>(std::thread::hardware_concurrency())); - addProperty(P_COMPUTATION_METHOD_ANALYTICAL, true); - addProperty(P_MC_POINTS, 100)->setEnabled(false); - addProperty(P_AVERAGE_MATERIAL, false); - addProperty(P_INCLUDE_SPECULAR_PEAK, false); - - // -- add translators for legacy XML reading - - getItem(P_RUN_IMMEDIATELY) - ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) { - if (role == Qt::DisplayRole && value.canConvert<ComboProperty>()) - return QVariant(value.value<ComboProperty>().currentIndex() - == 0); // 0 was "immediately" - return value; - }); - - getItem(P_NTHREADS)->setTranslatorForRolePropertySetter([](int role, const QVariant& value) { - if (role == Qt::DisplayRole && value.canConvert<ComboProperty>()) { - // first item was nThreads. Number of max threads has to be - // read from value, not from current machine's capabilities - const auto comboProperty = value.value<ComboProperty>(); - const int nThreads = comboProperty.getValues().size(); - const int selectedThreads = nThreads - comboProperty.currentIndex(); - return QVariant(selectedThreads); - } - return value; - }); - - getItem(P_COMPUTATION_METHOD_ANALYTICAL) - ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) { - if (role == Qt::DisplayRole && value.canConvert<ComboProperty>()) - return QVariant(value.value<ComboProperty>().currentIndex() - == 0); // 0 was "Analytical" - return value; - }); +using namespace GUI::Session::XML; - getItem(P_AVERAGE_MATERIAL) - ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) { - if (role == Qt::DisplayRole && value.canConvert<ComboProperty>()) - return QVariant(value.value<ComboProperty>().currentIndex() - == 1); // 1 was "Average" - return value; - }); - - getItem(P_INCLUDE_SPECULAR_PEAK) - ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) { - if (role == Qt::DisplayRole && value.canConvert<ComboProperty>()) - return QVariant(value.value<ComboProperty>().currentIndex() == 1); // 1 was "Yes" - return value; - }); +SimulationOptionsItem::SimulationOptionsItem() +{ + m_runImmediately = true; + m_numberOfThreads = std::thread::hardware_concurrency(); + m_computationMethodAnalytical = true; + m_numberOfMonteCarloPoints = 100; + m_useAverageMaterials = false; + m_includeSpecularPeak = false; } -int SimulationOptionsItem::numberOfThreads() const +unsigned SimulationOptionsItem::numberOfThreads() const { - return getItemValue(P_NTHREADS).toInt(); + return m_numberOfThreads; } -void SimulationOptionsItem::setNumberOfThreads(int number) +void SimulationOptionsItem::setNumberOfThreads(unsigned number) { - setItemValue(P_NTHREADS, number); + m_numberOfThreads = number; } bool SimulationOptionsItem::runImmediately() const { - return getItemValue(P_RUN_IMMEDIATELY).toBool(); + return m_runImmediately; } bool SimulationOptionsItem::runInBackground() const @@ -96,18 +63,18 @@ bool SimulationOptionsItem::runInBackground() const void SimulationOptionsItem::setRunImmediately(bool runImmediately) { - setItemValue(P_RUN_IMMEDIATELY, runImmediately); + m_runImmediately = runImmediately; } -void SimulationOptionsItem::setUseMonteCarloIntegration(int numberOfPoints) +void SimulationOptionsItem::setUseMonteCarloIntegration(unsigned numberOfPoints) { - setItemValue(P_COMPUTATION_METHOD_ANALYTICAL, false); - setNumberOfMonteCarloPoints(numberOfPoints); + m_computationMethodAnalytical = false; + m_numberOfMonteCarloPoints = numberOfPoints; } void SimulationOptionsItem::setUseAnalytical() { - setItemValue(P_COMPUTATION_METHOD_ANALYTICAL, true); + m_computationMethodAnalytical = true; } bool SimulationOptionsItem::useMonteCarloIntegration() const @@ -117,35 +84,59 @@ bool SimulationOptionsItem::useMonteCarloIntegration() const bool SimulationOptionsItem::useAnalytical() const { - return getItemValue(P_COMPUTATION_METHOD_ANALYTICAL).toBool(); -} - -int SimulationOptionsItem::numberOfMonteCarloPoints() const -{ - return getItemValue(P_MC_POINTS).toInt(); + return m_computationMethodAnalytical; } -void SimulationOptionsItem::setNumberOfMonteCarloPoints(int npoints) +unsigned SimulationOptionsItem::numberOfMonteCarloPoints() const { - setItemValue(P_MC_POINTS, npoints); + return m_numberOfMonteCarloPoints; } void SimulationOptionsItem::setUseAverageMaterials(bool useAverageMaterials) { - setItemValue(P_AVERAGE_MATERIAL, useAverageMaterials); + m_useAverageMaterials = useAverageMaterials; } bool SimulationOptionsItem::useAverageMaterials() const { - return getItemValue(P_AVERAGE_MATERIAL).toBool(); + return m_useAverageMaterials; } void SimulationOptionsItem::setIncludeSpecularPeak(bool includeSpecularPeak) { - setItemValue(P_INCLUDE_SPECULAR_PEAK, includeSpecularPeak); + m_includeSpecularPeak = includeSpecularPeak; } bool SimulationOptionsItem::includeSpecularPeak() const { - return getItemValue(P_INCLUDE_SPECULAR_PEAK).toBool(); + return m_includeSpecularPeak; +} + +void SimulationOptionsItem::writeContentTo(QXmlStreamWriter* writer) const +{ + writeAttribute(writer, GUI::Session::XML::Version, int(1)); + writeAttribute(writer, Tags::RunImmediately, m_runImmediately); + writeAttribute(writer, Tags::NumberOfThreads, m_numberOfThreads); + writeAttribute(writer, Tags::Analytical, m_computationMethodAnalytical); + writeAttribute(writer, Tags::NumberOfMonteCarloPoints, m_numberOfMonteCarloPoints); + writeAttribute(writer, Tags::UseAverageMaterials, m_useAverageMaterials); + writeAttribute(writer, Tags::IncludeSpecularPeak, m_includeSpecularPeak); +} + +void SimulationOptionsItem::readContentFrom(QXmlStreamReader* reader) +{ + const int version = reader->attributes().value(GUI::Session::XML::Version).toInt(); + + if (version < 1) + throw DeserializationException::tooOld(); + + if (version > 1) + throw DeserializationException::tooNew(); + + m_runImmediately = readBoolAttribute(reader, Tags::RunImmediately); + m_numberOfThreads = readUIntAttribute(reader, Tags::NumberOfThreads); + m_computationMethodAnalytical = readBoolAttribute(reader, Tags::Analytical); + m_numberOfMonteCarloPoints = readUIntAttribute(reader, Tags::NumberOfMonteCarloPoints); + m_useAverageMaterials = readBoolAttribute(reader, Tags::UseAverageMaterials); + m_includeSpecularPeak = readBoolAttribute(reader, Tags::IncludeSpecularPeak); } diff --git a/GUI/Model/Session/SimulationOptionsItem.h b/GUI/Model/Session/SimulationOptionsItem.h index 983351aca8e33a24a265cde7c5754f472afa90f8..50b27147e85d0355090c1b464ea2721ae626fc86 100644 --- a/GUI/Model/Session/SimulationOptionsItem.h +++ b/GUI/Model/Session/SimulationOptionsItem.h @@ -15,47 +15,47 @@ #ifndef BORNAGAIN_GUI_MODEL_SESSION_SIMULATIONOPTIONSITEM_H #define BORNAGAIN_GUI_MODEL_SESSION_SIMULATIONOPTIONSITEM_H -#include "GUI/Model/Session/SessionItem.h" -#include <QMap> +class QXmlStreamWriter; +class QXmlStreamReader; //! The SimulationOptionsItem class holds simulation status (run policy, number of threads, //! integration flag). Used in SimulationView to define job settings. When job is started, -//! item is copied to the job as a child. - -class BA_CORE_API_ SimulationOptionsItem : public SessionItem { -private: - static constexpr auto P_RUN_IMMEDIATELY{"Run Policy"}; - static constexpr auto P_NTHREADS{"Number of Threads"}; - static constexpr auto P_COMPUTATION_METHOD_ANALYTICAL{"Computation method"}; - static constexpr auto P_MC_POINTS{"Number of MC points"}; - static constexpr auto P_AVERAGE_MATERIAL{"Material for Fresnel calculations"}; - static constexpr auto P_INCLUDE_SPECULAR_PEAK{"Include specular peak"}; +//! item is copied to the job. +class SimulationOptionsItem { public: - static constexpr auto M_TYPE{"SimulationOptions"}; - explicit SimulationOptionsItem(); - void setNumberOfThreads(int n); - int numberOfThreads() const; + void setNumberOfThreads(unsigned n); + unsigned numberOfThreads() const; void setRunImmediately(bool runImmediately); bool runImmediately() const; bool runInBackground() const; - void setUseMonteCarloIntegration(int numberOfPoints); + void setUseMonteCarloIntegration(unsigned numberOfPoints); void setUseAnalytical(); bool useMonteCarloIntegration() const; bool useAnalytical() const; - void setNumberOfMonteCarloPoints(int npoints); - int numberOfMonteCarloPoints() const; + unsigned numberOfMonteCarloPoints() const; void setUseAverageMaterials(bool useAverageMaterials); bool useAverageMaterials() const; void setIncludeSpecularPeak(bool includeSpecularPeak); bool includeSpecularPeak() const; + + void writeContentTo(QXmlStreamWriter* writer) const; + void readContentFrom(QXmlStreamReader* reader); + +private: + bool m_runImmediately; + unsigned m_numberOfThreads; + bool m_computationMethodAnalytical; + unsigned m_numberOfMonteCarloPoints; + bool m_useAverageMaterials; + bool m_includeSpecularPeak; }; #endif // BORNAGAIN_GUI_MODEL_SESSION_SIMULATIONOPTIONSITEM_H diff --git a/GUI/Model/To/DomainSimulationBuilder.cpp b/GUI/Model/To/DomainSimulationBuilder.cpp index aa516add07cda1200334bc5dbc0686ade6f23103..a358a3812a23cc3d31f8c2b9aaef3cabfe0a49a9 100644 --- a/GUI/Model/To/DomainSimulationBuilder.cpp +++ b/GUI/Model/To/DomainSimulationBuilder.cpp @@ -21,20 +21,20 @@ #include "Core/Simulation/includeSimulations.h" #include "Device/Beam/Beam.h" #include "Device/Beam/IFootprintFactor.h" -#include "Param/Distrib/RangedDistributions.h" -#include "Sample/Multilayer/MultiLayer.h" -#include "Resample/Options/SimulationOptions.h" #include "GUI/Model/Data/AxesItems.h" +#include "GUI/Model/Instrument/BackgroundItems.h" #include "GUI/Model/Instrument/BeamAngleItems.h" #include "GUI/Model/Instrument/BeamItems.h" #include "GUI/Model/Instrument/BeamWavelengthItem.h" -#include "GUI/Model/Instrument/BackgroundItems.h" #include "GUI/Model/Instrument/FootprintItems.h" #include "GUI/Model/Instrument/InstrumentItems.h" #include "GUI/Model/Sample/MultiLayerItem.h" #include "GUI/Model/Session/SimulationOptionsItem.h" #include "GUI/Model/To/DomainObjectBuilder.h" #include "GUI/Util/Error.h" +#include "Param/Distrib/RangedDistributions.h" +#include "Resample/Options/SimulationOptions.h" +#include "Sample/Multilayer/MultiLayer.h" namespace { @@ -54,8 +54,7 @@ void setParameterDistributionToSimulation(ParameterDistribution::WhichParameter } //! adds DistributionParameters to the ISimulation -void addDistributionParametersToSimulation(const BeamItem& beam_item, - GISASSimulation& simulation) +void addDistributionParametersToSimulation(const BeamItem& beam_item, GISASSimulation& simulation) { if (beam_item.modelType() != GISASBeamItem::M_TYPE) { ASSERT(beam_item.modelType() == GISASBeamItem::M_TYPE); @@ -113,34 +112,27 @@ void addBeamDivergencesToScan(const BeamItem& beam_item, AlphaScan& scan) scan.setAngleResolution(*resolution); } -void setSimulationOptions(ISimulation* simulation, const SessionItem& item) +void setSimulationOptions(ISimulation* simulation, const SimulationOptionsItem& optionItem) { - ASSERT(item.modelType() == SimulationOptionsItem::M_TYPE); - - if (const auto* optionItem = dynamic_cast<const SimulationOptionsItem*>(&item)) { - simulation->options().setNumberOfThreads(optionItem->numberOfThreads()); - if (optionItem->useMonteCarloIntegration()) - simulation->options().setMonteCarloIntegration(true, - optionItem->numberOfMonteCarloPoints()); - simulation->options().setUseAvgMaterials(optionItem->useAverageMaterials()); - simulation->options().setIncludeSpecular(optionItem->includeSpecularPeak()); - } + simulation->options().setNumberOfThreads(optionItem.numberOfThreads()); + if (optionItem.useMonteCarloIntegration()) + simulation->options().setMonteCarloIntegration(true, optionItem.numberOfMonteCarloPoints()); + simulation->options().setUseAvgMaterials(optionItem.useAverageMaterials()); + simulation->options().setIncludeSpecular(optionItem.includeSpecularPeak()); } std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLayer> multilayer, const GISASInstrumentItem* instrumentItem, - const SimulationOptionsItem* optionsItem) + const SimulationOptionsItem& optionsItem) { std::unique_ptr<const Instrument> instrument = instrumentItem->createInstrument(); std::unique_ptr<GISASSimulation> ret{ new GISASSimulation(instrument->beam(), *multilayer, instrument->detector())}; - addDistributionParametersToSimulation(*instrumentItem->beamItem(), - *ret); + addDistributionParametersToSimulation(*instrumentItem->beamItem(), *ret); // ISimulation options - if (optionsItem) - setSimulationOptions(ret.get(), *optionsItem); + setSimulationOptions(ret.get(), optionsItem); addBackgroundToSimulation(*instrumentItem, *ret); @@ -150,7 +142,7 @@ std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLaye std::unique_ptr<OffSpecularSimulation> createOffSpecularSimulation(std::unique_ptr<MultiLayer> multilayer, const OffSpecularInstrumentItem* instrumentItem, - const SimulationOptionsItem* optionsItem) + const SimulationOptionsItem& optionsItem) { std::unique_ptr<const Instrument> instrument = instrumentItem->createInstrument(); std::unique_ptr<OffSpecularSimulation> ret{ @@ -166,8 +158,7 @@ createOffSpecularSimulation(std::unique_ptr<MultiLayer> multilayer, // gisas.get()); // ISimulation options - if (optionsItem) - setSimulationOptions(ret.get(), *optionsItem); + setSimulationOptions(ret.get(), optionsItem); addBackgroundToSimulation(*instrumentItem, *ret); @@ -177,7 +168,7 @@ createOffSpecularSimulation(std::unique_ptr<MultiLayer> multilayer, std::unique_ptr<SpecularSimulation> createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer, const SpecularInstrumentItem* instrument, - const SimulationOptionsItem* options_item) + const SimulationOptionsItem& optionsItem) { std::unique_ptr<SpecularSimulation> ret = std::make_unique<SpecularSimulation>(); ret->setSample(*P_multilayer); @@ -195,8 +186,7 @@ createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer, ret->setScan(scan); // ISimulation options - if (options_item) - setSimulationOptions(ret.get(), *options_item); + setSimulationOptions(ret.get(), optionsItem); addBackgroundToSimulation(*instrument, *ret); @@ -206,13 +196,12 @@ createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer, std::unique_ptr<DepthProbeSimulation> createDepthProbeSimulation(std::unique_ptr<MultiLayer> multilayer, const DepthProbeInstrumentItem* instrument, - const SimulationOptionsItem* options_item) + const SimulationOptionsItem& optionsItem) { std::unique_ptr<DepthProbeSimulation> ret = instrument->createSimulation(); ret->setSample(*multilayer); - if (options_item) - setSimulationOptions(ret.get(), *options_item); + setSimulationOptions(ret.get(), optionsItem); return ret; } @@ -223,7 +212,7 @@ createDepthProbeSimulation(std::unique_ptr<MultiLayer> multilayer, std::unique_ptr<ISimulation> GUI::Model::DomainSimulationBuilder::createSimulation(const MultiLayerItem* sampleItem, const InstrumentItem* instrumentItem, - const SimulationOptionsItem* optionsItem) + const SimulationOptionsItem& optionsItem) { if (sampleItem == nullptr || instrumentItem == nullptr) { QString message( diff --git a/GUI/Model/To/DomainSimulationBuilder.h b/GUI/Model/To/DomainSimulationBuilder.h index 94b18d236689f8cdd26509fab4c17760408b1c4d..a3c30c6115dd1aef67d1535860b12d374a8efad4 100644 --- a/GUI/Model/To/DomainSimulationBuilder.h +++ b/GUI/Model/To/DomainSimulationBuilder.h @@ -30,7 +30,7 @@ namespace GUI::Model::DomainSimulationBuilder { std::unique_ptr<ISimulation> createSimulation(const MultiLayerItem* sampleItem, const InstrumentItem* instrumentItem, - const SimulationOptionsItem* optionsItem = nullptr); + const SimulationOptionsItem& optionsItem); } // namespace GUI::Model::DomainSimulationBuilder #endif // BORNAGAIN_GUI_MODEL_TO_DOMAINSIMULATIONBUILDER_H diff --git a/GUI/Model/To/ToDomain.cpp b/GUI/Model/To/ToDomain.cpp index 2f7511339f3b086448416c24a698807b7472575e..1d4d61e52b74e2f7df6e9cbc32fd3937f35421eb 100644 --- a/GUI/Model/To/ToDomain.cpp +++ b/GUI/Model/To/ToDomain.cpp @@ -21,7 +21,6 @@ #include "GUI/Model/Sample/ParticleCoreShellItem.h" #include "GUI/Model/Sample/ParticleItem.h" #include "GUI/Model/Sample/ParticleLayoutItem.h" -#include "GUI/Model/Session/SimulationOptionsItem.h" #include "GUI/Model/Types/DoubleDescriptor.h" #include "GUI/Model/Types/UIntDescriptor.h" #include "Sample/Particle/MesoCrystal.h" diff --git a/GUI/View/Script/PythonScriptWidget.cpp b/GUI/View/Script/PythonScriptWidget.cpp index 8495a6aea040b2bf0dac6d7482c8aa2fcd002906..a2679968b82d026fe88e02ec5b1d26844bc9dac5 100644 --- a/GUI/View/Script/PythonScriptWidget.cpp +++ b/GUI/View/Script/PythonScriptWidget.cpp @@ -83,7 +83,7 @@ PythonScriptWidget::~PythonScriptWidget() void PythonScriptWidget::generatePythonScript(const MultiLayerItem* sampleItem, const InstrumentItem* instrumentItem, - const SimulationOptionsItem* optionItem, + const SimulationOptionsItem& optionItem, const QString& outputDir) { m_outputDir = outputDir; diff --git a/GUI/View/Script/PythonScriptWidget.h b/GUI/View/Script/PythonScriptWidget.h index 6acfca8101ab1ae7f1becac7ae1f0f2e090751a1..c2a69a1b00ee28ffb79ff243c4251f0e4192740a 100644 --- a/GUI/View/Script/PythonScriptWidget.h +++ b/GUI/View/Script/PythonScriptWidget.h @@ -35,7 +35,7 @@ public: void generatePythonScript(const MultiLayerItem* sampleItem, const InstrumentItem* instrumentItem, - const SimulationOptionsItem* optionItem = nullptr, + const SimulationOptionsItem& optionItem, const QString& outputDir = ""); private slots: diff --git a/GUI/View/Toplevel/SimulationView.cpp b/GUI/View/Toplevel/SimulationView.cpp index a5d99b6a8e7b641d5c85497eb900994e486293d1..61ce8f530907819c6c290cdf1e9206d3f886e826 100644 --- a/GUI/View/Toplevel/SimulationView.cpp +++ b/GUI/View/Toplevel/SimulationView.cpp @@ -13,18 +13,18 @@ // ************************************************************************************************ #include "GUI/View/Toplevel/SimulationView.h" -#include "GUI/Model/Data/DocumentModel.h" #include "GUI/Model/Data/RealDataItem.h" #include "GUI/Model/Data/RealDataModel.h" #include "GUI/Model/Instrument/InstrumentItems.h" +#include "GUI/Model/Instrument/InstrumentModel.h" #include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Job/JobModel.h" +#include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Model/Sample/MultiLayerItem.h" #include "GUI/Model/Sample/SampleModel.h" #include "GUI/Model/Sample/SampleValidator.h" #include "GUI/Model/Session/ModelUtils.h" #include "GUI/Model/Session/SimulationOptionsItem.h" -#include "GUI/Model/State/SessionData.h" #include "GUI/View/Main/MainWindow.h" #include "GUI/View/Main/ProjectManager.h" #include "GUI/View/Script/PythonScriptWidget.h" @@ -74,25 +74,21 @@ SimulationView::SimulationView(QWidget* parent, ProjectDocument* document) &SimulationView::updateEnabling); connect(m_ui->runPolicyImmediatelyRadio, &QRadioButton::toggled, - []() { gSessionData->projectDocument->setModified(true); }); + [=]() { document->setModified(true); }); - connect(m_ui->analyticalRadio, &QRadioButton::toggled, - []() { gSessionData->projectDocument->setModified(true); }); + connect(m_ui->analyticalRadio, &QRadioButton::toggled, [=]() { document->setModified(true); }); connect(m_ui->averageLayerRadio, &QRadioButton::toggled, - []() { gSessionData->projectDocument->setModified(true); }); + [=]() { document->setModified(true); }); connect(m_ui->numberOfThreadsCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), - []() { gSessionData->projectDocument->setModified(true); }); + [=]() { document->setModified(true); }); connect(m_ui->numberOfMonteCarloPoints, QOverload<int>::of(&QSpinBox::valueChanged), - []() { gSessionData->projectDocument->setModified(true); }); + [=]() { document->setModified(true); }); connect(m_ui->includeSpecularCheck, &QCheckBox::toggled, - []() { gSessionData->projectDocument->setModified(true); }); - - connect(ProjectManager::instance(), &ProjectManager::documentOpenedOrClosed, this, - &SimulationView::writeOptionsToUI); + [=]() { document->setModified(true); }); connect(m_document, &ProjectDocument::modified, this, &SimulationView::updateFunctionalityNarrowing); @@ -152,8 +148,8 @@ void SimulationView::runSimulation() return; } JobModel* jobModel = m_document->jobModel(); - JobItem* jobItem = - jobModel->addJob(selectedSample(), selectedInstrument(), selectedRealData(), optionsItem()); + JobItem* jobItem = jobModel->addJob(selectedSample(), selectedInstrument(), selectedRealData(), + *optionsItem()); jobModel->runJob(jobItem->index()); } @@ -168,7 +164,7 @@ void SimulationView::exportPythonScript() auto* pythonWidget = new PythonScriptWidget(baWin); pythonWidget->show(); pythonWidget->raise(); - pythonWidget->generatePythonScript(selectedSample(), selectedInstrument(), optionsItem(), + pythonWidget->generatePythonScript(selectedSample(), selectedInstrument(), *optionsItem(), ProjectManager::instance()->projectDir()); } diff --git a/Tests/Functional/GUI/Check.cpp b/Tests/Functional/GUI/Check.cpp index 480d108d1a1c3af14a4f94fad949e0840f308c11..8a2a0ec5bf95d2543460726e38676a3b7ecddab7 100644 --- a/Tests/Functional/GUI/Check.cpp +++ b/Tests/Functional/GUI/Check.cpp @@ -19,13 +19,13 @@ #include "Device/Data/DataUtils.h" #include "Device/Histo/IntensityDataIOFactory.h" #include "Device/Histo/SimulationResult.h" -#include "GUI/Model/Data/DocumentModel.h" +#include "GUI/Model/From/GUIDomainSampleVisitor.h" #include "GUI/Model/From/GUIObjectBuilder.h" #include "GUI/Model/Instrument/InstrumentItems.h" #include "GUI/Model/Instrument/InstrumentModel.h" #include "GUI/Model/Material/MaterialModel.h" -#include "GUI/Model/From/GUIDomainSampleVisitor.h" #include "GUI/Model/Sample/SampleModel.h" +#include "GUI/Model/Session/SimulationOptionsItem.h" #include "GUI/Model/To/DomainSimulationBuilder.h" #include <iostream> @@ -35,7 +35,7 @@ std::unique_ptr<OutputData<double>> domainData(const std::string& /*test_name*/, const ISimulation& direct_simulation) { // initializing necessary GUI - DocumentModel documentModel; + SimulationOptionsItem optionsItem; SampleModel sampleModel; InstrumentModel instrumentModel; MaterialModel materialModel; @@ -44,12 +44,11 @@ std::unique_ptr<OutputData<double>> domainData(const std::string& /*test_name*/, GUIDomainSampleVisitor().populateSampleModel(&sampleModel, &materialModel, *direct_simulation.sample()); GUI::Model::ObjectBuilder::populateInstrumentModel(&instrumentModel, direct_simulation); - GUI::Model::ObjectBuilder::populateDocumentModel(&documentModel, direct_simulation); + GUI::Model::ObjectBuilder::populateSimulationOptions(&optionsItem, direct_simulation); std::unique_ptr<ISimulation> domain_simulation = GUI::Model::DomainSimulationBuilder::createSimulation( - sampleModel.multiLayerItem(), instrumentModel.instrumentItems().front(), - documentModel.simulationOptionsItem()); + sampleModel.multiLayerItem(), instrumentModel.instrumentItems().front(), optionsItem); domain_simulation->runSimulation(); return std::unique_ptr<OutputData<double>>(domain_simulation->result().data()); diff --git a/Tests/Unit/GUI/TestMapperCases.cpp b/Tests/Unit/GUI/TestMapperCases.cpp index 03161be67212c0753c9084bea6d8d5e70543272c..e3d85696d86937c168ca7e59dbdee1350d0a040c 100644 --- a/Tests/Unit/GUI/TestMapperCases.cpp +++ b/Tests/Unit/GUI/TestMapperCases.cpp @@ -1,12 +1,8 @@ -#include "GUI/Model/Data/DocumentModel.h" #include "GUI/Model/Sample/LayerItem.h" #include "GUI/Model/Sample/MultiLayerItem.h" #include "GUI/Model/Sample/ParticleCompositionItem.h" -#include "GUI/Model/Sample/ParticleItem.h" #include "GUI/Model/Sample/ParticleLayoutItem.h" #include "GUI/Model/Sample/SampleModel.h" -#include "GUI/Model/Session/SessionItemUtils.h" -#include "GUI/Model/Session/SimulationOptionsItem.h" #include "Tests/GTestWrapper/google_test.h" #include <QtTest>