From 15f7e914a970ffc01cf958533ac8a16584e44108 Mon Sep 17 00:00:00 2001 From: Stefan Hoops Date: Thu, 14 Nov 2024 11:06:55 -0500 Subject: [PATCH] Improved performance managing the active parameter set. --- CMakeLists.txt | 1 + CMakeModules/FindCLAPACK.cmake | 2 +- copasi/CopasiDataModel/CDataModel.cpp | 29 +++++++++--------- copasi/CopasiSE/CopasiSE.cpp | 7 +++-- copasi/UI/CQParameterOverviewWidget.cpp | 3 +- copasi/UI/CQParameterSetsDM.cpp | 4 +-- copasi/model/CCompartment.cpp | 2 +- copasi/model/CModel.cpp | 27 ++--------------- copasi/model/CModel.h | 11 ++----- copasi/model/CModelParameterSet.cpp | 40 +++++++++++++++++++++++-- copasi/model/CModelParameterSet.h | 8 +++++ copasi/optimization/COptMethodPS.cpp | 10 +++---- copasi/plotUI/CQMarchingSquares.cpp | 5 ++-- copasi/sbml/SBMLImporter.cpp | 4 +-- copasi/sedml/SEDMLImporter.cpp | 11 +++---- copasi/xml/CCopasiXML.cpp | 5 ++-- copasi/xml/parser/ModelHandler.cpp | 3 +- tests/ModelLoading.cpp | 13 ++++---- tests/test_CDataHandler.cpp | 5 ++-- tests/test_model_creation.cpp | 31 ++++++++----------- tests/test_sedml.cpp | 6 ++-- 21 files changed, 120 insertions(+), 107 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e023689ee5..ac6f3171df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -938,6 +938,7 @@ message(STATUS "----------------------------------------------------------- Vendor = ${BLA_VENDOR} LAPACK Libs = ${CLAPACK_LIBRARIES} LAPACK LDFLAGS = ${CLAPACK_LINKER_FLAGS} + LAPACK include = ${CLAPACK_INCLUDE_DIR} crossguid Libs = ${CROSSGUID_LIBRARY} cross include = ${CROSSGUID_INCLUDE_DIR} diff --git a/CMakeModules/FindCLAPACK.cmake b/CMakeModules/FindCLAPACK.cmake index a264e57621..8173de350b 100644 --- a/CMakeModules/FindCLAPACK.cmake +++ b/CMakeModules/FindCLAPACK.cmake @@ -326,7 +326,7 @@ if (NOT CLAPACK_INCLUDE_DIR) endif (NOT CLAPACK_INCLUDE_DIR) if (NOT CLAPACK_INCLUDE_DIR) - set(CLAPACK_INCLUDE_DIR "${COPASI_SOURCE_DIR}") + set(CLAPACK_INCLUDE_DIR "${COPASI_SOURCE_DIR}/copasi/lapack") endif (NOT CLAPACK_INCLUDE_DIR) diff --git a/copasi/CopasiDataModel/CDataModel.cpp b/copasi/CopasiDataModel/CDataModel.cpp index 583b8ca920..625f374895 100644 --- a/copasi/CopasiDataModel/CDataModel.cpp +++ b/copasi/CopasiDataModel/CDataModel.cpp @@ -922,7 +922,7 @@ bool CDataModel::saveModel(const std::string & fileName, CProcessReport * pProce mData.pModel->compileIfNecessary(pProcessReport); // Assure that the parameter set reflects all changes made to the model. - mData.pModel->getActiveModelParameterSet().refreshFromModel(false); + mData.pModel->refreshActiveParameterSet(); } catch (...) @@ -1012,7 +1012,7 @@ std::string CDataModel::saveModelToString(CProcessReport * pProcessReport) mData.pModel->compileIfNecessary(pProcessReport); // Assure that the parameter set reflects all changes made to the model. - mData.pModel->getActiveModelParameterSet().refreshFromModel(false); + mData.pModel->refreshActiveParameterSet(); } catch (...) @@ -1203,7 +1203,6 @@ bool CDataModel::importSBML(const std::string & fileName, importer.setImportHandler(pProcessReport); importer.setImportInitialValueAnnotation(importInitialValues); - CModel * pModel = NULL; SBMLDocument * pSBMLDocument = NULL; @@ -2391,7 +2390,7 @@ bool CDataModel::importSEDML(const std::string & fileName, // Later this will be settable by the user in the preferences dialog // Later this will be settable by the user in the preferences dialog // importer.setImportCOPASIMIRIAM(true); - importer.setImportHandler(pProcessReport); + importer.setImportHandler(pProcessReport); CModel * pModel = NULL; @@ -3419,7 +3418,7 @@ void CDataModel::commonAfterLoad(CProcessReport * pProcessReport, CCopasiMessage(CCopasiMessage::WARNING, validity.getIssueMessages().c_str()); } - mData.pModel->updateInitialValues(CCore::Framework::ParticleNumbers); + mData.pModel->updateInitialValues(CCore::Framework::ParticleNumbers, false); } changed(false); @@ -3466,12 +3465,12 @@ bool CDataModel::changeModelParameter(CDataObject * element, double value) bool isInitialConcentration = pRef->getObjectName() == "InitialConcentration" && pRef->getObjectDataModel() != NULL && pRef->getObjectDataModel()->getModel() != NULL; if (isInitialConcentration) - pRef->getObjectDataModel()->getModel()->updateInitialValues(pRef); + pRef->getObjectDataModel()->getModel()->updateInitialValues(pRef, false); *static_cast< double * >(pRef->getValuePointer()) = value; if (isInitialConcentration) - pRef->getObjectDataModel()->getModel()->updateInitialValues(pRef); + pRef->getObjectDataModel()->getModel()->updateInitialValues(pRef, false); return true; } @@ -3537,6 +3536,7 @@ void CDataModel::reparameterizeFromIniFile(const std::string & fileName) } getModel()->compileIfNecessary(NULL); // compile if needed + getModel()->refreshActiveParameterSet(); } const CDataObject * CDataModel::findObjectByDisplayName(const std::string & displayString) const @@ -3692,7 +3692,6 @@ const CDataObject * CDataModel::findObjectByDisplayName(const std::string & disp return NULL; } - #include #include @@ -3703,12 +3702,13 @@ bool CDataModel::convertODEsToReactions() { std::string sbml = exportSBMLToString(NULL, 3, 1); - + auto *doc = readSBMLFromString(sbml.c_str()); ConversionProperties props; props.addOption("inferReactions", true, "Infer reactions from rateRules in the model"); + if (doc->convert(props) != LIBSBML_OPERATION_SUCCESS) { CCopasiMessage(CCopasiMessage::ERROR, "Couldn't infer reactions: %s", doc->getErrorLog()->toString().c_str()); @@ -3723,16 +3723,17 @@ CDataModel::convertODEsToReactions() /* * Converts Reactions in this model to ODEs */ -bool +bool CDataModel::convertReactionsToODEs() { std::string sbml = exportSBMLToString(NULL, 3, 1); - + auto *doc = readSBMLFromString(sbml.c_str()); ConversionProperties props; props.addOption("replaceReactions", true, - "Replace reactions with rateRules" ); + "Replace reactions with rateRules"); + if (doc->convert(props) != LIBSBML_OPERATION_SUCCESS) { CCopasiMessage(CCopasiMessage::ERROR, "Couldn't convert reactions to ODEs: %s", doc->getErrorLog()->toString().c_str()); @@ -3744,8 +3745,7 @@ CDataModel::convertReactionsToODEs() return importSBMLFromString(newSBML.c_str()); } - -bool +bool CDataModel::convertParametersToGlobal() { std::string sbml = exportSBMLToString(NULL, 3, 1); @@ -3755,6 +3755,7 @@ CDataModel::convertParametersToGlobal() ConversionProperties props; props.addOption("promoteLocalParameters", true, "Promotes all Local Parameters to Global ones"); + if (doc->convert(props) != LIBSBML_OPERATION_SUCCESS) { CCopasiMessage(CCopasiMessage::ERROR, "Couldn't promote local parameters: %s", doc->getErrorLog()->toString().c_str()); diff --git a/copasi/CopasiSE/CopasiSE.cpp b/copasi/CopasiSE/CopasiSE.cpp index 9ff6e6599b..e377a44167 100644 --- a/copasi/CopasiSE/CopasiSE.cpp +++ b/copasi/CopasiSE/CopasiSE.cpp @@ -214,7 +214,8 @@ int main(int argc, char *argv[]) COptions::getValue("License", License); COptions::getValue("ReportFile", ReportFileName); - // should a report filename be given, ensure that + + // should a report filename be given, ensure that // it is an absolute path if (!ReportFileName.empty()) CDirEntry::makePathAbsolute(ReportFileName, COptions::getPWD()); @@ -625,8 +626,8 @@ int exportParametersToIniFile() if (!pDataModel || !pDataModel->getModel()) return -2; - pDataModel->getModel()->getActiveModelParameterSet(). - saveToStream(fs, CCore::Framework::Concentration, "ini", ""); + pDataModel->getModel()->refreshActiveParameterSet(); + pDataModel->getModel()->getActiveModelParameterSet().saveToStream(fs, CCore::Framework::Concentration, "ini", ""); fs.close(); diff --git a/copasi/UI/CQParameterOverviewWidget.cpp b/copasi/UI/CQParameterOverviewWidget.cpp index d6a8218247..4c106e0414 100644 --- a/copasi/UI/CQParameterOverviewWidget.cpp +++ b/copasi/UI/CQParameterOverviewWidget.cpp @@ -399,10 +399,11 @@ void CQParameterOverviewWidget::slotBtnNew() if (answer == QMessageBox::Save) { // Save the parameter set to a new or existing set + pModel->refreshActiveParameterSet(); saveParameterSet(&pModel->getActiveModelParameterSet()); } - // TODO CRITICAL We need to record all changes to the model + // We need to record all changes to the model pSetToApply->updateModel(); // Notify the GUI that the model state has changed. diff --git a/copasi/UI/CQParameterSetsDM.cpp b/copasi/UI/CQParameterSetsDM.cpp index bb9d707db4..f91dce5bae 100644 --- a/copasi/UI/CQParameterSetsDM.cpp +++ b/copasi/UI/CQParameterSetsDM.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 - 2021 by Pedro Mendes, Rector and Visitors of the +// Copyright (C) 2019 - 2024 by Pedro Mendes, Rector and Visitors of the // University of Virginia, University of Heidelberg, and University // of Connecticut School of Medicine. // All rights reserved. @@ -189,7 +189,7 @@ bool CQParameterSetsDM::insertRows(int position, int rows, const QModelIndex & p while (pModel->getModelParameterSets().getIndex(TO_UTF8(Name)) != C_INVALID_INDEX) Name = QString("Parameter Set %1").arg(LocalTimeStamp().c_str()); - CModelParameterSet * pNew = new CModelParameterSet(pModel->getActiveModelParameterSet(), NULL, false); + CModelParameterSet * pNew = new CModelParameterSet(pModel, NULL); pNew->setObjectName(TO_UTF8(Name)); mpListOfParameterSets->add(pNew, true); ++mFetched; diff --git a/copasi/model/CCompartment.cpp b/copasi/model/CCompartment.cpp index aa74a5db08..a59d19576e 100644 --- a/copasi/model/CCompartment.cpp +++ b/copasi/model/CCompartment.cpp @@ -74,7 +74,7 @@ bool CCompartment::applyData(const CData & data, CUndoData::CChangeSet & changes { const CData & Data = data.getProperty(CData::INITIAL_VALUE).toData(); mIValue = Data.getProperty(CData::VALUE).toDouble(); - mpModel->updateInitialValues(CCore::FrameworkNames.toEnum(Data.getProperty(CData::FRAMEWORK).toString(), CCore::Framework::ParticleNumbers)); + mpModel->updateInitialValues(CCore::FrameworkNames.toEnum(Data.getProperty(CData::FRAMEWORK).toString(), CCore::Framework::ParticleNumbers), false); changes.add({CUndoData::Type::CHANGE, "State", mpModel->getStringCN(), mpModel->getStringCN()}); } diff --git a/copasi/model/CModel.cpp b/copasi/model/CModel.cpp index 975d5edf4d..c2ac87e350 100644 --- a/copasi/model/CModel.cpp +++ b/copasi/model/CModel.cpp @@ -1307,32 +1307,9 @@ CModelParameterSet & CModel::getActiveModelParameterSet() return mParameterSet; } -void CModel::applyActiveParameterSet() -{ - CModelParameterSet * pParameterSet = - dynamic_cast< CModelParameterSet * >(CRootContainer::getKeyFactory()->get(mActiveParameterSetKey)); - - if (pParameterSet != NULL) - { - pParameterSet->updateModel(); - } - else - { - /* - CModelParameterSet * pParameterSet = new CModelParameterSet(UTCTimeStamp()); - mParameterSets.add(pParameterSet, true); - mActiveParameterSetKey = pParameterSet->getKey(); - pParameterSet->createFromModel(); - */ - } - - mParameterSet.createFromModel(); - mActiveParameterSetKey = mParameterSet.getKey(); -} - void CModel::refreshActiveParameterSet() { - mParameterSet.refreshFromModel(false); + mParameterSet.createFromModel(); } CDataVectorN < CEvent > & CModel::getEvents() @@ -1780,7 +1757,7 @@ bool CModel::setQuantityUnit(const std::string & name, mNumber2QuantityFactor = 1.0 / mQuantity2NumberFactor; - updateInitialValues(framework); + updateInitialValues(framework, false); return true; } diff --git a/copasi/model/CModel.h b/copasi/model/CModel.h index ae3fa62345..28f52e2107 100644 --- a/copasi/model/CModel.h +++ b/copasi/model/CModel.h @@ -325,11 +325,6 @@ class CModel : public CModelEntity const CModelParameterSet & getActiveModelParameterSet() const; CModelParameterSet & getActiveModelParameterSet(); - /** - * Update the model initial values from the active parameter set. - */ - void applyActiveParameterSet(); - /** * refresh the active parameter set from the model initial values */ @@ -511,7 +506,7 @@ class CModel : public CModelEntity * @param refreshParameterSet (default: true) if true the active parameter set is refreshed * @return bool success */ - bool updateInitialValues(const CCore::Framework & framework, bool refreshParameterSet=true); + bool updateInitialValues(const CCore::Framework & framework, bool refreshParameterSet = true); /** * Copy the current state value to the initial state @@ -1036,7 +1031,7 @@ class CModel : public CModelEntity * * @see buildInitialRefreshSequence(std::set< const CDataObject * > & changedObjects) */ - void updateInitialValues(std::set< const CDataObject * > & changedObjects, bool refreshParameterSet=true); + void updateInitialValues(std::set< const CDataObject * > & changedObjects, bool refreshParameterSet = true); /** * Builds and executes the the update sequence used to calculate all initial @@ -1049,7 +1044,7 @@ class CModel : public CModelEntity * * @see updateInitialValues(std::set< const CDataObject * > & changedObjects) */ - void updateInitialValues(const CDataObject * changedObject, bool refreshParameterSet=true); + void updateInitialValues(const CDataObject * changedObject, bool refreshParameterSet = true); /** * Initialize a vector of individual absolute tolerances diff --git a/copasi/model/CModelParameterSet.cpp b/copasi/model/CModelParameterSet.cpp index 725cb112a7..ffe4dab4c8 100644 --- a/copasi/model/CModelParameterSet.cpp +++ b/copasi/model/CModelParameterSet.cpp @@ -203,6 +203,41 @@ CModelParameterSet::CModelParameterSet(const CModelParameterSet & src, compile(); } +CModelParameterSet::CModelParameterSet(CModel * pModel, + const CDataContainer * pParent): + CDataContainer("No Name", pParent, "ModelParameterSet"), + CAnnotation(), + CModelParameterGroup(NULL, CModelParameter::Type::Set), + mKey(CRootContainer::getKeyFactory()->add("ModelParameterSet", this)), + mpModel(pModel), + mpTimes(NULL), + mpCompartments(NULL), + mpSpecies(NULL), + mpModelValues(NULL), + mpReactions(NULL) +{ + initMiriamAnnotation(mKey); + + // Create the proper structure that fits the parameter overview in the GUI + mpTimes = static_cast< CModelParameterGroup * >(CModelParameterGroup::add(Type::Group)); + mpTimes->setCN(CDataString("Initial Time").getCN()); + + mpCompartments = static_cast< CModelParameterGroup * >(CModelParameterGroup::add(Type::Group)); + mpCompartments->setCN(CDataString("Initial Compartment Sizes").getCN()); + + mpSpecies = static_cast< CModelParameterGroup * >(CModelParameterGroup::add(Type::Group)); + mpSpecies->setCN(CDataString("Initial Species Values").getCN()); + + mpModelValues = static_cast< CModelParameterGroup * >(CModelParameterGroup::add(Type::Group)); + mpModelValues->setCN(CDataString("Initial Global Quantities").getCN()); + + mpReactions = static_cast< CModelParameterGroup * >(CModelParameterGroup::add(Type::Group)); + mpReactions->setCN(CDataString("Kinetic Parameters").getCN()); + setObjectParent(pParent); + + createFromModel(); +} + // virtual CModelParameterSet::~CModelParameterSet() { @@ -299,7 +334,8 @@ bool CModelParameterSet::setObjectParent(const CDataContainer * pParent) { bool success = CDataObject::setObjectParent(pParent); - mpModel = dynamic_cast< CModel * >(getObjectAncestor("Model")); + if (mpModel == nullptr) + mpModel = dynamic_cast< CModel * >(getObjectAncestor("Model")); return success; } @@ -464,7 +500,7 @@ bool CModelParameterSet::updateModel() bool success = CModelParameterGroup::updateModel(); - mpModel->updateInitialValues(CCore::Framework::ParticleNumbers); + mpModel->updateInitialValues(CCore::Framework::ParticleNumbers, true); return success; } diff --git a/copasi/model/CModelParameterSet.h b/copasi/model/CModelParameterSet.h index 31f1a7f28f..af33f59ea6 100644 --- a/copasi/model/CModelParameterSet.h +++ b/copasi/model/CModelParameterSet.h @@ -100,6 +100,14 @@ class CModelParameterSet: public CDataContainer, public CModelParameterGroup, pu const CDataContainer * pParent, const bool & createMissing = false); + /** + * Specific constructor + * @param CModel * pModel + * @param const CDataContainer * pParent + */ + CModelParameterSet(CModel * pModel, + const CDataContainer * pParent); + /** * Destructor */ diff --git a/copasi/optimization/COptMethodPS.cpp b/copasi/optimization/COptMethodPS.cpp index b62b866ef6..ac6ed95372 100644 --- a/copasi/optimization/COptMethodPS.cpp +++ b/copasi/optimization/COptMethodPS.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 - 2023 by Pedro Mendes, Rector and Visitors of the +// Copyright (C) 2019 - 2024 by Pedro Mendes, Rector and Visitors of the // University of Virginia, University of Heidelberg, and University // of Connecticut School of Medicine. // All rights reserved. @@ -104,7 +104,7 @@ C_FLOAT64 COptMethodPS::evaluate() // evaluate the fitness if (!pOptProblem->calculate()) -#pragma omp critical +#pragma omp critical (ps_evaluate_continue) mContinue = false; C_FLOAT64 EvaluationValue; @@ -117,7 +117,7 @@ C_FLOAT64 COptMethodPS::evaluate() if (mProblemContext.isThread(&pOptProblem)) { -#pragma omp critical +#pragma omp critical (ps_evaluate_increment_counters) mProblemContext.master()->incrementCounters(pOptProblem->getCounters()); pOptProblem->resetCounters(); @@ -198,7 +198,7 @@ bool COptMethodPS::move(const size_t & index) { Improved = true; -#pragma omp critical +#pragma omp critical (ps_move_best_value) { mImprovements[index] = EvaluationValue; @@ -340,7 +340,7 @@ bool COptMethodPS::create(const size_t & index) memcpy(mBestPositions[index], mIndividuals[index]->array(), sizeof(C_FLOAT64) * mVariableSize); if (mBestValues[index] < mBestValue) -#pragma omp critical +#pragma omp critical (ps_create_best_value) { // and store that value mBestIndex = index; diff --git a/copasi/plotUI/CQMarchingSquares.cpp b/copasi/plotUI/CQMarchingSquares.cpp index 40cb84b9d9..56b78b419c 100644 --- a/copasi/plotUI/CQMarchingSquares.cpp +++ b/copasi/plotUI/CQMarchingSquares.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2023 by Pedro Mendes, Rector and Visitors of the +// Copyright (C) 2023 - 2024 by Pedro Mendes, Rector and Visitors of the // University of Virginia, University of Heidelberg, and University // of Connecticut School of Medicine. // All rights reserved. @@ -7,7 +7,6 @@ #if defined(COPASI_USE_QCUSTOMPLOT) - void CQMarchingSquares::levelPaths::openPoligon(double x, double y) { _current.push_back(QPointF(x, y)); @@ -86,6 +85,8 @@ QPointF CQMarchingSquares::IsoCell::normalizedPointCCW(side cellSide) case TOP: return QPointF(_top, 1); } + + return QPointF(); } /** diff --git a/copasi/sbml/SBMLImporter.cpp b/copasi/sbml/SBMLImporter.cpp index 040dd3ba09..6b936d1d42 100644 --- a/copasi/sbml/SBMLImporter.cpp +++ b/copasi/sbml/SBMLImporter.cpp @@ -2568,7 +2568,7 @@ SBMLImporter::createCReactionFromReaction(Reaction* sbmlReaction, Model* pSBMLMo if (pNonconstFun->getInfix() == "@") { - // set infix to something more usable which even though + // set infix to something more usable which even though // invalid, may help others to fix this pNonconstFun->setInfix(SBML_formulaToL3String(kLawMath)); } @@ -6217,7 +6217,7 @@ bool SBMLImporter::setInitialValues(CModel* pModel, const std::mapgetObject(std::string("Reference=Avogadro Constant")))); mChangedObjects.insert(CObjectInterface::DataObject(pModel->getObject(std::string("Reference=Quantity Conversion Factor")))); - pModel->updateInitialValues(mChangedObjects); + pModel->updateInitialValues(mChangedObjects, false); return true; } diff --git a/copasi/sedml/SEDMLImporter.cpp b/copasi/sedml/SEDMLImporter.cpp index 522b6492ae..068cef844f 100644 --- a/copasi/sedml/SEDMLImporter.cpp +++ b/copasi/sedml/SEDMLImporter.cpp @@ -184,18 +184,18 @@ void SEDMLImporter::updateCopasiTaskForSimulation( if (mpCopasiModel) { mpCopasiModel->setInitialTime(initialTime); - mpCopasiModel->updateInitialValues(mpCopasiModel->getInitialValueReference()); + mpCopasiModel->updateInitialValues(mpCopasiModel->getInitialValueReference(), false); } tProblem->setDuration(outputEndTime - initialTime); - + // in COPASI the number of points calculated will be for the total duration of - // initialTime ... ouputEndTime, so if the outputStartTime is not equal to the - // initial time, the number of points will differ so we have to adjust: + // initialTime ... ouputEndTime, so if the outputStartTime is not equal to the + // initial time, the number of points will differ so we have to adjust: if (outputStartTime != initialTime) { - tProblem->setStepSize((outputEndTime-outputStartTime)/numberOfPoints); + tProblem->setStepSize((outputEndTime - outputStartTime) / numberOfPoints); } else { @@ -1608,6 +1608,7 @@ CModel * SEDMLImporter::importModel(const std::string & modelId) // apply possible changes to the model if (sedmlModel != NULL && sedmlModel->getNumChanges() > 0) { + mpCopasiModel->refreshActiveParameterSet(); CModelParameterSet & set = mpCopasiModel->getActiveModelParameterSet(); bool valueChanged = false; diff --git a/copasi/xml/CCopasiXML.cpp b/copasi/xml/CCopasiXML.cpp index aa869c8dbe..6524be2417 100644 --- a/copasi/xml/CCopasiXML.cpp +++ b/copasi/xml/CCopasiXML.cpp @@ -1123,7 +1123,10 @@ void CCopasiXML::saveModelParameterSets() CXMLAttributeList Attributes; size_t imax = 0, i = 0; Attributes.erase(); + + mpModel->refreshActiveParameterSet(); const CModelParameterSet * pSet = &mpModel->getActiveModelParameterSet(); + Attributes.add("activeSet", pSet->getKey()); startSaveElement("ListOfModelParameterSets", Attributes); @@ -1132,8 +1135,6 @@ void CCopasiXML::saveModelParameterSets() Attributes.add("key", ""); Attributes.add("name", ""); - pSet = &mpModel->getActiveModelParameterSet(); - Attributes.setValue(0, pSet->getKey()); Attributes.setValue(1, pSet->getObjectName()); diff --git a/copasi/xml/parser/ModelHandler.cpp b/copasi/xml/parser/ModelHandler.cpp index 42ea68f28e..a16d742c29 100644 --- a/copasi/xml/parser/ModelHandler.cpp +++ b/copasi/xml/parser/ModelHandler.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 - 2020 by Pedro Mendes, Rector and Visitors of the +// Copyright (C) 2019 - 2024 by Pedro Mendes, Rector and Visitors of the // University of Virginia, University of Heidelberg, and University // of Connecticut School of Medicine. // All rights reserved. @@ -207,6 +207,7 @@ bool ModelHandler::processEnd(const XML_Char * pszName) { size_t Size = CCopasiMessage::size(); + mpData->pModel->refreshActiveParameterSet(); mpData->pModel->getActiveModelParameterSet().assignSetContent(*pModelParameterSet, false); delete pModelParameterSet; mActiveSet = ""; diff --git a/tests/ModelLoading.cpp b/tests/ModelLoading.cpp index c3420cd1a9..7f99056fca 100644 --- a/tests/ModelLoading.cpp +++ b/tests/ModelLoading.cpp @@ -1,7 +1,7 @@ -// Copyright (C) 2021 - 2024 by Pedro Mendes, Rector and Visitors of the -// University of Virginia, University of Heidelberg, and University -// of Connecticut School of Medicine. -// All rights reserved. +// Copyright (C) 2021 - 2024 by Pedro Mendes, Rector and Visitors of the +// University of Virginia, University of Heidelberg, and University +// of Connecticut School of Medicine. +// All rights reserved. // BEGIN: Copyright // END: Copyright @@ -115,7 +115,7 @@ TEST_CASE("Update Model", "[COPASI]") // reset the values again x.setInitialValue(1); y.setInitialValue(1); - model->updateInitialValues(CCore::Framework::Concentration); + model->updateInitialValues(CCore::Framework::Concentration, false); model->applyInitialValues(); REQUIRE(x.getInitialValue() == 1); @@ -135,7 +135,6 @@ TEST_CASE("Update Model", "[COPASI]") CRootContainer::removeDatamodel(dm); } - TEST_CASE("Species ODE expressions", "[COPASI][multiple_models]") { CDataModel * dm = CRootContainer::addDatamodel(); @@ -156,7 +155,7 @@ TEST_CASE("Species ODE expressions", "[COPASI][multiple_models]") std::string expression = species.getExpression(); REQUIRE(expression.find("Model=New Model") != std::string::npos); - + CRootContainer::removeDatamodel(dm); CRootContainer::removeDatamodel(dm2); } diff --git a/tests/test_CDataHandler.cpp b/tests/test_CDataHandler.cpp index a78e96ca19..7b6c48507b 100644 --- a/tests/test_CDataHandler.cpp +++ b/tests/test_CDataHandler.cpp @@ -23,7 +23,7 @@ TEST_CASE("1: load model, simulate, collect data", "[copasi][datahandler]") // change the initial time dm->getModel()->setInitialTime(20); - dm->getModel()->updateInitialValues(dm->getModel()->getInitialValueReference()); + dm->getModel()->updateInitialValues(dm->getModel()->getInitialValueReference(), false); dm->getModel()->forceCompile(NULL); dm->getModel()->applyInitialValues(); @@ -127,7 +127,6 @@ TEST_CASE("ensure that data handler with function evaluations can be compiled", CRootContainer::removeDatamodel(dm); } - TEST_CASE("Test resolving of reactions with )", "[copasi][datahandler]") { auto * dm = CRootContainer::addDatamodel(); @@ -140,7 +139,7 @@ TEST_CASE("Test resolving of reactions with )", "[copasi][datahandler]") reaction->setReactionScheme("A -> D"); model->compileIfNecessary(NULL); - // try and retrieve the reaction by display name: + // try and retrieve the reaction by display name: auto fluxName = reaction->getFluxReference()->getObjectDisplayName(); auto* obj = dm->findObjectByDisplayName(fluxName); REQUIRE(obj != nullptr); diff --git a/tests/test_model_creation.cpp b/tests/test_model_creation.cpp index 16e68cc8d8..b6e571b040 100644 --- a/tests/test_model_creation.cpp +++ b/tests/test_model_creation.cpp @@ -1,7 +1,7 @@ -// Copyright (C) 2021 - 2024 by Pedro Mendes, Rector and Visitors of the -// University of Virginia, University of Heidelberg, and University -// of Connecticut School of Medicine. -// All rights reserved. +// Copyright (C) 2021 - 2024 by Pedro Mendes, Rector and Visitors of the +// University of Virginia, University of Heidelberg, and University +// of Connecticut School of Medicine. +// All rights reserved. #include "catch.hpp" @@ -70,7 +70,7 @@ TEST_CASE("create a model with inhibited reaciton", "[copasi][creation]") auto & vars = pFunc->getVariables(); -for (auto & var : vars) + for (auto & var : vars) { if (var.getObjectName() == "A" || var.getObjectName() == "B") var.setUsage(CFunctionParameter::Role::SUBSTRATE); @@ -160,18 +160,18 @@ TEST_CASE("changing initial concentrations", "[copasi][manipulation]") auto * pMetab = model->createMetabolite("speciesB", "compartment"); // change initial concentration -for (auto & metab : model->getMetabolites()) + for (auto & metab : model->getMetabolites()) { if (metab.getObjectDisplayName() != "speciesB") continue; - model->updateInitialValues(metab.getInitialConcentrationReference()); + model->updateInitialValues(metab.getInitialConcentrationReference(), false); metab.setInitialConcentration(0.4); - model->updateInitialValues(metab.getInitialConcentrationReference()); + model->updateInitialValues(metab.getInitialConcentrationReference(), false); } // retrieve metab again -for (auto & metab : model->getMetabolites()) + for (auto & metab : model->getMetabolites()) { if (metab.getObjectDisplayName() != "speciesB") continue; @@ -255,7 +255,6 @@ TEST_CASE("use binary min and max", "[copasi][sbml]") CRootContainer::removeDatamodel(dm); } - TEST_CASE("set up opt problem subtype", "[copasi][optimization]") { auto * dm = CRootContainer::addDatamodel(); @@ -280,7 +279,7 @@ TEST_CASE("set up opt problem subtype", "[copasi][optimization]") REQUIRE(problem != NULL); REQUIRE((problem->getSubtaskType() == CTaskEnum::Task::timeCourse)); } - + CRootContainer::removeDatamodel(dm); } @@ -304,11 +303,9 @@ TEST_CASE("import sbml model and test miriam info", "[copasi][sbml][miriam]") auto miriam = info->getRDFGraph()->toXmlString(); REQUIRE(!miriam.empty()); - CRootContainer::removeDatamodel(dm); } - TEST_CASE("manually create miriam using libsbml", "[copasi][miriam]") { auto * dm = CRootContainer::addDatamodel(); @@ -344,7 +341,6 @@ TEST_CASE("manually create miriam using libsbml", "[copasi][miriam]") #ifdef COPASI_USE_RAPTOR - #include #include #include @@ -376,12 +372,11 @@ TEST_CASE("miriam parsing using libsbml", "[copasi][miriam]") auto incoming = graph1->getIncomingTriplets(start); auto parents = graph1->getParentSubjects(start); - - // now ensure that serializing to string works + // now ensure that serializing to string works CRDFWriter writer; auto * raptorSerialization = writer.write(graph2); auto serialization = graph2->toXmlString(); - + free(raptorSerialization); pdelete(graph1); pdelete(graph2); @@ -401,12 +396,10 @@ TEST_CASE("miriam parsing using libsbml", "[copasi][miriam]") raptorSerialization = writer.write(graph2); serialization = graph2->toXmlString(); - free(raptorSerialization); pdelete(graph1); pdelete(graph2); - CRootContainer::removeDatamodel(dm); } diff --git a/tests/test_sedml.cpp b/tests/test_sedml.cpp index eb0c86628e..2a2d78122a 100644 --- a/tests/test_sedml.cpp +++ b/tests/test_sedml.cpp @@ -25,7 +25,7 @@ TEST_CASE("exporting sedml file with non-zero initial time", "[copasi][sedml]") r->setReactionScheme("A -> B"); model->setInitialTime(10.0); - model->updateInitialValues(model->getInitialValueReference()); + model->updateInitialValues(model->getInitialValueReference(), false); auto & task = dynamic_cast((*dm->getTaskList())["Time-Course"]); task.setScheduled(true); @@ -41,7 +41,7 @@ TEST_CASE("exporting sedml file with non-zero initial time", "[copasi][sedml]") // now lets try and read it back in ensuring that the initial time is being set. model->setInitialTime(0.0); - model->updateInitialValues(model->getInitialValueReference()); + model->updateInitialValues(model->getInitialValueReference(), false); // also reset the task values, to see that hey are updated correctly problem->setDuration(1); problem->setStepNumber(10); @@ -67,7 +67,6 @@ TEST_CASE("exporting sedml file with non-zero initial time", "[copasi][sedml]") CRootContainer::removeDatamodel(dm); } - TEST_CASE("exporting sedml file with non-zero start time", "[copasi][sedml]") { auto * dm = CRootContainer::addDatamodel(); @@ -316,7 +315,6 @@ TEST_CASE("importing document with remote model should fail", "[copasi][sedml]") auto sedml = writeSedMLToStdString(doc); delete doc; - auto * dm = CRootContainer::addDatamodel(); REQUIRE(dm != nullptr);