// ************************************************************************************************ // // BornAgain: simulate and fit reflection and scattering // //! @file GUI/Models/JobItem.cpp //! @brief Implements class JobItem //! //! @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/Models/JobItem.h" #include "GUI/Models/Data1DViewItem.h" #include "GUI/Models/FitSuiteItem.h" #include "GUI/Models/InstrumentItems.h" #include "GUI/Models/IntensityDataItem.h" #include "GUI/Models/ItemFileNameUtils.h" #include "GUI/Models/JobItemUtils.h" #include "GUI/Models/MaterialItemContainer.h" #include "GUI/Models/MultiLayerItem.h" #include "GUI/Models/ParameterTreeItems.h" #include "GUI/Models/RealDataItem.h" #include "GUI/Models/SessionModel.h" #include "GUI/Models/SimulationOptionsItem.h" #include "GUI/Models/SpecularDataItem.h" #include "GUI/utils/GUIHelpers.h" const QString JobItem::P_IDENTIFIER = "Identifier"; const QString JobItem::P_SAMPLE_NAME = "Sample"; const QString JobItem::P_INSTRUMENT_NAME = "Instrument"; const QString JobItem::P_WITH_FITTING = "With fitting"; const QString JobItem::P_STATUS = "Status"; const QString JobItem::P_BEGIN_TIME = "Begin time"; const QString JobItem::P_END_TIME = "End time"; const QString JobItem::P_DURATION = "Duration"; const QString JobItem::P_COMMENTS = "Comments"; const QString JobItem::P_PROGRESS = "Progress"; const QString JobItem::P_PRESENTATION_TYPE = "Presentation type"; const QString JobItem::T_SAMPLE = "Sample tag"; const QString JobItem::T_MATERIAL_CONTAINER = "Material container tag"; const QString JobItem::T_INSTRUMENT = "Instrument tag"; const QString JobItem::T_OUTPUT = "Output tag"; const QString JobItem::T_REALDATA = "Real Data tag"; const QString JobItem::T_DATAVIEW = "Data View tag"; const QString JobItem::T_PARAMETER_TREE = "Parameter tree tag"; const QString JobItem::T_SIMULATION_OPTIONS = "Simulation options tag"; const QString JobItem::T_FIT_SUITE = "Fit suite tag"; JobItem::JobItem() : SessionItem("JobItem") { setItemName("JobItem"); addProperty(P_IDENTIFIER, QString())->setVisible(false); addProperty(P_SAMPLE_NAME, QString())->setEditable(false); addProperty(P_INSTRUMENT_NAME, QString())->setEditable(false); addProperty(P_WITH_FITTING, false)->setVisible(false); addProperty(P_STATUS, "Idle")->setEditable(false); addProperty(P_BEGIN_TIME, QString())->setEditable(false); addProperty(P_END_TIME, QString())->setEditable(false); auto durationItem = addProperty(P_DURATION, QString()); durationItem->setEditable(false); durationItem->setToolTip("Duration of DWBA simulation in sec.msec format"); addProperty(P_COMMENTS, QString())->setVisible(false); addProperty(P_PROGRESS, 0)->setVisible(false); addProperty(P_PRESENTATION_TYPE, QVariant::Type::Invalid)->setVisible(false); registerTag(T_SAMPLE, 1, 1, QStringList() << "MultiLayer"); registerTag(T_MATERIAL_CONTAINER, 1, 1, QStringList{"MaterialContainer"}); registerTag(T_INSTRUMENT, 1, 1, { GISASInstrumentItem::M_TYPE, OffSpecularInstrumentItem::M_TYPE, SpecularInstrumentItem::M_TYPE, DepthProbeInstrumentItem::M_TYPE }); registerTag(T_OUTPUT, 1, 1, { IntensityDataItem::M_TYPE, SpecularDataItem::M_TYPE }); registerTag(T_REALDATA, 1, 1, QStringList() << "RealData"); registerTag(T_DATAVIEW, 1, 1, QStringList() << "Data1DViewItem"); registerTag(T_PARAMETER_TREE, 0, -1, QStringList() << "Parameter Container"); registerTag(T_SIMULATION_OPTIONS, 1, 1, QStringList() << "SimulationOptions"); registerTag(T_FIT_SUITE, 1, 1, QStringList() << "FitSuite"); mapper()->setOnChildPropertyChange([this](SessionItem* item, const QString& name) { if (item->parent() == this && dynamic_cast<DataItem*>(item) && DataItem::isAxesUnitsPropertyName(name)) dynamic_cast<DataItem*>(item)->updateCoords(instrumentItem()); }); mapper()->setOnPropertyChange([this](const QString& name) { if (name == P_NAME) updateIntensityDataFileName(); }); } QString JobItem::getIdentifier() const { return getItemValue(P_IDENTIFIER).toString(); } void JobItem::setIdentifier(const QString& identifier) { setItemValue(JobItem::P_IDENTIFIER, identifier); } IntensityDataItem* JobItem::intensityDataItem() { return dynamic_cast<IntensityDataItem*>(getItem(T_OUTPUT)); } DataItem* JobItem::dataItem() { return dynamic_cast<DataItem*>(getItem(T_OUTPUT)); } QString JobItem::getStatus() const { return getItemValue(P_STATUS).toString(); } void JobItem::setStatus(const QString& status) { setItemValue(P_STATUS, status); if (status == "Failed") { if (DataItem* intensityItem = dataItem()) { if (intensityItem->getOutputData()) intensityItem->getOutputData()->setAllTo(0.0); emit intensityItem->emitDataChanged(); } } } bool JobItem::isStatusPropertyName(const QString& name) { return name == P_STATUS; } bool JobItem::isIdle() const { return getStatus() == "Idle"; } bool JobItem::isRunning() const { return getStatus() == "Running"; } bool JobItem::isCompleted() const { return getStatus() == "Completed"; } bool JobItem::isCanceled() const { return getStatus() == "Canceled"; } bool JobItem::isFailed() const { return getStatus() == "Failed"; } bool JobItem::isValidForFitting() { return isTag(T_REALDATA) && getItem(T_REALDATA); } void JobItem::setBeginTime(const QString& begin_time) { setItemValue(P_BEGIN_TIME, begin_time); } void JobItem::setEndTime(const QString& end_time) { setItemValue(P_END_TIME, end_time); } // Sets duration (msec -> "sec.msec") void JobItem::setDuration(int duration) { QString str; if (duration != 0) str = QString("%7.3f").arg(duration / 1000.); setItemValue(P_DURATION, str.simplified()); } QString JobItem::getComments() const { return getItemValue(P_COMMENTS).toString(); } void JobItem::setComments(const QString& comments) { setItemValue(P_COMMENTS, comments); } bool JobItem::isCommentsPropertyName(const QString& name) { return name == P_COMMENTS; } int JobItem::getProgress() const { return getItemValue(P_PROGRESS).toInt(); } void JobItem::setProgress(int progress) { setItemValue(P_PROGRESS, progress); } bool JobItem::runImmediately() const { return simulationOptionsItem()->runImmediately(); } bool JobItem::runInBackground() const { return simulationOptionsItem()->runInBackground(); } MultiLayerItem* JobItem::sampleItem() { return dynamic_cast<MultiLayerItem*>(getItem(T_SAMPLE)); } MultiLayerItem* JobItem::copySampleIntoJob(const MultiLayerItem* sample) { return model()->copyItem(sample, this, T_SAMPLE); } InstrumentItem* JobItem::instrumentItem() { return dynamic_cast<InstrumentItem*>(getItem(T_INSTRUMENT)); } void JobItem::setResults(const ISimulation* simulation) { JobItemUtils::setResults(dataItem(), simulation); updateIntensityDataFileName(); } FitSuiteItem* JobItem::fitSuiteItem() { return dynamic_cast<FitSuiteItem*>(getItem(JobItem::T_FIT_SUITE)); } ParameterContainerItem* JobItem::parameterContainerItem() { return const_cast<ParameterContainerItem*>( static_cast<const JobItem*>(this)->parameterContainerItem()); } const ParameterContainerItem* JobItem::parameterContainerItem() const { return dynamic_cast<ParameterContainerItem*>(getItem(JobItem::T_PARAMETER_TREE)); } FitParameterContainerItem* JobItem::fitParameterContainerItem() { if (FitSuiteItem* item = fitSuiteItem()) return item->fitParameterContainerItem(); return nullptr; } RealDataItem* JobItem::realDataItem() { return dynamic_cast<RealDataItem*>(getItem(JobItem::T_REALDATA)); } MaterialItemContainer* JobItem::materialContainerItem() const { return static_cast<MaterialItemContainer*>(getItem(JobItem::T_MATERIAL_CONTAINER)); } MaterialItemContainer* JobItem::createMaterialContainer() { return model()->insertItem<MaterialItemContainer> (this, -1, T_MATERIAL_CONTAINER); } Data1DViewItem* JobItem::dataItemView() { return dynamic_cast<Data1DViewItem*>(getItem(JobItem::T_DATAVIEW)); } void JobItem::setSampleName(const QString& name) { getItem(P_SAMPLE_NAME)->setValue(name); } void JobItem::setInstrumentName(const QString& name) { getItem(P_INSTRUMENT_NAME)->setValue(name); } const QString JobItem::presentationType() const { return getItemValue(P_PRESENTATION_TYPE).toString(); } void JobItem::setPresentationType(const QString& type) { setItemValue(P_PRESENTATION_TYPE, type); } //! Updates the name of file to store intensity data. void JobItem::updateIntensityDataFileName() { if (DataItem* item = dataItem()) item->setFileName(ItemFileNameUtils::jobResultsFileName(*this)); if (RealDataItem* realItem = realDataItem()) { if (DataItem* item = realItem->dataItem()) item->setFileName(ItemFileNameUtils::jobReferenceFileName(*this)); if (DataItem* item = realItem->nativeData()) item->setFileName(ItemFileNameUtils::jobNativeDataFileName(*this)); } } SimulationOptionsItem* JobItem::simulationOptionsItem() { return const_cast<SimulationOptionsItem*>( static_cast<const JobItem*>(this)->simulationOptionsItem()); } const SimulationOptionsItem* JobItem::simulationOptionsItem() const { return item<const SimulationOptionsItem>(T_SIMULATION_OPTIONS); }