/*
 * Converts a Watt Unit into the corresponding UnitDefinition
 * consisting only of SI units.
 * If the given unit does not have the correct kind, a NULL pointer is
 * returned.
 * It is up to the receiver to free the memory of the returned
 * UnitDefinition.
 * @param const Unit& unit
 * @return UnitDefinition* result
 */
LIBSBML_EXTERN
UnitDefinition* UnitConversionFactory::convertWattToSI(const Unit& unit)
{
    UnitKind_t uKind = unit.getKind();

    if (uKind != UNIT_KIND_WATT) return NULL;

    UnitDefinition* pUdef = new UnitDefinition(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    Unit* pU = new Unit(unit);
    pU->setOffset(0.0);
    pU->setKind(UNIT_KIND_KILOGRAM);
    pU->setExponent(unit.getExponent());
    pUdef->addUnit(pU);
    delete pU;
    pU = new Unit(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    pU->setKind(UNIT_KIND_METER);
    pU->setExponent(2*unit.getExponent());
    pUdef->addUnit(pU);
    delete pU;
    pU = new Unit(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    pU->setKind(UNIT_KIND_SECOND);
    pU->setExponent(-3*unit.getExponent());
    pUdef->addUnit(pU);
    delete pU;
    return pUdef;
}
END_TEST


START_TEST(test_unitdefinition_areEquivalent)
{
  UnitDefinition* ud  = new UnitDefinition(2, 4);
  UnitDefinition* ud1 = new UnitDefinition(2, 4);

  Unit* u  = new Unit(2, 4);
  u->setKind(UNIT_KIND_JOULE);
  Unit* u1 = new Unit(2, 4);
  u1->setKind(UNIT_KIND_NEWTON);
  Unit* u2 = new Unit(2, 4);
  u->setKind(UNIT_KIND_METRE);

  u1->setExponent(-1);

  ud->addUnit(u);
  ud->addUnit(u1);

  ud1->addUnit(u2);

  int equivalent = UnitDefinition::areEquivalent(ud, ud1);

  //fail_unless(equivalent == 1);

  ud->addUnit(u2);

  equivalent = UnitDefinition::areEquivalent(ud, ud1);
 
  fail_unless(equivalent == 0);

  /* NULL case*/
  ud = NULL;

  equivalent = UnitDefinition::areEquivalent(ud, ud1);
  
  fail_unless(equivalent == 0);
 
  equivalent = UnitDefinition::areEquivalent(ud1, ud);
  
  fail_unless(equivalent == 0);
 
  ud1 = NULL;

  equivalent = UnitDefinition::areEquivalent(ud, ud1);
  
  fail_unless(equivalent == 1);

  delete u;
  delete u1;
  delete u2;
  delete ud;
  delete ud1;
}
END_TEST

START_TEST(test_unitdefinition_convert_SI)
{
  UnitDefinition* ud  = new UnitDefinition(2, 4);
  UnitDefinition* ud1 = new UnitDefinition(2, 4);

  Unit* u  = new Unit(2, 4);
  u->setKind(UNIT_KIND_JOULE);
  Unit* u1 = new Unit(2, 4);
  u1->setKind(UNIT_KIND_NEWTON);

  u1->setExponent(-1);

  ud->addUnit(u);
  ud->addUnit(u1);

  ud1 = UnitDefinition::convertToSI(ud);

  fail_unless(ud1->getNumUnits() == 1);
  fail_unless(ud1->getUnit(0)->getKind() == UNIT_KIND_METRE);

  /* NULL case*/
  ud = NULL;

  ud1 = UnitDefinition::convertToSI(ud);
  
  fail_unless(ud1 == NULL);

  delete u;
  delete u1;
  delete ud;
  delete ud1;
}
END_TEST



START_TEST(test_unitdefinition_divide2)
{
  UnitDefinition* ud = new UnitDefinition(2, 2);
  UnitDefinition* ud1 = new UnitDefinition(2, 2);
  UnitDefinition* udTemp;

  Unit* u  = ud->createUnit();
  u->setKind(UNIT_KIND_METRE);
  Unit* u1 = ud1->createUnit();
  u1->setKind(UNIT_KIND_MOLE);
  
  udTemp = UnitDefinition::divide(ud, ud1);

  fail_unless(udTemp->getNumUnits() == 2);
  fail_unless(udTemp->getUnit(0)->getKind() == UNIT_KIND_METRE);
  fail_unless(udTemp->getUnit(1)->getKind() == UNIT_KIND_MOLE);
  fail_unless(udTemp->getUnit(1)->getExponent() == -1);
  fail_unless(udTemp->getLevel() == 2);
  fail_unless(udTemp->getVersion() == 2);

  delete ud1;
  delete ud;
  delete udTemp;
 }
END_TEST


START_TEST(test_unitdefinition_divide1)
{
  UnitDefinition* ud = new UnitDefinition(2, 1);
  UnitDefinition* ud1 = new UnitDefinition(2, 2);
  UnitDefinition* udTemp;

  Unit* u  = new Unit(2, 1);
  u->setKind(UNIT_KIND_METRE);
  Unit* u1 = new Unit(2, 2);
  u1->setKind(UNIT_KIND_MOLE);
 
  ud->addUnit(u);
  ud1->addUnit(u1);
  
  udTemp = UnitDefinition::divide(ud, ud1);

  fail_unless(udTemp == 0);

  delete u;
  delete ud1;
  delete u1;
  delete ud;
 }
/**
  * Checks that the units of the arguments 
  * of the function are dimensionless
  * and that there is only one argument
  *
  * If inconsistent units are found, an error message is logged.
  */
void 
ArgumentsUnitsCheckWarnings::checkDimensionlessArgs (const Model& m, 
                                           const ASTNode& node, 
                                           const SBase & sb, 
                                           bool inKL, int reactNo)
{
  /* check that node has children */
  if (node.getNumChildren() == 0)
  {
    return;
  }

  UnitDefinition *dim = new UnitDefinition(m.getSBMLNamespaces());
  Unit *unit = new Unit(m.getSBMLNamespaces());
  unit->setKind(UNIT_KIND_DIMENSIONLESS);
  unit->initDefaults();
  UnitDefinition * tempUD;
  dim->addUnit(unit);
  
  UnitFormulaFormatter *unitFormat = new UnitFormulaFormatter(&m);

  tempUD = unitFormat->getUnitDefinition(node.getChild(0), inKL, reactNo);
  
  if (tempUD->getNumUnits() != 0 && 
    !UnitDefinition::areEquivalent(dim, tempUD)) 
  {
    logInconsistentDimensionless(node, sb);
  }

  delete tempUD;
  delete dim;
  delete unit;
  delete unitFormat;

}
END_TEST

START_TEST(test_unitdefinition_areIdentical2)
{
  UnitDefinition* ud  = new UnitDefinition(2, 2);
  UnitDefinition* ud1 = new UnitDefinition(2, 2);

  Unit* u  = new Unit(2, 2);
  u->setKind(UNIT_KIND_JOULE);
  Unit* u1 = new Unit(2, 2);
  u1->setKind(UNIT_KIND_NEWTON);
  
  ud->addUnit(u);
  ud->addUnit(u1);

  ud1->addUnit(u);
  ud1->addUnit(u1);

  int identical = UnitDefinition::areIdentical(ud, ud1);

  fail_unless(identical == 1);

  delete u;
  delete u1;
  delete ud;
  delete ud1;

}
END_TEST


START_TEST (test_unitdefinition_convert_SI2)
{
  UnitDefinition *ud = new UnitDefinition(1, 1);
  UnitDefinition *ud1;
  
  Unit * u = ud->createUnit();
  u->setKind(UNIT_KIND_FARAD);

  ud1 = UnitDefinition::convertToSI(ud);

  fail_unless( ud1->getNumUnits() == 4);
  fail_unless( ud1->getLevel() == 1);
  fail_unless( ud1->getVersion() == 1);
  fail_unless( ud1->getUnit(0)->getKind() == UNIT_KIND_AMPERE );
  fail_unless( ud1->getUnit(0)->getExponent() == 2);
  fail_unless( ud1->getUnit(1)->getKind() == UNIT_KIND_KILOGRAM );
  fail_unless( ud1->getUnit(1)->getExponent() == -1);
  fail_unless( ud1->getUnit(2)->getKind() == UNIT_KIND_METRE );
  fail_unless( ud1->getUnit(2)->getExponent() == -2);
  fail_unless( ud1->getUnit(3)->getKind() == UNIT_KIND_SECOND );
  fail_unless( ud1->getUnit(3)->getExponent() == 4);


  UnitDefinition_free(ud);
}
END_TEST


START_TEST(test_unitdefinition_areIdentical)
{
  UnitDefinition* ud  = new UnitDefinition(2, 4);
  UnitDefinition* ud1 = new UnitDefinition(2, 4);

  Unit* u  = new Unit(2, 4);
  u->setKind(UNIT_KIND_JOULE);
  Unit* u1 = new Unit(2, 4);
  u1->setKind(UNIT_KIND_NEWTON);
  Unit* u2 = new Unit(2, 4);
  u2->setKind(UNIT_KIND_METRE);
  
  ud->addUnit(u);
  ud->addUnit(u1);

  ud1->addUnit(u);
  ud1->addUnit(u1);

  int identical = UnitDefinition::areIdentical(ud, ud1);

  fail_unless(identical == 1);

  ud->addUnit(u2);

  identical = UnitDefinition::areIdentical(ud, ud1);
 
  fail_unless(identical == 0);

  /* NULL case*/
  ud = NULL;

  identical = UnitDefinition::areIdentical(ud, ud1);;
  
  fail_unless(identical == 0);
 
  identical = UnitDefinition::areIdentical(ud1, ud);;
  
  fail_unless(identical == 0);
  
  ud1 = NULL;

  identical = UnitDefinition::areIdentical(ud, ud1);;
  
  fail_unless(identical == 1);

  delete u;
  delete u1;
  delete u2;
  delete ud;
  delete ud1;

}
Example #10
0
/*
 * Converts a Coulomb Unit into the corresponding UnitDefinition
 * consisting only of SI units.
 * If the given unit does not have the correct kind, a NULL pointer is
 * returned.
 * It is up to the receiver to free the memory of the returned
 * UnitDefinition.
 * @param const Unit& unit
 * @return UnitDefinition* result
 */
LIBSBML_EXTERN
UnitDefinition* UnitConversionFactory::convertCoulombToSI(const Unit& unit)
{
    UnitKind_t uKind = unit.getKind();

    if (uKind != UNIT_KIND_COULOMB) return NULL;

    UnitDefinition* pUdef = new UnitDefinition(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    Unit* pU = new Unit(unit);
    pU->setKind(UNIT_KIND_AMPERE);
    pU->setOffset(0.0);
    pUdef->addUnit(pU);
    delete pU;
    pU = new Unit(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    pU->setKind(UNIT_KIND_SECOND);
    pU->setExponent(unit.getExponent());
    pUdef->addUnit(pU);
    delete pU;
    return pUdef;
}
Example #11
0
CSBMLunit::CSBMLunit(unsigned int sbmlLevel, unsigned int sbmlVersion)
    : mUD(UnitDefinition(sbmlLevel, sbmlVersion)),
    mSymExp(),
    mSymExpExp(0)
{
  Unit *tmp = mUD.createUnit();
  tmp->setKind(UNIT_KIND_DIMENSIONLESS);

#if LIBSBML_VERSION > 40100
  tmp->initDefaults();
#endif
}
Example #12
0
/*
 * Converts a Lumen Unit into the corresponding UnitDefinition
 * consisting only of SI units.
 * If the given unit does not have the correct kind, a NULL pointer is
 * returned.
 * It is up to the receiver to free the memory of the returned
 * UnitDefinition.
 * @param const Unit& unit
 * @return UnitDefinition* result
 */
LIBSBML_EXTERN
UnitDefinition* UnitConversionFactory::convertLumenToSI(const Unit& unit)
{
    UnitKind_t uKind = unit.getKind();

    if (uKind != UNIT_KIND_LUMEN) return NULL;

    Unit* pU = new Unit(unit);
    pU->setKind(UNIT_KIND_CANDELA);
    UnitDefinition* pUdef = convertCandelaToSI(*pU);
    delete pU;
    return pUdef;
}
Example #13
0
/*
 * Converts a frequency Unit into the corresponding UnitDefinition
 * consisting only of SI units. This could be e.g. a Hertz or Bequerel unit.
 * If the given unit does not have the correct kind, a NULL pointer is
 * returned.
 * It is up to the receiver to free the memory of the returned
 * UnitDefinition.
 * @param const Unit& unit
 * @return UnitDefinition* result
 */
LIBSBML_EXTERN
UnitDefinition* UnitConversionFactory::convertFrequencyToSI(const Unit& unit)
{
    UnitKind_t uKind = unit.getKind();

    if (uKind != UNIT_KIND_HERTZ && uKind != UNIT_KIND_BECQUEREL) return NULL;

    UnitDefinition* pUdef = new UnitDefinition(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    Unit* pU = new Unit(unit);
    pU->setKind(UNIT_KIND_SECOND);
    pU->setOffset(0.0);
    pU->setExponent(-1*pU->getExponent());
    return pUdef;
}
END_TEST

START_TEST ( test_Unit )
{
  Unit* u = new Unit(2, 4);
  
  fail_unless (!(u->hasRequiredAttributes()));

  u->setKind(UNIT_KIND_MOLE);

  fail_unless (u->hasRequiredAttributes());

  delete u;
}
/*
  * Constructs and returns a UnitDefinition that expresses the units of this 
  * LocalParameter.
  */
UnitDefinition *
LocalParameter::getDerivedUnitDefinition()
{
  /* if we have the whole model but it is not in a document
   * it is still possible to determine the units
   */
  Model * m = static_cast <Model *> (getAncestorOfType(SBML_MODEL));

  if (m != NULL)
  {
    if (!m->isPopulatedListFormulaUnitsData())
    {
      m->populateListFormulaUnitsData();
    }

    UnitDefinition *ud = NULL;
    const char * units = getUnits().c_str();
    if (!strcmp(units, ""))
    {
      ud   = new UnitDefinition(getSBMLNamespaces());
      return ud;
    }
    else
    {
      if (UnitKind_isValidUnitKindString(units, 
                                getLevel(), getVersion()))
      {
        Unit * unit = new Unit(getSBMLNamespaces());
        unit->setKind(UnitKind_forName(units));
        unit->initDefaults();
        ud   = new UnitDefinition(getSBMLNamespaces());
        
        ud->addUnit(unit);

        delete unit;
      }
      else
      {
        /* must be a unit definition */
        ud = static_cast <Model *> (getAncestorOfType(SBML_MODEL))->getUnitDefinition(units);
      }
      return ud;
    }
  }
  else
  {
    return NULL;
  }
}
Example #16
0
/*
 * Converts a "Dimensionless" Unit into the corresponding UnitDefinition
 * consisting only of SI units. This would include e.g. the Radian unit.
 * If the given unit does not have the correct kind, a NULL pointer is
 * returned.
 * It is up to the receiver to free the memory of the returned
 * UnitDefinition.
 * @param const Unit& unit
 * @return UnitDefinition* result
 */
LIBSBML_EXTERN
UnitDefinition* UnitConversionFactory::convertDimensionlessToSI(const Unit& unit)
{
    UnitKind_t uKind = unit.getKind();

    if (uKind != UNIT_KIND_DIMENSIONLESS && uKind != UNIT_KIND_ITEM && uKind != UNIT_KIND_RADIAN && uKind != UNIT_KIND_STERADIAN) return NULL;

    UnitDefinition* pUdef = new UnitDefinition(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    Unit* pU = new Unit(unit);
    pU->setKind(UNIT_KIND_DIMENSIONLESS);
    pU->setOffset(0.0);
    pUdef->addUnit(pU);
    delete pU;
    return pUdef;
}
Example #17
0
/*
 * Converts a Celsius Unit into the corresponding UnitDefinition
 * consisting only of SI units.
 * If the given unit does not have the correct kind, a NULL pointer is
 * returned.
 * It is up to the receiver to free the memory of the returned
 * UnitDefinition.
 * @param const Unit& unit
 * @return UnitDefinition* result
 */
LIBSBML_EXTERN
UnitDefinition* UnitConversionFactory::convertCelsiusToSI(const Unit& unit)
{
    UnitKind_t uKind = unit.getKind();

    if (uKind != UNIT_KIND_CELSIUS) return NULL;

    UnitDefinition* pUdef = new UnitDefinition(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION);
    Unit* pU = new Unit(unit);
    pU->setKind(UNIT_KIND_KELVIN);
    pU->setOffset(0.0);
    pUdef->addUnit(pU);
    delete pU;
    return pUdef;
}
/*
  * Checks that the units of the delay function are consistent
  *
  * If inconsistent units are found, an error message is logged.
  */
void 
ArgumentsUnitsCheck::checkUnitsFromDelay (const Model& m, 
                                        const ASTNode& node, 
                                        const SBase & sb, bool inKL, int reactNo)
{
  /* check that node has two children */
  if (node.getNumChildren() != 2)
  {
    return;
  }

  if (!m.getSBMLNamespaces()->getNamespaces())
  {
#if 0
    cout << "[DEBUG] XMLNS IS NULL" << endl;
#endif
  }

  /* delay(x, t) 
   * no restrictions on units of x
   * but t must have units of time
   */
  UnitDefinition *time = new UnitDefinition(m.getSBMLNamespaces());
  Unit *unit = new Unit(m.getSBMLNamespaces());
  unit->setKind(UNIT_KIND_SECOND);
  unit->initDefaults();
  UnitDefinition * tempUD;
  time->addUnit(unit);
  
  UnitFormulaFormatter *unitFormat = new UnitFormulaFormatter(&m);

  tempUD = unitFormat->getUnitDefinition(node.getRightChild(), inKL, reactNo);
  
  if (!unitFormat->getContainsUndeclaredUnits())
  {
    if (!UnitDefinition::areEquivalent(time, tempUD)) 
    {
      logInconsistentDelay(node, sb);
    }
  }

  delete time;
  delete tempUD;
  delete unit;
  delete unitFormat;

  checkUnits(m, *node.getLeftChild(), sb, inKL, reactNo);
}
Example #19
0
END_TEST


START_TEST (test_WriteL3SBML_Unit)
{
  const char* expected = "<unit kind=\"kilogram\" exponent=\"0.2\""
    " scale=\"-3\" multiplier=\"3.2\"/>";


  Unit* u = D->createModel()->createUnitDefinition()->createUnit();
  u->setKind(UNIT_KIND_KILOGRAM);
  double exp = 0.2;
  u->setExponent(exp);
  u->setScale(-3);
  u->setMultiplier(3.2);

  char* sbml = u->toSBML();
  fail_unless( equals(expected, sbml) );
  safe_free(sbml);
}
END_TEST


START_TEST (test_unitdefinition_simplify1)
{
  UnitDefinition *ud = new UnitDefinition(2, 1);
  
  Unit * u = ud->createUnit();
  u->setKind(UNIT_KIND_MOLE);

  Unit * u1 = ud->createUnit();
  u1->setKind(UNIT_KIND_MOLE);
  u1->setExponent(-1);

  UnitDefinition::simplify(ud);

  fail_unless( ud->getNumUnits() == 1);
  fail_unless( ud->getUnit(0)->getKind() == UNIT_KIND_DIMENSIONLESS );

  delete ud;
}
END_TEST


START_TEST ( test_Unit_parent_add )
{
    UnitDefinition* ud=new UnitDefinition(2, 4);

    Unit * u = new Unit(2, 4);
    u->setKind(UNIT_KIND_MOLE);
    ud->addUnit(u);
    delete u;

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

    ListOf *lo = ud->getListOfUnits();

    fail_unless(lo == ud->getUnit(0)->getParentSBMLObject());
    fail_unless(ud == lo->getParentSBMLObject());

    delete ud;
}
END_TEST


START_TEST (test_unitdefinition_convert_SI1)
{
  UnitDefinition *ud = new UnitDefinition(2, 1);
  UnitDefinition *ud1;
  
  Unit * u = ud->createUnit();
  u->setKind(UNIT_KIND_HERTZ);

  ud1 = UnitDefinition::convertToSI(ud);

  fail_unless( ud1->getNumUnits() == 1);
  fail_unless( ud1->getUnit(0)->getKind() == UNIT_KIND_SECOND );
  fail_unless( ud1->getUnit(0)->getExponent() == -1);
  fail_unless( ud1->getLevel() == 2);
  fail_unless( ud1->getVersion() == 1);


  UnitDefinition_free(ud);
}
END_TEST


START_TEST(test_unitdefinition_order)
{
  UnitDefinition* ud = new UnitDefinition(2, 4);

  Unit* u  = new Unit(2, 4);
  u->setKind(UNIT_KIND_METRE);
  Unit* u1 = new Unit(2, 4);
  u1->setKind(UNIT_KIND_AMPERE);
  Unit* u2 = new Unit(2, 4);
  u2->setKind(UNIT_KIND_HERTZ);

  ud->addUnit(u);
  ud->addUnit(u1);
  ud->addUnit(u2);

  UnitDefinition::reorder(ud);

  fail_unless(ud->getNumUnits() == 3);
  fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_AMPERE);
  fail_unless(ud->getUnit(1)->getKind() == UNIT_KIND_HERTZ);
  fail_unless(ud->getUnit(2)->getKind() == UNIT_KIND_METRE);

  /* NULL case*/
  ud = NULL;

  UnitDefinition::reorder(ud);
  
  fail_unless(ud == NULL);

  delete u;
  delete u1;
  delete u2;
  delete ud;
}
/**
 *
 * Creates an SBML model represented in "7.2 Example involving units"
 * in the SBML Level 2 Version 4 Specification.
 *
 */
SBMLDocument* createExampleInvolvingUnits()
{
  const unsigned int level   = Level;
  const unsigned int version = Version;

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

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

  // Adds the namespace for XHTML to the SBMLDocument object.  We need this
  // because we will add notes to the model.  (By default, the SBML document
  // created by SBMLDocument only declares the SBML XML namespace.)

  sbmlDoc->getNamespaces()->add("http://www.w3.org/1999/xhtml", "xhtml");

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

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

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

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

  UnitDefinition* unitdef;
  Unit *unit;

  //---------------------------------------------------------------------------  
  // (UnitDefinition1) Creates an UnitDefinition object ("substance").
  //
  // This has the effect of redefining the default unit of subtance for the
  // whole model.
  //---------------------------------------------------------------------------

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

  //  Creates an Unit inside the UnitDefinition object 

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setScale(-3);

  //--------------------------------------------------------------------------------
  // (UnitDefinition2) Creates an UnitDefinition object ("mmls") 
  //--------------------------------------------------------------------------------
    
  // 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("mmls");
    
  //  Creates an Unit inside the UnitDefinition object ("mmls")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setScale(-3);

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

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

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

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

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

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setScale(-3);

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

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


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

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

  // Creates a Compartment object ("cell")

  comp = model->createCompartment();
  comp->setId(compName);
 
  // Sets the "size" attribute of the Compartment object.
  //
  //   The units of this Compartment object is the default SBML 
  //   units of volume (litre), and thus we don't have to explicitly invoke 
  //   setUnits("litre") function to set the default units.
  //
  comp->setSize(1);


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

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

  sp = model->createSpecies();
  sp->setId("x0");

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

  sp->setCompartment(compName);

  // Sets the "initialConcentration" attribute of the Species object.
  //
  //  The units of this Species object is determined by two attributes of this 
  //  Species object ("substanceUnits" and "hasOnlySubstanceUnits") and the
  //  "spatialDimensions" attribute of the Compartment object ("cytosol") in which 
  //  this species object is located.
  //  Since the default values are used for "substanceUnits" (substance (mole)) 
  //  and "hasOnlySubstanceUnits" (false) and the value of "spatialDimension" (3) 
  //  is greater than 0, the units of this Species object is  moles/liters . 
  //
  sp->setInitialConcentration(1);

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

  sp = model->createSpecies();
  sp->setId("x1");
  sp->setCompartment(compName);
  sp->setInitialConcentration(1);

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

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("s1");
  sp->setInitialConcentration(1);

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

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("s2");
  sp->setInitialConcentration(1);

  //---------------------------------------------------------------------------
  //
  // Creates global Parameter objects inside the Model object. 
  //
  //---------------------------------------------------------------------------

  Parameter* para;

  // Creates a Parameter ("vm")  

  para = model->createParameter();
  para->setId("vm");
  para->setValue(2);
  para->setUnits("mmls");

  // Creates a Parameter ("km")  

  para = model->createParameter();
  para->setId("km");
  para->setValue(2);
  para->setUnits("mml");


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

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

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

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

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

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

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

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("v1"). 
  //---------------------------------------------------------------------------

  // Creates a Product object that references Species "s1" in the model. 

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

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

  // Creates a <notes> element in the KineticLaw object.
  // Here we illustrate how to do it using a literal string.  This requires
  // known the required syntax of XHTML and the requirements for SBML <notes>
  // elements.  Later below, we show how to create notes using objects instead
  // of strings.

  string notesString = "<xhtml:p> ((vm * s1)/(km + s1)) * cell </xhtml:p>";
  kl->setNotes(notesString);

  //---------------------------------------------------------------------------
  // Creates an ASTNode object which represents the following KineticLaw object.
  //
  //  <math xmlns=\"http://www.w3.org/1998/Math/MathML\">
  //   <apply>
  //     <times/>
  //     <apply>
  //       <divide/>
  //       <apply>
  //         <times/>
  //           <ci> vm </ci>
  //           <ci> s1 </ci>
  //       </apply>
  //       <apply>
  //         <plus/>
  //           <ci> km </ci>
  //           <ci> s1 </ci>
  //       </apply>
  //     </apply>
  //     <ci> cell </ci>
  //    </apply>
  //  </math>
  //---------------------------------------------------------------------------

  //
  // In the following code, ASTNode objects, which construct an ASTNode tree 
  // of the above math, are created and added in the order of preorder traversal 
  // of the tree (i.e. the order corresponds to the nested structure of the above 
  // MathML elements), and thus the following code maybe a bit more efficient but 
  // maybe a bit difficult to read.
  //

  ASTNode* astMath = new ASTNode(AST_TIMES);

  astMath->addChild(new ASTNode(AST_DIVIDE));
  ASTNode* astDivide = astMath->getLeftChild();

  astDivide->addChild(new ASTNode(AST_TIMES));
  ASTNode* astTimes = astDivide->getLeftChild();

  astTimes->addChild(new ASTNode(AST_NAME));
  astTimes->getLeftChild()->setName("vm");

  astTimes->addChild(new ASTNode(AST_NAME));
  astTimes->getRightChild()->setName("s1");

  astDivide->addChild(new ASTNode(AST_PLUS));
  ASTNode* astPlus = astDivide->getRightChild();

  astPlus->addChild(new ASTNode(AST_NAME));
  astPlus->getLeftChild()->setName("km");

  astPlus->addChild(new ASTNode(AST_NAME));
  astPlus->getRightChild()->setName("s1");


  astMath->addChild(new ASTNode(AST_NAME));
  astMath->getRightChild()->setName("cell");

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

  kl->setMath(astMath);
  delete astMath;


  //---------------------------------------------------------------------------
  // (Reaction2) Creates a Reaction object ("v2").
  //---------------------------------------------------------------------------

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

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

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

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

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("v2"). 
  //---------------------------------------------------------------------------

  // Creates a Product object that references Species "s2" in the model. 

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

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

  // Sets a notes (by XMLNode) to the KineticLaw object.
  //
  // The following code is an alternative to using setNotes(const string&).
  // The equivalent code would be like this:
  //   
  //     notesString = "<xhtml:p>((vm * s2)/(km + s2))*cell</xhtml:p>";
  //     kl->setNotes(notesString);

  // Creates an XMLNode of start element (<xhtml:p>) without attributes.

  XMLNode notesXMLNode(XMLTriple("p", "", "xhtml"), XMLAttributes());

  // Adds a text element to the start element.

  notesXMLNode.addChild(XMLNode(" ((vm * s2)/(km + s2)) * cell ")); 

  // Adds it to the kineticLaw object.

  kl->setNotes(&notesXMLNode);

  //---------------------------------------------------------------------------
  // 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/>"
                         "    <apply>"
                         "      <divide/>"
                         "      <apply>"
                         "        <times/>"
                         "        <ci> vm </ci>"
                         "        <ci> s2 </ci>"
                         "      </apply>"
                         "      <apply>"
                         "        <plus/>"
                         "          <ci> km </ci>"
                         "          <ci> s2 </ci>"
                         "      </apply>"
                         "    </apply>"
                         "    <ci> cell </ci>"
                         "  </apply>"
                         "</math>";

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


  //---------------------------------------------------------------------------
  // (Reaction3) Creates a Reaction object ("v3").
  //---------------------------------------------------------------------------

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

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

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

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

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("v3"). 
  //---------------------------------------------------------------------------

  // Creates a Product object that references Species "x1" in the model. 

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


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

  // Sets a notes (by string) to the KineticLaw object.

  notesString = "<xhtml:p> ((vm * x1)/(km + x1)) * cell </xhtml:p>";
  kl->setNotes(notesString);

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

  mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
                  "  <apply>"
                  "    <times/>"
                  "    <apply>"
                  "      <divide/>"
                  "      <apply>"
                  "        <times/>"
                  "        <ci> vm </ci>"
                  "        <ci> x1 </ci>"
                  "      </apply>"
                  "      <apply>"
                  "        <plus/>"
                  "          <ci> km </ci>"
                  "          <ci> x1 </ci>"
                  "      </apply>"
                  "    </apply>"
                  "    <ci> cell </ci>"
                  "  </apply>"
                  "</math>";

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


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

  return sbmlDoc;

}
/**
 *
 * 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;

}
Example #26
0
/*
  * Constructs and returns a UnitDefinition that expresses the units of this 
  * Parameter.
  */
UnitDefinition *
Parameter::getDerivedUnitDefinition()
{
  /* if we have the whole model but it is not in a document
   * it is still possible to determine the units
   */
  Model * m = static_cast <Model *> (getAncestorOfType(SBML_MODEL));

  if (m != NULL)
  {
    if (!m->isPopulatedListFormulaUnitsData())
    {
      m->populateListFormulaUnitsData();
    }
    
    /* need to distinguish between a global and local parameter
    * for a global parameter a unit definition will have been created
    * for a local parameter need to create one based on the units field
    */
    bool globalParameter = false;
    SBase *parent  = getParentSBMLObject();
    SBase *pparent = (parent) ? parent->getParentSBMLObject() : NULL; 
    if (pparent != NULL && dynamic_cast<Model*>(pparent) != 0)
      globalParameter = true;

    if (globalParameter)
    {
      if (m->getFormulaUnitsData(getId(), getTypeCode()) != NULL)
      {
        return m->getFormulaUnitsData(getId(), getTypeCode())
                                              ->getUnitDefinition();
    }
    else
    {
      return NULL;
    }
  }
  else
  {
    UnitDefinition *ud = NULL;
    const char * units = getUnits().c_str();
    if (!strcmp(units, ""))
    {
      ud   = new UnitDefinition(getSBMLNamespaces());
      return ud;
    }
    else
    {
      if (UnitKind_isValidUnitKindString(units, 
                                getLevel(), getVersion()))
      {
        Unit * unit = new Unit(getSBMLNamespaces());
        unit->setKind(UnitKind_forName(units));
        unit->initDefaults();
        ud   = new UnitDefinition(getSBMLNamespaces());
        
        ud->addUnit(unit);

        delete unit;
      }
      else
      {
        /* must be a unit definition */
        ud = static_cast <Model *> (getAncestorOfType(SBML_MODEL))->getUnitDefinition(units);
      }
      return ud;
      }
    }
  }
  else
  {
    return NULL;
  }
}
/*
  * Checks that the units of the piecewise function are consistent
  *
  * If inconsistent units are found, an error message is logged.
  */
void 
ArgumentsUnitsCheck::checkUnitsFromPiecewise (const Model& m, 
                                        const ASTNode& node, 
                                        const SBase & sb, bool inKL, int reactNo)
{
  /* check that node has children */
  if (node.getNumChildren() == 0)
  {
    return;
  }

  /* piecewise(a0, a1, a2, a3, ...)
   * a0 and a2, a(n_even) must have same units
   * a1, a3, a(n_odd) must be dimensionless
   */
  unsigned int n;
  UnitDefinition *dim = new UnitDefinition(m.getSBMLNamespaces());
  Unit *unit = new Unit(m.getSBMLNamespaces());
  unit->setKind(UNIT_KIND_DIMENSIONLESS);
  unit->initDefaults();
  UnitDefinition * tempUD;
  UnitDefinition * tempUD1 = NULL;
  dim->addUnit(unit);
  
  UnitFormulaFormatter *unitFormat = new UnitFormulaFormatter(&m);

  tempUD = unitFormat->getUnitDefinition(node.getChild(0), inKL, reactNo);

  for(n = 2; n < node.getNumChildren(); n+=2)
  {
    tempUD1 = unitFormat->getUnitDefinition(node.getChild(n), inKL, reactNo);
  
    if (!unitFormat->getContainsUndeclaredUnits())
    {
      if (!UnitDefinition::areEquivalent(tempUD, tempUD1)) 
      {
        logInconsistentPiecewise(node, sb);
      }
    }
    delete tempUD1;
  }

  delete tempUD;

  for(n = 1; n < node.getNumChildren(); n+=2)
  {
    tempUD = unitFormat->getUnitDefinition(node.getChild(n), inKL, reactNo);

    if (!UnitDefinition::areEquivalent(tempUD, dim)) 
    {
      logInconsistentPiecewiseCondition(node, sb);
    }
    delete tempUD;
  }
 
  delete dim;
  delete unit;
  delete unitFormat;

  for(n = 0; n < node.getNumChildren(); n++)
  {
    checkUnits(m, *node.getChild(n), sb, inKL, reactNo);
  }

}
Example #28
0
/* in L1 and L2 there were built in values for key units
 * such as 'volume', 'length', 'area', 'substance' and 'time'
 * In L3 these have been removed - thus if a model uses one of these
 * it needs a unitDefinition to define it
 */
void
Model::addDefinitionsForDefaultUnits()
{
  /* create a list of unit values */
  IdList unitsUsed;
  unsigned int n;
  bool implicitVolume = false;
  bool implicitArea = false;
  bool implicitLength = false;
  bool implicitSubstance = false;

  for (n = 0; n < getNumCompartments(); n++)
  {
    if (getCompartment(n)->isSetUnits())
    {
      unitsUsed.append(getCompartment(n)->getUnits());
    }
    else
    {
      if (getCompartment(n)->getSpatialDimensions() == 3)
      {
        implicitVolume = true;
        getCompartment(n)->setUnits("volume");
      }
      else if (getCompartment(n)->getSpatialDimensions() == 2)
      {
        implicitArea = true;
        getCompartment(n)->setUnits("area");
      }
      else if (getCompartment(n)->getSpatialDimensions() == 1)
      {
        implicitLength = true;
        getCompartment(n)->setUnits("length");
      }
    }
  }

  for (n = 0; n < getNumSpecies(); n++)
  {
    if (getSpecies(n)->isSetSubstanceUnits())
    {
      unitsUsed.append(getSpecies(n)->getSubstanceUnits());
    }
    else
    {
      implicitSubstance = true;
      getSpecies(n)->setSubstanceUnits("substance");
    }
 
    if (getSpecies(n)->isSetSpatialSizeUnits())
      unitsUsed.append(getSpecies(n)->getSpatialSizeUnits());
  }

  for (n = 0; n < getNumParameters(); n++)
  {
    if (getParameter(n)->isSetUnits())
      unitsUsed.append(getParameter(n)->getUnits());
  }

  if (getUnitDefinition("volume") == NULL)
  {
    if (unitsUsed.contains("volume") || implicitVolume)
    {
      UnitDefinition * ud = createUnitDefinition();
      ud->setId("volume");
      Unit * u = ud->createUnit();
      u->setKind(UnitKind_forName("litre"));
      u->setScale(0);
      u->setExponent(1.0);
      u->setMultiplier(1.0);
      setVolumeUnits("volume");
    }
    else
    {
      setVolumeUnits("litre");
    }
  }
  else
  {
    setVolumeUnits("volume");
  }


  if (getUnitDefinition("substance") == NULL)
  {
    if (unitsUsed.contains("substance") || implicitSubstance)
    {
      UnitDefinition * ud = createUnitDefinition();
      ud->setId("substance");
      Unit * u = ud->createUnit();
      u->setKind(UnitKind_forName("mole"));
      u->setScale(0);
      u->setExponent(1.0);
      u->setMultiplier(1.0);
      setSubstanceUnits("substance");
      setExtentUnits("substance");
    }
    else
    {
      setSubstanceUnits("mole");
      setExtentUnits("mole");
    }
  }
  else
  {
    setSubstanceUnits("substance");
    setExtentUnits("substance");
  }

  if (getUnitDefinition("area") == NULL)
  {
    UnitDefinition * ud = createUnitDefinition();
    ud->setId("area");
    Unit * u = ud->createUnit();
    u->setKind(UnitKind_forName("metre"));
    u->setScale(0);
    u->setExponent(2.0);
    u->setMultiplier(1.0);
    setAreaUnits("area");
  }
  else
  {
    setAreaUnits("area");
  }

  if (getUnitDefinition("length") == NULL)
  {
    if (unitsUsed.contains("length") || implicitLength)
    {
      UnitDefinition * ud = createUnitDefinition();
      ud->setId("length");
      Unit * u = ud->createUnit();
      u->setKind(UnitKind_forName("metre"));
      u->setScale(0);
      u->setExponent(1.0);
      u->setMultiplier(1.0);
      setLengthUnits("length");
    }
    else
    {
      setLengthUnits("metre");
    }
  }
  else
  {
    setLengthUnits("length");
  }

  if (getUnitDefinition("time") == NULL)
  {
    setTimeUnits("second");
  }
  else
  {
    setTimeUnits("time");
  }

}
Example #29
0
void
Model::dealWithModelUnits()
{
  UnitRefsFilter filter;
  List * elements = getAllElements(&filter);
  unsigned int n = 0;
  unsigned int num = elements->getSize();
  
  if (isSetVolumeUnits())
  {
    std::string volume = getVolumeUnits();
    // if in an L3 model a user used volume as an id of a UnitDefinition
    // but they declared the volume units of teh model to be something 
    // else then the UD with id volume is nothing to do with the 
    // L2 interpretation of volume
    // so replace that UD and all references to it 
    if (volume != "volume")
    {
      UnitDefinition * existingUD = removeUnitDefinition("volume");
      if (existingUD != NULL)
      {
        std::string newSubsName = "volumeFromOriginal";
        existingUD->setId(newSubsName);
        SBase* obj;
        for (n = 0; n < num; n++)
        {
          obj = (SBase*)(elements->get(n));
          obj->renameUnitSIdRefs("volume", newSubsName);
        }
        addUnitDefinition(existingUD);
      }
    }
    UnitDefinition * ud = getUnitDefinition(volume) != NULL ? 
                          getUnitDefinition(volume)->clone() : NULL;
    if (ud != NULL)
    {
      ud->setId("volume");
    }
    else
    {
      Unit *u = new Unit(getSBMLNamespaces());
      u->initDefaults();
      u->setKind(UnitKind_forName(volume.c_str()));
      ud = new UnitDefinition(getSBMLNamespaces());
      ud->setId("volume");
      ud->addUnit(u);
    }
    addUnitDefinition(ud);
  }
  if (isSetAreaUnits())
  {
    std::string area = getAreaUnits();
    // if in an L3 model a user used area as an id of a UnitDefinition
    // but they declared the area units of teh model to be something 
    // else then the UD with id area is nothing to do with the 
    // L2 interpretation of area
    // so replace that UD and all references to it 
    if (area != "area")
    {
      UnitDefinition * existingUD = removeUnitDefinition("area");
      if (existingUD != NULL)
      {
        std::string newSubsName = "areaFromOriginal";
        existingUD->setId(newSubsName);
        SBase* obj;
        for (n = 0; n < num; n++)
        {
          obj = (SBase*)(elements->get(n));
          obj->renameUnitSIdRefs("area", newSubsName);
        }
        addUnitDefinition(existingUD);
      }
    }
    UnitDefinition * ud = getUnitDefinition(area) != NULL ? 
                          getUnitDefinition(area)->clone() : NULL;
    if (ud != NULL)
    {
      ud->setId("area");
    }
    else
    {
      Unit *u = new Unit(getSBMLNamespaces());
      u->initDefaults();
      u->setKind(UnitKind_forName(area.c_str()));
      ud = new UnitDefinition(getSBMLNamespaces());
      ud->setId("area");
      ud->addUnit(u);
    }
    addUnitDefinition(ud);
  }
  if (isSetLengthUnits())
  {
    std::string length = getLengthUnits();
    // if in an L3 model a user used length as an id of a UnitDefinition
    // but they declared the length units of teh model to be something 
    // else then the UD with id length is nothing to do with the 
    // L2 interpretation of length
    // so replace that UD and all references to it 
    if (length != "length")
    {
      UnitDefinition * existingUD = removeUnitDefinition("length");
      if (existingUD != NULL)
      {
        std::string newSubsName = "lengthFromOriginal";
        existingUD->setId(newSubsName);
        SBase* obj;
        for (n = 0; n < num; n++)
        {
          obj = (SBase*)(elements->get(n));
          obj->renameUnitSIdRefs("length", newSubsName);
        }
        addUnitDefinition(existingUD);
      }
    }
    UnitDefinition * ud = getUnitDefinition(length) != NULL ? 
                          getUnitDefinition(length)->clone() : NULL;
    if (ud != NULL)
    {
      ud->setId("length");
    }
    else
    {
      Unit *u = new Unit(getSBMLNamespaces());
      u->initDefaults();
      u->setKind(UnitKind_forName(length.c_str()));
      ud = new UnitDefinition(getSBMLNamespaces());
      ud->setId("length");
      ud->addUnit(u);
    }
    addUnitDefinition(ud);
  }
  if (isSetSubstanceUnits())
  {
    std::string substance = getSubstanceUnits();
    // if in an L3 model a user used substance as an id of a UnitDefinition
    // but they declared the substance units of teh model to be something 
    // else then the UD with id substance is nothing to do with the 
    // L2 interpretation of substance
    // so replace that UD and all references to it 
    if (substance != "substance")
    {
      UnitDefinition * existingUD = removeUnitDefinition("substance");
      if (existingUD != NULL)
      {
        std::string newSubsName = "substanceFromOriginal";
        existingUD->setId(newSubsName);
        SBase* obj;
        for (n = 0; n < num; n++)
        {
          obj = (SBase*)(elements->get(n));
          obj->renameUnitSIdRefs("substance", newSubsName);
        }
        addUnitDefinition(existingUD);
      }
    }
    UnitDefinition * ud = getUnitDefinition(substance) != NULL ? 
                          getUnitDefinition(substance)->clone() : NULL;
    if (ud != NULL)
    {
      ud->setId("substance");
    }
    else
    {
      Unit *u = new Unit(getSBMLNamespaces());
      u->initDefaults();
      u->setKind(UnitKind_forName(substance.c_str()));
      ud = new UnitDefinition(getSBMLNamespaces());
      ud->setId("substance");
      ud->addUnit(u);
    }
    addUnitDefinition(ud);
  }
  if (isSetTimeUnits())
  {
    std::string time = getTimeUnits();
    // if in an L3 model a user used time as an id of a UnitDefinition
    // but they declared the time units of teh model to be something 
    // else then the UD with id time is nothing to do with the 
    // L2 interpretation of time
    // so replace that UD and all references to it 
    if (time != "time")
    {
      UnitDefinition * existingUD = removeUnitDefinition("time");
      if (existingUD != NULL)
      {
        std::string newSubsName = "timeFromOriginal";
        existingUD->setId(newSubsName);
        SBase* obj;
        for (n = 0; n < num; n++)
        {
          obj = (SBase*)(elements->get(n));
          obj->renameUnitSIdRefs("time", newSubsName);
        }
        addUnitDefinition(existingUD);
      }
    }
    UnitDefinition * ud = getUnitDefinition(time) != NULL ? 
                          getUnitDefinition(time)->clone() : NULL;
    if (ud != NULL)
    {
      ud->setId("time");
    }
    else
    {
      ud = new UnitDefinition(getSBMLNamespaces());
      ud->setId("time");
      Unit *u = ud->createUnit();
      u->initDefaults();
      u->setKind(UnitKind_forName(time.c_str()));
    }
    addUnitDefinition(ud);
  }
}
Example #30
0
/*
 * Converts a Unit into the corresponding UnitDefinition that consists
 * only of SI units.
 * Possible offsets are ignored.
 * Freeing the memory for the returned UnitDefinition is up to the
 * receiver.
 * On failure a NULL pointer is returned.
 * @param const Unit& unit
 * @return UnitDefinition* result
 */
LIBSBML_EXTERN
UnitDefinition* UnitConversionFactory::convertToSI(const Unit& unit)
{
    UnitDefinition* pUdef = NULL;
    Unit* pU = NULL;

    if (!unit.isSetKind()) return pUdef;

    UnitKind_t uKind = unit.getKind();

    switch (uKind)
    {
    case UNIT_KIND_AMPERE:
        pUdef = convertAmpereToSI(unit);
        break;

    case UNIT_KIND_BECQUEREL:
    case UNIT_KIND_HERTZ:
        pUdef = convertFrequencyToSI(unit);
        break;

    case UNIT_KIND_CANDELA:
        pUdef = convertCandelaToSI(unit);
        break;

    case UNIT_KIND_CELSIUS:
        pUdef = convertCelsiusToSI(unit);
        break;

    case UNIT_KIND_COULOMB:
        pUdef = convertCoulombToSI(unit);
        break;

    case UNIT_KIND_DIMENSIONLESS:
    case UNIT_KIND_ITEM:
    case UNIT_KIND_RADIAN:
    case UNIT_KIND_STERADIAN:
        pUdef = convertDimensionlessToSI(unit);
        break;

    case UNIT_KIND_FARAD:
        pUdef = convertFaradToSI(unit);
        break;

    case UNIT_KIND_GRAM:
        pU = new Unit(unit);
        pU->setScale(pU->getScale() - 3);
        pU->setKind(UNIT_KIND_KILOGRAM);
        pUdef = convertKilogramToSI(*pU);
        delete pU;
        break;

    case UNIT_KIND_GRAY:
    case UNIT_KIND_SIEVERT:
        pUdef = convertDoseToSI(unit);
        break;

    case UNIT_KIND_HENRY:
        pUdef = convertHenryToSI(unit);
        break;

    case UNIT_KIND_JOULE:
        pUdef = convertJouleToSI(unit);
        break;

    case UNIT_KIND_KATAL:
        pUdef = convertKatalToSI(unit);
        break;

    case UNIT_KIND_KELVIN:
        pUdef = convertKelvinToSI(unit);
        break;

    case UNIT_KIND_KILOGRAM:
        pUdef = convertKilogramToSI(unit);
        break;

    case UNIT_KIND_LITER:
    case UNIT_KIND_LITRE:
        pU = new Unit(unit);
        pU->setKind(UNIT_KIND_METER);
        pU->setExponent(pU->getExponent()*3);
        pU->setScale(pU->getScale() - 3);
        pUdef = convertMeterToSI(*pU);
        delete pU;
        break;

    case UNIT_KIND_LUMEN:
        pUdef = convertLumenToSI(unit);
        break;

    case UNIT_KIND_LUX:
        pUdef = convertLuxToSI(unit);
        break;

    case UNIT_KIND_METER:
    case UNIT_KIND_METRE:
        pUdef = convertMeterToSI(unit);
        break;

    case UNIT_KIND_MOLE:
#if LIBSBML_VERSION >= 40100
    // this may be not totally correct, but this is the way we currently intend to
    // handle it in COPASI
    case UNIT_KIND_AVOGADRO:
#endif // LIBSBML_VERSION
        pUdef = convertMoleToSI(unit);
        break;

    case UNIT_KIND_NEWTON:
        pUdef = convertNewtonToSI(unit);
        break;

    case UNIT_KIND_OHM:
        pUdef = convertOhmToSI(unit);
        break;

    case UNIT_KIND_PASCAL:
        pUdef = convertPascalToSI(unit);
        break;

    case UNIT_KIND_SECOND:
        pUdef = convertSecondToSI(unit);
        break;

    case UNIT_KIND_SIEMENS:
        pUdef = convertSiemensToSI(unit);
        break;

    case UNIT_KIND_TESLA:
        pUdef = convertTeslaToSI(unit);
        break;

    case UNIT_KIND_VOLT:
        pUdef = convertVoltToSI(unit);
        break;

    case UNIT_KIND_WATT:
        pUdef = convertWattToSI(unit);
        break;

    case UNIT_KIND_WEBER:
        pUdef = convertWeberToSI(unit);
        break;

    case UNIT_KIND_INVALID:
        delete pUdef;
        pUdef = NULL;
        break;
    }

    if (pUdef != NULL)
    {
        unsigned int num = 1;
        std::stringstream ss;
        ss << "UnitDefinition_" << num;

        while (!UnitConversionFactory::isIdUnused(ss.str()))
        {
            ++num;
            ss.str("");
            ss << "UnitDefinition_" << num;
        }

        std::string id = ss.str();
        usedIds.push_back(id);
        pUdef->setId(id);
        UnitKind_t uKind = unit.getKind();
        pUdef->setName(UnitKind_toString(uKind));
    }

    return pUdef;
}