COPASI API  4.16.103
Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
SBMLImporter Class Reference

#include <SBMLImporter.h>

Collaboration diagram for SBMLImporter:
Collaboration graph
[legend]

Public Member Functions

void deleteCopasiModel ()
 
std::string findIdInASTTree (const ASTNode *pMath, const std::set< std::string > &reactionIds)
 
std::string findIdInASTTree (const ASTNode *pMath, const std::map< std::string, double > &reactionIds)
 
bool getImportCOPASIMIRIAM () const
 
CProcessReportgetImportHandlerAddr ()
 
CModelparseSBML (const std::string &sbmlDocumentText, CFunctionDB *funDB, SBMLDocument *&pSBMLDocument, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, CListOfLayouts *&prLol, CCopasiDataModel *pDataModel)
 
CModelreadSBML (std::string filename, CFunctionDB *funDB, SBMLDocument *&pSBMLDocument, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, CListOfLayouts *&prLol, CCopasiDataModel *pDataModel)
 
void restoreFunctionDB ()
 
 SBMLImporter ()
 
void setImportCOPASIMIRIAM (bool import)
 
void setImportHandler (CProcessReport *pHandler)
 
 ~SBMLImporter ()
 

Static Public Member Functions

static bool areEqualFunctions (const CFunction *pFun, const CFunction *pFun2)
 
static bool areEqualSubtrees (const CEvaluationNode *pNode1, const CEvaluationNode *pNode2)
 
static bool areSBMLUnitDefinitionsIdentical (const UnitDefinition *pUdef1, const UnitDefinition *pUdef2)
 
static CEvaluationNodedivideByObject (const CEvaluationNode *pOrigNode, const CCopasiObject *pObject)
 
static UnitDefinition * getSBMLUnitDefinitionForId (const std::string &unitId, const Model *pSBMLModel)
 
static bool importNotes (CAnnotation *pAnno, const SBase *pSBase)
 

Protected Member Functions

void applyStoichiometricExpressions (std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Model *pSBMLModel)
 
void areRulesUnique (const Model *copasiMode)
 
void checkElementUnits (const Model *pSBMLModel, CModel *pCopasiModel, int level, int version)
 
void checkRuleMathConsistency (const Rule *pRule, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
bool containsVolume (const ASTNode *pNode, const std::string &compartmentCN)
 
std::map< std::string, ASTNode * > createBVarMap (const ASTNode *uDefFunction, const ASTNode *function)
 
CCompartmentcreateCCompartmentFromCompartment (const Compartment *sbmlComp, CModel *copasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, const Model *pSBMLModel)
 
CFunctioncreateCFunctionFromFunctionDefinition (const FunctionDefinition *sbmlFunction, CFunctionDB *pTmpFunctionDB, Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
CFunctioncreateCFunctionFromFunctionTree (const FunctionDefinition *pSBMLFunction, Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
CMetabcreateCMetabFromSpecies (const Species *sbmlSpecies, CModel *copasiModel, CCompartment *copasiCompartment, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, const Model *pSBMLModel)
 
CModelcreateCModelFromSBMLDocument (SBMLDocument *doc, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
CModelValuecreateCModelValueFromParameter (const Parameter *sbmlParameter, CModel *copasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
CReactioncreateCReactionFromReaction (Reaction *sbmlReaction, Model *sbmlModel, CModel *cmodel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, CFunctionDB *pTmpFunctionDB)
 
void createDelayFunctionDefinition ()
 
CEvaluationTreecreateExpressionFromFunction (const CFunction *pFun, const std::vector< std::vector< std::string > > &functionArgumentCNs)
 
void createHasOnlySubstanceUnitFactor (Model *pSBMLModel, double factor, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
void doMapping (CReaction *pCopasiReaction, const CEvaluationNodeCall *pCallNode)
 
void find_local_parameters_in_delay (ASTNode *pNode, Reaction *pSBMLReaction, Model *pModel, std::map< std::string, std::string > &localReplacementMap, const std::set< std::string > &localIds, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
void findAvogadroConstant (Model *pSBMLModel, double factor)
 
CFunctionfindCorrespondingFunction (const CExpression *pExpression, const CReaction *reaction)
 
void findFunctionCalls (const CEvaluationNode *pNode, std::set< std::string > &functionNameSet)
 
const FunctionDefinition * getFunctionDefinitionForName (const std::string name, const Model *model)
 
void getIdsFromNode (const ASTNode *pNode, std::set< std::string > &idSet)
 
std::pair< CModel::AreaUnit, bool > handleAreaUnit (const UnitDefinition *uDef)
 
std::pair< CModel::LengthUnit,
bool > 
handleLengthUnit (const UnitDefinition *uDef)
 
std::pair
< CModel::QuantityUnit, bool > 
handleSubstanceUnit (const UnitDefinition *uDef)
 
std::pair< CModel::TimeUnit, bool > handleTimeUnit (const UnitDefinition *uDef)
 
std::pair< CModel::VolumeUnit,
bool > 
handleVolumeUnit (const UnitDefinition *uDef)
 
void importEvent (const Event *pEvent, Model *pSBMLModel, CModel *pCopasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
void importEvents (Model *pSBMLModel, CModel *pCopasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
CFunctionDBimportFunctionDefinitions (Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
void importInitialAssignments (Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlMap, const CModel *pCOPASIModel)
 
bool importMIRIAM (const SBase *pSBMLObject, CCopasiObject *pCOPASIObject)
 
void importRule (const Rule *rule, CModelEntity::Status ruleType, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Model *pSBMLModel)
 
void importRuleForModelEntity (const Rule *rule, CModelEntity *pMV, CModelEntity::Status ruleType, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Model *pSBMLModel)
 
void importSBMLRule (const Rule *sbmlRule, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Model *pSBMLModel)
 
CCopasiObjectisConstantFlux (const CEvaluationNode *pRoot, CModel *pModel, CFunctionDB *pFunctionDB)
 
bool isDelayFunctionUsed (ConverterASTNode *pNode)
 
std::vector
< CEvaluationNodeObject * > * 
isMassAction (const CEvaluationTree *pTree, const CChemEq &chemicalEquation, const CEvaluationNodeCall *pCallNode=NULL)
 
std::vector
< CEvaluationNodeObject * > * 
isMassActionExpression (const CEvaluationNode *pRootNode, const CChemEq &chemicalEquation)
 
std::vector
< CEvaluationNodeObject * > * 
isMassActionFunction (const CFunction *pFun, const CChemEq &chemicalEquation, const std::vector< std::vector< std::string > > &functionArgumentCNs)
 
ConverterASTNodeisMultipliedByVolume (const ASTNode *node, const std::string &compartmentSBMLId)
 
bool isSimpleFunctionCall (const CEvaluationNode *pRootNode)
 
bool isStochasticModel (const Model *pSBMLModel)
 
void multiplySubstanceOnlySpeciesByVolume (ConverterASTNode *pNode)
 
void preprocessNode (ConverterASTNode *pNode, Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Reaction *pSBMLReaction=NULL)
 
bool removeUnusedFunctions (CFunctionDB *pTmpFunctionDB, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
void renameMassActionParameters (CEvaluationNodeCall *pCallNode)
 
void replace_delay_nodes (ConverterASTNode *pNode, Model *pModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Reaction *pSBMLReaction, std::map< std::string, std::string > &localReplacementMap)
 
void replace_name_nodes (ASTNode *pNode, const std::map< std::string, std::string > &replacementMap)
 
void replace_time_with_initial_time (ASTNode *pNode, const CModel *pCOPASIModel)
 
void replaceAmountReferences (ConverterASTNode *pNode, Model *pSBMLModel, double factor, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
void replaceCallNodeNames (ASTNode *pNode)
 
void replaceLog (ConverterASTNode *sourceNode)
 
void replaceObjectNames (ASTNode *pNode, const std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, bool initialExpression=false)
 
void replacePowerFunctionNodes (ASTNode *node)
 
void replaceRoot (ConverterASTNode *sourceNode)
 
void replaceTimeAndAvogadroNodeNames (ASTNode *pNode)
 
void replaceTimeDependentFunctionCalls (ASTNode *root)
 
bool replaceTimeNodesInFunctionDefinition (ASTNode *root, std::string newNodeName)
 
bool sbmlId2CopasiCN (ASTNode *pNode, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, CCopasiParameterGroup &pParamGroup)
 
void separateProductArguments (const CEvaluationNode *pRootNode, std::vector< const CEvaluationNode * > &arguments)
 
void setCorrectUsage (CReaction *pCopasiReaction, const CEvaluationNodeCall *pCallNode)
 
bool setInitialValues (CModel *pModel, const std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
 
CEvaluationNodevariables2objects (const CEvaluationNode *pOrigNode, const std::map< std::string, std::string > &replacementMap)
 

Static Protected Member Functions

static bool areApproximatelyEqual (const double &x, const double &y, const double &t=1e-9)
 
static Unit * convertSBMLCubicmetresToLitres (const Unit *pU)
 
static void findDirectDependencies (const FunctionDefinition *pFunDef, std::map< const FunctionDefinition *, std::set< std::string > > &dependencies)
 
static void findDirectDependencies (const ASTNode *pNode, std::set< std::string > &dependencies)
 
static void normalizeSBMLUnit (Unit *pU)
 
static C_FLOAT64 round (const C_FLOAT64 &x)
 

Protected Attributes

CFunctionDBfunctionDB
 
bool mAssignmentToSpeciesReferenceFound
 
bool mAvogadroCreated
 
bool mAvogadroSet
 
bool mDelayFound
 
std::map< std::string,
std::string > 
mDelayNodeMap
 
std::set< std::string > mDivisionByCompartmentReactions
 
std::set< std::string > mExplicitelyTimeDependentFunctionDefinitions
 
std::set< std::string > mFastReactions
 
std::map< std::string,
std::string > 
mFunctionNameMapping
 
size_t mhImportStep
 
std::vector< std::string > mIgnoredParameterUnits
 
std::set< unsigned int > mIgnoredSBMLMessages
 
bool mImportCOPASIMIRIAM
 
unsigned C_INT32 mImportStep
 
bool mIncompleteModel
 
std::map< std::string,
std::string > 
mKnownCustomUserDefinedFunctions
 
std::map< std::string,
std::string > 
mKnownInitalValues
 
unsigned int mLevel
 
unsigned int mOriginalLevel
 
CModelmpCopasiModel
 
CCopasiDataModelmpDataModel
 
CProcessReportmpImportHandler
 
std::set< const Parameter * > mPotentialAvogadroNumbers
 
std::set< std::string > mReactionsWithReplacedLocalParameters
 
std::map< const ASTNode
*, CChemEqElement * > 
mStoichiometricExpressionMap
 
std::map< Species
*, Compartment * > 
mSubstanceOnlySpecies
 
unsigned C_INT32 mTotalSteps
 
bool mUnitOnNumberFound
 
bool mUnsupportedAssignmentRuleFound
 
bool mUnsupportedRateRuleFound
 
bool mUnsupportedRuleFound
 
std::set< std::string > mUsedFunctions
 
std::set< std::string > mUsedSBMLIds
 
bool mUsedSBMLIdsPopulated
 
unsigned int mVersion
 
std::map< CFunction
*, std::string > 
sbmlIdMap
 
std::map< std::string, CMetab * > speciesMap
 

Detailed Description

Definition at line 44 of file SBMLImporter.h.

Constructor & Destructor Documentation

SBMLImporter::SBMLImporter ( )

Constructor that initializes speciesMap and the FunctionDB object

Definition at line 3045 of file SBMLImporter.cpp.

References functionDB, mAssignmentToSpeciesReferenceFound, mAvogadroCreated, mDelayFound, mIgnoredSBMLMessages, mIncompleteModel, mpImportHandler, mUnitOnNumberFound, mUnsupportedAssignmentRuleFound, mUnsupportedRateRuleFound, mUnsupportedRuleFound, and speciesMap.

3045  :
3047  speciesMap(),
3048  functionDB(NULL),
3049  mIncompleteModel(false),
3050  mUnsupportedRuleFound(false),
3053  mUnitOnNumberFound(false),
3055  mLevel(0),
3056  mOriginalLevel(0),
3057  mVersion(0),
3058  sbmlIdMap(),
3059  mUsedFunctions(),
3060  mpDataModel(NULL),
3061  mpCopasiModel(NULL),
3064  mpImportHandler(NULL),
3065  mImportStep(0),
3067  mTotalSteps(0),
3069  mFastReactions(),
3074  mDelayFound(false),
3076  mAvogadroCreated(false),
3077  mImportCOPASIMIRIAM(true),
3078  mDelayNodeMap(),
3079  mUsedSBMLIds(),
3080  mUsedSBMLIdsPopulated(false),
3081  mAvogadroSet(false),
3083 #if LIBSBML_VERSION >= 40100
3084  mpModelConversionFactor(NULL),
3085  mChemEqElementSpeciesIdMap(),
3086  mSpeciesConversionParameterMap(),
3087  mSBMLIdModelValueMap(),
3088  mSBMLSpeciesReferenceIds(),
3089  mRateRuleForSpeciesReferenceIgnored(false),
3090  mEventAssignmentForSpeciesReferenceIgnored(false),
3091  mConversionFactorFound(false),
3092 # if LIBSBML_VERSION >= 40200
3093  mEventPrioritiesIgnored(false),
3094  mInitialTriggerValues(false),
3095  mNonPersistentTriggerFound(false)
3096 # endif // LIBSBML_VERSION >= 40200
3097 #endif // LIBSBML_VERSION >= 40100
3098 {
3099  this->speciesMap = std::map<std::string, CMetab*>();
3100  this->functionDB = NULL;
3101  this->mIncompleteModel = false;
3102  this->mUnsupportedRuleFound = false;
3103  this->mUnsupportedRateRuleFound = false;
3104  this->mUnsupportedAssignmentRuleFound = false;
3105  this->mUnitOnNumberFound = false;
3106  this->mAssignmentToSpeciesReferenceFound = false;
3107  this->mpImportHandler = NULL;
3108  this->mDelayFound = false;
3109  this->mAvogadroCreated = false;
3110  // these data structures are used to handle the new conversion factores in
3111  // SBML L3 models and references to species references
3112  this->mpModelConversionFactor = NULL;
3113  this->mChemEqElementSpeciesIdMap.clear();
3114  this->mSpeciesConversionParameterMap.clear();
3115  this->mSBMLIdModelValueMap.clear();
3116  this->mRateRuleForSpeciesReferenceIgnored = false;
3117  this->mEventAssignmentForSpeciesReferenceIgnored = false;
3118  this->mConversionFactorFound = false;
3119  this->mEventPrioritiesIgnored = false;
3120  this->mInitialTriggerValues = false;
3121  this->mNonPersistentTriggerFound = false;
3122 
3123  this->mIgnoredSBMLMessages.insert(10501);
3124  this->mIgnoredSBMLMessages.insert(10512);
3125  this->mIgnoredSBMLMessages.insert(10513);
3126  this->mIgnoredSBMLMessages.insert(10522);
3127  this->mIgnoredSBMLMessages.insert(10533);
3128  this->mIgnoredSBMLMessages.insert(10541);
3129  this->mIgnoredSBMLMessages.insert(10551);
3130  this->mIgnoredSBMLMessages.insert(10562);
3131  this->mIgnoredSBMLMessages.insert(80701);
3132  this->mIgnoredSBMLMessages.insert(99505);
3133 }
std::set< unsigned int > mIgnoredSBMLMessages
Definition: SBMLImporter.h:54
size_t mhImportStep
Definition: SBMLImporter.h:74
bool mAvogadroCreated
Definition: SBMLImporter.h:84
bool mUnitOnNumberFound
Definition: SBMLImporter.h:61
bool mUnsupportedRateRuleFound
Definition: SBMLImporter.h:59
unsigned int mLevel
Definition: SBMLImporter.h:63
CModel * mpCopasiModel
Definition: SBMLImporter.h:69
std::map< std::string, std::string > mFunctionNameMapping
Definition: SBMLImporter.h:70
std::set< std::string > mReactionsWithReplacedLocalParameters
Definition: SBMLImporter.h:78
std::map< Species *, Compartment * > mSubstanceOnlySpecies
Definition: SBMLImporter.h:76
CProcessReport * mpImportHandler
Definition: SBMLImporter.h:72
bool mDelayFound
Definition: SBMLImporter.h:82
#define C_INVALID_INDEX
Definition: copasi.h:222
bool mUnsupportedRuleFound
Definition: SBMLImporter.h:58
unsigned int mVersion
Definition: SBMLImporter.h:65
std::set< const Parameter * > mPotentialAvogadroNumbers
Definition: SBMLImporter.h:83
std::set< std::string > mUsedFunctions
Definition: SBMLImporter.h:67
std::set< std::string > mUsedSBMLIds
Definition: SBMLImporter.h:89
unsigned C_INT32 mImportStep
Definition: SBMLImporter.h:73
std::map< std::string, std::string > mKnownCustomUserDefinedFunctions
Definition: SBMLImporter.h:92
CCopasiDataModel * mpDataModel
Definition: SBMLImporter.h:68
bool mAvogadroSet
Definition: SBMLImporter.h:91
CFunctionDB * functionDB
Definition: SBMLImporter.h:56
bool mIncompleteModel
Definition: SBMLImporter.h:57
bool mAssignmentToSpeciesReferenceFound
Definition: SBMLImporter.h:62
std::map< const ASTNode *, CChemEqElement * > mStoichiometricExpressionMap
Definition: SBMLImporter.h:81
std::set< std::string > mDivisionByCompartmentReactions
Definition: SBMLImporter.h:71
std::set< std::string > mFastReactions
Definition: SBMLImporter.h:77
std::map< std::string, std::string > mDelayNodeMap
Definition: SBMLImporter.h:88
std::set< std::string > mExplicitelyTimeDependentFunctionDefinitions
Definition: SBMLImporter.h:79
bool mImportCOPASIMIRIAM
Definition: SBMLImporter.h:85
std::map< CFunction *, std::string > sbmlIdMap
Definition: SBMLImporter.h:66
unsigned C_INT32 mTotalSteps
Definition: SBMLImporter.h:75
std::map< std::string, CMetab * > speciesMap
Definition: SBMLImporter.h:55
std::vector< std::string > mIgnoredParameterUnits
Definition: SBMLImporter.h:80
unsigned int mOriginalLevel
Definition: SBMLImporter.h:64
bool mUnsupportedAssignmentRuleFound
Definition: SBMLImporter.h:60
bool mUsedSBMLIdsPopulated
Definition: SBMLImporter.h:90
SBMLImporter::~SBMLImporter ( )

Destructor that does nothing.

Definition at line 3138 of file SBMLImporter.cpp.

3139 {}

Member Function Documentation

void SBMLImporter::applyStoichiometricExpressions ( std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap,
Model *  pSBMLModel 
)
protected

This method evaluates all stoichiometric expressions and sets them as constants on the CChemEqElement.

Definition at line 8980 of file SBMLImporter.cpp.

References CChemEq::addMetabolite(), CCopasiVector< T >::begin(), CExpression::calcValue(), CExpression::compile(), CCopasiVector< T >::end(), fatalError, CChemEqElement::getMetabolite(), CChemEqElement::getMetaboliteKey(), CChemEqElement::getMultiplicity(), CCopasiObject::getObjectParent(), CEvaluationTree::getRoot(), CModelEntity::getSBMLId(), CReaction::getSBMLId(), CChemEq::getSubstrates(), MCSBML, mpCopasiModel, mpDataModel, mStoichiometricExpressionMap, preprocessNode(), CChemEq::PRODUCT, replaceObjectNames(), CEvaluationTree::setTree(), CChemEq::SUBSTRATE, and CCopasiMessage::WARNING.

Referenced by createCModelFromSBMLDocument().

8981 {
8982  bool warningDone = false;
8983  std::map<const ASTNode*, CChemEqElement* >::iterator it = this->mStoichiometricExpressionMap.begin(), end = this->mStoichiometricExpressionMap.end();
8984  std::vector<CCopasiContainer*> listOfContainers;
8985  listOfContainers.push_back(this->mpCopasiModel);
8986 
8987  while (it != end)
8988  {
8989  assert(it->second != NULL);
8990  CChemEqElement* pChemEqElement = it->second;
8991  ConverterASTNode* pNode = new ConverterASTNode(*it->first);
8992  this->preprocessNode(pNode, pSBMLModel, copasi2sbmlmap);
8993  this->replaceObjectNames(pNode, copasi2sbmlmap, true);
8994  CExpression* pExpr = new CExpression("", mpDataModel);
8995  pExpr->setTree(*pNode);
8996  pExpr->compile(listOfContainers);
8997  delete pNode;
8998 
8999  if (pExpr->getRoot() == NULL)
9000  {
9001  const CReaction* pR = dynamic_cast<const CReaction*>(pChemEqElement->getObjectParent()->getObjectParent()->getObjectParent());
9002  std::string id = pChemEqElement->getMetabolite()->getSBMLId();
9003  // create an error message that some stoichiometric expression
9004  // could not be evaluated that the value for the stoichiometry has
9005  // been set to 1.0
9006  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 65, id.c_str(), pR->getSBMLId().c_str());
9007  }
9008  else
9009  {
9010  double value = pExpr->calcValue();
9011  value -= pChemEqElement->getMultiplicity();
9012  // find out if the metabolite is a substrate or a product
9013  delete pExpr;
9014  CChemEq* pChemEq = dynamic_cast<CChemEq*>(pChemEqElement->getObjectParent()->getObjectParent());
9015  assert(pChemEq != NULL);
9016 
9017  if (pChemEq != NULL)
9018  {
9019  CCopasiVector < CChemEqElement >::const_iterator iit = pChemEq->getSubstrates().begin(), iendit = pChemEq->getSubstrates().end();
9020 
9021  while (iit != iendit)
9022  {
9023  if ((*iit) == pChemEqElement)
9024  {
9025  break;
9026  }
9027 
9028  ++iit;
9029  }
9030 
9031  if (iit != iendit)
9032  {
9033  pChemEq->addMetabolite(pChemEqElement->getMetaboliteKey(), value, CChemEq::SUBSTRATE);
9034  }
9035  else
9036  {
9037  pChemEq->addMetabolite(pChemEqElement->getMetaboliteKey(), value, CChemEq::PRODUCT);
9038  }
9039 
9040  // give a warning that an stoichiometric expression has been
9041  // converted into a constant
9042  if (!warningDone && !this->mStoichiometricExpressionMap.empty())
9043  {
9045  warningDone = true;
9046  }
9047  }
9048  else
9049  {
9050  fatalError();
9051  }
9052  }
9053 
9054  ++it;
9055  }
9056 }
const std::string & getSBMLId() const
CModel * mpCopasiModel
Definition: SBMLImporter.h:69
iterator begin()
const CMetab * getMetabolite() const
#define fatalError()
void replaceObjectNames(ASTNode *pNode, const std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, bool initialExpression=false)
virtual bool compile(std::vector< CCopasiContainer * > listOfContainer=CCopasiContainer::EmptyList)
Definition: CExpression.cpp:97
const std::string & getSBMLId() const
Definition: CReaction.cpp:1654
#define MCSBML
iterator end()
CCopasiDataModel * mpDataModel
Definition: SBMLImporter.h:68
virtual const C_FLOAT64 & calcValue()
const C_FLOAT64 & getMultiplicity() const
const std::string & getMetaboliteKey() const
void preprocessNode(ConverterASTNode *pNode, Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Reaction *pSBMLReaction=NULL)
std::map< const ASTNode *, CChemEqElement * > mStoichiometricExpressionMap
Definition: SBMLImporter.h:81
bool setTree(const ASTNode &pRootNode)
const CCopasiVector< CChemEqElement > & getSubstrates() const
Definition: CChemEq.cpp:60
bool addMetabolite(const std::string &key, const C_FLOAT64 multiplicity, const MetaboliteRole &role)
Definition: CChemEq.cpp:80
CEvaluationNode * getRoot()
CCopasiContainer * getObjectParent() const
bool SBMLImporter::areApproximatelyEqual ( const double &  x,
const double &  y,
const double &  t = 1e-9 
)
staticprotected

Definition at line 177 of file SBMLImporter.cpp.

References min.

Referenced by areSBMLUnitDefinitionsIdentical(), findAvogadroConstant(), handleAreaUnit(), handleLengthUnit(), handleSubstanceUnit(), handleTimeUnit(), handleVolumeUnit(), isMassActionExpression(), and replaceAmountReferences().

178 {
179  double Scale =
180  (fabs(x) + fabs(y)) * t;
181 
182  // Avoid underflow
183  if (Scale < 100.0 * std::numeric_limits< C_FLOAT64 >::min())
184  return true;
185 
186  return 2 * fabs(x - y) < Scale;
187 }
#define min(a, b)
Definition: f2c.h:175
bool SBMLImporter::areEqualFunctions ( const CFunction pFun,
const CFunction pFun2 
)
static

Definition at line 5121 of file SBMLImporter.cpp.

References areEqualSubtrees(), CCopasiObject::getObjectName(), CEvaluationTree::getRoot(), CFunction::getVariables(), and CFunctionParameters::size().

Referenced by createCFunctionFromFunctionDefinition(), findCorrespondingFunction(), and CReaction::setFunctionFromExpressionTree().

5122 {
5123  bool result = true;
5124  const CFunctionParameters& funParams1 = pFun->getVariables();
5125  const CFunctionParameters& funParams2 = pFun2->getVariables();
5126 
5127  if (funParams1.size() == funParams2.size())
5128  {
5129  size_t i, iMax = funParams1.size();
5130 
5131  for (i = 0; i < iMax; ++i)
5132  {
5133  const CFunctionParameter* pFunParam1 = funParams1[i];
5134  const CFunctionParameter* pFunParam2 = funParams2[i];
5135 
5136  if (pFunParam1->getObjectName() != pFunParam2->getObjectName())
5137  {
5138  result = false;
5139  break;
5140  }
5141  }
5142 
5143  if (result == true)
5144  {
5145  const CEvaluationNode* pNodeFun1 = static_cast<const CEvaluationNode*>(pFun->getRoot());
5146  const CEvaluationNode* pNodeFun2 = static_cast<const CEvaluationNode*>(pFun2->getRoot());
5147  result = areEqualSubtrees(pNodeFun1, pNodeFun2);
5148  }
5149  }
5150  else
5151  {
5152  result = false;
5153  }
5154 
5155  return result;
5156 }
const std::string & getObjectName() const
static bool areEqualSubtrees(const CEvaluationNode *pNode1, const CEvaluationNode *pNode2)
CEvaluationNode * getRoot()
CFunctionParameters & getVariables()
Definition: CFunction.cpp:148
bool SBMLImporter::areEqualSubtrees ( const CEvaluationNode pNode1,
const CEvaluationNode pNode2 
)
static

Compares to CEvaluationNode based subtrees recursively.

Definition at line 5159 of file SBMLImporter.cpp.

References CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getData(), CCopasiNode< _Data >::getSibling(), and CEvaluationNode::getType().

Referenced by areEqualFunctions().

5160 {
5161  // TODO CRITICAL We need to use a node iterator
5162  bool result = ((pNode1->getType() == pNode2->getType()) && (pNode1->getData() == pNode2->getData()));
5163  const CEvaluationNode* pChild1 = static_cast<const CEvaluationNode*>(pNode1->getChild());
5164  const CEvaluationNode* pChild2 = static_cast<const CEvaluationNode*>(pNode2->getChild());
5165 
5166  while (result && pChild1 && pChild2)
5167  {
5168  result = areEqualSubtrees(pChild1, pChild2);
5169  pChild1 = static_cast<const CEvaluationNode*>(pChild1->getSibling());
5170  pChild2 = static_cast<const CEvaluationNode*>(pChild2->getSibling());
5171  }
5172 
5173  result = (result && !pChild1 && !pChild2);
5174  return result;
5175 }
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
const Type & getType() const
static bool areEqualSubtrees(const CEvaluationNode *pNode1, const CEvaluationNode *pNode2)
virtual const Data & getData() const
Definition: CCopasiNode.h:118
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
void SBMLImporter::areRulesUnique ( const Model *  copasiMode)
protected

Checks if no id is used in more than one Assignment and RateRule.

Definition at line 6662 of file SBMLImporter.cpp.

References CCopasiMessage::EXCEPTION, and MCSBML.

Referenced by createCModelFromSBMLDocument().

6663 {
6664  std::set<std::string> idSet;
6665 
6666  // go through the rules and check that no id is used in more than one rule
6667  unsigned int i, iMax = sbmlModel->getNumRules();
6668 
6669  for (i = 0; i < iMax; ++i)
6670  {
6671  const Rule* pRule = sbmlModel->getRule(i);
6672  std::string id;
6673 
6674  switch (pRule->getTypeCode())
6675  {
6676  case SBML_ASSIGNMENT_RULE:
6677  id = dynamic_cast<const AssignmentRule*>(pRule)->getVariable();
6678  break;
6679 
6680  case SBML_RATE_RULE:
6681  id = dynamic_cast<const RateRule*>(pRule)->getVariable();
6682  break;
6683 
6684  default:
6685  break;
6686  }
6687 
6688  if (!id.empty())
6689  {
6690  if (!idSet.insert(id).second)
6691  {
6692  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 35, id.c_str());
6693  break;
6694  }
6695  }
6696  }
6697 }
#define MCSBML
const char * id
Definition: stdsoap2.h:1262
bool SBMLImporter::areSBMLUnitDefinitionsIdentical ( const UnitDefinition *  pUdef1,
const UnitDefinition *  pUdef2 
)
static

Enhanced method to identify identical SBML unit definitions. This method uses the areIdentical method from libSBML, but if the method return false, it does some extra checks. Right now it check for example if two volumes, one given in litre and one given in cubic meters are identical.

Enhanced method to identify identical sbml unit definitions. The method first converts the unit definitions to SI units and simplifies them, only then they are compared.

Definition at line 8297 of file SBMLImporter.cpp.

References areApproximatelyEqual().

Referenced by CSBMLExporter::check_for_spatial_size_units(), checkElementUnits(), CSBMLExporter::createAreaUnit(), createCModelFromSBMLDocument(), CSBMLExporter::createLengthUnit(), CSBMLExporter::createSubstanceUnit(), CSBMLExporter::createTimeUnit(), and CSBMLExporter::createVolumeUnit().

8298 {
8299  UnitDefinition* pTmpUdef1 = UnitDefinition::convertToSI(pUdef1);
8300  UnitDefinition::simplify(pTmpUdef1);
8301  UnitDefinition* pTmpUdef2 = UnitDefinition::convertToSI(pUdef2);
8302  UnitDefinition::simplify(pTmpUdef2);
8303  bool result = UnitDefinition::areIdentical(pUdef1, pUdef2);
8304 
8305  if (result == false)
8306  {
8307  // check if maybe everything is the same, only the multipliers are
8308  // somewhat off due to rounding errors
8309  bool newResult = true;
8310 
8311  if (pTmpUdef1->getNumUnits() == pTmpUdef2->getNumUnits())
8312  {
8313  UnitDefinition::reorder(pTmpUdef1);
8314  UnitDefinition::reorder(pTmpUdef2);
8315  unsigned int i = 0, iMax = pTmpUdef1->getNumUnits();
8316 
8317  // for COPASI mole and avogadro are the same units, so in order to compare them,
8318  // we replace the avogadro unit by mole
8319  for (i = 0; i < iMax; ++i)
8320  {
8321  if (pTmpUdef1->getUnit(i)->getKind() == UNIT_KIND_AVOGADRO)
8322  {
8323  pTmpUdef1->getUnit(i)->setKind(UNIT_KIND_MOLE);
8324  }
8325 
8326  if (pTmpUdef2->getUnit(i)->getKind() == UNIT_KIND_AVOGADRO)
8327  {
8328  pTmpUdef2->getUnit(i)->setKind(UNIT_KIND_MOLE);
8329  }
8330  }
8331 
8332  // we have to reset i to 0
8333  i = 0;
8334  const Unit *pU1, *pU2;
8335 
8336  while (newResult == true && i != iMax)
8337  {
8338  pU1 = pTmpUdef1->getUnit(i);
8339  pU2 = pTmpUdef2->getUnit(i);
8340 
8341  if (pU1->getKind() != pU2->getKind() ||
8342  pU1->getExponent() != pU2->getExponent() ||
8343  pU1->getScale() != pU2->getScale() ||
8344  !areApproximatelyEqual(pU2->getMultiplier(), pU1->getMultiplier()))
8345  {
8346  newResult = false;
8347  }
8348 
8349  ++i;
8350  }
8351 
8352  result = newResult;
8353  }
8354  }
8355 
8356  delete pTmpUdef1;
8357  delete pTmpUdef2;
8358  return result;
8359 }
static bool areApproximatelyEqual(const double &x, const double &y, const double &t=1e-9)
void SBMLImporter::checkElementUnits ( const Model *  pSBMLModel,
CModel pCopasiModel,
int  level,
int  version 
)
protected

Definition at line 7353 of file SBMLImporter.cpp.

References areSBMLUnitDefinitionsIdentical(), CModel::dimensionlessArea, CModel::dimensionlessLength, CModel::dimensionlessVolume, CCopasiMessage::EXCEPTION, fatalError, getSBMLUnitDefinitionForId(), handleAreaUnit(), handleLengthUnit(), handleSubstanceUnit(), handleTimeUnit(), handleVolumeUnit(), MCSBML, CModel::setAreaUnit(), CModel::setLengthUnit(), CModel::setTimeUnit(), CModel::setVolumeUnit(), and CCopasiMessage::WARNING.

Referenced by createCModelFromSBMLDocument().

7354 {
7355  unsigned int i, iMax = pSBMLModel->getNumCompartments();
7356  std::vector<std::string> nonDefaultCompartments;
7357  std::vector<std::string> nonDefaultSpecies;
7358  std::vector<std::string> nonDefaultKineticTime;
7359  std::vector<std::string> nonDefaultKineticSubstance;
7360  std::vector<std::string> nonDefaultEventTime;
7361  const Compartment* pCompartment;
7362  const Species* pSpecies;
7363  const Reaction* pReaction;
7364  const KineticLaw* pKineticLaw;
7365  UnitDefinition* pDimensionlessUnits = getSBMLUnitDefinitionForId("dimensionless", pSBMLModel);
7366  UnitDefinition* pLengthUnits = getSBMLUnitDefinitionForId("length", pSBMLModel);
7367  UnitDefinition* pAreaUnits = getSBMLUnitDefinitionForId("area", pSBMLModel);
7368  UnitDefinition* pVolumeUnits = getSBMLUnitDefinitionForId("volume", pSBMLModel);
7369  UnitDefinition* pTimeUnits = getSBMLUnitDefinitionForId("time", pSBMLModel);
7370  UnitDefinition* pSubstanceUnits = getSBMLUnitDefinitionForId("substance", pSBMLModel);
7371  std::string lastVolumeUnit = "";
7372  std::string lastAreaUnit = "";
7373  std::string lastLengthUnit = "";
7374  std::string lastDimensionlessUnit = "";
7375  bool inconsistentVolumeUnits = false;
7376  bool inconsistentAreaUnits = false;
7377  bool inconsistentLengthUnits = false;
7378  bool inconsistentDimensionlessUnits = false;
7379  bool defaultVolumeUsed = false;
7380  bool defaultAreaUsed = false;
7381  bool defaultLengthUsed = false;
7382 
7383  for (i = 0; i < iMax; ++i)
7384  {
7385  pCompartment = pSBMLModel->getCompartment(i);
7386 
7387  if (pCompartment->getSpatialDimensions() == 3)
7388  {
7389  if (pCompartment->isSetUnits())
7390  {
7391  std::string unitId = pCompartment->getUnits();
7392  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
7393 
7394  if (pUdef1 == NULL)
7395  {
7396  // error message
7397  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "units", "compartment", pCompartment->getId().c_str());
7398  }
7399  else
7400  {
7401  std::pair<CModel::VolumeUnit, bool> result = this->handleVolumeUnit(pUdef1);
7402 
7403  if (result.second == false)
7404  {
7405  // we did not recognize the unit
7406  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "volume", "the 3 dimensional compartment", pCompartment->getId().c_str());
7407  delete pUdef1;
7408  continue;
7409  }
7410  }
7411 
7412  if (unitId != "volume" && !areSBMLUnitDefinitionsIdentical(pVolumeUnits, pUdef1))
7413  {
7414  nonDefaultCompartments.push_back(pCompartment->getId());
7415  }
7416  else if (unitId == "volume")
7417  {
7418  defaultVolumeUsed = true;
7419  }
7420 
7421  if (lastVolumeUnit == "")
7422  {
7423  lastVolumeUnit = unitId;
7424  }
7425  else if (unitId != lastVolumeUnit)
7426  {
7427  // check if the two units have identical definitions
7428  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastVolumeUnit, pSBMLModel);
7429  assert(pUdef2 != NULL);
7430 
7431  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
7432  {
7433  inconsistentVolumeUnits = true;
7434  }
7435 
7436  delete pUdef2;
7437  }
7438 
7439  delete pUdef1;
7440  }
7441  else if (lastVolumeUnit == "")
7442  {
7443  lastVolumeUnit = "volume";
7444  defaultVolumeUsed = true;
7445  }
7446  else
7447  {
7448  defaultVolumeUsed = true;
7449  // compare the default volume unit to the lastVolumeUnit
7450  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastVolumeUnit, pSBMLModel);
7451  assert(pUdef2 != NULL);
7452 
7453  if (!areSBMLUnitDefinitionsIdentical(pVolumeUnits, pUdef2))
7454  {
7455  inconsistentVolumeUnits = true;
7456  }
7457 
7458  delete pUdef2;
7459  lastVolumeUnit = "volume";
7460  }
7461  }
7462  else if (pCompartment->getSpatialDimensions() == 2)
7463  {
7464  if (pCompartment->isSetUnits())
7465  {
7466  std::string unitId = pCompartment->getUnits();
7467  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
7468 
7469  if (pUdef1 == NULL)
7470  {
7471  // error message
7472  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "units", "compartment", pCompartment->getId().c_str());
7473  }
7474  else
7475  {
7476  std::pair<CModel::AreaUnit, bool> result = this->handleAreaUnit(pUdef1);
7477 
7478  if (result.second == false)
7479  {
7480  // we did not recognize the unit
7481  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "area", "the 2 dimensional compartment", pCompartment->getId().c_str());
7482  continue;
7483  }
7484  }
7485 
7486  if (unitId != "area" && !areSBMLUnitDefinitionsIdentical(pAreaUnits, pUdef1))
7487  {
7488  nonDefaultCompartments.push_back(pCompartment->getId());
7489  }
7490  else if (unitId == "area")
7491  {
7492  defaultAreaUsed = true;
7493  }
7494 
7495  if (lastAreaUnit == "")
7496  {
7497  lastAreaUnit = unitId;
7498  }
7499  else if (unitId != lastAreaUnit)
7500  {
7501  // check if the two units have identical definitions
7502  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastAreaUnit, pSBMLModel);
7503  assert(pUdef2 != NULL);
7504 
7505  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
7506  {
7507  inconsistentAreaUnits = true;
7508  }
7509 
7510  delete pUdef2;
7511  }
7512 
7513  delete pUdef1;
7514  }
7515  else if (lastAreaUnit == "")
7516  {
7517  lastAreaUnit = "area";
7518  defaultAreaUsed = true;
7519  }
7520  else
7521  {
7522  defaultAreaUsed = true;
7523  // compare the default area unit to the lastAreaUnit
7524  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastAreaUnit, pSBMLModel);
7525  assert(pUdef2 != NULL);
7526 
7527  if (!areSBMLUnitDefinitionsIdentical(pAreaUnits, pUdef2))
7528  {
7529  inconsistentAreaUnits = true;
7530  }
7531 
7532  delete pUdef2;
7533  lastAreaUnit = "area";
7534  }
7535  }
7536  else if (pCompartment->getSpatialDimensions() == 1)
7537  {
7538  if (pCompartment->isSetUnits())
7539  {
7540  std::string unitId = pCompartment->getUnits();
7541  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
7542 
7543  if (pUdef1 == NULL)
7544  {
7545  // error message
7546  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "units", "compartment", pCompartment->getId().c_str());
7547  }
7548  else
7549  {
7550  std::pair<CModel::LengthUnit, bool> result = this->handleLengthUnit(pUdef1);
7551 
7552  if (result.second == false)
7553  {
7554  // we did not recognize the unit
7555  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "length", "the 1 dimensional compartment", pCompartment->getId().c_str());
7556  continue;
7557  }
7558  }
7559 
7560  if (unitId != "length" && !areSBMLUnitDefinitionsIdentical(pLengthUnits, pUdef1))
7561  {
7562  nonDefaultCompartments.push_back(pCompartment->getId());
7563  }
7564  else if (unitId == "length")
7565  {
7566  defaultLengthUsed = true;
7567  }
7568 
7569  if (lastLengthUnit == "")
7570  {
7571  lastLengthUnit = unitId;
7572  }
7573  else if (unitId != lastLengthUnit)
7574  {
7575  // check if the two units have identical definitions
7576  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastLengthUnit, pSBMLModel);
7577  assert(pUdef2 != NULL);
7578 
7579  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
7580  {
7581  inconsistentLengthUnits = true;
7582  }
7583 
7584  delete pUdef2;
7585  }
7586 
7587  delete pUdef1;
7588  }
7589  else if (lastLengthUnit == "")
7590  {
7591  lastLengthUnit = "length";
7592  defaultLengthUsed = true;
7593  }
7594  else
7595  {
7596  defaultLengthUsed = true;
7597  // compare the default length unit to the lastLengthUnit
7598  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastLengthUnit, pSBMLModel);
7599  assert(pUdef2 != NULL);
7600 
7601  if (!areSBMLUnitDefinitionsIdentical(pLengthUnits, pUdef2))
7602  {
7603  inconsistentLengthUnits = true;
7604  }
7605 
7606  delete pUdef2;
7607  lastLengthUnit = "length";
7608  }
7609  }
7610  else if (pCompartment->getSpatialDimensions() == 0)
7611  {
7612  if (pCompartment->isSetUnits())
7613  {
7614  std::string unitId = pCompartment->getUnits();
7615  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
7616 
7617  if (pUdef1 == NULL)
7618  {
7619  // error message
7620  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "units", "compartment", pCompartment->getId().c_str());
7621  }
7622 
7623  if (unitId != "dimensionless" && !areSBMLUnitDefinitionsIdentical(pDimensionlessUnits, pUdef1))
7624  {
7625  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "dimensionless", "the 0 dimensional compartment", pCompartment->getId().c_str());
7626  continue;
7627  }
7628 
7629  if (lastDimensionlessUnit == "")
7630  {
7631  lastDimensionlessUnit = unitId;
7632  }
7633  else if (unitId != lastDimensionlessUnit)
7634  {
7635  // check if the two units have identical definitions
7636  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastDimensionlessUnit, pSBMLModel);
7637  assert(pUdef2 != NULL);
7638 
7639  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
7640  {
7641  inconsistentDimensionlessUnits = true;
7642  }
7643 
7644  delete pUdef2;
7645  }
7646 
7647  delete pUdef1;
7648  }
7649  else if (lastDimensionlessUnit == "")
7650  {
7651  lastDimensionlessUnit = "dimensionless";
7652  }
7653  }
7654  }
7655 
7656  if (!inconsistentVolumeUnits && lastVolumeUnit != "" && lastVolumeUnit != "volume")
7657  {
7658  // try to set the default volume unit to the unit defined by lastUnit
7659  const UnitDefinition* pUdef = SBMLImporter::getSBMLUnitDefinitionForId(lastVolumeUnit, pSBMLModel);
7660  assert(pUdef != NULL);
7661  std::pair<CModel::VolumeUnit, bool> volume = this->handleVolumeUnit(pUdef);
7662 
7663  if (volume.second == true)
7664  {
7665  // set the default volume unit
7666  pCopasiModel->setVolumeUnit(volume.first);
7667  delete pVolumeUnits;
7668  pVolumeUnits = dynamic_cast<UnitDefinition*>(pUdef->clone());
7669  }
7670  else
7671  {
7672  inconsistentVolumeUnits = true;
7673  }
7674 
7675  delete pUdef;
7676  }
7677 
7678  if (!inconsistentAreaUnits && lastAreaUnit != "" && lastAreaUnit != "area")
7679  {
7680  // try to set the default area unit to the unit defined by lastAreaUnit
7681  const UnitDefinition* pUdef = SBMLImporter::getSBMLUnitDefinitionForId(lastAreaUnit, pSBMLModel);
7682  assert(pUdef != NULL);
7683  std::pair<CModel::AreaUnit, bool> area = this->handleAreaUnit(pUdef);
7684 
7685  if (area.second == true)
7686  {
7687  // set the default area unit
7688  pCopasiModel->setAreaUnit(area.first);
7689  delete pAreaUnits;
7690  pAreaUnits = dynamic_cast<UnitDefinition*>(pUdef->clone());
7691  }
7692  else
7693  {
7694  inconsistentAreaUnits = true;
7695  }
7696 
7697  delete pUdef;
7698  }
7699 
7700  if (!inconsistentLengthUnits && lastLengthUnit != "" && lastLengthUnit != "length")
7701  {
7702  // try to set the default length unit to the unit defined by lastLengthUnit
7703  const UnitDefinition* pUdef = SBMLImporter::getSBMLUnitDefinitionForId(lastLengthUnit, pSBMLModel);
7704  assert(pUdef != NULL);
7705  std::pair<CModel::LengthUnit, bool> length = this->handleLengthUnit(pUdef);
7706 
7707  if (length.second == true)
7708  {
7709  // set the default length unit
7710  pCopasiModel->setLengthUnit(length.first);
7711  delete pLengthUnits;
7712  pLengthUnits = dynamic_cast<UnitDefinition*>(pUdef->clone());
7713  }
7714  else
7715  {
7716  inconsistentLengthUnits = true;
7717  }
7718 
7719  delete pUdef;
7720  }
7721 
7722  if (inconsistentVolumeUnits || inconsistentAreaUnits || inconsistentLengthUnits || inconsistentDimensionlessUnits)
7723  {
7724  // warn about inconsistent units and that they have been ignored and
7725  // report the actual units used
7726  // one warning for every entry in nonDefaultCompartment
7727  std::vector<std::string>::iterator errorIt = nonDefaultCompartments.begin(), errorEndit = nonDefaultCompartments.end();
7728  std::ostringstream os;
7729 
7730  while (errorIt != errorEndit)
7731  {
7732  os << *errorIt << ", ";
7733  ++errorIt;
7734  }
7735 
7736  std::string s = os.str();
7737  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 24 , s.substr(0, s.size() - 2).c_str());
7738  // check if the default units have been used for any of the compartments
7739  // if so, the models has to use the defaults, otherwise we can just
7740  // choose one
7741  std::pair<CModel::LengthUnit, bool> length = std::pair<CModel::LengthUnit, bool>(CModel::dimensionlessLength, false);
7742  const UnitDefinition* pUdef = NULL;
7743 
7744  if (defaultLengthUsed)
7745  {
7746  pUdef = SBMLImporter::getSBMLUnitDefinitionForId("length", pSBMLModel);
7747  assert(pUdef != NULL);
7748  length = this->handleLengthUnit(pUdef);
7749  }
7750  else
7751  {
7752  if (lastLengthUnit != "")
7753  {
7754  pUdef = SBMLImporter::getSBMLUnitDefinitionForId(lastLengthUnit, pSBMLModel);
7755  assert(pUdef != NULL);
7756  length = this->handleLengthUnit(pUdef);
7757  }
7758  }
7759 
7760  if (length.second == true)
7761  {
7762  // set the default length unit
7763  pCopasiModel->setLengthUnit(length.first);
7764  delete pLengthUnits;
7765  pLengthUnits = dynamic_cast<UnitDefinition*>(pUdef->clone());
7766  }
7767 
7768  if (pUdef)
7769  {
7770  delete pUdef;
7771  pUdef = NULL;
7772  }
7773 
7774  std::pair<CModel::AreaUnit, bool> area = std::pair<CModel::AreaUnit, bool>(CModel::dimensionlessArea, false);
7775 
7776  if (defaultAreaUsed)
7777  {
7778  pUdef = SBMLImporter::getSBMLUnitDefinitionForId("area", pSBMLModel);
7779  assert(pUdef != NULL);
7780  area = this->handleAreaUnit(pUdef);
7781  }
7782  else
7783  {
7784  if (lastAreaUnit != "")
7785  {
7786  pUdef = SBMLImporter::getSBMLUnitDefinitionForId(lastAreaUnit, pSBMLModel);
7787  assert(pUdef != NULL);
7788  area = this->handleAreaUnit(pUdef);
7789  }
7790  }
7791 
7792  if (area.second == true)
7793  {
7794  // set the default area unit
7795  pCopasiModel->setAreaUnit(area.first);
7796  delete pAreaUnits;
7797  pAreaUnits = dynamic_cast<UnitDefinition*>(pUdef->clone());
7798  }
7799 
7800  if (pUdef)
7801  {
7802  delete pUdef;
7803  pUdef = NULL;
7804  }
7805 
7806  std::pair<CModel::VolumeUnit, bool> volume = std::pair<CModel::VolumeUnit, bool>(CModel::dimensionlessVolume, false);
7807 
7808  if (defaultVolumeUsed)
7809  {
7810  pUdef = SBMLImporter::getSBMLUnitDefinitionForId("volume", pSBMLModel);
7811  assert(pUdef != NULL);
7812  volume = this->handleVolumeUnit(pUdef);
7813  }
7814  else
7815  {
7816  if (lastVolumeUnit != "")
7817  {
7818  pUdef = SBMLImporter::getSBMLUnitDefinitionForId(lastVolumeUnit, pSBMLModel);
7819  assert(pUdef != NULL);
7820  volume = this->handleVolumeUnit(pUdef);
7821  }
7822  }
7823 
7824  if (volume.second == true)
7825  {
7826  // set the default length unit
7827  pCopasiModel->setVolumeUnit(volume.first);
7828  delete pVolumeUnits;
7829  pVolumeUnits = dynamic_cast<UnitDefinition*>(pUdef->clone());
7830  }
7831 
7832  if (pUdef)
7833  {
7834  delete pUdef;
7835  pUdef = NULL;
7836  }
7837  }
7838 
7839  bool inconsistentUnits = false;
7840  std::string lastUnit = "";
7841 
7842  iMax = pSBMLModel->getNumSpecies();
7843 
7844  for (i = 0; i < iMax; ++i)
7845  {
7846  pSpecies = pSBMLModel->getSpecies(i);
7847 
7848  if (level < 2 || (level == 2 && version < 3))
7849  {
7850  // check the isSetSpatialSizeUnits flag for models prior to L2V3.
7851  if (pSpecies->isSetSpatialSizeUnits() == true)
7852  {
7853  // check if the spatialSizeUnits is consistent with the
7854  // pVolumeUnits, pAreaUnits, pLengthUnits or pDimensionlessUnits
7855  // first we need to find the compartment
7856  pCompartment = pSBMLModel->getCompartment(pSpecies->getCompartment());
7857  assert(pCompartment != NULL);
7858  std::string spatialSizeUnits = pSpecies->getSpatialSizeUnits();
7859  UnitDefinition* pTmpUdef2 = getSBMLUnitDefinitionForId(spatialSizeUnits, pSBMLModel);
7860 
7861  if (pTmpUdef2 == NULL)
7862  {
7863  // error message
7864  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, spatialSizeUnits.c_str(), "spatialSizeUnits", "species", pSpecies->getId().c_str());
7865  }
7866 
7867  switch (pCompartment->getSpatialDimensions())
7868  {
7869  case 0:
7870 
7871  if (!areSBMLUnitDefinitionsIdentical(pDimensionlessUnits, pTmpUdef2))
7872  {
7873  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 19, pSpecies->getId().c_str());
7874  }
7875 
7876  break;
7877 
7878  case 1:
7879 
7880  if (!areSBMLUnitDefinitionsIdentical(pLengthUnits, pTmpUdef2))
7881  {
7882  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 19, pSpecies->getId().c_str());
7883  }
7884 
7885  break;
7886 
7887  case 2:
7888 
7889  if (!areSBMLUnitDefinitionsIdentical(pAreaUnits, pTmpUdef2))
7890  {
7891  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 19, pSpecies->getId().c_str());
7892  }
7893 
7894  break;
7895 
7896  case 3:
7897 
7898  if (!areSBMLUnitDefinitionsIdentical(pVolumeUnits, pTmpUdef2))
7899  {
7900  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 19, pSpecies->getId().c_str());
7901  }
7902 
7903  break;
7904 
7905  default:
7906  fatalError();
7907  break;
7908  }
7909 
7910  delete pTmpUdef2;
7911  }
7912  }
7913 
7914  if (pSpecies->isSetUnits())
7915  {
7916  std::string unitId = pSpecies->getUnits();
7917  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
7918 
7919  if (pUdef1 == NULL)
7920  {
7921  // error message
7922  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "substanceUnits", "species", pSpecies->getId().c_str());
7923  }
7924 
7925  else
7926  {
7927  std::pair<CModel::QuantityUnit, bool> result = this->handleSubstanceUnit(pUdef1);
7928 
7929  if (result.second == false)
7930  {
7931  // we did not recognize the unit
7932  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "substance", "species", pSpecies->getId().c_str());
7933  continue;
7934  }
7935  }
7936 
7937  if (unitId != "substance" && !areSBMLUnitDefinitionsIdentical(pSubstanceUnits, pUdef1))
7938  {
7939  nonDefaultSpecies.push_back(pSpecies->getId());
7940  }
7941 
7942  if (lastUnit == "")
7943  {
7944  lastUnit = unitId;
7945  }
7946  else if (unitId != lastUnit)
7947  {
7948  // check if the two units have identical definitions
7949  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastUnit, pSBMLModel);
7950  assert(pUdef2 != NULL);
7951 
7952  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
7953  {
7954  inconsistentUnits = true;
7955  }
7956 
7957  delete pUdef2;
7958  }
7959 
7960  delete pUdef1;
7961  }
7962  else if (lastUnit == "")
7963  {
7964  lastUnit = "substance";
7965  }
7966  }
7967 
7968  bool inconsistentTimeUnits = false;
7969  std::string lastTimeUnits = "";
7970  iMax = pSBMLModel->getNumReactions();
7971 
7972  for (i = 0; i < iMax; ++i)
7973  {
7974  pReaction = pSBMLModel->getReaction(i);
7975  pKineticLaw = pReaction->getKineticLaw();
7976 
7977  if (pKineticLaw != NULL)
7978  {
7979  std::string unitId;
7980 
7981  if (pKineticLaw->isSetSubstanceUnits())
7982  {
7983  unitId = pKineticLaw->getSubstanceUnits();
7984  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
7985 
7986  if (pUdef1 == NULL)
7987  {
7988  // error message
7989  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "substanceUnits", "kinetic law of the reaction", pReaction->getId().c_str());
7990  }
7991 
7992  else
7993  {
7994  std::pair<CModel::QuantityUnit, bool> result = this->handleSubstanceUnit(pUdef1);
7995 
7996  if (result.second == false)
7997  {
7998  // we did not recognize the unit
7999  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "substance", "the kinetic law in reaction", pReaction->getId().c_str());
8000 
8001  continue;
8002  }
8003  }
8004 
8005  if (unitId != "substance" && !areSBMLUnitDefinitionsIdentical(pSubstanceUnits, pUdef1))
8006  {
8007  nonDefaultKineticSubstance.push_back(pReaction->getId());
8008  }
8009 
8010  if (lastUnit == "")
8011  {
8012  lastUnit = unitId;
8013  }
8014  else if (unitId != lastUnit)
8015  {
8016  // check if the two units have identical definitions
8017  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastUnit, pSBMLModel);
8018  assert(pUdef2 != NULL);
8019 
8020  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
8021  {
8022  inconsistentUnits = true;
8023  }
8024 
8025  delete pUdef2;
8026  }
8027 
8028  delete pUdef1;
8029  }
8030  else if (lastUnit == "")
8031  {
8032  lastUnit = "substance";
8033  }
8034 
8035  if (pKineticLaw->isSetTimeUnits())
8036  {
8037  unitId = pKineticLaw->getTimeUnits();
8038  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
8039 
8040  if (pUdef1 == NULL)
8041  {
8042  // error message
8043  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "timeUnits", "kinetic law of the reaction", pReaction->getId().c_str());
8044  }
8045  else
8046  {
8047  std::pair<CModel::TimeUnit, bool> result = this->handleTimeUnit(pUdef1);
8048 
8049  if (result.second == false)
8050  {
8051  // we did not recognize the unit
8052  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "time", "the kinetic law in reaction", pReaction->getId().c_str());
8053 
8054  continue;
8055  }
8056  }
8057 
8058  if (unitId != "time" && !areSBMLUnitDefinitionsIdentical(pTimeUnits, pUdef1))
8059  {
8060  nonDefaultKineticTime.push_back(pReaction->getId());
8061  }
8062 
8063  if (lastTimeUnits == "")
8064  {
8065  lastTimeUnits = unitId;
8066  }
8067  else if (unitId != lastTimeUnits)
8068  {
8069  // check if the two units have identical definitions
8070  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastTimeUnits, pSBMLModel);
8071  assert(pUdef2 != NULL);
8072 
8073  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
8074  {
8075  inconsistentTimeUnits = true;
8076  }
8077 
8078  delete pUdef2;
8079  }
8080 
8081  delete pUdef1;
8082  }
8083  else if (lastTimeUnits == "") // set the last time unit to time
8084  {
8085  lastTimeUnits = "time";
8086  }
8087  }
8088  }
8089 
8090  if (!inconsistentUnits && lastUnit != "" && lastUnit != "substance")
8091  {
8092  // we have to check if lastUnit is different from the global substance
8093  // unit
8094  // if it differs, we have to issue a warning because we can't just set
8095  // another global substance unit since this would change the units for
8096  // the kinetic laws
8097  UnitDefinition* pUdef = getSBMLUnitDefinitionForId(lastUnit, pSBMLModel);
8098  const UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId("substance", pSBMLModel);
8099  assert(pUdef2 != NULL);
8100  assert(pUdef != NULL);
8101 
8102  if (!areSBMLUnitDefinitionsIdentical(pUdef, pUdef2))
8103  {
8104  // warning
8105  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 78 , "substance", "substance", "substance");
8106  }
8107 
8108  delete pUdef2;
8109  delete pUdef;
8110  }
8111 
8112  if (inconsistentUnits)
8113  {
8114  // warn about inconsistent units and that they have been ignored
8115  // one warning SBML + 25 for each species in nonDefaultSpecies
8116  // and one for each KineticLaw in nonDefaultKineticSubstance
8117  std::vector<std::string>::iterator errorIt = nonDefaultSpecies.begin(), errorEndit = nonDefaultSpecies.end();
8118  std::ostringstream os;
8119 
8120  while (errorIt != errorEndit)
8121  {
8122  os << *errorIt << ", ";
8123  ++errorIt;
8124  }
8125 
8126  std::string s = os.str();
8127  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 25 , s.substr(0, s.size() - 2).c_str());
8128  os.str("");
8129  errorIt = nonDefaultKineticSubstance.begin(), errorEndit = nonDefaultKineticSubstance.end();
8130 
8131  while (errorIt != errorEndit)
8132  {
8133  os << *errorIt << ", ";
8134  ++errorIt;
8135  }
8136 
8137  s = os.str();
8138  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 44 , s.substr(0, s.size() - 2).c_str());
8139  }
8140 
8141  if (!inconsistentTimeUnits && lastTimeUnits != "" && lastTimeUnits != "time")
8142  {
8143  // we have to check if lastUnit is different from the global substance
8144  // unit
8145  // if it differs, we have to issue a warning because we can't just set
8146  // another global substance unit since this would change the units for
8147  // the kinetic laws
8148  UnitDefinition* pUdef = getSBMLUnitDefinitionForId(lastTimeUnits, pSBMLModel);
8149  const UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId("time", pSBMLModel);
8150  assert(pUdef2 != NULL);
8151  assert(pUdef != NULL);
8152 
8153  if (!areSBMLUnitDefinitionsIdentical(pUdef, pUdef2))
8154  {
8155  // warning
8156  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 78 , "time", "time", "time");
8157  }
8158 
8159  delete pUdef2;
8160  }
8161 
8162  if (inconsistentTimeUnits)
8163  {
8164  // warn about inconsistent time unit
8165  // one error for each entry in nonDefaultKineticTime
8166  std::ostringstream os;
8167  std::vector<std::string>::iterator errorIt = nonDefaultKineticTime.begin(), errorEndit = nonDefaultKineticTime.end();
8168 
8169  while (errorIt != errorEndit)
8170  {
8171  os << *errorIt << ", ";
8172  ++errorIt;
8173  }
8174 
8175  std::string s = os.str();
8176  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 53, s.substr(0, s.size() - 2).c_str());
8177  }
8178 
8179  // delete the units we created
8180  delete pSubstanceUnits;
8181  delete pVolumeUnits;
8182  const Event* pEvent = NULL;
8183  inconsistentTimeUnits = false;
8184  iMax = pSBMLModel->getNumEvents();
8185 
8186  for (i = 0; i < iMax; ++i)
8187  {
8188  pEvent = pSBMLModel->getEvent(i);
8189  std::string unitId;
8190 
8191  if (pEvent->isSetTimeUnits())
8192  {
8193  unitId = pEvent->getTimeUnits();
8194  UnitDefinition* pUdef1 = getSBMLUnitDefinitionForId(unitId, pSBMLModel);
8195 
8196  if (pUdef1 == NULL)
8197  {
8198  // error message
8199  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 55, unitId.c_str(), "time units", "the event", pEvent->getId().c_str());
8200  }
8201 
8202  else
8203  {
8204  std::pair<CModel::TimeUnit, bool> result = this->handleTimeUnit(pUdef1);
8205 
8206  if (result.second == false)
8207  {
8208  // we did not recognize the unit
8209  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 79, "time", "the event", pEvent->getId().c_str());
8210 
8211  continue;
8212  }
8213  }
8214 
8215  if (unitId != "time" && !areSBMLUnitDefinitionsIdentical(pTimeUnits, pUdef1))
8216  {
8217  if (pEvent->isSetId())
8218  {
8219  nonDefaultEventTime.push_back(pEvent->getId());
8220  }
8221  }
8222 
8223  if (lastTimeUnits == "")
8224  {
8225  lastTimeUnits = unitId;
8226  }
8227  else if (unitId != lastTimeUnits)
8228  {
8229  // check if the two units have identical definitions
8230  UnitDefinition* pUdef2 = getSBMLUnitDefinitionForId(lastTimeUnits, pSBMLModel);
8231  assert(pUdef2 != NULL);
8232 
8233  if (!areSBMLUnitDefinitionsIdentical(pUdef1, pUdef2))
8234  {
8235  inconsistentTimeUnits = true;
8236  }
8237 
8238  delete pUdef2;
8239  }
8240 
8241  delete pUdef1;
8242  }
8243  else if (lastTimeUnits == "") // set the last time unit to time
8244  {
8245  lastTimeUnits = "time";
8246  }
8247  }
8248 
8249  if (!inconsistentTimeUnits && lastTimeUnits != "" && lastTimeUnits != "time")
8250  {
8251  // try to set the default time units
8252  UnitDefinition* pUdef = getSBMLUnitDefinitionForId(lastTimeUnits, pSBMLModel);
8253  assert(pUdef != NULL);
8254  std::pair<CModel::TimeUnit, bool> time = this->handleTimeUnit(pUdef);
8255  delete pUdef;
8256 
8257  if (time.second == true)
8258  {
8259  // set the default volume unit
8260  pCopasiModel->setTimeUnit(time.first);
8261  }
8262  else
8263  {
8264  inconsistentTimeUnits = true;
8265  }
8266  }
8267 
8268  if (inconsistentTimeUnits)
8269  {
8270  // warn about inconsistent time unit
8271  // one error for each entry in nonDefaultKineticTime
8272  std::ostringstream os;
8273  std::vector<std::string>::iterator errorIt = nonDefaultEventTime.begin(), errorEndit = nonDefaultEventTime.end();
8274 
8275  while (errorIt != errorEndit)
8276  {
8277  os << *errorIt << ", ";
8278  ++errorIt;
8279  }
8280 
8281  std::string s = os.str();
8282  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 53, s.substr(0, s.size() - 2).c_str());
8283  }
8284 
8285  // delete the units we created
8286  delete pTimeUnits;
8287  delete pDimensionlessUnits;
8288  delete pLengthUnits;
8289  delete pAreaUnits;
8290 }
std::pair< CModel::TimeUnit, bool > handleTimeUnit(const UnitDefinition *uDef)
bool setAreaUnit(const std::string &name)
Definition: CModel.cpp:2182
bool setVolumeUnit(const std::string &name)
Definition: CModel.cpp:2159
bool setLengthUnit(const std::string &name)
Definition: CModel.cpp:2204
bool setTimeUnit(const std::string &name)
Definition: CModel.cpp:2227
#define fatalError()
std::pair< CModel::QuantityUnit, bool > handleSubstanceUnit(const UnitDefinition *uDef)
#define MCSBML
std::pair< CModel::AreaUnit, bool > handleAreaUnit(const UnitDefinition *uDef)
static UnitDefinition * getSBMLUnitDefinitionForId(const std::string &unitId, const Model *pSBMLModel)
std::pair< CModel::LengthUnit, bool > handleLengthUnit(const UnitDefinition *uDef)
std::pair< CModel::VolumeUnit, bool > handleVolumeUnit(const UnitDefinition *uDef)
static bool areSBMLUnitDefinitionsIdentical(const UnitDefinition *pUdef1, const UnitDefinition *pUdef2)
void SBMLImporter::checkRuleMathConsistency ( const Rule *  pRule,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap 
)
protected

Checks the expression for a give rate or assignment rule for consistency. This basically means it checks that no id present in the expression is the target for one of the following rate or assignment rules.

Definition at line 6793 of file SBMLImporter.cpp.

References CCopasiMessage::EXCEPTION, fatalError, findIdInASTTree(), getIdsFromNode(), MCSBML, mLevel, mpCopasiModel, and mVersion.

Referenced by importRuleForModelEntity().

6794 {
6795  // only check if Level2 Version1
6796  if (this->mLevel == 2 && this->mVersion == 1)
6797  {
6798  // check if no nodes with ids of objects are used in an assignment that are
6799  // set in another assignment rule later on
6800  std::set<std::string> idSet;
6801  const ASTNode* pNode = pRule->getMath();
6802  this->getIdsFromNode(pNode, idSet);
6803  Model* sbmlModel = dynamic_cast<Model*>(copasi2sbmlmap[mpCopasiModel]);
6804 
6805  if (!sbmlModel) fatalError();
6806 
6807  unsigned int i, iMax = sbmlModel->getNumRules();
6808 
6809  for (i = 0; i < iMax; ++i)
6810  {
6811  if (sbmlModel->getRule(i) == pRule)
6812  {
6813  break;
6814  }
6815  }
6816 
6817  Rule* pR;
6818  int type;
6819 
6820  while (i < iMax)
6821  {
6822  pR = sbmlModel->getRule(i);
6823  type = pR->getTypeCode();
6824 
6825  if (type == SBML_ASSIGNMENT_RULE)
6826  {
6827  if (idSet.find(dynamic_cast<AssignmentRule*>(pR)->getVariable()) != idSet.end())
6828  {
6829  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 37, dynamic_cast<AssignmentRule*>(pR)->getVariable().c_str());
6830  }
6831  }
6832 
6833  ++i;
6834  }
6835 
6836  // Check if there is a reference to a reaction in the expression
6837  // This is not allowed for L2V1
6838  const ASTNode* pMath = pRule->getMath();
6839 
6840  if (pMath != NULL)
6841  {
6842  std::set<std::string> reactionIds;
6843 
6844  for (i = 0; i < sbmlModel->getListOfReactions()->size(); i++)
6845  {
6846  reactionIds.insert(sbmlModel->getReaction(i)->getId());
6847  }
6848 
6849  std::string id = SBMLImporter::findIdInASTTree(pMath, reactionIds);
6850 
6851  if (!id.empty())
6852  {
6853  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 81, id.c_str());
6854  }
6855  }
6856  }
6857 
6858  // In SBML Level 3 documents,
6859  if (this->mLevel == 3)
6860  {
6861  // TODO we need to check if we have a species reference as the target of
6862  // TODO a rule because COPASI currently can not handle this and we have
6863  // TODO to warn the user that we will ignore the rule
6864  //
6865  // TODO Likewise we have to check if the id of a species reference is reference in the
6866  // TODO expression of the rule because this is also not implemented in COPASI yet and
6867  // TODO we ignore the rule
6868  }
6869 }
unsigned int mLevel
Definition: SBMLImporter.h:63
CModel * mpCopasiModel
Definition: SBMLImporter.h:69
#define fatalError()
void getIdsFromNode(const ASTNode *pNode, std::set< std::string > &idSet)
unsigned int mVersion
Definition: SBMLImporter.h:65
#define MCSBML
std::string findIdInASTTree(const ASTNode *pMath, const std::set< std::string > &reactionIds)
bool SBMLImporter::containsVolume ( const ASTNode *  pNode,
const std::string &  compartmentCN 
)
protected

Checks if the volume with the given CN is one of the parameters to the given call node.

Definition at line 6065 of file SBMLImporter.cpp.

Referenced by createCReactionFromReaction().

6066 {
6067  bool result = false;
6068  unsigned int i, iMax = pNode->getNumChildren();
6069 
6070  for (i = 0; i < iMax; ++i)
6071  {
6072  if (pNode->getChild(i)->getType() == AST_NAME &&
6073  pNode->getChild(i)->getName() == compartmentSBMLId)
6074  {
6075  result = true;
6076  break;
6077  }
6078  }
6079 
6080  return result;
6081 }
Unit * SBMLImporter::convertSBMLCubicmetresToLitres ( const Unit *  pU)
staticprotected

If the given UnitDefinition can be converted to a form of litre, the function return the UnitDefinition in litre, otherwise NULL is returned.

Definition at line 8361 of file SBMLImporter.cpp.

References normalizeSBMLUnit(), and pResult.

Referenced by handleVolumeUnit().

8362 {
8363  Unit* pResult = NULL;
8364 
8365  if (pU != NULL)
8366  {
8367  if ((pU->getKind() == UNIT_KIND_METER || pU->getKind() == UNIT_KIND_METRE) && pU->getExponent() % 3 == 0)
8368  {
8369  pResult = dynamic_cast<Unit*>(pU->clone());
8370  assert(pResult != NULL);
8371  Unit::removeScale(pResult);
8372  pResult->setExponent(pResult->getExponent() / 3);
8373  pResult->setKind(UNIT_KIND_LITRE);
8374  pResult->setMultiplier(pow(pResult->getMultiplier(), 3));
8375  normalizeSBMLUnit(pResult);
8376  }
8377  }
8378 
8379  return pResult;
8380 }
static void normalizeSBMLUnit(Unit *pU)
const CArrayAnnotation * pResult
std::map< std::string, ASTNode * > SBMLImporter::createBVarMap ( const ASTNode *  uDefFunction,
const ASTNode *  function 
)
protected

Creates a map of each parameter of the function definition and its corresponding parameter in the function call.

Definition at line 2953 of file SBMLImporter.cpp.

References fatalError.

2954 {
2955  /* the first n-1 children, where n is the number of children, of a function definition ASTnode are the
2956  * arguments to the function. These correspond to the m=n-1 children of the
2957  * function call.
2958  */
2959  if (uDefFunction->getNumChildren() != function->getNumChildren() + 1)
2960  {
2961  std::string functionName = uDefFunction->getName();
2962  fatalError();
2963  }
2964 
2965  std::map<std::string, ASTNode*> varMap;
2966  unsigned int counter;
2967 
2968  for (counter = 0; counter < uDefFunction->getNumChildren() - 1; counter++)
2969  {
2970  varMap[uDefFunction->getChild(counter)->getName()] = function->getChild(counter);
2971  }
2972 
2973  return varMap;
2974 }
#define fatalError()
CCompartment * SBMLImporter::createCCompartmentFromCompartment ( const Compartment *  sbmlCompartment,
CModel copasiModel,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap,
const Model *  pSBMLModel 
)
protected

Creates and returns a COPASI CCompartment from the SBML Compartment given as argument.

Definition at line 1950 of file SBMLImporter.cpp.

References C_INVALID_INDEX, CModel::createCompartment(), CModel::getCompartments(), CCopasiVectorN< CType >::getIndex(), CCopasiContainer::getUnits(), importMIRIAM(), importNotes(), MCSBML, mLevel, CCompartment::setDimensionality(), CModelEntity::setSBMLId(), and CCopasiMessage::WARNING.

Referenced by createCModelFromSBMLDocument().

1951 {
1952  if (sbmlCompartment->isSetUnits())
1953  {
1954  std::string cU = sbmlCompartment->getUnits();
1955  }
1956 
1957  unsigned int dimensionality = 3;
1958 
1959  if (sbmlCompartment->isSetSpatialDimensions())
1960  {
1961  dimensionality = sbmlCompartment->getSpatialDimensions();
1962 
1963  // starting with SBML Level 3, the spatial dimensions of a compartment can be
1964  // any rational number
1965  double dDimensionality = sbmlCompartment->getSpatialDimensions();
1966 
1967  if (this->mLevel > 2)
1968  {
1969  dDimensionality = sbmlCompartment->getSpatialDimensionsAsDouble();
1970  }
1971 
1972  // check if the unsigned int dimensionality corresponds to the double
1973  // dimensionality, otherwise give an error message
1974  // Actually if we wanted to be correct, we would have to check if the
1975  // part before the komma also matches and maybe have a separate error message if not
1976  dDimensionality -= dimensionality;
1977 
1978  if (fabs(dDimensionality) > 1e-9)
1979  {
1980  CCopasiMessage Message(CCopasiMessage::WARNING, MCSBML + 89, sbmlCompartment->getId().c_str());
1981  dimensionality = 3;
1982  }
1983  }
1984  else
1985  {
1986  CCopasiMessage Message(CCopasiMessage::WARNING, MCSBML + 90, sbmlCompartment->getId().c_str());
1987  dimensionality = 3;
1988  }
1989 
1990  if (dimensionality > 3)
1991  {
1993  "Reaction with id \"%s\" has dimensions of %d, this is not supported by COPASI. COPASI will assume that the compartment is three dimensional."
1994  , sbmlCompartment->getId().c_str(), dimensionality);
1995  dimensionality = 3;
1996  //fatalError();
1997  }
1998 
1999  std::string name = sbmlCompartment->getName();
2000 
2001  if (name == "")
2002  {
2003  name = sbmlCompartment->getId();
2004  }
2005 
2006  std::string appendix = "";
2007  unsigned int counter = 2;
2008  std::ostringstream numberStream;
2009 
2010  while (copasiModel->getCompartments().getIndex(name + appendix) != C_INVALID_INDEX)
2011  {
2012  numberStream.str("");
2013  numberStream << "_" << counter;
2014  counter++;
2015  appendix = numberStream.str();
2016  }
2017 
2018  double value;
2019  CCompartment* copasiCompartment = copasiModel->createCompartment(name + appendix, value);
2020 
2021  if (this->mLevel == 1)
2022  {
2023  copasiCompartment->setSBMLId(sbmlCompartment->getName());
2024  }
2025  else
2026  {
2027  copasiCompartment->setSBMLId(sbmlCompartment->getId());
2028  }
2029 
2030  // set the dimension of the compartment
2031  copasiCompartment->setDimensionality(dimensionality);
2032 
2033  //DebugFile << "Created Compartment: " << copasiCompartment->getObjectName() << std::endl;
2034  SBMLImporter::importMIRIAM(sbmlCompartment, copasiCompartment);
2035  SBMLImporter::importNotes(copasiCompartment, sbmlCompartment);
2036  copasi2sbmlmap[copasiCompartment] = const_cast<Compartment*>(sbmlCompartment);
2037  return copasiCompartment;
2038 }
unsigned int mLevel
Definition: SBMLImporter.h:63
bool setDimensionality(unsigned C_INT32 dim)
#define C_INVALID_INDEX
Definition: copasi.h:222
virtual size_t getIndex(const std::string &name) const
#define MCSBML
struct MESSAGES Message
CCopasiVectorNS< CCompartment > & getCompartments()
Definition: CModel.cpp:1145
bool importMIRIAM(const SBase *pSBMLObject, CCopasiObject *pCOPASIObject)
static bool importNotes(CAnnotation *pAnno, const SBase *pSBase)
void setSBMLId(const std::string &id)
CCompartment * createCompartment(const std::string &name, const C_FLOAT64 &volume=1.0)
Definition: CModel.cpp:2698
CFunction * SBMLImporter::createCFunctionFromFunctionDefinition ( const FunctionDefinition *  sbmlFunction,
CFunctionDB pTmpFunctionDB,
Model *  pSBMLModel,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap 
)
protected

Creates and returns a COPASI CFunction from the SBML FunctionDefinition given as argument.

Definition at line 1727 of file SBMLImporter.cpp.

References CFunctionDB::add(), addToKnownFunctionToMap(), areEqualFunctions(), createCFunctionFromFunctionTree(), ensureAllArgsAreBeingUsedInFunctionDefinition(), CCopasiMessage::EXCEPTION, CFunctionDB::findFunction(), functionDB, CFunction::getSBMLId(), CEvaluationTree::getType(), importMIRIAM(), importNotes(), CFunctionDB::loadedFunctions(), MCSBML, mKnownCustomUserDefinedFunctions, pdelete, CCopasiObject::setObjectName(), CFunction::setSBMLId(), CCopasiVector< T >::size(), and CEvaluationTree::UserDefined.

Referenced by importFunctionDefinitions().

1728 {
1729 
1731 
1733 
1734  CFunction* pTmpFunction = this->createCFunctionFromFunctionTree(sbmlFunction, pSBMLModel, copasi2sbmlmap);
1735 
1736  if (pTmpFunction == NULL)
1737  {
1738  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 14, sbmlFunction->getId().c_str());
1739  return NULL;
1740  }
1741 
1742  std::string sbmlId = sbmlFunction->getId();
1743  pTmpFunction->setSBMLId(sbmlId);
1744  // check if the id is already taken by another function definition, maybe
1745  // from an earlier import, if this is the case, delete the id on the old
1746  // function definition
1747  // if we don't do this, two functions might have the same SBML id during
1748  // export which makes the exporter code so much more difficult
1749  size_t i, iMax = this->functionDB->loadedFunctions().size();
1750 
1751  for (i = 0; i < iMax; ++i)
1752  {
1753  CFunction* pFun = this->functionDB->loadedFunctions()[i];
1754 
1755  if (pFun->getSBMLId() == sbmlId)
1756  {
1757  pFun->setSBMLId("");
1758  }
1759  }
1760 
1761  std::string functionName = sbmlFunction->getName();
1762 
1763  if (functionName == "")
1764  {
1765  functionName = sbmlFunction->getId();
1766  }
1767 
1768  unsigned int counter = 1;
1769  std::ostringstream numberStream;
1770  std::string appendix = "";
1771  CFunction * pExistingFunction = NULL;
1772 
1773  while ((pExistingFunction = functionDB->findFunction(functionName + appendix)))
1774  {
1775  if (areEqualFunctions(pExistingFunction, pTmpFunction))
1776  {
1777  pdelete(pTmpFunction);
1778  pTmpFunction = pExistingFunction;
1779 
1780  break;
1781  }
1782 
1783  // We need to check whether the functions are identical.
1784  numberStream.str("");
1785  numberStream << "_" << counter;
1786  counter++;
1787  appendix = numberStream.str();
1788  }
1789 
1790  if (pTmpFunction != pExistingFunction)
1791  {
1792  pTmpFunction->setObjectName(functionName + appendix);
1793  functionDB->add(pTmpFunction, true);
1794  pTmpFunctionDB->add(pTmpFunction, false);
1795  }
1796 
1797  if (pTmpFunction->getType() == CEvaluationTree::UserDefined)
1798  {
1799  SBMLImporter::importMIRIAM(sbmlFunction, pTmpFunction);
1800  SBMLImporter::importNotes(pTmpFunction, sbmlFunction);
1801  }
1802 
1803  return pTmpFunction;
1804 }
CCopasiVectorN< CFunction > & loadedFunctions()
#define pdelete(p)
Definition: copasi.h:215
virtual size_t size() const
const CEvaluationTree::Type & getType() const
CFunction * createCFunctionFromFunctionTree(const FunctionDefinition *pSBMLFunction, Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
#define MCSBML
std::map< std::string, std::string > mKnownCustomUserDefinedFunctions
Definition: SBMLImporter.h:92
CFunctionDB * functionDB
Definition: SBMLImporter.h:56
void setSBMLId(const std::string &id)
Definition: CFunction.cpp:63
static bool areEqualFunctions(const CFunction *pFun, const CFunction *pFun2)
bool addToKnownFunctionToMap(std::map< std::string, std::string > &map, const FunctionDefinition *sbmlFunction)
const std::string & getSBMLId() const
Definition: CFunction.cpp:68
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
bool importMIRIAM(const SBase *pSBMLObject, CCopasiObject *pCOPASIObject)
void ensureAllArgsAreBeingUsedInFunctionDefinition(const FunctionDefinition *sbmlFunction)
static bool importNotes(CAnnotation *pAnno, const SBase *pSBase)
bool setObjectName(const std::string &name)
CFunction * findFunction(const std::string &functionName)
bool add(CFunction *pFunction, const bool &adopt)
CFunction * SBMLImporter::createCFunctionFromFunctionTree ( const FunctionDefinition *  pSBMLFunction,
Model *  pSBMLModel,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap 
)
protected

Definition at line 1806 of file SBMLImporter.cpp.

References CFunction::addVariable(), CEvaluationNodeVariable::ANY, CEvaluationTree::compile(), CCopasiMessage::EXCEPTION, CEvaluationTree::getRoot(), isDelayFunctionUsed(), MCSBML, mExplicitelyTimeDependentFunctionDefinitions, preprocessNode(), replaceTimeNodesInFunctionDefinition(), CEvaluationTree::setRoot(), CEvaluationTree::setTree(), and CEvaluationTree::updateTree().

Referenced by createCFunctionFromFunctionDefinition().

1807 {
1808  CFunction* pFun = NULL;
1809 
1810  if (!pSBMLFunction->isSetMath())
1811  return NULL;
1812 
1813  ConverterASTNode root(*pSBMLFunction->getMath());
1814 
1816  {
1817  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 85, pSBMLFunction->getId().c_str());
1818  }
1819 
1820  this->preprocessNode(&root, pSBMLModel, copasi2sbmlmap);
1821 
1822  if (root.getType() != AST_LAMBDA)
1823  {
1824  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 11, pSBMLFunction->getId().c_str());
1825  return NULL;
1826  }
1827 
1828  // get the number of children.
1829  // the first n-1 children are the parameters for the function
1830  // the last child is the actual function
1831  pFun = new CKinFunction();
1832  unsigned int i, iMax = root.getNumChildren() - 1;
1833  std::set<std::string> variableNames;
1834 
1835  for (i = 0; i < iMax; ++i)
1836  {
1837  ASTNode* pVarNode = root.getChild(i);
1838 
1839  if (pVarNode->getType() != AST_NAME)
1840  {
1841  delete pFun;
1842  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 12, pSBMLFunction->getId().c_str());
1843  }
1844 
1845  pFun->addVariable(pVarNode->getName());
1846  variableNames.insert(pVarNode->getName());
1847  }
1848 
1849  // now we check if the AST tree has a node that represents the time
1850  // object
1851  // find a unique name for the time variable
1852  std::ostringstream sstream;
1853  std::string timeVariableName = "time";
1854  unsigned int postfix = 1;
1855 
1856  while (variableNames.find(timeVariableName) != variableNames.end())
1857  {
1858  sstream.str("");
1859  sstream << "time_" << postfix;
1860  timeVariableName = sstream.str();
1861  ++postfix;
1862  }
1863 
1864  if (this->replaceTimeNodesInFunctionDefinition(root.getChild(iMax), timeVariableName))
1865  {
1866  // add another variable to the function
1867  ASTNode* pVarNode = new ASTNode(AST_NAME);
1868  pVarNode->setName(timeVariableName.c_str());
1869  ASTNode* pTmpNode = root.removeChild(iMax);
1870  root.addChild(pVarNode);
1871  root.addChild(pTmpNode);
1872  // increase iMax since we now have one more child
1873  ++iMax;
1874  pFun->addVariable(timeVariableName);
1875  this->mExplicitelyTimeDependentFunctionDefinitions.insert(pSBMLFunction->getId());
1876  }
1877 
1878  pFun->setTree(*root.getChild(iMax));
1880 
1881  // if the root node already is an object node, this has to be dealt with separately
1882  if (dynamic_cast<CEvaluationNodeObject*>(&(*treeIt)))
1883  {
1884  CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNodeVariable::ANY, (*treeIt).getData().substr(1, (*treeIt).getData().length() - 2));
1885  pFun->setRoot(pVariableNode);
1886  }
1887  else
1888  {
1889  while (treeIt != NULL)
1890  {
1891  if (dynamic_cast<CEvaluationNodeObject*>(&(*treeIt)))
1892  {
1893  CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNodeVariable::ANY, (*treeIt).getData().substr(1, (*treeIt).getData().length() - 2));
1894 
1895  if ((*treeIt).getParent())
1896  {
1897  (*treeIt).getParent()->addChild(pVariableNode, &(*treeIt));
1898  (*treeIt).getParent()->removeChild(&(*treeIt));
1899  }
1900 
1901  delete &(*treeIt);
1902  treeIt = pVariableNode;
1903  }
1904 
1905  ++treeIt;
1906  }
1907  }
1908 
1909  pFun->updateTree();
1910 
1911  if (!pFun->compile())
1912  {
1913  delete pFun;
1914  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 28, pSBMLFunction->getId().c_str());
1915  }
1916 
1917  if (pFun->getRoot() == NULL)
1918  {
1919  delete pFun;
1920  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 13, pSBMLFunction->getId().c_str());
1921  }
1922 
1923  return pFun;
1924 }
virtual bool setRoot(CEvaluationNode *pRootNode)
bool isDelayFunctionUsed(ConverterASTNode *pNode)
bool addVariable(const std::string &name, CFunctionParameter::Role usage=CFunctionParameter::VARIABLE, const CFunctionParameter::DataType &type=CFunctionParameter::FLOAT64)
Definition: CFunction.cpp:154
#define MCSBML
void preprocessNode(ConverterASTNode *pNode, Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Reaction *pSBMLReaction=NULL)
bool setTree(const ASTNode &pRootNode)
std::set< std::string > mExplicitelyTimeDependentFunctionDefinitions
Definition: SBMLImporter.h:79
bool replaceTimeNodesInFunctionDefinition(ASTNode *root, std::string newNodeName)
virtual bool compile()
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
CEvaluationNode * getRoot()
CMetab * SBMLImporter::createCMetabFromSpecies ( const Species *  sbmlSpecies,
CModel copasiModel,
CCompartment copasiCompartment,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap,
const Model *  pSBMLModel 
)
protected

Creates and returns a COPASI CMetab from the given SBML Species object.

Creates and returns a Copasi CMetab from the given SBML Species object.

Definition at line 2044 of file SBMLImporter.cpp.

References C_INVALID_INDEX, CModel::createMetabolite(), fatalError, CModelEntity::FIXED, CCopasiVectorN< CType >::getIndex(), CCompartment::getMetabolites(), CCopasiObject::getObjectName(), if(), importMIRIAM(), importNotes(), mLevel, mSubstanceOnlySpecies, CModelEntity::REACTIONS, CModelEntity::setSBMLId(), and CMetab::setStatus().

Referenced by createCModelFromSBMLDocument().

2045 {
2046  if (sbmlSpecies->isSetSubstanceUnits())
2047  {
2048  std::string cU = sbmlSpecies->getSubstanceUnits();
2049  }
2050 
2051  std::map<CCopasiObject*, SBase*>::iterator it = copasi2sbmlmap.find(copasiCompartment);
2052 
2053  if (it == copasi2sbmlmap.end())
2054  {
2055  fatalError();
2056  }
2057 
2058  Compartment* pSBMLCompartment = (Compartment*)it->second;
2059 
2060  if (sbmlSpecies->getHasOnlySubstanceUnits() == true)
2061  {
2062  this->mSubstanceOnlySpecies.insert(std::make_pair(const_cast<Species*>(sbmlSpecies), pSBMLCompartment));
2063  }
2064 
2065  std::string name = sbmlSpecies->getName();
2066 
2067  if (name == "")
2068  {
2069  name = sbmlSpecies->getId();
2070  }
2071 
2072  std::string appendix = "";
2073  unsigned int counter = 2;
2074  std::ostringstream numberStream;
2075 
2076  while (copasiCompartment->getMetabolites().getIndex(name + appendix) != C_INVALID_INDEX)
2077  {
2078  numberStream.str("");
2079  numberStream << "_" << counter;
2080  counter++;
2081  appendix = numberStream.str();
2082  }
2083 
2084  CMetab* copasiMetabolite = copasiModel->createMetabolite(name + appendix, copasiCompartment->getObjectName());
2085 
2086  if (copasiMetabolite == NULL)
2087  {
2088  //DebugFile << "Could not create Copasi species." << std::endl;
2089  fatalError();
2090  }
2091 
2092  if (sbmlSpecies->getConstant() || sbmlSpecies->getBoundaryCondition())
2093  {
2094  copasiMetabolite->setStatus(CModelEntity::FIXED);
2095  }
2096  else
2097  {
2098  copasiMetabolite->setStatus(CModelEntity::REACTIONS);
2099  }
2100 
2101  // also check if the compartment has a spatialSize of 0 because this also implies hasOnlySubstanceUnits for the species in this compartment
2102  // In Level 3 files this no longer seems to be the case however, so we only
2103  // do this for L1 and L2 files
2104  if (pSBMLCompartment->isSetSpatialDimensions() && pSBMLCompartment->getSpatialDimensions() == 0 && this->mLevel < 3)
2105  {
2106  this->mSubstanceOnlySpecies.insert(std::make_pair(const_cast<Species*>(sbmlSpecies), pSBMLCompartment));
2107  }
2108 
2109  //DebugFile << "Created species: " << copasiMetabolite->getObjectName() << std::endl;
2110  copasi2sbmlmap[copasiMetabolite] = const_cast<Species*>(sbmlSpecies);
2111 
2112  if (this->mLevel == 1)
2113  {
2114  copasiMetabolite->setSBMLId(sbmlSpecies->getName());
2115  }
2116  else
2117  {
2118  copasiMetabolite->setSBMLId(sbmlSpecies->getId());
2119  }
2120 
2121  SBMLImporter::importMIRIAM(sbmlSpecies, copasiMetabolite);
2122  SBMLImporter::importNotes(copasiMetabolite, sbmlSpecies);
2123  return copasiMetabolite;
2124 }
CCopasiVectorNS< CMetab > & getMetabolites()
unsigned int mLevel
Definition: SBMLImporter.h:63
const std::string & getObjectName() const
virtual void setStatus(const CModelEntity::Status &status)
Definition: CMetab.cpp:291
std::map< Species *, Compartment * > mSubstanceOnlySpecies
Definition: SBMLImporter.h:76
#define fatalError()
#define C_INVALID_INDEX
Definition: copasi.h:222
virtual size_t getIndex(const std::string &name) const
Definition: CMetab.h:178
bool importMIRIAM(const SBase *pSBMLObject, CCopasiObject *pCOPASIObject)
if(!yymsg) yymsg
static bool importNotes(CAnnotation *pAnno, const SBase *pSBase)
void setSBMLId(const std::string &id)
CMetab * createMetabolite(const std::string &name, const std::string &compartment, const C_FLOAT64 &iconc=1.0, const CModelEntity::Status &status=CModelEntity::REACTIONS)
Definition: CModel.cpp:2622
CModel * SBMLImporter::createCModelFromSBMLDocument ( SBMLDocument *  sbmlDocument,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap 
)
protected

Creates and returns a COPASI CModel from the SBMLDocument given as argument.

Creates and returns a Copasi CModel from the SBMLDocument given as argument.

Definition at line 243 of file SBMLImporter.cpp.

References CProcessReport::addItem(), applyStoichiometricExpressions(), areRulesUnique(), areSBMLUnitDefinitionsIdentical(), C_INT32, C_INVALID_INDEX, checkElementUnits(), createCCompartmentFromCompartment(), createCMetabFromSpecies(), createCModelValueFromParameter(), createCReactionFromReaction(), CModel::deterministic, CCopasiMessage::EXCEPTION, fatalError, findAvogadroConstant(), CProcessReport::finishItem(), CModel::forceCompile(), functionDB, getInitialCNForSBase(), CCopasiContainer::getObject(), getOriginalSBMLId(), CModel::getQuantity2NumberFactor(), CFunction::getSBMLId(), CCopasiMessage::getText(), handleAreaUnit(), handleLengthUnit(), handleSubstanceUnit(), handleTimeUnit(), handleVolumeUnit(), importEvents(), importFunctionDefinitions(), importInitialAssignments(), importMIRIAM(), importNotes(), importSBMLRule(), INIT_DEFAULTS, isStochasticModel(), CModel::l, CFunctionDB::loadedFunctions(), CModel::m, CModel::m2, mAvogadroCreated, mAvogadroSet, MCSBML, mDelayFound, mDivisionByCompartmentReactions, mFastReactions, mhImportStep, mIgnoredParameterUnits, mImportStep, mKnownInitalValues, mLevel, CModel::Mol, mpCopasiModel, mpDataModel, mpImportHandler, mPotentialAvogadroNumbers, mReactionsWithReplacedLocalParameters, mSubstanceOnlySpecies, mUnitOnNumberFound, mUnsupportedRuleFound, mVersion, CCopasiMessage::peekLastMessage(), CProcessReport::progressItem(), removeUnusedFunctions(), CModel::s, sbmlIdMap, CModel::setAreaUnit(), CModel::setAvogadro(), CModel::setCompileFlag(), setInitialValues(), CModel::setLengthUnit(), CModel::setModelType(), CCopasiObject::setObjectName(), CModel::setQuantityUnit(), CFunction::setSBMLId(), CModelEntity::setSBMLId(), CModel::setTimeUnit(), CModel::setVolumeUnit(), CCopasiVector< T >::size(), speciesMap, CModel::stochastic, and CCopasiMessage::WARNING.

Referenced by parseSBML().

244 {
245  Model* sbmlModel = sbmlDocument->getModel();
246 
247  /* Create an empty model and set the title. */
248  this->mpCopasiModel = new CModel(mpDataModel);
249  copasi2sbmlmap[this->mpCopasiModel] = sbmlModel;
255  this->mpCopasiModel->setSBMLId(sbmlModel->getId());
256 
257  unsigned C_INT32 step = 0, totalSteps = 0;
258  size_t hStep = C_INVALID_INDEX;
259 
260  mImportStep = 1;
261 
263 
264  SBMLImporter::importMIRIAM(sbmlModel, this->mpCopasiModel);
265  UnitDefinition *pSubstanceUnits = NULL;
266  UnitDefinition *pTimeUnits = NULL;
267  UnitDefinition *pVolumeUnits = NULL;
268  UnitDefinition *pAreaUnits = NULL;
269  UnitDefinition *pLengthUnits = NULL;
270  /* Set standard units to match the standard units of SBML files. */
271 
272  // for SBML L3 files the default units are defined on the model
273  if (this->mLevel > 2)
274  {
275  this->mpCopasiModel->setAvogadro(6.02214179e23);
276  this->mAvogadroSet = true;
277 
278  // we make copies of the unit definitions so that we do not have to remember
279  // if we created them or not
280  std::string units;
281  UnitDefinition* pUDef = NULL;
282  Unit unit(sbmlModel->getLevel(), sbmlModel->getVersion());
283  INIT_DEFAULTS(unit);
284 
285  if (sbmlModel->isSetSubstanceUnits())
286  {
287  units = sbmlModel->getSubstanceUnits();
288  assert(units != "");
289  pUDef = sbmlModel->getUnitDefinition(units);
290 
291  if (pUDef != NULL)
292  {
293  pSubstanceUnits = new UnitDefinition(*pUDef);
294  }
295  else
296  {
297  if (units == "mole")
298  {
299  unit.setKind(UNIT_KIND_MOLE);
300  unit.setExponent(1);
301  unit.setMultiplier(1.0);
302  unit.setScale(0);
303  pSubstanceUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
304  pSubstanceUnits->addUnit(&unit);
305  }
306  else if (units == "item")
307  {
308  unit.setKind(UNIT_KIND_ITEM);
309  unit.setExponent(1);
310  unit.setMultiplier(1.0);
311  unit.setScale(0);
312  pSubstanceUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
313  pSubstanceUnits->addUnit(&unit);
314  }
315  else if (units == "dimensionless")
316  {
317  unit.setKind(UNIT_KIND_DIMENSIONLESS);
318  unit.setExponent(1);
319  unit.setMultiplier(1.0);
320  unit.setScale(0);
321  pSubstanceUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
322  pSubstanceUnits->addUnit(&unit);
323  }
324  else
325  {
326  std::string message = "COPASI can't handle substance unit \"" + units + "\". Setting unit for substances to dimensionless.";
327  CCopasiMessage(CCopasiMessage::WARNING, message.c_str());
328  unit.setKind(UNIT_KIND_DIMENSIONLESS);
329  unit.setExponent(1);
330  unit.setMultiplier(1.0);
331  unit.setScale(0);
332  pSubstanceUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
333  pSubstanceUnits->addUnit(&unit);
334  }
335  }
336  }
337 
338  if (sbmlModel->isSetTimeUnits())
339  {
340  units = sbmlModel->getTimeUnits();
341  assert(units != "");
342  pUDef = sbmlModel->getUnitDefinition(units);
343 
344  if (pUDef != NULL)
345  {
346  pTimeUnits = new UnitDefinition(*pUDef);
347  }
348  else
349  {
350  if (units == "second")
351  {
352  unit.setKind(UNIT_KIND_SECOND);
353  unit.setExponent(1);
354  unit.setMultiplier(1.0);
355  unit.setScale(0);
356  pTimeUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
357  pTimeUnits->addUnit(&unit);
358  }
359  else if (units == "dimensionless")
360  {
361  unit.setKind(UNIT_KIND_DIMENSIONLESS);
362  unit.setExponent(1);
363  unit.setMultiplier(1.0);
364  unit.setScale(0);
365  pTimeUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
366  pTimeUnits->addUnit(&unit);
367  }
368  else
369  {
370  std::string message = "COPASI can't handle time unit \"" + units + "\". Setting unit for time to dimensionless.";
371  CCopasiMessage(CCopasiMessage::WARNING, message.c_str());
372  unit.setKind(UNIT_KIND_DIMENSIONLESS);
373  unit.setExponent(1);
374  unit.setMultiplier(1.0);
375  unit.setScale(0);
376  pTimeUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
377  pTimeUnits->addUnit(&unit);
378  }
379  }
380  }
381 
382  if (sbmlModel->isSetVolumeUnits())
383  {
384  units = sbmlModel->getVolumeUnits();
385  assert(units != "");
386  pUDef = sbmlModel->getUnitDefinition(units);
387 
388  if (pUDef != NULL)
389  {
390  pVolumeUnits = new UnitDefinition(*pUDef);
391  }
392  else
393  {
394  if (units == "litre")
395  {
396  unit.setKind(UNIT_KIND_LITRE);
397  unit.setExponent(1);
398  unit.setMultiplier(1.0);
399  unit.setScale(0);
400  pVolumeUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
401  pVolumeUnits->addUnit(&unit);
402  }
403  else if (units == "dimensionless")
404  {
405  unit.setKind(UNIT_KIND_DIMENSIONLESS);
406  unit.setExponent(1);
407  unit.setMultiplier(1.0);
408  unit.setScale(0);
409  pVolumeUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
410  pVolumeUnits->addUnit(&unit);
411  }
412  else
413  {
414  std::string message = "COPASI can't handle volume unit \"" + units + "\". Setting unit for volume to dimensionless.";
415  CCopasiMessage(CCopasiMessage::WARNING, message.c_str());
416  unit.setKind(UNIT_KIND_DIMENSIONLESS);
417  unit.setExponent(1);
418  unit.setMultiplier(1.0);
419  unit.setScale(0);
420  pVolumeUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
421  pVolumeUnits->addUnit(&unit);
422  }
423  }
424  }
425 
426  if (sbmlModel->isSetAreaUnits())
427  {
428  units = sbmlModel->getAreaUnits();
429  assert(units != "");
430  pUDef = sbmlModel->getUnitDefinition(units);
431 
432  if (pUDef != NULL)
433  {
434  pAreaUnits = new UnitDefinition(*pUDef);
435  }
436  else
437  {
438  if (units == "dimensionless")
439  {
440  unit.setKind(UNIT_KIND_DIMENSIONLESS);
441  unit.setExponent(1);
442  unit.setMultiplier(1.0);
443  unit.setScale(0);
444  pAreaUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
445  pAreaUnits->addUnit(&unit);
446  }
447  else
448  {
449  std::string message = "COPASI can't handle area unit \"" + units + "\". Setting unit for area to dimensionless.";
450  CCopasiMessage(CCopasiMessage::WARNING, message.c_str());
451  unit.setKind(UNIT_KIND_DIMENSIONLESS);
452  unit.setExponent(1);
453  unit.setMultiplier(1.0);
454  unit.setScale(0);
455  pAreaUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
456  pAreaUnits->addUnit(&unit);
457  }
458  }
459  }
460 
461  if (sbmlModel->isSetLengthUnits())
462  {
463  units = sbmlModel->getLengthUnits();
464  assert(units != "");
465  pUDef = sbmlModel->getUnitDefinition(units);
466 
467  if (pUDef != NULL)
468  {
469  pLengthUnits = new UnitDefinition(*pUDef);
470  }
471  else
472  {
473  if (units == "litre")
474  {
475  unit.setKind(UNIT_KIND_LITRE);
476  unit.setExponent(1);
477  unit.setMultiplier(1.0);
478  unit.setScale(0);
479  pLengthUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
480  pLengthUnits->addUnit(&unit);
481  }
482  else if (units == "metre")
483  {
484  unit.setKind(UNIT_KIND_METRE);
485  unit.setExponent(1);
486  unit.setMultiplier(1.0);
487  unit.setScale(0);
488  pLengthUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
489  pLengthUnits->addUnit(&unit);
490  }
491  else if (units == "dimensionless")
492  {
493  unit.setKind(UNIT_KIND_DIMENSIONLESS);
494  unit.setExponent(1);
495  unit.setMultiplier(1.0);
496  unit.setScale(0);
497  pLengthUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
498  pLengthUnits->addUnit(&unit);
499  }
500  else
501  {
502  std::string message = "COPASI can't handle length unit \"" + units + "\". Setting unit for length to dimensionless.";
503  CCopasiMessage(CCopasiMessage::WARNING, message.c_str());
504  unit.setKind(UNIT_KIND_DIMENSIONLESS);
505  unit.setExponent(1);
506  unit.setMultiplier(1.0);
507  unit.setScale(0);
508  pLengthUnits = new UnitDefinition(sbmlModel->getLevel(), sbmlModel->getVersion());
509  pLengthUnits->addUnit(&unit);
510  }
511  }
512  }
513  }
514  else
515  {
516  if (sbmlModel->getNumUnitDefinitions() != 0)
517  {
518  unsigned int counter;
519 
520  // we make copies o the unit definitions so that we do not have to remember
521  // if we created them or not
522  for (counter = 0; counter < sbmlModel->getNumUnitDefinitions(); counter++)
523  {
524  UnitDefinition* uDef = sbmlModel->getUnitDefinition(counter);
525  std::string unitId = uDef->getId();
526 
527  if (unitId == "substance")
528  {
529  pSubstanceUnits = new UnitDefinition(*uDef);
530  }
531  else if (unitId == "time")
532  {
533  pTimeUnits = new UnitDefinition(*uDef);
534  }
535  else if (unitId == "volume")
536  {
537  pVolumeUnits = new UnitDefinition(*uDef);
538  }
539  else if ((unitId == "area"))
540  {
541  pAreaUnits = new UnitDefinition(*uDef);
542  }
543  else if ((unitId == "length"))
544  {
545  pLengthUnits = new UnitDefinition(*uDef);
546  }
547  }
548  }
549  }
550 
551  // create the default units if some unit has not been specified
552  if (pSubstanceUnits == NULL)
553  {
554  if (this->mLevel > 2)
555  {
556  // issue a warning
557  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 91, "substance", "mole" , "substance");
558  }
559 
560  // create the default units
561  pSubstanceUnits = new UnitDefinition(this->mLevel, this->mVersion);
562  pSubstanceUnits->setId("dummy_substance");
563  pSubstanceUnits->setName("dummy_substance");
564  Unit* pUnit = pSubstanceUnits->createUnit();
565  pUnit->setKind(UNIT_KIND_MOLE);
566  pUnit->setExponent(1);
567  pUnit->setMultiplier(1.0);
568  pUnit->setScale(0);
569  }
570 
571  if (pTimeUnits == NULL)
572  {
573  if (this->mLevel > 2)
574  {
575  // issue a warning
576  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 91, "time", "second" , "time");
577  }
578 
579  // create the default units
580  pTimeUnits = new UnitDefinition(this->mLevel, this->mVersion);
581  pTimeUnits->setId("dummy_time");
582  pTimeUnits->setName("dummy_time");
583  Unit* pUnit = pTimeUnits->createUnit();
584  pUnit->setKind(UNIT_KIND_SECOND);
585  pUnit->setExponent(1);
586  pUnit->setMultiplier(1.0);
587  pUnit->setScale(0);
588  }
589 
590  if (pVolumeUnits == NULL)
591  {
592  if (this->mLevel > 2)
593  {
594  // issue a warning
595  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 91, "volume", "litre" , "volume");
596  }
597 
598  // create the default units
599  pVolumeUnits = new UnitDefinition(this->mLevel, this->mVersion);
600  pVolumeUnits->setId("dummy_volume");
601  pVolumeUnits->setName("dummy_volume");
602  Unit* pUnit = pVolumeUnits->createUnit();
603  pUnit->setKind(UNIT_KIND_LITRE);
604  pUnit->setExponent(1);
605  pUnit->setMultiplier(1.0);
606  pUnit->setScale(0);
607  }
608 
609  if (pAreaUnits == NULL)
610  {
611  if (this->mLevel > 2)
612  {
613  // issue a warning
614  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 91, "area", "m^2" , "area");
615  }
616 
617  // create the default units
618  pAreaUnits = new UnitDefinition(this->mLevel, this->mVersion);
619  pAreaUnits->setId("dummy_area");
620  pAreaUnits->setName("dummy_area");
621  Unit* pUnit = pAreaUnits->createUnit();
622  pUnit->setKind(UNIT_KIND_METRE);
623  pUnit->setExponent(2);
624  pUnit->setMultiplier(1.0);
625  pUnit->setScale(0);
626  }
627 
628  if (pLengthUnits == NULL)
629  {
630  if (this->mLevel > 2)
631  {
632  // issue a warning
633  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 91, "length", "m" , "length");
634  }
635 
636  // create the default units
637  pLengthUnits = new UnitDefinition(this->mLevel, this->mVersion);
638  pLengthUnits->setId("dummy_length");
639  pLengthUnits->setName("dummy_length");
640  Unit* pUnit = pLengthUnits->createUnit();
641  pUnit->setKind(UNIT_KIND_METRE);
642  pUnit->setExponent(1);
643  pUnit->setMultiplier(1.0);
644  pUnit->setScale(0);
645  }
646 
647  // now we have some common code to actually import the units
648 
649  // handle the substance units
650  assert(pSubstanceUnits != NULL);
651 
652  if (pSubstanceUnits != NULL)
653  {
654  std::pair<CModel::QuantityUnit, bool> qUnit;
655 
656  try
657  {
658  qUnit = this->handleSubstanceUnit(pSubstanceUnits);
659  }
660  catch (...)
661  {
662  std::ostringstream os;
663  os << "Error while importing substance units.";
664 
665  // check if the last message on the stack is an exception
666  // and if so, add the message text to the current exception
668  {
669  // we only want the message, not the timestamp line
670  std::string text = CCopasiMessage::peekLastMessage().getText();
671  os << text.substr(text.find("\n"));
672  }
673 
674  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
675  }
676 
677  if (qUnit.second == false)
678  {
679  // the unit could not be handled, give an error message and
680  // set the units to mole
681  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 66, "substance", "Mole");
683  }
684  else
685  {
686  this->mpCopasiModel->setQuantityUnit(qUnit.first);
687  }
688 
689  // check if the extends units are set and if they are equal to the substance units
690  // otherwise issue a warning
691  if (this->mLevel > 2)
692  {
693  if (!sbmlModel->isSetExtentUnits())
694  {
696  }
697  else
698  {
699  const UnitDefinition* pExtendsUnits = sbmlModel->getUnitDefinition(sbmlModel->getExtentUnits());
700 
701  if (pExtendsUnits != NULL)
702  {
703  if (!areSBMLUnitDefinitionsIdentical(pSubstanceUnits, pExtendsUnits))
704  {
706  }
707  }
708  else
709  {
710  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 66, "extends", "the same units as the substances");
711  }
712  }
713  }
714 
715  delete pSubstanceUnits;
716  pSubstanceUnits = NULL;
717  }
718 
719  // handle the time units
720  assert(pTimeUnits != NULL);
721 
722  if (pTimeUnits != NULL)
723  {
724  std::pair<CModel::TimeUnit, bool> tUnit;
725 
726  try
727  {
728  tUnit = this->handleTimeUnit(pTimeUnits);
729  }
730  catch (...)
731  {
732  std::ostringstream os;
733  os << "Error while importing time units.";
734 
735  // check if the last message on the stack is an exception
736  // and if so, add the message text to the current exception
738  {
739  // we only want the message, not the timestamp line
740  std::string text = CCopasiMessage::peekLastMessage().getText();
741  os << text.substr(text.find("\n"));
742  }
743 
744  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
745  }
746 
747  if (tUnit.second == false)
748  {
749  // the unit could not be handled, give an error message and
750  // set the units to second
751  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 66, "time", "second");
753  }
754  else
755  {
756  this->mpCopasiModel->setTimeUnit(tUnit.first);
757  }
758 
759  delete pTimeUnits;
760  pTimeUnits = NULL;
761  }
762 
763  // handle the volume units
764  assert(pVolumeUnits != NULL);
765 
766  if (pVolumeUnits != NULL)
767  {
768  std::pair<CModel::VolumeUnit, bool> vUnit;
769 
770  try
771  {
772  vUnit = this->handleVolumeUnit(pVolumeUnits);
773  }
774  catch (...)
775  {
776  std::ostringstream os;
777  os << "Error while importing volume units.";
778 
779  // check if the last message on the stack is an exception
780  // and if so, add the message text to the current exception
782  {
783  // we only want the message, not the timestamp line
784  std::string text = CCopasiMessage::peekLastMessage().getText();
785  os << text.substr(text.find("\n"));
786  }
787 
788  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
789  }
790 
791  if (vUnit.second == false)
792  {
793  // the unit could not be handled, give an error message and
794  // set the units to litre
795  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 66, "volume", "litre");
797  }
798  else
799  {
800  this->mpCopasiModel->setVolumeUnit(vUnit.first);
801  }
802 
803  delete pVolumeUnits;
804  pVolumeUnits = NULL;
805  }
806 
807  // handle the area units
808  assert(pAreaUnits != NULL);
809 
810  if (pAreaUnits != NULL)
811  {
812  std::pair<CModel::AreaUnit, bool> vUnit;
813 
814  try
815  {
816  vUnit = this->handleAreaUnit(pAreaUnits);
817  }
818  catch (...)
819  {
820  std::ostringstream os;
821  os << "Error while importing area units.";
822 
823  // check if the last message on the stack is an exception
824  // and if so, add the message text to the current exception
826  {
827  // we only want the message, not the timestamp line
828  std::string text = CCopasiMessage::peekLastMessage().getText();
829  os << text.substr(text.find("\n"));
830  }
831 
832  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
833  }
834 
835  if (vUnit.second == false)
836  {
837  // the unit could not be handled, give an error message and
838  // set the units to litre
839  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 66, "area", "square meter");
841  }
842  else
843  {
844  this->mpCopasiModel->setAreaUnit(vUnit.first);
845  }
846 
847  delete pAreaUnits;
848  pAreaUnits = NULL;
849  }
850 
851  // handle the length units
852  assert(pLengthUnits != NULL);
853 
854  if (pLengthUnits != NULL)
855  {
856  std::pair<CModel::LengthUnit, bool> vUnit;
857 
858  try
859  {
860  vUnit = this->handleLengthUnit(pLengthUnits);
861  }
862  catch (...)
863  {
864  std::ostringstream os;
865  os << "Error while importing length units.";
866 
867  // check if the last message on the stack is an exception
868  // and if so, add the message text to the current exception
870  {
871  // we only want the message, not the timestamp line
872  std::string text = CCopasiMessage::peekLastMessage().getText();
873  os << text.substr(text.find("\n"));
874  }
875 
876  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
877  }
878 
879  if (vUnit.second == false)
880  {
881  // the unit could not be handled, give an error message and
882  // set the units to litre
883  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 66, "length", "meter");
885  }
886  else
887  {
888  this->mpCopasiModel->setLengthUnit(vUnit.first);
889  }
890 
891  delete pLengthUnits;
892  pLengthUnits = NULL;
893  }
894 
895  // go through all compartments and species and check if the units are
896  // consistent
897  checkElementUnits(sbmlModel, this->mpCopasiModel, this->mLevel, this->mVersion);
898  std::string title;
899 
900  if (this->isStochasticModel(sbmlModel))
901  {
903  }
904  else
905  {
907  }
908 
909  SBMLImporter::importNotes(this->mpCopasiModel, sbmlModel);
910 
911  title = sbmlModel->getName();
912 
913  if (title == "")
914  {
915  title = "NoName";
916  }
917 
918  size_t idCount = 0;
919 
920  while (mpDataModel->getObject("Model=" + title) != NULL)
921  {
922  std::stringstream str; str << sbmlModel->getName() << "_" << ++idCount;
923  title = str.str();
924  }
925 
926  this->mpCopasiModel->setObjectName(title.c_str());
927  // fill the set of SBML species reference ids because
928  // we need this to check for references to species references in all expressions
929  // as long as we do not support these references
930  SBMLImporter::updateSBMLSpeciesReferenceIds(sbmlModel, this->mSBMLSpeciesReferenceIds);
931 
932  /* import the functions */
933  unsigned int counter;
934  CCopasiVectorN< CFunction >* functions = &(this->functionDB->loadedFunctions());
935 
936  size_t num = (*functions).size();
937 
938  if (mpImportHandler)
939  {
940  mImportStep = 2;
941 
942  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
943 
944  totalSteps = (unsigned C_INT32) num;
945  hStep = mpImportHandler->addItem("Importing function definitions",
946  step,
947  &totalSteps);
948  }
949 
950  this->sbmlIdMap.clear();
951 
952  for (counter = 0; counter < num; ++counter)
953  {
954  CFunction* tree = (*functions)[counter];
955 
956  if (!tree->getSBMLId().empty())
957  {
958  this->sbmlIdMap[tree] = tree->getSBMLId();
959  tree->setSBMLId("");
960  }
961  }
962 
963  CFunctionDB* pTmpFunctionDB = this->importFunctionDefinitions(sbmlModel, copasi2sbmlmap);
964  // try to find global parameters that represent avogadros number
966 
967  std::map<std::string, CCompartment*> compartmentMap;
968 
969  /* Create the compartments */
970  num = sbmlModel->getNumCompartments();
971 
972  if (mpImportHandler)
973  {
974  mpImportHandler->finishItem(hStep);
975  mImportStep = 3;
976 
977  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
978 
979  step = 0;
980  totalSteps = (unsigned C_INT32) num;
981  hStep = mpImportHandler->addItem("Importing compartments...",
982  step,
983  &totalSteps);
984  }
985 
986  for (counter = 0; counter < num; counter++)
987  {
988  Compartment* sbmlCompartment = sbmlModel->getCompartment(counter);
989 
990  if (sbmlCompartment == NULL)
991  {
992  fatalError();
993  }
994 
995  CCompartment* pCopasiCompartment = NULL;
996 
997  try
998  {
999  pCopasiCompartment = this->createCCompartmentFromCompartment(sbmlCompartment, this->mpCopasiModel, copasi2sbmlmap, sbmlModel);
1000  }
1001  catch (...)
1002  {
1003  std::ostringstream os;
1004  os << "Error while importing compartment \"";
1005  os << sbmlCompartment->getId() << "\".";
1006 
1007  // check if the last message on the stack is an exception
1008  // and if so, add the message text to the current exception
1010  {
1011  // we only want the message, not the timestamp line
1012  std::string text = CCopasiMessage::peekLastMessage().getText();
1013  os << text.substr(text.find("\n"));
1014  }
1015 
1016  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
1017  }
1018 
1019  std::string key = sbmlCompartment->getId();
1020 
1021  if (mLevel == 1)
1022  {
1023  key = sbmlCompartment->getName();
1024  }
1025 
1026  compartmentMap[key] = pCopasiCompartment;
1027  ++step;
1028 
1029  if (mpImportHandler && !mpImportHandler->progressItem(hStep)) return NULL;
1030  }
1031 
1032  /* Create all species */
1033  num = sbmlModel->getNumSpecies();
1034 
1035  if (mpImportHandler)
1036  {
1037  mpImportHandler->finishItem(hStep);
1038  mImportStep = 4;
1039 
1040  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
1041 
1042  step = 0;
1043  totalSteps = (unsigned C_INT32) num;
1044  hStep = mpImportHandler->addItem("Importing species...",
1045  step,
1046  &totalSteps);
1047  }
1048 
1049  for (counter = 0; counter < num; ++counter)
1050  {
1051  Species* sbmlSpecies = sbmlModel->getSpecies(counter);
1052 
1053  if (sbmlSpecies == NULL)
1054  {
1055  fatalError();
1056  }
1057 
1058  CCompartment* pCopasiCompartment = compartmentMap[sbmlSpecies->getCompartment()];
1059 
1060  if (pCopasiCompartment != NULL)
1061  {
1062  CMetab* pCopasiMetabolite = NULL;
1063 
1064  try
1065  {
1066  pCopasiMetabolite = this->createCMetabFromSpecies(sbmlSpecies, this->mpCopasiModel, pCopasiCompartment, copasi2sbmlmap, sbmlModel);
1067  }
1068  catch (...)
1069  {
1070  std::ostringstream os;
1071  os << "Error while importing species \"";
1072  os << sbmlSpecies->getId() << "\".";
1073 
1074  // check if the last message on the stack is an exception
1075  // and if so, add the message text to the current exception
1077  {
1078  // we only want the message, not the timestamp line
1079  std::string text = CCopasiMessage::peekLastMessage().getText();
1080  os << text.substr(text.find("\n"));
1081  }
1082 
1083  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
1084  }
1085 
1086  std::string key;
1087 
1088  if (this->mLevel == 1)
1089  {
1090  key = sbmlSpecies->getName();
1091  }
1092  else
1093  {
1094  key = sbmlSpecies->getId();
1095  }
1096 
1097  this->speciesMap[key] = pCopasiMetabolite;
1098  }
1099  else
1100  {
1101  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 5 , sbmlSpecies->getCompartment().c_str(), sbmlSpecies->getId().c_str());
1102  }
1103 
1104  ++step;
1105 
1106  if (mpImportHandler && !mpImportHandler->progressItem(hStep)) return NULL;
1107  }
1108 
1109  /* Create the global Parameters */
1110  num = sbmlModel->getNumParameters();
1111 
1112  if (mpImportHandler)
1113  {
1114  mpImportHandler->finishItem(hStep);
1115  mImportStep = 5;
1116 
1117  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
1118 
1119  step = 0;
1120  totalSteps = (unsigned C_INT32) num;
1121  hStep = mpImportHandler->addItem("Importing global parameters...",
1122  step,
1123  &totalSteps);
1124  }
1125 
1126  for (counter = 0; counter < num; ++counter)
1127  {
1128  Parameter* sbmlParameter = sbmlModel->getParameter(counter);
1129 
1130  if (sbmlParameter == NULL)
1131  {
1132  fatalError();
1133  }
1134 
1135  try
1136  {
1137  std::string sbmlId = getOriginalSBMLId(sbmlParameter);
1138 
1139  // don't import parameter if it is one of our special ones instead get the cn to the target
1140  if (!sbmlId.empty())
1141  {
1142  Species* species = sbmlModel->getSpecies(sbmlId);
1143 
1144  if (species != NULL)
1145  {
1146  mKnownInitalValues[sbmlParameter->getId()] = getInitialCNForSBase(species, copasi2sbmlmap);
1147  continue;
1148  }
1149 
1150  Compartment *comp = sbmlModel->getCompartment(sbmlId);
1151 
1152  if (comp != NULL)
1153  {
1154  mKnownInitalValues[sbmlParameter->getId()] = getInitialCNForSBase(comp, copasi2sbmlmap);
1155  continue;
1156  }
1157 
1158  Parameter* param = sbmlModel->getParameter(sbmlId);
1159 
1160  if (param != NULL)
1161  {
1162  mKnownInitalValues[sbmlParameter->getId()] = getInitialCNForSBase(param, copasi2sbmlmap);
1163  continue;
1164  }
1165  }
1166 
1167  this->createCModelValueFromParameter(sbmlParameter, this->mpCopasiModel, copasi2sbmlmap);
1168  }
1169  catch (...)
1170  {
1171  std::ostringstream os;
1172  os << "Error while importing parameter \"";
1173  os << sbmlParameter->getId() << "\".";
1174 
1175  // check if the last message on the stack is an exception
1176  // and if so, add the message text to the current exception
1178  {
1179  // we only want the message, not the timestamp line
1180  std::string text = CCopasiMessage::peekLastMessage().getText();
1181  os << text.substr(text.find("\n"));
1182  }
1183 
1184  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
1185  }
1186 
1187  ++step;
1188 
1189  if (mpImportHandler && !mpImportHandler->progressItem(hStep)) return NULL;
1190  }
1191 
1192  // the information that is collected here is used in the creation of the reactions to
1193  // adjust the stoichiometry of substrates and products with the conversion factos from
1194  // the SBML model
1195 
1196  // now that all parameters have been imported, we can check if the model
1197  // defines a global conversion factor
1198  if (this->mLevel > 2 && sbmlModel->isSetConversionFactor())
1199  {
1200  this->mConversionFactorFound = true;
1201  std::string id = sbmlModel->getConversionFactor();
1202  assert(id != "");
1203  std::map<std::string, const CModelValue*>::const_iterator pos = this->mSBMLIdModelValueMap.find(id);
1204  assert(pos != this->mSBMLIdModelValueMap.end());
1205 
1206  if (pos != this->mSBMLIdModelValueMap.end())
1207  {
1208  this->mpModelConversionFactor = pos->second;
1209  }
1210  else
1211  {
1212  fatalError();
1213  }
1214  }
1215 
1216  // we need to go through all species again and find conversion factors
1217  // right now I don't want to change the order of importing model values
1218  // and species since I am not sure what implications that would have
1219  if (this->mLevel > 2)
1220  {
1221  num = sbmlModel->getNumSpecies();
1222 
1223  for (counter = 0; counter < num; ++counter)
1224  {
1225  Species* sbmlSpecies = sbmlModel->getSpecies(counter);
1226 
1227  if (sbmlSpecies->isSetConversionFactor())
1228  {
1229  this->mConversionFactorFound = true;
1230  std::map<std::string, const CModelValue*>::const_iterator pos = this->mSBMLIdModelValueMap.find(sbmlSpecies->getConversionFactor());
1231 
1232  if (pos != this->mSBMLIdModelValueMap.end())
1233  {
1234  this->mSpeciesConversionParameterMap[sbmlSpecies->getId()] = pos->second;
1235  }
1236  }
1237  }
1238  }
1239 
1240  if (!this->mIgnoredParameterUnits.empty())
1241  {
1242  std::ostringstream os;
1243  std::vector<std::string>::iterator errorIt = this->mIgnoredParameterUnits.begin();
1244 
1245  while (errorIt != this->mIgnoredParameterUnits.end())
1246  {
1247  os << *errorIt << ", ";
1248  ++errorIt;
1249  }
1250 
1251  std::string s = os.str();
1252  CCopasiMessage Message(CCopasiMessage::WARNING, MCSBML + 26, s.substr(0, s.size() - 2).c_str());
1253  }
1254 
1255  /* Create all reactions */
1256  num = sbmlModel->getNumReactions();
1257 
1258  if (mpImportHandler)
1259  {
1260  mpImportHandler->finishItem(hStep);
1261  mImportStep = 6;
1262 
1263  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
1264 
1265  step = 0;
1266  totalSteps = (unsigned C_INT32) num;
1267  hStep = mpImportHandler->addItem("Importing reactions...",
1268  step,
1269  &totalSteps);
1270  }
1271 
1272  this->mDivisionByCompartmentReactions.clear();
1273  this->mFastReactions.clear();
1275 
1276  for (counter = 0; counter < num; counter++)
1277  {
1278  try
1279  {
1280  this->createCReactionFromReaction(sbmlModel->getReaction(counter), sbmlModel, this->mpCopasiModel, copasi2sbmlmap, pTmpFunctionDB);
1281  }
1282  catch (...)
1283  {
1284  std::ostringstream os;
1285  os << "Error while importing reaction \"";
1286  os << sbmlModel->getReaction(counter)->getId() << "\".";
1287 
1288  // check if the last message on the stack is an exception
1289  // and if so, add the message text to the current exception
1291  {
1292  // we only want the message, not the timestamp line
1293  std::string text = CCopasiMessage::peekLastMessage().getText();
1294  os << text.substr(text.find("\n"));
1295  }
1296 
1297  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
1298  }
1299 
1300  ++step;
1301 
1302  if (mpImportHandler && !mpImportHandler->progressItem(hStep)) return NULL;
1303  }
1304 
1305  if (!this->mDivisionByCompartmentReactions.empty())
1306  {
1307  // create the error message
1308  std::string idList;
1309  std::set<std::string>::const_iterator it = this->mDivisionByCompartmentReactions.begin();
1310  std::set<std::string>::const_iterator endit = this->mDivisionByCompartmentReactions.end();
1311 
1312  while (it != endit)
1313  {
1314  idList += (*it);
1315  idList += ", ";
1316  ++it;
1317  }
1318 
1319  idList = idList.substr(0, idList.length() - 2);
1320  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 17, idList.c_str());
1321  }
1322 
1323  if (!this->mFastReactions.empty())
1324  {
1325  // create the error message
1326  std::string idList;
1327  std::set<std::string>::const_iterator it = this->mFastReactions.begin();
1328  std::set<std::string>::const_iterator endit = this->mFastReactions.end();
1329 
1330  while (it != endit)
1331  {
1332  idList += (*it);
1333  idList += ", ";
1334  ++it;
1335  }
1336 
1337  idList = idList.substr(0, idList.length() - 2);
1338  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 29, idList.c_str());
1339  }
1340 
1341  if (!this->mReactionsWithReplacedLocalParameters.empty())
1342  {
1343  // create the error message
1344  std::string idList;
1345  std::set<std::string>::const_iterator it = this->mReactionsWithReplacedLocalParameters.begin();
1346  std::set<std::string>::const_iterator endit = this->mReactionsWithReplacedLocalParameters.end();
1347 
1348  while (it != endit)
1349  {
1350  idList += (*it);
1351  idList += ", ";
1352  ++it;
1353  }
1354 
1355  idList = idList.substr(0, idList.length() - 2);
1356  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 87, idList.c_str());
1357  }
1358 
1359  // import the initial assignments
1360  // we do this after the reactions since intial assignments can reference reaction ids.
1361  if (mpImportHandler)
1362  {
1363  mpImportHandler->finishItem(hStep);
1364  mImportStep = 7;
1365 
1366  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
1367  }
1368 
1369  importInitialAssignments(sbmlModel, copasi2sbmlmap, this->mpCopasiModel);
1370 
1371  // import all rules
1372  // we have to import them after the reactions since they can reference a reaction
1373  // id which has to be known when importing the rule
1374 
1375  /* Create the rules */
1376  // rules should be imported after reactions because we use the mSBMLSpeciesReferenceIds to determine if a
1377  // rule changes a species reference (stoichiometry
1378  // Since COPASI does not support this, we need to ignore the rule
1379  this->areRulesUnique(sbmlModel);
1380  num = sbmlModel->getNumRules();
1381 
1382  if (mpImportHandler)
1383  {
1384  mpImportHandler->finishItem(hStep);
1385  mImportStep = 8;
1386 
1387  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
1388 
1389  step = 0;
1390  totalSteps = (unsigned C_INT32) num;
1391  hStep = mpImportHandler->addItem("Importing global parameters...",
1392  step,
1393  &totalSteps);
1394  }
1395 
1396  for (counter = 0; counter < num; ++counter)
1397  {
1398  Rule* sbmlRule = sbmlModel->getRule(counter);
1399 
1400  if (sbmlRule == NULL)
1401  {
1402  fatalError();
1403  }
1404 
1405  // improve the error message a bit.
1406  try
1407  {
1408  this->importSBMLRule(sbmlRule, copasi2sbmlmap, sbmlModel);
1409  }
1410  catch (...)
1411  {
1412  std::ostringstream os;
1413  os << "Error while importing rule for variable \"";
1414  os << sbmlRule->getVariable() << "\".";
1415 
1416  // check if the last message on the stack is an exception
1417  // and if so, add the message text to the current exception
1419  {
1420  // we only want the message, not the time stamp line
1421  std::string text = CCopasiMessage::peekLastMessage().getText();
1422  os << text.substr(text.find("\n"));
1423  }
1424 
1425  CCopasiMessage(CCopasiMessage::EXCEPTION, os.str().c_str());
1426  }
1427 
1428  ++step;
1429 
1430  if (mpImportHandler && !mpImportHandler->progressItem(hStep)) return NULL;
1431  }
1432 
1433  if (sbmlModel->getNumConstraints() > 0)
1434  {
1436  }
1437 
1438  // TODO Create all constraints
1439  // TODO Since we don't have constraints yet, there is no code here.
1440  // TODO When implementing import of constraints, don't forget to replace calls to
1441  // TODO explicitly time dependent functions in the constraints math expression.
1442 
1443  // import all events
1444  // events should be imported after reactions because we use the mSBMLSpeciesReferenceIds to determine if an
1445  // event assignment changes a species reference (stoichiometry
1446  // Since COPASI does not support this, we need to ignore the event assignment
1447  if (mpImportHandler)
1448  {
1449  mpImportHandler->finishItem(hStep);
1450  mImportStep = 9;
1451 
1452  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
1453  }
1454 
1455  this->importEvents(sbmlModel, this->mpCopasiModel, copasi2sbmlmap);
1456 
1457  this->mpCopasiModel->setCompileFlag();
1458 
1459  if (this->mUnsupportedRuleFound)
1460  {
1462  }
1463 
1464  if (this->mRateRuleForSpeciesReferenceIgnored == true)
1465  {
1466  CCopasiMessage Message(CCopasiMessage::WARNING, MCSBML + 94 , "Rate rule" , "Rate rule");
1467  }
1468 
1469  if (this->mEventAssignmentForSpeciesReferenceIgnored == true)
1470  {
1471  CCopasiMessage Message(CCopasiMessage::WARNING, MCSBML + 94 , "Event assignment", "event assignment");
1472  }
1473 
1474  if (this->mConversionFactorFound == true)
1475  {
1477  }
1478 
1479  if (this->mEventPrioritiesIgnored == true)
1480  {
1482  }
1483 
1484  if (this->mInitialTriggerValues == true)
1485  {
1487  }
1488 
1489  if (this->mNonPersistentTriggerFound == true)
1490  {
1492  }
1493 
1494  if (mpImportHandler)
1495  {
1496  mpImportHandler->finishItem(hStep);
1497  mImportStep = 10;
1498 
1499  if (!mpImportHandler->progressItem(mhImportStep)) return NULL;
1500  }
1501 
1502  // unset the hasOnlySubstanceUnits flag on all such species
1503  std::map<Species*, Compartment*>::iterator it = this->mSubstanceOnlySpecies.begin();
1504  std::map<Species*, Compartment*>::iterator endIt = this->mSubstanceOnlySpecies.end();
1505 
1506  while (it != endIt)
1507  {
1508  it->first->setHasOnlySubstanceUnits(false);
1509  ++it;
1510  }
1511 
1512  setInitialValues(this->mpCopasiModel, copasi2sbmlmap);
1513  // evaluate and apply the initial expressions
1514  this->applyStoichiometricExpressions(copasi2sbmlmap, sbmlModel);
1515 
1516  // now we apply the conversion factors
1517  if (this->mLevel > 2)
1518  {
1519  this->applyConversionFactors();
1520  }
1521 
1522  this->removeUnusedFunctions(pTmpFunctionDB, copasi2sbmlmap);
1523 
1524  // remove the temporary avogadro parameter if one was created
1525  if (this->mAvogadroCreated == true)
1526  {
1527  const Parameter* pParameter = *this->mPotentialAvogadroNumbers.begin();
1528  ListOf* pList = sbmlModel->getListOfParameters();
1529  unsigned i, iMax = pList->size();
1530 
1531  for (i = 0; i < iMax; ++i)
1532  {
1533  if (pList->get(i)->getId() == pParameter->getId())
1534  {
1535  pList->remove(i);
1536  break;
1537  }
1538  }
1539  }
1540 
1541  delete pTmpFunctionDB;
1542 
1543  // create a warning if the delay function is used in the model
1544  if (this->mDelayFound)
1545  {
1547  }
1548 
1549  // give a warning that units on pure number as allowed in SBML L3 and above
1550  // are ignored by COPASI
1551  if (this->mLevel > 2 && this->mUnitOnNumberFound)
1552  {
1554  }
1555 
1557  return this->mpCopasiModel;
1558 }
static const CCopasiMessage & peekLastMessage()
std::pair< CModel::TimeUnit, bool > handleTimeUnit(const UnitDefinition *uDef)
CCopasiVectorN< CFunction > & loadedFunctions()
size_t mhImportStep
Definition: SBMLImporter.h:74
bool setAreaUnit(const std::string &name)
Definition: CModel.cpp:2182
bool setVolumeUnit(const std::string &name)
Definition: CModel.cpp:2159
void importSBMLRule(const Rule *sbmlRule, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Model *pSBMLModel)
bool mAvogadroCreated
Definition: SBMLImporter.h:84
bool mUnitOnNumberFound
Definition: SBMLImporter.h:61
unsigned int mLevel
Definition: SBMLImporter.h:63
std::map< std::string, std::string > mKnownInitalValues
Definition: SBMLImporter.h:93
CModel * mpCopasiModel
Definition: SBMLImporter.h:69
virtual size_t size() const
const std::string & getText() const
bool setLengthUnit(const std::string &name)
Definition: CModel.cpp:2204
std::set< std::string > mReactionsWithReplacedLocalParameters
Definition: SBMLImporter.h:78
void importInitialAssignments(Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlMap, const CModel *pCOPASIModel)
void findAvogadroConstant(Model *pSBMLModel, double factor)
bool setTimeUnit(const std::string &name)
Definition: CModel.cpp:2227
std::map< Species *, Compartment * > mSubstanceOnlySpecies
Definition: SBMLImporter.h:76
#define fatalError()
std::string getInitialCNForSBase(SBase *sbase, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
CProcessReport * mpImportHandler
Definition: SBMLImporter.h:72
bool mDelayFound
Definition: SBMLImporter.h:82
#define C_INVALID_INDEX
Definition: copasi.h:222
bool mUnsupportedRuleFound
Definition: SBMLImporter.h:58
#define INIT_DEFAULTS(element)
CFunctionDB * importFunctionDefinitions(Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
unsigned int mVersion
Definition: SBMLImporter.h:65
#define C_INT32
Definition: copasi.h:90
std::set< const Parameter * > mPotentialAvogadroNumbers
Definition: SBMLImporter.h:83
Definition: CMetab.h:178
virtual bool progressItem(const size_t &handle)
CMetab * createCMetabFromSpecies(const Species *sbmlSpecies, CModel *copasiModel, CCompartment *copasiCompartment, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, const Model *pSBMLModel)
void checkElementUnits(const Model *pSBMLModel, CModel *pCopasiModel, int level, int version)
unsigned C_INT32 mImportStep
Definition: SBMLImporter.h:73
std::pair< CModel::QuantityUnit, bool > handleSubstanceUnit(const UnitDefinition *uDef)
#define MCSBML
CCopasiDataModel * mpDataModel
Definition: SBMLImporter.h:68
const C_FLOAT64 & getQuantity2NumberFactor() const
Definition: CModel.cpp:2354
bool mAvogadroSet
Definition: SBMLImporter.h:91
CFunctionDB * functionDB
Definition: SBMLImporter.h:56
size_t addItem(const std::string &name, const std::string &value, const std::string *pEndValue=NULL)
void setSBMLId(const std::string &id)
Definition: CFunction.cpp:63
bool setInitialValues(CModel *pModel, const std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
struct MESSAGES Message
void areRulesUnique(const Model *copasiMode)
std::set< std::string > mDivisionByCompartmentReactions
Definition: SBMLImporter.h:71
virtual bool finishItem(const size_t &handle)
bool removeUnusedFunctions(CFunctionDB *pTmpFunctionDB, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
bool isStochasticModel(const Model *pSBMLModel)
std::pair< CModel::AreaUnit, bool > handleAreaUnit(const UnitDefinition *uDef)
void setCompileFlag(bool flag=true)
Definition: CModel.cpp:607
std::set< std::string > mFastReactions
Definition: SBMLImporter.h:77
CCompartment * createCCompartmentFromCompartment(const Compartment *sbmlComp, CModel *copasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, const Model *pSBMLModel)
const std::string & getSBMLId() const
Definition: CFunction.cpp:68
void importEvents(Model *pSBMLModel, CModel *pCopasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
std::map< CFunction *, std::string > sbmlIdMap
Definition: SBMLImporter.h:66
bool setQuantityUnit(const std::string &name)
Definition: CModel.cpp:2250
std::pair< CModel::LengthUnit, bool > handleLengthUnit(const UnitDefinition *uDef)
bool importMIRIAM(const SBase *pSBMLObject, CCopasiObject *pCOPASIObject)
CReaction * createCReactionFromReaction(Reaction *sbmlReaction, Model *sbmlModel, CModel *cmodel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, CFunctionDB *pTmpFunctionDB)
CModelValue * createCModelValueFromParameter(const Parameter *sbmlParameter, CModel *copasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
std::map< std::string, CMetab * > speciesMap
Definition: SBMLImporter.h:55
std::vector< std::string > mIgnoredParameterUnits
Definition: SBMLImporter.h:80
Definition: CModel.h:50
std::string getOriginalSBMLId(Parameter *parameter)
virtual const CObjectInterface * getObject(const CCopasiObjectName &cn) const
void setAvogadro(const C_FLOAT64 &avogadro)
Definition: CModel.cpp:2342
static bool importNotes(CAnnotation *pAnno, const SBase *pSBase)
bool setObjectName(const std::string &name)
void setSBMLId(const std::string &id)
void setModelType(const ModelType &modelType)
Definition: CModel.cpp:2336
std::pair< CModel::VolumeUnit, bool > handleVolumeUnit(const UnitDefinition *uDef)
void applyStoichiometricExpressions(std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Model *pSBMLModel)
static bool areSBMLUnitDefinitionsIdentical(const UnitDefinition *pUdef1, const UnitDefinition *pUdef2)
bool forceCompile(CProcessReport *pProcessReport)
Definition: CModel.cpp:636
CModelValue * SBMLImporter::createCModelValueFromParameter ( const Parameter *  sbmlParameter,
CModel copasiModel,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap 
)
protected

Creates and returns a COPASI CModelValue from the given SBML Parameter object.

Definition at line 4436 of file SBMLImporter.cpp.

References C_INVALID_INDEX, CModel::createModelValue(), CCopasiVectorN< CType >::getIndex(), CModel::getModelValues(), importMIRIAM(), importNotes(), mIgnoredParameterUnits, mLevel, and CModelEntity::setSBMLId().

Referenced by createCModelFromSBMLDocument(), createHasOnlySubstanceUnitFactor(), find_local_parameters_in_delay(), and replace_delay_nodes().

4437 {
4438  if (sbmlParameter->isSetUnits())
4439  {
4440  /* !!!! create a warning that the units will be ignored. */
4441  //CCopasiMessage Message(CCopasiMessage::WARNING, MCSBML + 26, sbmlParameter->getId().c_str());
4442  mIgnoredParameterUnits.push_back(sbmlParameter->getId());
4443  const_cast<Parameter*>(sbmlParameter)->unsetUnits();
4444  }
4445 
4446  std::string name = sbmlParameter->getName();
4447 
4448  if (!sbmlParameter->isSetName())
4449  {
4450  name = sbmlParameter->getId();
4451  }
4452 
4453  std::string appendix = "";
4454  unsigned int counter = 2;
4455  std::ostringstream numberStream;
4456 
4457  while (copasiModel->getModelValues().getIndex(name + appendix) != C_INVALID_INDEX)
4458  {
4459  numberStream.str("");
4460  numberStream << "_" << counter;
4461  counter++;
4462  appendix = numberStream.str();
4463  }
4464 
4465  std::string sbmlId;
4466 
4467  if (this->mLevel == 1)
4468  {
4469  sbmlId = sbmlParameter->getName();
4470  }
4471  else
4472  {
4473  sbmlId = sbmlParameter->getId();
4474  }
4475 
4476  CModelValue* pMV = copasiModel->createModelValue(name + appendix, 0.0);
4477  copasi2sbmlmap[pMV] = const_cast<Parameter*>(sbmlParameter);
4478  pMV->setSBMLId(sbmlId);
4479  SBMLImporter::importMIRIAM(sbmlParameter, pMV);
4480  SBMLImporter::importNotes(pMV, sbmlParameter);
4481 
4482  if (this->mLevel > 2)
4483  {
4484  this->mSBMLIdModelValueMap[sbmlId] = pMV;
4485  }
4486 
4487  return pMV;
4488 }
unsigned int mLevel
Definition: SBMLImporter.h:63
const CCopasiVectorN< CModelValue > & getModelValues() const
Definition: CModel.cpp:1060
#define C_INVALID_INDEX
Definition: copasi.h:222
CModelValue * createModelValue(const std::string &name, const C_FLOAT64 &value=0.0)
Definition: CModel.cpp:2838
virtual size_t getIndex(const std::string &name) const
bool importMIRIAM(const SBase *pSBMLObject, CCopasiObject *pCOPASIObject)
std::vector< std::string > mIgnoredParameterUnits
Definition: SBMLImporter.h:80
static bool importNotes(CAnnotation *pAnno, const SBase *pSBase)
void setSBMLId(const std::string &id)
CReaction * SBMLImporter::createCReactionFromReaction ( Reaction *  sbmlReaction,
Model *  pSBMLModel,
CModel copasiModel,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap,
CFunctionDB pTmpFunctionDB 
)
protected

Creates and returns a COPASI CReaction object from the given SBML Reaction object.

Definition at line 2146 of file SBMLImporter.cpp.

References CFunctionDB::add(), CEvaluationNodeCall::addChild(), CReaction::addModifier(), CCopasiParameterGroup::addParameter(), CReaction::addProduct(), CReaction::addSubstrate(), CCopasiVector< T >::begin(), C_FLOAT64, C_INVALID_INDEX, containsVolume(), CEvaluationNode::copyBranch(), CModel::createReaction(), doMapping(), CCopasiParameter::DOUBLE, CCopasiVector< T >::end(), CCopasiMessage::EXCEPTION, CEvaluationNodeCall::EXPRESSION, fatalError, findCorrespondingFunction(), CFunctionDB::findFunction(), findIdInASTTree(), CEvaluationTree::fromAST(), functionDB, CReaction::getChemEq(), CCopasiNode< _Data >::getChild(), CCopasiObject::getCN(), CCopasiNode< _Data >::getData(), CCompartment::getDimensionality(), CCopasiVectorN< CType >::getIndex(), CChemEq::getModifiers(), CCopasiObject::getObjectName(), CCopasiObject::getObjectType(), CReaction::getParameters(), CChemEq::getProducts(), CModel::getReactions(), CEvaluationTree::getRoot(), CModelEntity::getSBMLId(), CCopasiNode< _Data >::getSibling(), CChemEq::getSubstrates(), CEvaluationTree::getType(), CEvaluationNode::getType(), CFunction::getVariables(), importMIRIAM(), importNotes(), isConstantFlux(), isMassAction(), isMultipliedByVolume(), CReaction::isReversible(), isSimpleFunctionCall(), CFunction::isSuitable(), MCSBML, mDivisionByCompartmentReactions, mFastReactions, mIncompleteModel, mLevel, mStoichiometricExpressionMap, mUsedFunctions, CEvaluationNode::OBJECT, pdelete, preprocessNode(), CChemEq::PRODUCT, renameMassActionParameters(), sbmlId2CopasiCN(), CReaction::setFunction(), CReaction::setFunctionFromExpressionTree(), CCopasiObject::setObjectName(), CFunction::setReversible(), CReaction::setReversible(), CEvaluationTree::setRoot(), CReaction::setSBMLId(), CFunctionParameters::size(), CCopasiVector< T >::size(), speciesMap, CChemEq::SUBSTRATE, TriFalse, TriTrue, TriUnspecified, CEvaluationNode::type(), CEvaluationTree::UserDefined, variables2objects(), and CCopasiMessage::WARNING.

Referenced by createCModelFromSBMLDocument().

2147 {
2148  if (sbmlReaction == NULL)
2149  {
2150  fatalError();
2151  }
2152 
2153  std::string name = sbmlReaction->getName();
2154 
2155  if (name == "")
2156  {
2157  name = sbmlReaction->getId();
2158  }
2159 
2160  /* Check if the name of the reaction is unique. */
2161  std::string appendix = "";
2162  unsigned int counter = 2;
2163  std::ostringstream numberStream;
2164 
2165  while (copasiModel->getReactions().getIndex(name + appendix) != C_INVALID_INDEX)
2166  {
2167  numberStream.str("");
2168  numberStream << "_" << counter;
2169  counter++;
2170  appendix = numberStream.str();
2171  }
2172 
2173  /* create a new reaction with the unique name */
2174  CReaction* copasiReaction = copasiModel->createReaction(name + appendix);
2175 
2176  if (copasiReaction == NULL)
2177  {
2178  fatalError();
2179  }
2180 
2181  copasiReaction->setReversible(sbmlReaction->getReversible());
2182 
2183  if (this->mLevel == 1)
2184  {
2185  copasiReaction->setSBMLId(sbmlReaction->getName());
2186  }
2187  else
2188  {
2189  copasiReaction->setSBMLId(sbmlReaction->getId());
2190  }
2191 
2192  copasi2sbmlmap[copasiReaction] = const_cast<Reaction*>(sbmlReaction);
2193 
2194  if (sbmlReaction->isSetFast() && sbmlReaction->getFast() == true)
2195  {
2196  const_cast<Reaction*>(sbmlReaction)->setFast(false);
2197  this->mFastReactions.insert(sbmlReaction->getId());
2198  }
2199 
2200  // store if the reaction involves species that need a conversion factor
2201  bool mConversionFactorNeeded = false;
2202 
2203  /* Add all substrates to the reaction */
2204  unsigned int num = sbmlReaction->getNumReactants();
2205  bool singleCompartment = true;
2206  const CCompartment* compartment = NULL;
2207  bool hasOnlySubstanceUnitPresent = false;
2208  bool ignoreMassAction = false;
2209 
2210  for (counter = 0; counter < num; counter++)
2211  {
2212  const SpeciesReference* sr = sbmlReaction->getReactant(counter);
2213 
2214  if (sr == NULL)
2215  {
2216  delete copasiReaction;
2217  fatalError();
2218  }
2219 
2220  C_FLOAT64 stoi = 1.0;
2221 
2222  if (this->mLevel < 3)
2223  {
2224  // We may not use Mass Action kinetics if we do not know the actual stoichiometry.
2225  if (sr->isSetStoichiometryMath())
2226  {
2227  ignoreMassAction = true;
2228  }
2229  else
2230  {
2231  stoi = sr->getStoichiometry() / sr->getDenominator();
2232  }
2233  }
2234  else
2235  {
2236  // We may not use Mass Action kinetics if we do not know the actual stoichiometry.
2237  if (sr->isSetId() &&
2238  (pSBMLModel->getInitialAssignment(sr->getId()) ||
2239  pSBMLModel->getRule(sr->getId())))
2240  {
2241  ignoreMassAction = true;
2242  }
2243 
2244  if (sr->isSetStoichiometry())
2245  {
2246  stoi = sr->getStoichiometry();
2247  }
2248  }
2249 
2250  std::map<std::string, CMetab*>::iterator pos;
2251  pos = this->speciesMap.find(sr->getSpecies());
2252 
2253  // check if we have a conversion factor
2254  if (pos == this->speciesMap.end())
2255  {
2256  delete copasiReaction;
2257  fatalError();
2258  }
2259  else
2260  {
2261  // check if there is a conversion factor on the species
2262  if (this->mpModelConversionFactor != NULL || this->mSpeciesConversionParameterMap.find(pos->second->getSBMLId()) != this->mSpeciesConversionParameterMap.end())
2263  {
2264  mConversionFactorNeeded = true;
2265  }
2266  }
2267 
2268  std::map<CCopasiObject*, SBase*>::const_iterator spos = copasi2sbmlmap.find(pos->second);
2269  assert(spos != copasi2sbmlmap.end());
2270  Species* pSBMLSpecies = dynamic_cast<Species*>(spos->second);
2271  assert(pSBMLSpecies != NULL);
2272  hasOnlySubstanceUnitPresent = (hasOnlySubstanceUnitPresent | (pSBMLSpecies->getHasOnlySubstanceUnits() == true));
2273 
2274  if (compartment == NULL)
2275  {
2276  compartment = pos->second->getCompartment();
2277  }
2278  else
2279  {
2280  if (singleCompartment && compartment != pos->second->getCompartment())
2281  {
2282  singleCompartment = false;
2283  }
2284  }
2285 
2286  copasiReaction->addSubstrate(pos->second->getKey(), stoi);
2287 
2288  // we need to store the id of the species reference if it is set because SBML Level 3 allows
2289  // references to species references and if we want to support his, we need the id to import
2290  // expressions that reference a species reference
2291  if (this->mLevel > 2)
2292  {
2293  CCopasiVector<CChemEqElement>::const_iterator it = copasiReaction->getChemEq().getSubstrates().begin(), endit = copasiReaction->getChemEq().getSubstrates().end();
2294  CChemEqElement* pElement = NULL;
2295 
2296  while (it != endit)
2297  {
2298  if ((*it)->getMetaboliteKey() == pos->second->getKey())
2299  {
2300  pElement = const_cast<CChemEqElement*>(*it);
2301  break;
2302  }
2303 
2304  ++it;
2305  }
2306 
2307  assert(pElement != NULL);
2308 
2309  if (pElement != NULL)
2310  {
2311  copasi2sbmlmap[pElement] = const_cast<SpeciesReference*>(sr);
2312 
2313  this->mChemEqElementSpeciesIdMap[pElement] = std::pair<std::string, CChemEq::MetaboliteRole>(sr->getSpecies(), CChemEq::SUBSTRATE);
2314  }
2315  }
2316 
2317  // find the CChemEqElement that belongs to the added substrate
2318  if (this->mLevel < 3 && sr->isSetStoichiometryMath())
2319  {
2320  CChemEq& chemEq = copasiReaction->getChemEq();
2323  CChemEqElement* pChemEqElement = NULL;
2324 
2325  while (it != end)
2326  {
2327  if ((*it)->getMetabolite() == pos->second)
2328  {
2329  pChemEqElement = (*it);
2330  break;
2331  }
2332 
2333  ++it;
2334  }
2335 
2336  assert(pChemEqElement != NULL);
2337  mStoichiometricExpressionMap.insert(std::make_pair(sr->getStoichiometryMath()->getMath(), pChemEqElement));
2338  }
2339  }
2340 
2341  /* Add all products to the reaction */
2342  num = sbmlReaction->getNumProducts();
2343 
2344  for (counter = 0; counter < num; counter++)
2345  {
2346  const SpeciesReference* sr = sbmlReaction->getProduct(counter);
2347 
2348  if (sr == NULL)
2349  {
2350  delete copasiReaction;
2351  fatalError();
2352  }
2353 
2354  C_FLOAT64 stoi = 1.0;
2355 
2356  if (this->mLevel < 3)
2357  {
2358  if (sr->isSetStoichiometryMath())
2359  {
2360  ignoreMassAction = true;
2361  }
2362  else
2363  {
2364  stoi = sr->getStoichiometry() / sr->getDenominator();
2365  }
2366  }
2367  else
2368  {
2369  // We may not use Mass Action kinetics if we do not know the actual stoichiometry.
2370  if (sr->isSetId() &&
2371  (pSBMLModel->getInitialAssignment(sr->getId()) ||
2372  pSBMLModel->getRule(sr->getId())))
2373  {
2374  ignoreMassAction = true;
2375  }
2376 
2377  if (sr->isSetStoichiometry())
2378  {
2379  stoi = sr->getStoichiometry();
2380  }
2381  }
2382 
2383  std::map<std::string, CMetab*>::iterator pos;
2384  pos = this->speciesMap.find(sr->getSpecies());
2385 
2386  if (pos == this->speciesMap.end())
2387  {
2388  delete copasiReaction;
2389  fatalError();
2390  }
2391  else
2392  {
2393  // check if there is a conversion factor on the species
2394  if (this->mpModelConversionFactor != NULL || this->mSpeciesConversionParameterMap.find(pos->second->getSBMLId()) != this->mSpeciesConversionParameterMap.end())
2395  {
2396  mConversionFactorNeeded = true;
2397  }
2398  }
2399 
2400  std::map<CCopasiObject*, SBase*>::const_iterator spos = copasi2sbmlmap.find(pos->second);
2401  assert(spos != copasi2sbmlmap.end());
2402  Species* pSBMLSpecies = dynamic_cast<Species*>(spos->second);
2403  assert(pSBMLSpecies != NULL);
2404  hasOnlySubstanceUnitPresent = (hasOnlySubstanceUnitPresent | (pSBMLSpecies->getHasOnlySubstanceUnits() == true));
2405 
2406  if (compartment == NULL)
2407  {
2408  compartment = pos->second->getCompartment();
2409  }
2410  else
2411  {
2412  if (singleCompartment && compartment != pos->second->getCompartment())
2413  {
2414  singleCompartment = false;
2415  }
2416  }
2417 
2418  copasiReaction->addProduct(pos->second->getKey(), stoi);
2419 
2420  // we need to store the id of the species reference if it is set because SBML Level 3 allows
2421  // references to species references and if we want to support his, we need the id to import
2422  // expressions that reference a species reference
2423  if (this->mLevel > 2)
2424  {
2425  CCopasiVector<CChemEqElement>::const_iterator it = copasiReaction->getChemEq().getProducts().begin(), endit = copasiReaction->getChemEq().getProducts().end();
2426  CChemEqElement* pElement = NULL;
2427 
2428  while (it != endit)
2429  {
2430  if ((*it)->getMetaboliteKey() == pos->second->getKey())
2431  {
2432  pElement = const_cast<CChemEqElement*>(*it);
2433  break;
2434  }
2435 
2436  ++it;
2437  }
2438 
2439  assert(pElement != NULL);
2440 
2441  if (pElement != NULL)
2442  {
2443  copasi2sbmlmap[pElement] = const_cast<SpeciesReference*>(sr);
2444  this->mChemEqElementSpeciesIdMap[pElement] = std::pair<std::string, CChemEq::MetaboliteRole>(sr->getSpecies(), CChemEq::PRODUCT);
2445  }
2446  }
2447 
2448  if (sr->isSetStoichiometryMath())
2449  {
2450  CChemEq& chemEq = copasiReaction->getChemEq();
2453  CChemEqElement* pChemEqElement = NULL;
2454 
2455  while (it != end)
2456  {
2457  if ((*it)->getMetabolite() == pos->second)
2458  {
2459  pChemEqElement = (*it);
2460  break;
2461  }
2462 
2463  ++it;
2464  }
2465 
2466  assert(pChemEqElement != NULL);
2467  mStoichiometricExpressionMap.insert(std::make_pair(sr->getStoichiometryMath()->getMath(), pChemEqElement));
2468  }
2469  }
2470 
2471  /* Add all modifiers to the reaction */
2472  num = sbmlReaction->getNumModifiers();
2473 
2474  for (counter = 0; counter < num; counter++)
2475  {
2476  const ModifierSpeciesReference* sr = sbmlReaction->getModifier(counter);
2477 
2478  if (sr == NULL)
2479  {
2480  delete copasiReaction;
2481  fatalError();
2482  }
2483 
2484  std::map<std::string, CMetab*>::iterator pos;
2485  pos = this->speciesMap.find(sr->getSpecies());
2486 
2487  if (pos == this->speciesMap.end())
2488  {
2489  delete copasiReaction;
2490  fatalError();
2491  }
2492 
2493  std::map<CCopasiObject*, SBase*>::const_iterator spos = copasi2sbmlmap.find(pos->second);
2494  assert(spos != copasi2sbmlmap.end());
2495  Species* pSBMLSpecies = dynamic_cast<Species*>(spos->second);
2496  assert(pSBMLSpecies != NULL);
2497  hasOnlySubstanceUnitPresent = (hasOnlySubstanceUnitPresent | (pSBMLSpecies->getHasOnlySubstanceUnits() == true));
2498  copasiReaction->addModifier(pos->second->getKey());
2499 
2500  // we need to store the id of the species reference if it is set because SBML Level 3 allows
2501  // references to species references and if we want to support his, we need the id to import
2502  // expressions that reference a species reference
2503  if (this->mLevel > 2)
2504  {
2505 
2506  CCopasiVector<CChemEqElement>::const_iterator it = copasiReaction->getChemEq().getModifiers().begin(), endit = copasiReaction->getChemEq().getModifiers().end();
2507  CChemEqElement* pElement = NULL;
2508 
2509  while (it != endit)
2510  {
2511  if ((*it)->getMetaboliteKey() == pos->second->getKey())
2512  {
2513  pElement = const_cast<CChemEqElement*>(*it);
2514  break;
2515  }
2516 
2517  ++it;
2518  }
2519 
2520  assert(pElement != NULL);
2521 
2522  if (pElement != NULL)
2523  {
2524  copasi2sbmlmap[pElement] = const_cast<ModifierSpeciesReference*>(sr);
2525  }
2526  }
2527  }
2528 
2529  /* in the newly created CFunction set the types for all parameters and
2530  * either a mapping or a value
2531  */
2532  const KineticLaw* kLaw = sbmlReaction->getKineticLaw();
2533 
2534  if (kLaw != NULL)
2535  {
2536  const ListOfParameters* pParamList = NULL;
2537 
2538  if (this->mLevel > 2)
2539  {
2540  pParamList = kLaw->getListOfLocalParameters();
2541  }
2542  else
2543  {
2544  pParamList = kLaw->getListOfParameters();
2545  }
2546 
2547  for (counter = 0; counter < pParamList->size(); ++counter)
2548  {
2549  const Parameter* pSBMLParameter = pParamList->get(counter);
2550  std::string id;
2551 
2552  if (this->mLevel == 1)
2553  {
2554  id = pSBMLParameter->getName();
2555  }
2556  else
2557  {
2558  id = pSBMLParameter->getId();
2559  }
2560 
2561  double value;
2562 
2563  if (pSBMLParameter->isSetValue() && pSBMLParameter->getValue() == pSBMLParameter->getValue()) // make sure it is not set to NaN
2564  {
2565  value = pSBMLParameter->getValue();
2566  }
2567  else
2568  {
2569  // Set value to NaN and create a warning if it is the first time
2570  // this happend
2571  value = std::numeric_limits<C_FLOAT64>::quiet_NaN();
2572 
2573  if (!this->mIncompleteModel)
2574  {
2575  this->mIncompleteModel = true;
2576  CCopasiMessage Message(CCopasiMessage::WARNING, MCSBML + 42, pSBMLParameter->getId().c_str());
2577  }
2578  }
2579 
2580  copasiReaction->getParameters().addParameter(id, CCopasiParameter::DOUBLE, value);
2581  }
2582 
2583  const ASTNode* kLawMath = kLaw->getMath();
2584 
2585  if (kLawMath == NULL || kLawMath->getType() == AST_UNKNOWN)
2586  {
2587  copasiReaction->setFunction(NULL);
2588  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 56, sbmlReaction->getId().c_str());
2589  }
2590  else
2591  {
2592  // check for references to species references in the expression because we don't support them yet
2593  if (!SBMLImporter::findIdInASTTree(kLawMath, this->mSBMLSpeciesReferenceIds).empty())
2594  {
2596  }
2597 
2598  ConverterASTNode* node = new ConverterASTNode(*kLawMath);
2599  this->preprocessNode(node, pSBMLModel, copasi2sbmlmap, sbmlReaction);
2600 
2601  if (node == NULL)
2602  {
2603  delete copasiReaction;
2604  fatalError();
2605  }
2606 
2607  /* if it is a single compartment reaction, we have to divide the whole kinetic
2608  ** equation by the compartment because COPASI expects
2609  ** kinetic laws that specify concentration/time for single compartment
2610  ** reactions.
2611  */
2612  if (singleCompartment)
2613  {
2614 
2615  if (compartment != NULL)
2616  {
2617  // only divide if it is not a 0-dimensional compartment
2618  if (compartment->getDimensionality() != 0)
2619  {
2620  // check if the root node is a multiplication node and it's first child
2621  // is a compartment node, if so, drop those two and make the second child
2622  // new new root node
2623  ConverterASTNode* tmpNode1 = this->isMultipliedByVolume(node, compartment->getSBMLId());
2624 
2625  if (tmpNode1)
2626  {
2627  delete node;
2628  node = tmpNode1;
2629 
2630  if (node->getType() == AST_DIVIDE && node->getNumChildren() != 2)
2631  {
2632  delete tmpNode1;
2633  fatalError();
2634  }
2635  }
2636  else
2637  {
2638  tmpNode1 = new ConverterASTNode();
2639  tmpNode1->setType(AST_DIVIDE);
2640  tmpNode1->addChild(node);
2641  ConverterASTNode* tmpNode2 = new ConverterASTNode();
2642  tmpNode2->setType(AST_NAME);
2643  tmpNode2->setName(compartment->getSBMLId().c_str());
2644  tmpNode1->addChild(tmpNode2);
2645  node = tmpNode1;
2646  std::map<CCopasiObject*, SBase*>::const_iterator pos = copasi2sbmlmap.find(const_cast<CCompartment*>(compartment));
2647  assert(pos != copasi2sbmlmap.end());
2648  Compartment* pSBMLCompartment = dynamic_cast<Compartment*>(pos->second);
2649  assert(pSBMLCompartment != NULL);
2650 
2651  if (!hasOnlySubstanceUnitPresent && ((this->mLevel == 1 && pSBMLCompartment->isSetVolume()) || (this->mLevel >= 2 && pSBMLCompartment->isSetSize())) && pSBMLCompartment->getSize() == 1.0)
2652  {
2653  // we have to check if all species used in the reaction
2654  // have the hasOnlySubstance flag set
2655 
2656  if (node->getChild(0)->getType() == AST_FUNCTION && (!this->containsVolume(node->getChild(0), compartment->getSBMLId())))
2657  {
2658  // add the id of the reaction to the set so that we can create an error message later.
2659  this->mDivisionByCompartmentReactions.insert(sbmlReaction->getId());
2660  }
2661  }
2662  }
2663  }
2664  }
2665  else
2666  {
2667  delete node;
2668  delete copasiReaction;
2669  fatalError();
2670  }
2671  }
2672 
2673  /* Create a new user defined CKinFunction */
2674  if (!sbmlId2CopasiCN(node, copasi2sbmlmap, copasiReaction->getParameters()))
2675  {
2676  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 27, copasiReaction->getObjectName().c_str());
2677  }
2678 
2679  CEvaluationNode* pExpressionTreeRoot = CEvaluationTree::fromAST(node);
2680  delete node;
2681  node = NULL;
2682 
2683  if (pExpressionTreeRoot)
2684  {
2685  CExpression KineticLawExpression;
2686  KineticLawExpression.setRoot(pExpressionTreeRoot);
2687 
2688  // check if the expression is constant flux
2689  CCopasiObject* pParamObject = SBMLImporter::isConstantFlux(pExpressionTreeRoot, copasiModel, pTmpFunctionDB);
2690 
2691  if (pParamObject != NULL)
2692  {
2693  // assert that the object really is a local or global
2694  // parameter
2695  assert(dynamic_cast<const CCopasiParameter*>(pParamObject) || dynamic_cast<const CModelValue*>(pParamObject));
2696  std::string functionName;
2697 
2698  if (copasiReaction->isReversible())
2699  {
2700  // set the function to Constant flux (reversible)
2701  functionName = "Constant flux (reversible)";
2702  }
2703  else
2704  {
2705  // set the function to Constant flux (irreversible)
2706  functionName = "Constant flux (irreversible)";
2707  }
2708 
2709  CFunction* pCFFun = dynamic_cast<CFunction*>(this->functionDB->findFunction(functionName));
2710  assert(pCFFun != NULL);
2711  CEvaluationNodeCall* pCallNode = NULL;
2712 
2713  if (CEvaluationNode::type(pExpressionTreeRoot->getType()) == CEvaluationNode::OBJECT)
2714  {
2715  pCallNode = new CEvaluationNodeCall(CEvaluationNodeCall::EXPRESSION, "dummy_call");
2716  // add the parameter
2717  pCallNode->addChild(pExpressionTreeRoot->copyBranch());
2718  }
2719  else
2720  {
2721  pCallNode = dynamic_cast<CEvaluationNodeCall*>(pExpressionTreeRoot->copyBranch());
2722  assert(pCallNode != NULL);
2723  }
2724 
2725  if (pParamObject->getObjectType() == "Parameter")
2726  {
2727  pParamObject->setObjectName("v");
2728  dynamic_cast<CEvaluationNode*>(pCallNode->getChild())->setData("<" + pParamObject->getCN() + ">");
2729  }
2730 
2731  copasiReaction->setFunction(pCFFun);
2732  // map the parameter
2733  this->doMapping(copasiReaction, pCallNode);
2734  delete pCallNode;
2735  }
2736  else
2737  {
2738  // check if the root node is a simple function call
2739  if (this->isSimpleFunctionCall(pExpressionTreeRoot))
2740  {
2741  // if yes, we check if it corresponds to an already existing function
2742  std::string functionName = pExpressionTreeRoot->getData();
2743  CFunction* pImportedFunction = dynamic_cast<CFunction*>(functionDB->findFunction(functionName));
2744  assert(pImportedFunction);
2745  std::vector<CEvaluationNodeObject*>* v = NULL;
2746 
2747  // only check for mass action if there is no conversion factor involved
2748  // for any of the species involved in the reaction (substrates and products)
2749  if (!mConversionFactorNeeded && !ignoreMassAction)
2750  {
2751  v = this->isMassAction(pImportedFunction, copasiReaction->getChemEq(), static_cast<const CEvaluationNodeCall*>(pExpressionTreeRoot));
2752 
2753  if (!v)
2754  {
2755  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 27, copasiReaction->getObjectName().c_str());
2756  }
2757  }
2758 
2759  if (v && !v->empty())
2760  {
2761  CFunction* pFun = NULL;
2762 
2763  if (copasiReaction->isReversible())
2764  {
2765  pFun = static_cast<CFunction*>(this->functionDB->findFunction("Mass action (reversible)"));
2766  }
2767  else
2768  {
2769  pFun = static_cast<CFunction*>(this->functionDB->findFunction("Mass action (irreversible)"));
2770  }
2771 
2772  if (!pFun)
2773  {
2774  fatalError();
2775  }
2776 
2777  // do the mapping
2779  size_t i, iMax = v->size();
2780 
2781  for (i = 0; i < iMax; ++i)
2782  {
2783  pCallNode->addChild((*v)[i]);
2784  }
2785 
2786  this->renameMassActionParameters(pCallNode);
2787  copasiReaction->setFunction(pFun);
2788  this->doMapping(copasiReaction, pCallNode);
2789  delete pCallNode;
2790  }
2791  else
2792  {
2793  // find corresponding reaction does *not* return the function if it is already in the function db
2794  // we better change this to return this instance.
2795  CFunction* pExistingFunction = findCorrespondingFunction(&KineticLawExpression, copasiReaction);
2796 
2797  // if it does, we set the existing function for this reaction
2798  if (pExistingFunction)
2799  {
2800  copasiReaction->setFunction(pExistingFunction);
2801  // do the mapping
2802  doMapping(copasiReaction, dynamic_cast<const CEvaluationNodeCall*>(pExpressionTreeRoot));
2803  }
2804  // else we take the function from the pTmpFunctionDB, copy it and set the usage correctly
2805  else
2806  {
2807  // replace the variable nodes in pImportedFunction with nodes from
2808  std::map<std::string, std::string > arguments;
2809  const CFunctionParameters& funParams = pImportedFunction->getVariables();
2810  const CEvaluationNode* pTmpNode = static_cast<const CEvaluationNode*>(pExpressionTreeRoot->getChild());
2811  size_t i, iMax = funParams.size();
2812 
2813  for (i = 0; (i < iMax) && pTmpNode; ++i)
2814  {
2815  if (!(pTmpNode->getType() == CEvaluationNode::OBJECT)) fatalError();
2816 
2817  arguments[funParams[i]->getObjectName()] = pTmpNode->getData().substr(1, pTmpNode->getData().length() - 2);
2818  pTmpNode = static_cast<const CEvaluationNode*>(pTmpNode->getSibling());
2819  }
2820 
2821  assert((i == iMax) && pTmpNode == NULL);
2822 
2823  CEvaluationNode* pTmpExpression = variables2objects(pImportedFunction->getRoot()->copyBranch(), arguments);
2824 
2825  CExpression TmpTree2;
2826  TmpTree2.setRoot(pTmpExpression);
2827 
2828  // code to fix bug 1874
2829  // since this is a user defined function, we want to retain the original name
2830  // next setFunctionFromExpressionTree will take this name if it is not 'Expression'
2831  // (the default)
2832  TmpTree2.setObjectName(functionName);
2833 
2834  CFunction * pNewFunction = copasiReaction->setFunctionFromExpressionTree(TmpTree2, copasi2sbmlmap, this->functionDB);
2835 
2836  if (pNewFunction != NULL &&
2837  pNewFunction->getType() == CEvaluationTree::UserDefined)
2838  {
2839  // code to fix Bug 1015
2840  if (!pNewFunction->isSuitable(copasiReaction->getChemEq().getSubstrates().size(),
2841  copasiReaction->getChemEq().getProducts().size(),
2842  copasiReaction->isReversible() ? TriTrue : TriFalse))
2843  {
2844  pNewFunction->setReversible(TriUnspecified);
2845  }
2846 
2847  pTmpFunctionDB->add(pNewFunction, false);
2848  mUsedFunctions.insert(pNewFunction->getObjectName());
2849  }
2850  }
2851  }
2852 
2853  pdelete(v);
2854  }
2855  else
2856  {
2857  std::vector<CEvaluationNodeObject*>* v = NULL;
2858 
2859  // only check for mass action if there is no conversion factor involved
2860  // for any of the species involved in the reaction (substrates and products)
2861  if (!mConversionFactorNeeded && !ignoreMassAction)
2862  {
2863  v = this->isMassAction(&KineticLawExpression, copasiReaction->getChemEq());
2864 
2865  if (!v)
2866  {
2867  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 27, copasiReaction->getObjectName().c_str());
2868  }
2869  }
2870 
2871  if (v && !v->empty())
2872  {
2873  CFunction* pFun = NULL;
2874 
2875  if (copasiReaction->isReversible())
2876  {
2877  pFun = static_cast<CFunction*>(this->functionDB->findFunction("Mass action (reversible)"));
2878  }
2879  else
2880  {
2881  pFun = static_cast<CFunction*>(this->functionDB->findFunction("Mass action (irreversible)"));
2882  }
2883 
2884  if (!pFun)
2885  {
2886  fatalError();
2887  }
2888 
2889  // do the mapping
2891  size_t i, iMax = v->size();
2892 
2893  for (i = 0; i < iMax; ++i)
2894  {
2895  pCallNode->addChild((*v)[i]);
2896  }
2897 
2898  // rename the function parameters to k1 and k2
2899  this->renameMassActionParameters(pCallNode);
2900  copasiReaction->setFunction(pFun);
2901  this->doMapping(copasiReaction, pCallNode);
2902  delete pCallNode;
2903  }
2904  else
2905  {
2906  CFunction* pNonconstFun = copasiReaction->setFunctionFromExpressionTree(KineticLawExpression, copasi2sbmlmap, this->functionDB);
2907 
2908  if (pNonconstFun != NULL &&
2909  pNonconstFun->getType() == CEvaluationTree::UserDefined)
2910  {
2911  // code to fix Bug 1015
2912  if (!pNonconstFun->isSuitable(copasiReaction->getChemEq().getSubstrates().size(),
2913  copasiReaction->getChemEq().getProducts().size(),
2914  copasiReaction->isReversible() ? TriTrue : TriFalse))
2915  {
2916  pNonconstFun->setReversible(TriUnspecified);
2917  }
2918 
2919  pTmpFunctionDB->add(pNonconstFun, false);
2920  mUsedFunctions.insert(pNonconstFun->getObjectName());
2921  }
2922  }
2923 
2924  pdelete(v);
2925  }
2926  }
2927  }
2928  else
2929  {
2930  // error message
2931  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 8, copasiReaction->getObjectName().c_str());
2932  }
2933  }
2934  }
2935  else
2936  {
2937  /* if no KineticLaw was defined for the reaction. */
2938  copasiReaction->setFunction(NULL);
2939  }
2940 
2941  //DebugFile << "Created reaction: " << copasiReaction->getObjectName() << std::endl;
2942  SBMLImporter::importMIRIAM(sbmlReaction, copasiReaction);
2943  SBMLImporter::importNotes(copasiReaction, sbmlReaction);
2944 
2945  return copasiReaction;
2946 }
void setReversible(bool reversible)
Definition: CReaction.cpp:247
virtual bool setRoot(CEvaluationNode *pRootNode)
CEvaluationNode * copyBranch() const
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
#define pdelete(p)
Definition: copasi.h:215
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
CFunction * setFunctionFromExpressionTree(const CExpression &tree, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, CFunctionDB *pFunctionDB)
Definition: CReaction.cpp:1343
virtual CCopasiObjectName getCN() const
bool addSubstrate(const std::string &metabKey, const C_FLOAT64 &multiplicity=1.0)
Definition: CReaction.cpp:232
const std::string & getSBMLId() const
unsigned int mLevel
Definition: SBMLImporter.h:63
bool containsVolume(const ASTNode *pNode, const std::string &compartmentCN)
const std::string & getObjectName() const
unsigned C_INT32 getDimensionality() const
virtual size_t size() const
iterator begin()
#define fatalError()
const Type & getType() const
bool addProduct(const std::string &metabKey, const C_FLOAT64 &multiplicity=1.0)
Definition: CReaction.cpp:236
bool isSuitable(const size_t noSubstrates, const size_t noProducts, const TriLogic reversible)
Definition: CFunction.cpp:254
void renameMassActionParameters(CEvaluationNodeCall *pCallNode)
const CEvaluationTree::Type & getType() const
const std::string & getObjectType() const
#define C_INVALID_INDEX
Definition: copasi.h:222
virtual size_t getIndex(const std::string &name) const
void setReversible(const TriLogic &reversible)
Definition: CFunction.cpp:142
CCopasiObject * isConstantFlux(const CEvaluationNode *pRoot, CModel *pModel, CFunctionDB *pFunctionDB)
static CEvaluationNode * fromAST(const ASTNode *pASTNode)
std::set< std::string > mUsedFunctions
Definition: SBMLImporter.h:67
ConverterASTNode * isMultipliedByVolume(const ASTNode *node, const std::string &compartmentSBMLId)
const CCopasiVector< CChemEqElement > & getProducts() const
Definition: CChemEq.cpp:63
static Type type(const Type &type)
#define MCSBML
iterator end()
std::vector< CEvaluationNodeObject * > * isMassAction(const CEvaluationTree *pTree, const CChemEq &chemicalEquation, const CEvaluationNodeCall *pCallNode=NULL)
CFunctionDB * functionDB
Definition: SBMLImporter.h:56
bool addModifier(const std::string &metabKey, const C_FLOAT64 &multiplicity=1.0)
Definition: CReaction.cpp:240
bool setFunction(const std::string &functionName)
Definition: CReaction.cpp:255
CReaction * createReaction(const std::string &name)
Definition: CModel.cpp:2760
struct MESSAGES Message
void setSBMLId(const std::string &id)
Definition: CReaction.cpp:1649
bool mIncompleteModel
Definition: SBMLImporter.h:57
CFunction * findCorrespondingFunction(const CExpression *pExpression, const CReaction *reaction)
CEvaluationNode * variables2objects(const CEvaluationNode *pOrigNode, const std::map< std::string, std::string > &replacementMap)
void preprocessNode(ConverterASTNode *pNode, Model *pSBMLModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, Reaction *pSBMLReaction=NULL)
bool sbmlId2CopasiCN(ASTNode *pNode, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap, CCopasiParameterGroup &pParamGroup)
bool isSimpleFunctionCall(const CEvaluationNode *pRootNode)
std::map< const ASTNode *, CChemEqElement * > mStoichiometricExpressionMap
Definition: SBMLImporter.h:81
std::set< std::string > mDivisionByCompartmentReactions
Definition: SBMLImporter.h:71
const CCopasiVector< CChemEqElement > & getSubstrates() const
Definition: CChemEq.cpp:60
bool isReversible() const
Definition: CReaction.cpp:229
std::set< std::string > mFastReactions
Definition: SBMLImporter.h:77
void doMapping(CReaction *pCopasiReaction, const CEvaluationNodeCall *pCallNode)
std::string findIdInASTTree(const ASTNode *pMath, const std::set< std::string > &reactionIds)
#define C_FLOAT64
Definition: copasi.h:92
const CCopasiVector< CChemEqElement > & getModifiers() const
Definition: CChemEq.cpp:66
const CCopasiParameterGroup & getParameters() const
Definition: CReaction.cpp:333
bool addParameter(const CCopasiParameter &parameter)
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
CCopasiVectorNS< CReaction > & getReactions()
Definition: CModel.cpp:1039
bool importMIRIAM(const SBase *pSBMLObject, CCopasiObject *pCOPASIObject)
std::map< std::string, CMetab * > speciesMap
Definition: SBMLImporter.h:55
virtual const Data & getData() const
Definition: CCopasiNode.h:118
static bool importNotes(CAnnotation *pAnno, const SBase *pSBase)
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
bool setObjectName(const std::string &name)
CFunction * findFunction(const std::string &functionName)
const char * id
Definition: stdsoap2.h:1262
const CChemEq & getChemEq() const
Definition: CReaction.cpp:223
CEvaluationNode * getRoot()
CFunctionParameters & getVariables()
Definition: CFunction.cpp:148
bool add(CFunction *pFunction, const bool &adopt)
void SBMLImporter::createDelayFunctionDefinition ( )
protected

Creates a function definition for the delay function.

CEvaluationTree * SBMLImporter::createExpressionFromFunction ( const CFunction pFun,
const std::vector< std::vector< std::string > > &  functionArgumentCNs 
)
protected

Definition at line 5516 of file SBMLImporter.cpp.

References CEvaluationTree::create(), CEvaluationTree::Expression, CCopasiObject::getObjectName(), CEvaluationTree::getRoot(), CFunction::getVariables(), CEvaluationTree::setRoot(), CFunctionParameters::size(), and variables2objects().

Referenced by isMassActionFunction().

5517 {
5518  CEvaluationTree* pTree = NULL;
5519  const CFunctionParameters& pFunParams = pFun->getVariables();
5520  std::string str;
5521 
5522  if (pFunParams.size() == functionArgumentCNs.size())
5523  {
5524  std::map<std::string , std::string> variable2CNMap;
5525  size_t i, iMax = pFunParams.size();
5526 
5527  for (i = 0; i < iMax; ++i)
5528  {
5529  // vectors should not occur here
5530  assert(functionArgumentCNs[i].size() == 1);
5531  variable2CNMap[pFunParams[i]->getObjectName()] = functionArgumentCNs[i][0];
5532  }
5533 
5534  CEvaluationNode* pTmpNode = this->variables2objects(pFun->getRoot(), variable2CNMap);
5535  assert(pTmpNode);
5537  pTree->setRoot(pTmpNode);
5538  }
5539 
5540  return pTree;
5541 }
virtual bool setRoot(CEvaluationNode *pRootNode)
const std::string & getObjectName() const
CEvaluationNode * variables2objects(const CEvaluationNode *pOrigNode, const std::map< std::string, std::string > &replacementMap)
CEvaluationNode * getRoot()
CFunctionParameters & getVariables()
Definition: CFunction.cpp:148
static CEvaluationTree * create(CEvaluationTree::Type type)
void SBMLImporter::createHasOnlySubstanceUnitFactor ( Model *  pSBMLModel,
double  factor,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap 
)
protected

This method creates a global parameter the represents the factor that is used to convert a particle number into the amount units set on the model. The parameter is only created if it is needed and after exporting the model, the parameter is deleted from the COPASI model again.

Definition at line 9106 of file SBMLImporter.cpp.

References createCModelValueFromParameter(), mAvogadroCreated, mpCopasiModel, and mPotentialAvogadroNumbers.

Referenced by replaceAmountReferences().

9107 {
9108  // find an ID that is unique at least within the list of parameters
9109  // since we remove this created parameter after import, it does not
9110  // have to be unique within the whole model
9111  std::set<std::string> ids;
9112  unsigned int i, iMax = pSBMLModel->getListOfParameters()->size();
9113 
9114  for (i = 0; i < iMax; ++i)
9115  {
9116  ids.insert(pSBMLModel->getListOfParameters()->get(i)->getId());
9117  }
9118 
9119  std::ostringstream os;
9120  i = 1;
9121  os << "parameter_" << i;
9122 
9123  while (ids.find(os.str()) != ids.end())
9124  {
9125  ++i;
9126  os.str("");
9127  os << "parameter_" << i;
9128  }
9129 
9130  Parameter *pParameter = pSBMLModel->createParameter();
9131  pParameter->setId(os.str());
9132  pParameter->setName("amount to particle factor");
9133  pParameter->setConstant(true);
9134  pParameter->setValue(factor);
9135  this->mAvogadroCreated = true;
9136  this->mPotentialAvogadroNumbers.insert(pParameter);
9137  this->createCModelValueFromParameter(pParameter, this->mpCopasiModel, copasi2sbmlmap);
9138 }
bool mAvogadroCreated
Definition: SBMLImporter.h:84
CModel * mpCopasiModel
Definition: SBMLImporter.h:69
std::set< const Parameter * > mPotentialAvogadroNumbers
Definition: SBMLImporter.h:83
CModelValue * createCModelValueFromParameter(const Parameter *sbmlParameter, CModel *copasiModel, std::map< CCopasiObject *, SBase * > &copasi2sbmlmap)
void SBMLImporter::deleteCopasiModel ( )

This call deletes an existing COPASI model. The method can e.g. be called to clean up if an import fails.

Definition at line 10681 of file SBMLImporter.cpp.

References mpCopasiModel.

Referenced by SEDMLImporter::importFirstSBMLModel(), CCopasiDataModel::importSBML(), and CCopasiDataModel::importSBMLFromString().

10682 {
10683  if (this->mpCopasiModel != NULL)
10684  {
10685  delete this->mpCopasiModel;
10686  this->mpCopasiModel = NULL;
10687  }
10688 }
CModel * mpCopasiModel
Definition: SBMLImporter.h:69
CEvaluationNode * SBMLImporter::divideByObject ( const CEvaluationNode pOrigNode,
const CCopasiObject pObject 
)
static

This method divides the given expression by the given object and returns a new expression. The caller is responsible for freeing the memory for the new expression.

Definition at line 10533 of file SBMLImporter.cpp.

References CCopasiNode< _Data >::addChild(), CEvaluationNodeObject::CN, CEvaluationNode::copyBranch(), CEvaluationNodeOperator::DIVIDE, CCopasiNode< _Data >::getChild(), CCopasiObject::getCN(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::OBJECT, CEvaluationNode::OPERATOR, pResult, CEvaluationNode::subType(), and CEvaluationNode::type().

Referenced by importEvent(), importInitialAssignments(), and importRuleForModelEntity().

10534 {
10535  bool reverse = false;
10536  CEvaluationNode* pResult = NULL;
10537  assert(pOrigNode != NULL);
10538  assert(pObject != NULL);
10539 
10540  if (pOrigNode != NULL && pObject != NULL)
10541  {
10542  // first we check if this is thie reverse operation with the object
10543  // if so, we just drop the reverse operaqtion, otherwise we apply the operation with the
10544  // object
10547  {
10548  // either child can be the object
10549  const CEvaluationNode* pChild = dynamic_cast<const CEvaluationNode*>(pOrigNode->getChild());
10550 
10551  if (CEvaluationNode::type(pChild->getType()) == CEvaluationNode::OBJECT && dynamic_cast<const CEvaluationNodeObject*>(pChild)->getData() == std::string("<" + pObject->getCN() + ">"))
10552  {
10553 
10554  pResult = dynamic_cast<const CEvaluationNode*>(pOrigNode->getChild())->copyBranch();
10555  reverse = true;
10556  }
10557 
10558  if (reverse == false)
10559  {
10560  pChild = dynamic_cast<const CEvaluationNode*>(pChild->getSibling());
10561 
10562  if (CEvaluationNode::type(pChild->getType()) == CEvaluationNode::OBJECT && dynamic_cast<const CEvaluationNodeObject*>(pChild)->getData() == std::string("<" + pObject->getCN() + ">"))
10563  {
10564 
10565  pResult = dynamic_cast<const CEvaluationNode*>(pOrigNode->getChild())->copyBranch();
10566  reverse = true;
10567  }
10568  }
10569  }
10570 
10571  if (reverse == false)
10572  {
10573  CEvaluationNodeObject* pVolumeNode = new CEvaluationNodeObject(CEvaluationNodeObject::CN, "<" + pObject->getCN() + ">");
10575  pResult->addChild(pOrigNode->copyBranch());
10576  pResult->addChild(pVolumeNode);
10577  }
10578  }
10579 
10580  return pResult;
10581 }
CEvaluationNode * copyBranch() const
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
virtual CCopasiObjectName getCN() const
const Type & getType() const
static Type type(const Type &type)
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
const CArrayAnnotation * pResult
static Type subType(const Type &type)
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
void SBMLImporter::doMapping ( CReaction pCopasiReaction,
const CEvaluationNodeCall pCallNode 
)
protected

Definition at line 5740 of file SBMLImporter.cpp.

References CReaction::addParameterMapping(), containsKey(), fatalError, CReaction::getChemEq(), CCopasiNode< _Data >::getChild(), CEvaluationNodeObject::getData(), CReaction::getFunction(), CCopasiObject::getKey(), CChemEq::getModifiers(), CCopasiObject::getObjectParent(), CCopasiObject::getObjectType(), CChemEq::getProducts(), CChemEq::getReversibility(), CCopasiNode< _Data >::getSibling(), CChemEq::getSubstrates(), CFunction::getVariables(), CCopasiObject::isReference(), CReaction::isReversible(), CFunctionParameter::MODIFIER, mpCopasiModel, mpDataModel, CCopasiDataModel::ObjectFromName(), CFunctionParameter::PARAMETER, CFunctionParameter::PRODUCT, CReaction::setParameterMapping(), CFunctionParameters::size(), CCopasiVector< T >::size(), CFunctionParameter::SUBSTRATE, CFunctionParameter::TIME, CFunctionParameter::VARIABLE, and CFunctionParameter::VOLUME.

Referenced by createCReactionFromReaction().

5741 {
5742  // map the first argument of the call node to the first variable of the function of the reaction
5743  // and so on
5744  if (!pCallNode)
5745  {
5746  fatalError();
5747  }
5748 
5749  std::vector<CCopasiContainer*> listOfContainers;
5750  listOfContainers.push_back(this->mpCopasiModel);
5751 
5752  if (dynamic_cast<const CMassAction*>(pCopasiReaction->getFunction()))
5753  {
5754  const CEvaluationNodeObject* pChild = dynamic_cast<const CEvaluationNodeObject*>(pCallNode->getChild());
5755  std::string objectCN = pChild->getData();
5756  objectCN = objectCN.substr(1, objectCN.length() - 2);
5757  CCopasiObject* pObject = mpDataModel->ObjectFromName(listOfContainers, objectCN);
5758 
5759  if (!pObject)
5760  {
5761  fatalError();
5762  }
5763 
5764  if (pObject->isReference())
5765  {
5766  pObject = pObject->getObjectParent();
5767  }
5768 
5769  const std::string& objectKey = pObject->getKey();
5770 
5771  pCopasiReaction->setParameterMapping("k1", objectKey);
5772 
5773  const CCopasiVector<CChemEqElement>* metabolites = &pCopasiReaction->getChemEq().getSubstrates();
5774 
5775  size_t i, iMax = metabolites->size();
5776 
5777  size_t j, jMax;
5778 
5779  for (i = 0; i < iMax; ++i)
5780  for (j = 0, jMax = static_cast<int>(fabs((*metabolites)[i]->getMultiplicity())); j < jMax; j++)
5781  pCopasiReaction->addParameterMapping("substrate", (*metabolites)[i]->getMetaboliteKey());
5782 
5783  if (pCopasiReaction->isReversible())
5784  {
5785  pChild = dynamic_cast<const CEvaluationNodeObject*>(pChild->getSibling());
5786  std::string objectCN = pChild->getData();
5787  objectCN = objectCN.substr(1, objectCN.length() - 2);
5788  CCopasiObject* pObject = mpDataModel->ObjectFromName(listOfContainers, objectCN);
5789 
5790  if (!pObject)
5791  {
5792  fatalError();
5793  }
5794 
5795  if (pObject->isReference())
5796  {
5797  pObject = pObject->getObjectParent();
5798  }
5799 
5800  const std::string& objectKey = pObject->getKey();
5801 
5802  pCopasiReaction->setParameterMapping("k2", objectKey);
5803 
5804  const CCopasiVector<CChemEqElement>* metabolites = &pCopasiReaction->getChemEq().getProducts();
5805 
5806  iMax = metabolites->size();
5807 
5808  for (i = 0; i < iMax; ++i)
5809  for (j = 0, jMax = static_cast<int>(fabs((*metabolites)[i]->getMultiplicity())); j < jMax; j++)
5810  pCopasiReaction->addParameterMapping("product", (*metabolites)[i]->getMetaboliteKey());
5811  }
5812  }
5813  else
5814  {
5815  const CFunctionParameters & Variables = pCopasiReaction->getFunction()->getVariables();
5816  size_t i, iMax = Variables.size();
5817  const CEvaluationNodeObject* pChild = dynamic_cast<const CEvaluationNodeObject*>(pCallNode->getChild());
5818 
5819  for (i = 0; i < iMax; ++i)
5820  {
5821  if (!pChild)
5822  {
5823  fatalError();
5824  }
5825 
5826  std::string objectCN = pChild->getData();
5827  objectCN = objectCN.substr(1, objectCN.length() - 2);
5828  CCopasiObject* pObject = mpDataModel->ObjectFromName(listOfContainers, objectCN);
5829 
5830  if (!pObject)
5831  {
5832  fatalError();
5833  }
5834 
5835  if (pObject->isReference())
5836  {
5837  pObject = pObject->getObjectParent();
5838  }
5839 
5840  const std::string& objectKey = pObject->getKey();
5841 
5842  pCopasiReaction->setParameterMapping(i, objectKey);
5843 
5844  const CChemEq& eqn = pCopasiReaction->getChemEq();
5845 
5846  bool reversible = eqn.getReversibility();
5847 
5848  // We guess what the role of a variable of newly imported function is:
5849  if (Variables[i]->getUsage() == CFunctionParameter::VARIABLE)
5850  {
5852 
5853  if (pObject->getObjectType() == "Metabolite")
5854  {
5855  if (containsKey(eqn.getSubstrates(), objectKey))
5857 
5858  if (Role == CFunctionParameter::PARAMETER &&
5859  containsKey(eqn.getProducts(), objectKey))
5860  {
5861  // Fix for Bug 1882: if not reversible, only mark as product if it does
5862  // not appear in the list of modifiers
5863  if (!reversible && containsKey(eqn.getModifiers(), objectKey))
5865  else
5867  }
5868 
5869  // It is not a substrate and not a product therefore we must have a modifier
5870  if (Role == CFunctionParameter::PARAMETER)
5871  {
5873  }
5874  }
5875  else if (pObject->getObjectType() == "Model")
5876  {
5877  Role = CFunctionParameter::TIME;
5878  }
5879  else if (pObject->getObjectType() == "Compartment")
5880  {
5882  }
5883 
5884  const_cast< CFunctionParameter * >(Variables[i])->setUsage(Role);
5885  }
5886 
5887  pChild = dynamic_cast<const CEvaluationNodeObject*>(pChild->getSibling());
5888  }
5889  }
5890 }
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
CModel * mpCopasiModel
Definition: SBMLImporter.h:69
virtual size_t size() const
#define fatalError()
const std::string & getObjectType() const
virtual const std::string & getKey() const
const CCopasiVector< CChemEqElement > & getProducts() const
Definition: CChemEq.cpp:63
const CFunction * getFunction() const
Definition: CReaction.cpp:252
CCopasiDataModel * mpDataModel
Definition: SBMLImporter.h:68
bool isReference() const
const bool & getReversibility() const
Definition: CChemEq.cpp:77
bool containsKey(const CCopasiVector< CChemEqElement > &list, const std::string &key)
const CCopasiVector< CChemEqElement > & getSubstrates() const
Definition: CChemEq.cpp:60
bool isReversible() const
Definition: CReaction.cpp:229
const CCopasiVector< CChemEqElement > & getModifiers() const
Definition: CChemEq.cpp:66
void setParameterMapping(const size_t &index, const std::string &key)
Definition: CReaction.cpp:339
virtual const Data & getData() const
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
CCopasiObject * ObjectFromName(const std::vector< CCopasiContainer * > &listOfContainer, const CCopasiObjectName &CN) const
const CChemEq & getChemEq() const
Definition: CReaction.cpp:223
CFunctionParameters & getVariables()
Definition: CFunction.cpp:148
CCopasiContainer * getObjectParent() const
void addParameterMapping(const size_t &index, const std::string &key)
Definition: CReaction.cpp:348
void SBMLImporter::find_local_parameters_in_delay ( ASTNode *  pASTNode,
Reaction *  pSBMLReaction,
Model *  pModel,
std::map< std::string, std::string > &  localReplacementMap,
const std::set< std::string > &  localIds,
std::map< CCopasiObject *, SBase * > &  copasi2sbmlmap 
)
protected

If we replace delay nodes within kineitc laws, we have to make sure that there is no reference to a local parameter within the replaced delay node because that would mean that we end up with a reference to a local parameter in the rule for the delay replacement which is not allowed in SBML. Therefore we have to convert all local parameters which occur within a delay call into global parameters. This method finds all local parameters that have to be converted to global parameters and it already creates the necessary global parameters. The localReplacementMap returns a mapping between the is of the original parameter and the id of the new parameter it will be replaced with. This map is used in a second step to actually replace the nodes in the expression.

If we replace delay nodes within kinetic laws, we have to make sure that there is no reference to a local parameter within the replaced delay node because that would mean that we end up with a reference to a local parameter in the rule for the delay replacement which is not allowed in SBML. Therefore we have to convert all local parameters which occur within a delay call into global parameters.

Definition at line 10234 of file SBMLImporter.cpp.

References createCModelValueFromParameter(), CNodeContextIterator< Node, int >::end(), CCopasiMessage::EXCEPTION, fatalError, mpCopasiModel, mUsedSBMLIds, and CNodeContextIterator< Node, int >::next().

Referenced by replace_delay_nodes().

10235 {
10236  CNodeIterator< ASTNode > itNode(pASTNode);
10237 
10238  while (itNode.next() != itNode.end())
10239  {
10240  if (*itNode == NULL)
10241  {
10242  continue;
10243  }
10244 
10245  if (itNode->getType() == AST_NAME)
10246  {
10247  // check it this is the name of a local parameter
10248 
10249  // maybe there already is a replacement for this
10250  std::map<std::string, std::string>::const_iterator pos = localReplacementMap.find(itNode->getName());
10251