From 057a75875886eea982b8609c8ca8c3f8a89ce4a4 Mon Sep 17 00:00:00 2001 From: Stefan Hoops Date: Wed, 20 Nov 2024 10:19:58 -0500 Subject: [PATCH] Bug 3265: Raised an issue of missing initial value. --- copasi/model/CReaction.cpp | 45 ++++++- copasi/model/CReaction.h | 1 + copasi/sbml/SBMLImporter.cpp | 253 +++++++++++++++++------------------ 3 files changed, 166 insertions(+), 133 deletions(-) diff --git a/copasi/model/CReaction.cpp b/copasi/model/CReaction.cpp index 1fc5783a5c..e55d782163 100644 --- a/copasi/model/CReaction.cpp +++ b/copasi/model/CReaction.cpp @@ -916,7 +916,6 @@ void CReaction::initializeParameters() mParameters.addParameter(name, CCopasiParameter::Type::DOUBLE, (C_FLOAT64) 1.0); - pParameter = mParameters.getParameter(name); } @@ -990,7 +989,7 @@ CIssue CReaction::compile() // Clear all mValidity flags which might be set here. mValidity.remove(CValidity::Severity::All, - CValidity::Kind(CIssue::eKind::KineticsUndefined) | CIssue::eKind::VariablesMismatch | CIssue::eKind::ObjectNotFound); + CValidity::Kind(CIssue::eKind::KineticsUndefined) | CIssue::eKind::VariablesMismatch | CIssue::eKind::ObjectNotFound | CIssue::eKind::MissingInitialValue); std::set< const CDataObject * > Dependencies; @@ -1003,7 +1002,6 @@ CIssue CReaction::compile() else { Issue &= CIssue(CIssue::eSeverity::Warning, CIssue::eKind::KineticsUndefined); - mValidity.add(Issue); mFlux = 0.0; mParticleFlux = 0.0; } @@ -1058,6 +1056,18 @@ CIssue CReaction::compile() mPrerequisits.erase(NULL); + // Check whether we have local parameters with value NaN + + CCopasiParameterGroup::const_name_iterator itParameter = mParameters.beginName(); + CCopasiParameterGroup::const_name_iterator endParameter = mParameters.endName(); + + for (; itParameter != endParameter; ++itParameter) + if (isLocalParameter(itParameter->getObjectName()) + && std::isnan(itParameter->getValue< C_FLOAT64 >())) + Issue &= CIssue(CIssue::eSeverity::Error, CIssue::eKind::MissingInitialValue); + + mValidity.add(Issue); + return Issue; } @@ -1513,10 +1523,10 @@ std::string CReaction::sanitizeSBMLId(const std::string & id) CEvaluationNodeVariable* CReaction::object2variable(const CEvaluationNodeObject* objectNode, std::map >& replacementMap, std::map& copasi2sbmlmap) { CEvaluationNodeVariable* pVariableNode = NULL; - std::string objectCN = objectNode->getData(); + std::string Data = objectNode->getData(); + CCommonName ObjectCN(Data.substr(1, Data.size() - 2)); - CDataObject * object = resolveCN(getFirstCModelOrDefault(copasi2sbmlmap), - CCommonName(objectCN.substr(1, objectCN.size() - 2))); + CDataObject * object = resolveCN(getFirstCModelOrDefault(copasi2sbmlmap), ObjectCN); std::string id; @@ -1705,6 +1715,29 @@ CEvaluationNodeVariable* CReaction::object2variable(const CEvaluationNodeObject* CCopasiMessage(CCopasiMessage::ERROR, MCReaction + 4); } } + else + { + // We have no mapped object. We will create a variable of type parameter which is not mapped. + // Check whether we already created a variable with that name: + CCommonName ParentCN; + std::string Type; + std::string Name; + + ObjectCN.split(ParentCN, Type, Name); + std::string Id(Name.empty() ? Type : Name); + + pVariableNode = new CEvaluationNodeVariable(CEvaluationNode::SubType::DEFAULT, Id); + + if (replacementMap.find(Id) == replacementMap.end()) + { + CFunctionParameter * pFunParam = new CFunctionParameter(Id, CFunctionParameter::DataType::FLOAT64, + CFunctionParameter::Role::PARAMETER); + mParameters.addParameter(Id, + CCopasiParameter::Type::DOUBLE, + std::numeric_limits< C_FLOAT64 >::quiet_NaN()); + replacementMap[Id] = std::make_pair(mParameters.getParameter(Id), pFunParam); + } + } return pVariableNode; } diff --git a/copasi/model/CReaction.h b/copasi/model/CReaction.h index 3bb980e80f..7b82db86a4 100644 --- a/copasi/model/CReaction.h +++ b/copasi/model/CReaction.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "copasi/model/CAnnotation.h" #include "copasi/model/CMetab.h" diff --git a/copasi/sbml/SBMLImporter.cpp b/copasi/sbml/SBMLImporter.cpp index 62822dc87f..022a48d372 100644 --- a/copasi/sbml/SBMLImporter.cpp +++ b/copasi/sbml/SBMLImporter.cpp @@ -3287,148 +3287,147 @@ CModelValue* SBMLImporter::createCModelValueFromParameter(const Parameter* sbmlP bool SBMLImporter::sbmlId2CopasiCN(ASTNode* pNode, std::map& copasi2sbmlmap, CCopasiParameterGroup& pParamGroup, SBase* pParentObject) { - // TODO CRITICAL We need to use a node iterator - + CNodeIterator< ASTNode > itNode(pNode); + itNode.setProcessingModes(CNodeIteratorMode::Before); bool success = true; - unsigned int i, iMax = pNode->getNumChildren(); - if (pNode->getType() == AST_NAME) + while (itNode.next() != itNode.end()) { - Reaction* pParentReaction = dynamic_cast(pParentObject); - Compartment* pSBMLCompartment = NULL; - Species* pSBMLSpecies = NULL; - Reaction* pSBMLReaction = NULL; - Parameter* pSBMLParameter = NULL; - std::string sbmlId; - std::string name = pNode->getName(); - CCopasiParameter* pParam = pParamGroup.getParameter(name); - - std::map::const_iterator speciesReference = mSBMLSpeciesReferenceIds.find(name); - - // replace species references only in case we don't have a local parameter - // that shadows it - if (speciesReference != mSBMLSpeciesReferenceIds.end() - && (pParentReaction == NULL - || pParentReaction->getKineticLaw() == NULL - || pParentReaction->getKineticLaw()->getParameter(name) == NULL)) - { - // replace the name with the value - pNode->setType(AST_REAL); - pNode->setValue(speciesReference->second); - } - else if (pParam) + if (*itNode == NULL) { - pNode->setName(pParam->getStringCN().c_str()); + continue; } - else + + if (itNode->getType() == AST_NAME) { - std::map::iterator it = copasi2sbmlmap.begin(); - std::map::iterator endIt = copasi2sbmlmap.end(); - bool found = false; + Reaction * pParentReaction = dynamic_cast< Reaction * >(pParentObject); + Compartment * pSBMLCompartment = NULL; + Species * pSBMLSpecies = NULL; + Reaction * pSBMLReaction = NULL; + Parameter * pSBMLParameter = NULL; + std::string sbmlId; + std::string name = itNode->getName(); + CCopasiParameter * pParam = pParamGroup.getParameter(name); - while (it != endIt) + std::map< std::string, double >::const_iterator speciesReference = mSBMLSpeciesReferenceIds.find(name); + + // replace species references only in case we don't have a local parameter + // that shadows it + if (speciesReference != mSBMLSpeciesReferenceIds.end() + && (pParentReaction == NULL + || pParentReaction->getKineticLaw() == NULL + || pParentReaction->getKineticLaw()->getParameter(name) == NULL)) + { + // replace the name with the value + itNode->setType(AST_REAL); + itNode->setValue(speciesReference->second); + } + else if (pParam) { - int type = it->second->getTypeCode(); + itNode->setName(pParam->getStringCN().c_str()); + } + else + { + std::map< const CDataObject *, SBase * >::iterator it = copasi2sbmlmap.begin(); + std::map< const CDataObject *, SBase * >::iterator endIt = copasi2sbmlmap.end(); + bool found = false; - switch (type) + while (it != endIt) { - case SBML_COMPARTMENT: - pSBMLCompartment = dynamic_cast(it->second); - - if (this->mLevel == 1) - { - sbmlId = pSBMLCompartment->getName(); - } - else - { - sbmlId = pSBMLCompartment->getId(); - } - - if (sbmlId == pNode->getName()) - { - pNode->setName(dynamic_cast(it->first)->getObject(CCommonName("Reference=InitialVolume"))->getStringCN().c_str()); - found = true; - } - - break; + int type = it->second->getTypeCode(); - case SBML_SPECIES: - pSBMLSpecies = dynamic_cast(it->second); - - if (this->mLevel == 1) - { - sbmlId = pSBMLSpecies->getName(); - } - else - { - sbmlId = pSBMLSpecies->getId(); - } - - if (sbmlId == pNode->getName()) - { - pNode->setName(dynamic_cast(it->first)->getObject(CCommonName("Reference=InitialConcentration"))->getStringCN().c_str()); - found = true; - } - - break; - - case SBML_REACTION: - pSBMLReaction = dynamic_cast(it->second); - - if (this->mLevel == 1) - { - sbmlId = pSBMLReaction->getName(); - } - else - { - sbmlId = pSBMLReaction->getId(); - } - - if (sbmlId == pNode->getName()) - { - pNode->setName(dynamic_cast(it->first)->getObject(CCommonName("Reference=ParticleFlux"))->getStringCN().c_str()); - found = true; - } - - break; - - case SBML_PARAMETER: - pSBMLParameter = dynamic_cast(it->second); - - if (this->mLevel == 1) - { - sbmlId = pSBMLParameter->getName(); - } - else - { - sbmlId = pSBMLParameter->getId(); - } - - if (sbmlId == pNode->getName()) - { - pNode->setName(dynamic_cast(it->first)->getValueReference()->getStringCN().c_str()); - found = true; - } - - break; + switch (type) + { + case SBML_COMPARTMENT: + pSBMLCompartment = dynamic_cast< Compartment * >(it->second); + + if (this->mLevel == 1) + { + sbmlId = pSBMLCompartment->getName(); + } + else + { + sbmlId = pSBMLCompartment->getId(); + } + + if (sbmlId == itNode->getName()) + { + itNode->setName(dynamic_cast< const CCompartment * >(it->first)->getObject(CCommonName("Reference=InitialVolume"))->getStringCN().c_str()); + found = true; + } + + break; + + case SBML_SPECIES: + pSBMLSpecies = dynamic_cast< Species * >(it->second); + + if (this->mLevel == 1) + { + sbmlId = pSBMLSpecies->getName(); + } + else + { + sbmlId = pSBMLSpecies->getId(); + } + + if (sbmlId == itNode->getName()) + { + itNode->setName(dynamic_cast< const CMetab * >(it->first)->getObject(CCommonName("Reference=InitialConcentration"))->getStringCN().c_str()); + found = true; + } + + break; + + case SBML_REACTION: + pSBMLReaction = dynamic_cast< Reaction * >(it->second); + + if (this->mLevel == 1) + { + sbmlId = pSBMLReaction->getName(); + } + else + { + sbmlId = pSBMLReaction->getId(); + } + + if (sbmlId == itNode->getName()) + { + itNode->setName(dynamic_cast< const CReaction * >(it->first)->getObject(CCommonName("Reference=ParticleFlux"))->getStringCN().c_str()); + found = true; + } + + break; + + case SBML_PARAMETER: + pSBMLParameter = dynamic_cast< Parameter * >(it->second); + + if (this->mLevel == 1) + { + sbmlId = pSBMLParameter->getName(); + } + else + { + sbmlId = pSBMLParameter->getId(); + } + + if (sbmlId == itNode->getName()) + { + itNode->setName(dynamic_cast< const CModelValue * >(it->first)->getValueReference()->getStringCN().c_str()); + found = true; + } + + break; + + default: + break; + } - default: - break; + ++it; } - ++it; + if (!found) + success = false; } - - if (!found) success = false; - } - } - - for (i = 0; i < iMax; ++i) - { - if (!this->sbmlId2CopasiCN(pNode->getChild(i), copasi2sbmlmap, pParamGroup, pParentObject)) - { - success = false; - break; } }