END_TEST


START_TEST (test_MathMLFromAST_scalarproduct)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <scalarproduct/>\n"
    "    <ci> y </ci>\n"
    "    <ci> z </ci>\n"
    "  </apply>\n"
  );


  ASTNode * y = new ASTNode(AST_NAME);
  fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS);

  ASTNode * z = new ASTNode(AST_NAME);
  fail_unless(z->setName("z") == LIBSBML_OPERATION_SUCCESS);

  N = new ASTNode(AST_LINEAR_ALGEBRA_SCALAR_PRODUCT);
  fail_unless( N->getPackageName() == "arrays");

  fail_unless(N->addChild(y) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(N->addChild(z) == LIBSBML_OPERATION_SUCCESS);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
END_TEST


START_TEST (test_MathMLFromAST_plus_nary_4)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <plus/>\n"
    "    <cn type=\"integer\"> 1 </cn>\n"
    "    <cn type=\"integer\"> 2 </cn>\n"
    "    <apply>\n"
    "      <times/>\n"
    "      <ci> x </ci>\n"
    "      <ci> y </ci>\n"
    "      <ci> z </ci>\n"
    "    </apply>\n"
    "    <cn type=\"integer\"> 3 </cn>\n"
    "  </apply>\n"
  );

//  N = SBML_parseFormula("1 + 2 + x * y * z + 3");
  
  N = new ASTNode(AST_PLUS);
  
  ASTNode *c1 = new ASTNode(AST_INTEGER);
  c1->setValue(1);
  ASTNode *c2 = new ASTNode(AST_INTEGER);
  c2->setValue(2);
  ASTNode *c3 = new ASTNode(AST_INTEGER);
  c3->setValue(3);
  ASTNode *cx = new ASTNode(AST_NAME);
  cx->setName("x");
  ASTNode *cy = new ASTNode(AST_NAME);
  cy->setName("y");
  ASTNode *cz = new ASTNode(AST_NAME);
  cz->setName("z");
  
  ASTNode *times = new ASTNode(AST_TIMES);
  times->addChild(cx);
  times->addChild(cy);
  times->addChild(cz);
  
  N->addChild(c1);
  N->addChild(c2);
  N->addChild(times);
  N->addChild(c3);
  
  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
ASTNode* CEvaluationNodeVariable::toAST(const CCopasiDataModel* /*pDataModel*/) const
{
  ASTNode* node = new ASTNode();
  node->setType(AST_NAME);
  node->setName(this->getData().c_str());
  return node;
}
END_TEST


START_TEST (test_getUnitDefinition_power_one_child)
{
  ASTNode * node = new ASTNode(AST_POWER);
  ASTNode * c = new ASTNode(AST_NAME);
  c->setName("k");
  node->addChild(c);

  UnitDefinition * ud = NULL;
    
  ud = uff->getUnitDefinition(node);
  
  fail_unless(uff->getContainsUndeclaredUnits() == true);
  fail_unless(uff->canIgnoreUndeclaredUnits() == false);

  fail_unless(ud != NULL);
  fail_unless(ud->getNumUnits() == 1);

  fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE);
  fail_unless(util_isEqual(ud->getUnit(0)->getExponent(), 1));


  delete node;
  delete ud;

}
END_TEST


START_TEST (test_MathMLFromAST_transpose)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <transpose/>\n"
    "    <ci> y </ci>\n"
    "  </apply>\n"
  );


  ASTNode * y = new ASTNode(AST_NAME);
  fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS);


  N = new ASTNode(AST_LINEAR_ALGEBRA_TRANSPOSE);
  fail_unless( N->getPackageName() == "arrays");

  fail_unless(N->addChild(y) == LIBSBML_OPERATION_SUCCESS);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
Example #6
0
/**
 * Sets the type of an ASTNode based on the given MathML <ci> element.
 * Errors will be logged in the stream's SBMLErrorLog object.
 */
static void
setTypeCI (ASTNode& node, const XMLToken& element, XMLInputStream& stream)
{
  if (element.getName() == "csymbol")
  {
    string url;
    element.getAttributes().readInto("definitionURL", url);

    if ( url == URL_DELAY ) node.setType(AST_FUNCTION_DELAY);
    else if ( url == URL_TIME  ) node.setType(AST_NAME_TIME);
    else if ( url == URL_AVOGADRO  ) node.setType(AST_NAME_AVOGADRO);
    else 
    {
      static_cast <SBMLErrorLog*>
	        (stream.getErrorLog())->logError(BadCsymbolDefinitionURLValue,
          stream.getSBMLNamespaces()->getLevel(), 
          stream.getSBMLNamespaces()->getVersion());
    }
  }
  else if (element.getName() == "ci")
  {
    node.setDefinitionURL(element.getAttributes());
  }

  const string name = trim( stream.next().getCharacters() );
  node.setName( name.c_str() );
}
END_TEST
#endif

START_TEST (test_getUnitDefinition_power_dim_param_exponent)
{
  ASTNode * node = new ASTNode(AST_POWER);
  ASTNode * c = new ASTNode(AST_NAME);
  c->setName("k");
  ASTNode * c1 = new ASTNode(AST_NAME);
  c1->setName("a");
  node->addChild(c);
  node->addChild(c1);

  UnitDefinition * ud = NULL;
    
  ud = uff->getUnitDefinition(node);
  
  fail_unless(uff->getContainsUndeclaredUnits() == false);
  fail_unless(uff->canIgnoreUndeclaredUnits() == false);

  fail_unless(ud != NULL);
  fail_unless(ud->getNumUnits() == 1);

  fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE);
  fail_unless(util_isEqual(ud->getUnit(0)->getExponentAsDouble(), 3.5));

  delete node;
  delete ud;

}
END_TEST

#if (0)
START_TEST (test_getUnitDefinition_power_minus_double_exponent)
{
  ASTNode * node = new ASTNode(AST_POWER);
  ASTNode * c = new ASTNode(AST_NAME);
  c->setName("k");
  ASTNode * c1 = new ASTNode(AST_REAL);
  c1->setValue(0.3);
  ASTNode * c2 = new ASTNode(AST_MINUS);
  c2->addChild(c1);
  node->addChild(c);
  node->addChild(c2);

  UnitDefinition * ud = NULL;
    
  ud = uff->getUnitDefinition(node);
  
  fail_unless(uff->getContainsUndeclaredUnits() == false);
  fail_unless(uff->canIgnoreUndeclaredUnits() == false);

  fail_unless(ud != NULL);
  fail_unless(ud->getNumUnits() == 1);

  fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE);
  fail_unless(util_isEqual(ud->getUnit(0)->getExponentAsDouble(), -0.3));

  delete node;
  delete ud;

}
END_TEST


START_TEST (test_getUnitDefinition_power_three_children)
{
  ASTNode * node = new ASTNode(AST_POWER);
  ASTNode * c = new ASTNode(AST_NAME);
  c->setName("k");
  ASTNode * c1 = new ASTNode(AST_INTEGER);
  c1->setValue(1);
  ASTNode * c2 = new ASTNode(AST_INTEGER);
  c2->setValue(2);
  node->addChild(c);
  node->addChild(c1);
  node->addChild(c2);

  UnitDefinition * ud = NULL;
    
  ud = uff->getUnitDefinition(node);
  
  fail_unless(uff->getContainsUndeclaredUnits() == true);
  fail_unless(uff->canIgnoreUndeclaredUnits() == false);

  fail_unless(ud != NULL);
  fail_unless(ud->getNumUnits() == 0);

  delete node;
  delete ud;

}
END_TEST


START_TEST (test_MathMLFromAST_function_2)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <ci> foo </ci>\n"
    "    <cn type=\"integer\"> 1 </cn>\n"
    "    <cn type=\"integer\"> 2 </cn>\n"
    "    <apply>\n"
    "      <ci> bar </ci>\n"
    "      <ci> z </ci>\n"
    "    </apply>\n"
    "  </apply>\n"
  );

  // N = SBML_parseFormula("foo(1, 2, bar(z))");
  N = new ASTNode(AST_FUNCTION);
  fail_unless( N->setName("foo") == LIBSBML_OPERATION_SUCCESS);
  
  ASTNode *c1 = new ASTNode(AST_INTEGER);
  c1->setValue(long(1));
  ASTNode *c2 = new ASTNode(AST_INTEGER);
  c2->setValue(long(2));

  ASTNode *bar = new ASTNode(AST_FUNCTION);
  bar->setName("bar");

  ASTNode *cz = new ASTNode(AST_NAME);
  cz->setName("z");

  fail_unless (bar->addChild(cz) == LIBSBML_OPERATION_SUCCESS);

  fail_unless (N->addChild(c1) == LIBSBML_OPERATION_SUCCESS);
  fail_unless (N->addChild(c2) == LIBSBML_OPERATION_SUCCESS);
  fail_unless (N->addChild(bar) == LIBSBML_OPERATION_SUCCESS);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
END_TEST


START_TEST (test_MathMLFromAST_selector)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <selector/>\n"
    "    <ci> y </ci>\n"
    "    <ci> z </ci>\n"
    "    <cn type=\"integer\"> 5 </cn>\n"
    "  </apply>\n"
  );


  ASTNode * y = new ASTNode(AST_NAME);
  fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS);

  ASTNode * z = new ASTNode(AST_NAME);
  fail_unless(z->setName("z") == LIBSBML_OPERATION_SUCCESS);

  ASTNode *int1 = new ASTNode(AST_INTEGER);
  fail_unless(int1->setValue((long)(5)) == LIBSBML_OPERATION_SUCCESS);

  N = new ASTNode(AST_LINEAR_ALGEBRA_SELECTOR);
  fail_unless( N->getPackageName() == "arrays");

  fail_unless(N->addChild(y) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(N->addChild(z) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(N->addChild(int1) == LIBSBML_OPERATION_SUCCESS);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
Example #12
0
ASTNode* CEvaluationNodeCall::toAST(const CCopasiDataModel* pDataModel) const
{
  ASTNode* pNode = NULL;

  pNode = new ASTNode(AST_FUNCTION);
  const std::string funName = this->getData();
  CFunction * pFun = CCopasiRootContainer::getFunctionList()->findFunction(funName);
  assert(pFun != NULL);

  if (pFun == NULL || pFun->getSBMLId().empty()) fatalError();

  pNode->setName(pFun->getSBMLId().c_str());

  const CEvaluationNode* child = static_cast<const CEvaluationNode*>(this->getChild());

  while (child)
    {
      pNode->addChild(child->toAST(pDataModel));
      child = static_cast<const CEvaluationNode*>(child->getSibling());
    }

  return pNode;
}
/**
 *
 * Creates an SBML model represented in "7.1 A Simple example application of SBML"
 * in the SBML Level 2 Version 4 Specification.
 *
 */
SBMLDocument* createExampleEnzymaticReaction()
{
  const unsigned int level   = Level;
  const unsigned int version = Version;

  //---------------------------------------------------------------------------
  //
  // Creates an SBMLDocument object 
  //
  //---------------------------------------------------------------------------

  SBMLDocument* sbmlDoc = new SBMLDocument(level,version);

  //---------------------------------------------------------------------------
  //
  // Creates a Model object inside the SBMLDocument object. 
  //
  //---------------------------------------------------------------------------

  Model* model = sbmlDoc->createModel();
  model->setId("EnzymaticReaction");

  //---------------------------------------------------------------------------
  //
  // Creates UnitDefinition objects inside the Model object.
  //
  //---------------------------------------------------------------------------

  // Temporary pointers (reused more than once below).

  UnitDefinition* unitdef;
  Unit* unit;

  //---------------------------------------------------------------------------  
  // (UnitDefinition1) Creates an UnitDefinition object ("per_second")
  //---------------------------------------------------------------------------

  unitdef = model->createUnitDefinition();
  unitdef->setId("per_second");

  //  Creates an Unit inside the UnitDefinition object 

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_SECOND);
  unit->setExponent(-1);

  //--------------------------------------------------------------------------------
  // (UnitDefinition2) Creates an UnitDefinition object ("litre_per_mole_per_second") 
  //--------------------------------------------------------------------------------
    
  // Note that we can reuse the pointers 'unitdef' and 'unit' because the
  // actual UnitDefinition object (along with the Unit objects within it)
  // is already attached to the Model object.

  unitdef = model->createUnitDefinition();
  unitdef->setId("litre_per_mole_per_second");
    
  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setExponent(-1);

  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_LITRE);
  unit->setExponent(1);

  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_SECOND);
  unit->setExponent(-1);


  //---------------------------------------------------------------------------
  //
  // Creates a Compartment object inside the Model object. 
  //
  //---------------------------------------------------------------------------

  Compartment* comp;
  const string compName = "cytosol";

  // Creates a Compartment object ("cytosol")

  comp = model->createCompartment();
  comp->setId(compName);
 
  // Sets the "size" attribute of the Compartment object.
  //
  // We are not setting the units on the compartment size explicitly, so
  // the units of this Compartment object will be the default SBML units of
  // volume, which are liters.
  //
  comp->setSize(1e-14);


  //---------------------------------------------------------------------------
  //
  // Creates Species objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  // Temporary pointer (reused more than once below).
  
  Species *sp;

  //---------------------------------------------------------------------------
  // (Species1) Creates a Species object ("ES")
  //---------------------------------------------------------------------------

  // Create the Species objects inside the Model object. 

  sp = model->createSpecies();
  sp->setId("ES");
  sp->setName("ES");

  // Sets the "compartment" attribute of the Species object to identify the 
  // compartment in which the Species object is located.

  sp->setCompartment(compName);

  // Sets the "initialAmount" attribute of the Species object.
  //
  //  In SBML, the units of a Species object's initial quantity are
  //  determined by two attributes, "substanceUnits" and
  //  "hasOnlySubstanceUnits", and the "spatialDimensions" attribute
  //  of the Compartment object ("cytosol") in which the species
  //  object is located.  Here, we are using the default values for
  //  "substanceUnits" (which is "mole") and "hasOnlySubstanceUnits"
  //  (which is "false").  The compartment in which the species is
  //  located uses volume units of liters, so the units of these
  //  species (when the species appear in numerical formulas in the
  //  model) will be moles/liters.  
  //
  sp->setInitialAmount(0);

  //---------------------------------------------------------------------------
  // (Species2) Creates a Species object ("P")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("P");
  sp->setName("P");
  sp->setInitialAmount(0);

  //---------------------------------------------------------------------------
  // (Species3) Creates a Species object ("S")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("S");
  sp->setName("S");
  sp->setInitialAmount(1e-20);

  //---------------------------------------------------------------------------
  // (Species4) Creates a Species object ("E")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("E");
  sp->setName("E");
  sp->setInitialAmount(5e-21);

  
  //---------------------------------------------------------------------------
  //
  // Creates Reaction objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  // Temporary pointers.

  Reaction* reaction;
  SpeciesReference* spr;
  KineticLaw* kl;

  //---------------------------------------------------------------------------
  // (Reaction1) Creates a Reaction object ("veq").
  //---------------------------------------------------------------------------

  reaction = model->createReaction();
  reaction->setId("veq");

  // (Reactant1) Creates a Reactant object that references Species "E"
  // in the model.  The object will be created within the reaction in the
  // SBML <listOfReactants>.

  spr = reaction->createReactant();
  spr->setSpecies("E");

  // (Reactant2) Creates a Reactant object that references Species "S"
  // in the model.

  spr = reaction->createReactant();
  spr->setSpecies("S");

  //---------------------------------------------------------------------------
  // (Product1) Creates a Product object that references Species "ES" in
  // the model.
  //---------------------------------------------------------------------------

  spr = reaction->createProduct();
  spr->setSpecies("ES");

  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("veq"). 
  //---------------------------------------------------------------------------

  kl = reaction->createKineticLaw();

 //---------------------------------------------------------------------------
   // Creates an ASTNode object which represents the following math of the
   // KineticLaw.
   //
   //      <math xmlns="http://www.w3.org/1998/Math/MathML">
   //        <apply>
   //          <times/>
   //          <ci> cytosol </ci>
   //          <apply>
   //            <minus/>
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //          </apply>
   //        </apply>
   //      </math>
   //
 //---------------------------------------------------------------------------

   //------------------------------------------
   //
   // create nodes representing the variables
   //
   //------------------------------------------

   ASTNode* astCytosol = new ASTNode(AST_NAME);
   astCytosol->setName("cytosol");

   ASTNode* astKon = new ASTNode(AST_NAME);
   astKon->setName("kon");

   ASTNode* astKoff = new ASTNode(AST_NAME);
   astKoff->setName("koff");

   ASTNode* astE = new ASTNode(AST_NAME);
   astE->setName("E");

   ASTNode* astS = new ASTNode(AST_NAME);
   astS->setName("S");

   ASTNode* astES = new ASTNode(AST_NAME);
   astES->setName("ES");


   //--------------------------------------------
   //
   // create node representing
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //
   //--------------------------------------------

   ASTNode *astTimes1 = new ASTNode(AST_TIMES);
   astTimes1->addChild(astKoff);
   astTimes1->addChild(astES);

   //--------------------------------------------
   //
   // create node representing
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //
   //
   // (NOTES)
   //
   //  Since there is a restriction with an ASTNode of "<times/>" operation
   //  such that the ASTNode is a binary class and thus only two operands can
   //  be directly added, the following code in this comment block is invalid
   //  because the code directly adds three <ci> ASTNodes to <times/> ASTNode.
   //
   //    ASTNode *astTimes = new ASTNode(AST_TIMES);
   //    astTimes->addChild(astKon);
   //    astTimes->addChild(astE);
   //    astTimes->addChild(astS);
   //
   // The following valid code after this comment block creates the ASTNode
   // as a binary tree.
   //
   // Please see "Converting between ASTs and text strings" described
   // at http://sbml.org/Software/libSBML/docs/cpp-api/class_a_s_t_node.html
   // for the detailed information.
   //
   //--------------------------------------------

   ASTNode *astTimes2 = new ASTNode(AST_TIMES);
   astTimes2->addChild(astE);
   astTimes2->addChild(astS);

   ASTNode *astTimes = new ASTNode(AST_TIMES);
   astTimes->addChild(astKon);
   astTimes->addChild(astTimes2);

   //--------------------------------------------
   //
   // create node representing
   //          <apply>
   //            <minus/>
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //          </apply>
   //
   //--------------------------------------------

   ASTNode *astMinus = new ASTNode(AST_MINUS);
   astMinus->addChild(astTimes);
   astMinus->addChild(astTimes1);


   //--------------------------------------------
   //
   // create node representing
   //        <apply>
   //          <times/>
   //          <ci> cytosol </ci>
   //          <apply>
   //            <minus/>
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //          </apply>
   //        </apply>
   //
   //--------------------------------------------

   ASTNode* astMath = new ASTNode(AST_TIMES);
   astMath->addChild(astCytosol);
   astMath->addChild(astMinus);

   //---------------------------------------------
   //
   // set the Math element
   //
   //------------------------------------------------

   kl->setMath(astMath);

  // KineticLaw::setMath(const ASTNode*) sets the math of the KineticLaw object
  // to a copy of the given ASTNode, and thus basically the caller should delete 
  // the original ASTNode object if the caller has the ownership of the object to 
  // avoid memory leak.

   delete astMath;


  //---------------------------------------------------------------------------
  // Creates local Parameter objects inside the KineticLaw object.
  //---------------------------------------------------------------------------

  // Creates a Parameter ("kon")

  Parameter* para = kl->createParameter();
  para->setId("kon");
  para->setValue(1000000);
  para->setUnits("litre_per_mole_per_second");

  // Creates a Parameter ("koff")

  para = kl->createParameter();
  para->setId("koff");
  para->setValue(0.2);
  para->setUnits("per_second");


  //---------------------------------------------------------------------------
  // (Reaction2) Creates a Reaction object ("vcat") .
  //---------------------------------------------------------------------------
  
  reaction = model->createReaction();
  reaction->setId("vcat");
  reaction->setReversible(false);

  //---------------------------------------------------------------------------
  // Creates Reactant objects inside the Reaction object ("vcat"). 
  //---------------------------------------------------------------------------

  // (Reactant1) Creates a Reactant object that references Species "ES" in the
  // model.

  spr = reaction->createReactant();
  spr->setSpecies("ES");

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("vcat"). 
  //---------------------------------------------------------------------------
  
  // (Product1) Creates a Product object that references Species "E" in the model.

  spr = reaction->createProduct();
  spr->setSpecies("E");

  // (Product2) Creates a Product object that references Species "P" in the model.

  spr = reaction->createProduct();
  spr->setSpecies("P");

  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("vcat"). 
  //---------------------------------------------------------------------------
  
  kl = reaction->createKineticLaw();

  //---------------------------------------------------------------------------
  // Sets a math (ASTNode object) to the KineticLaw object.
  //---------------------------------------------------------------------------

  // To create mathematical expressions, one would typically construct
  // an ASTNode tree as the above example code which creates a math of another
  // KineticLaw object.  Here, to save some space and illustrate another approach 
  // of doing it, we will write out the formula in MathML form and then use a 
  // libSBML convenience function to create the ASTNode tree for us.  
  // (This is a bit dangerous; it's very easy to make mistakes when writing MathML 
  // by hand, so in a real program, we would not really want to do it this way.)

  string mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
                         "  <apply>"
                         "    <times/>"
                         "    <ci> cytosol </ci>"
                         "    <ci> kcat </ci>"
                         "    <ci> ES </ci>"
                         "  </apply>"
                         "</math>";

  astMath = readMathMLFromString(mathXMLString.c_str());
  kl->setMath(astMath);
  delete astMath;

  //---------------------------------------------------------------------------
  // Creates local Parameter objects inside the KineticLaw object.
  //---------------------------------------------------------------------------

  // Creates a Parameter ("kcat")

  para = kl->createParameter();
  para->setId("kcat");
  para->setValue(0.1);
  para->setUnits("per_second");


  // Returns the created SBMLDocument object.
  // The returned object must be explicitly deleted by the caller,
  // otherwise a memory leak will happen.

  return sbmlDoc;

}
END_TEST


START_TEST (test_MathMLFromAST_matrix)
{
  const char* expected = wrapMathML
  (
    "  <matrix>\n"
    "    <matrixrow>\n"
    "      <apply>\n"
    "        <cos/>\n"
    "        <cn type=\"integer\"> 5 </cn>\n"
    "      </apply>\n"
    "      <ci> y </ci>\n"
    "    </matrixrow>\n"
    "    <matrixrow>\n"
    "      <cn type=\"integer\"> 2 </cn>\n"
    "      <cn type=\"integer\"> 4 </cn>\n"
    "    </matrixrow>\n"
    "  </matrix>\n"
  );


  ASTNode * y = new ASTNode(AST_NAME);
  fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS);

  ASTNode *int1 = new ASTNode(AST_INTEGER);
  fail_unless(int1->setValue((long)(5)) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *cos = new ASTNode(AST_FUNCTION_COS);
  fail_unless(cos->addChild(int1) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *row1 = new ASTNode(AST_LINEAR_ALGEBRA_MATRIXROW_CONSTRUCTOR);
  fail_unless( row1->getPackageName() == "arrays");

  fail_unless(row1->addChild(cos) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(row1->addChild(y) == LIBSBML_OPERATION_SUCCESS);


  ASTNode *int2 = new ASTNode(AST_INTEGER);
  fail_unless(int2->setValue((long)(2)) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *int3 = new ASTNode(AST_INTEGER);
  fail_unless(int3->setValue((long)(4)) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *row2 = new ASTNode(AST_LINEAR_ALGEBRA_MATRIXROW_CONSTRUCTOR);
  fail_unless( row2->getPackageName() == "arrays");

  fail_unless(row2->addChild(int2) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(row2->addChild(int3) == LIBSBML_OPERATION_SUCCESS);

  N = new ASTNode(AST_LINEAR_ALGEBRA_MATRIX_CONSTRUCTOR);
  fail_unless( N->getPackageName() == "arrays");

  fail_unless(N->addChild(row1) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(N->addChild(row2) == LIBSBML_OPERATION_SUCCESS);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
ASTNode* CEvaluationNodeObject::toAST(const CCopasiDataModel* pDataModel) const
{
  ASTNode* node = new ASTNode();
  node->setType(AST_NAME);
  // since I can not get the model in which this node is located, I just
  // assume that it will always be the current global model.
  const CCopasiObject* object = pDataModel->getObject(mRegisteredObjectCN);
  assert(object);

  // if it is a reference, we get the parent of the reference
  if (object->isReference())
    {
      object = object->getObjectParent();
    }

  const CModelEntity* pME = dynamic_cast<const CModelEntity*>(object);

  if (pME != NULL)
    {
      const CModel* pModel = dynamic_cast<const CModel*>(pME);

      if (pModel != NULL)
        {
          node->setType(AST_NAME_TIME);
          node->setName("time");

          if (pModel->getInitialTime() != 0.0)
            {
              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 1);
            }
        }
      else
        {
          node->setName(pME->getSBMLId().c_str());
        }
    }
  else
    {
      const CCopasiParameter* pPara = dynamic_cast<const CCopasiParameter*>(object);

      if (pPara != NULL)
        {
          // now we have to use the common name as the name for the
          // node since we need to be able to identify local parameters
          // in arbitrary expressions for the export
          node->setName(pPara->getCN().c_str());
        }
      else
        {
          const CReaction* pReaction = dynamic_cast<const CReaction*>(object);

          if (pReaction)
            {
              node->setName(pReaction->getSBMLId().c_str());
            }
          else
            {
              fatalError();
            }
        }
    }

  return node;
}
Example #16
0
ASTNode* CEvaluationNodeFunction::toAST(const CCopasiDataModel* pDataModel) const
{
    SubType subType = (SubType)this->subType();
    ASTNode* node = new ASTNode();
    bool needFirstArg = true;

    switch (subType)
    {
    case S_INVALID:
        break;

    case S_LOG:
        node->setType(AST_FUNCTION_LN);
        break;

    case S_LOG10:
    {
        // log 10 needs two children, the log and the base
        node->setType(AST_FUNCTION_LOG);

        ASTNode* logBase = new ASTNode();
        logBase->setType(AST_INTEGER);
        logBase->setValue(10);
        node->addChild(logBase);

        break;
    }

    case S_EXP:
        node->setType(AST_FUNCTION_EXP);
        break;

    case S_SIN:
        node->setType(AST_FUNCTION_SIN);
        break;

    case S_COS:
        node->setType(AST_FUNCTION_COS);
        break;

    case S_TAN:
        node->setType(AST_FUNCTION_TAN);
        break;

    case S_SEC:
        node->setType(AST_FUNCTION_SEC);
        break;

    case S_CSC:
        node->setType(AST_FUNCTION_CSC);
        break;

    case S_COT:
        node->setType(AST_FUNCTION_COT);
        break;

    case S_SINH:
        node->setType(AST_FUNCTION_SINH);
        break;

    case S_COSH:
        node->setType(AST_FUNCTION_COSH);
        break;

    case S_TANH:
        node->setType(AST_FUNCTION_TANH);
        break;

    case S_SECH:
        node->setType(AST_FUNCTION_SECH);
        break;

    case S_CSCH:
        node->setType(AST_FUNCTION_CSCH);
        break;

    case S_COTH:
        node->setType(AST_FUNCTION_COTH);
        break;

    case S_ARCSIN:
        node->setType(AST_FUNCTION_ARCSIN);
        break;

    case S_ARCCOS:
        node->setType(AST_FUNCTION_ARCCOS);
        break;

    case S_ARCTAN:
        node->setType(AST_FUNCTION_ARCTAN);
        break;

    case S_ARCSEC:
        node->setType(AST_FUNCTION_ARCSEC);
        break;

    case S_ARCCSC:
        node->setType(AST_FUNCTION_ARCCSC);
        break;

    case S_ARCCOT:
        node->setType(AST_FUNCTION_ARCCOT);
        break;

    case S_ARCSINH:
        node->setType(AST_FUNCTION_ARCSINH);
        break;

    case S_ARCCOSH:
        node->setType(AST_FUNCTION_ARCCOSH);
        break;

    case S_ARCTANH:
        node->setType(AST_FUNCTION_ARCTANH);
        break;

    case S_ARCSECH:
        node->setType(AST_FUNCTION_ARCSECH);
        break;

    case S_ARCCSCH:
        node->setType(AST_FUNCTION_ARCCSCH);
        break;

    case S_ARCCOTH:
        node->setType(AST_FUNCTION_ARCCOTH);
        break;

    case S_SQRT:
        node->setType(AST_FUNCTION_ROOT);
        break;

    case S_ABS:
        node->setType(AST_FUNCTION_ABS);
        break;

    case S_CEIL:
        node->setType(AST_FUNCTION_CEILING);
        break;

    case S_FLOOR:
        node->setType(AST_FUNCTION_FLOOR);
        break;

    case S_FACTORIAL:
        node->setType(AST_FUNCTION_FACTORIAL);
        break;

    case S_MINUS:
        node->setType(AST_MINUS);
        break;

    case S_PLUS:
        // if this is the unary plus as I suspect,
        // the node will be replaced by its only child
        delete node;
        node = dynamic_cast<const CEvaluationNode*>(this->getChild())->toAST(pDataModel);
        break;

    case S_NOT:
        node->setType(AST_LOGICAL_NOT);
        break;

    case S_RUNIFORM:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RUNIFORM");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_RNORMAL:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RNORMAL");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_RGAMMA:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RGAMMA");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_RPOISSON:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RPOISSON");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        node->addChild(child->toAST(pDataModel));
    }
    break;

    case S_MAX:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("MAX");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_MIN:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("MIN");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;
        // :TODO: Bug 894: Implement me.
        //fatalError();
    break;
    }

    if (subType != S_INVALID)
    {
        // the following is a workaround for a bug in libsbml 3.1.1 and 3.2.0
        // where libsbml does not handle the case correctly that a root
        // function can have one or two children (MathML.cpp in function
        // writeFunctionRoot)
        if (subType == S_SQRT)
        {
            // add a degree node of value 2 as the first child
            ASTNode* pDegreeNode = new ASTNode();
            pDegreeNode->setType(AST_INTEGER);
            pDegreeNode->setValue(2);
            node->addChild(pDegreeNode);
        }

        if (needFirstArg)
        {
            const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
            node->addChild(child->toAST(pDataModel));
        }
    }

    return node;
}