| Author | Topic |
Posts: 413
Registered: May 2004
|
|
Possible change to libSBML API
|
16 Sep '08 11:58
|
 |
|
ATTENTION:
A situation has arisen where it may be necessary to alter the existing
libSBML API and we would appreciate your comments and feedback regarding
this.
We especially want people's input on the important question near the end
of this message.
I know it's hard to believe but libSBML has a problem that has presented
itself in several ways :-) . Namely, it is possible to create
in-memory SBML object structures that are not actually valid SBML. It
also possible to "lose" attributes when you write out a document. A
detailed example of this is given here:
http://sbml.org/SBML_Projects/libSBML/Modularization#createSBML
Another example would be the case where a 2D Compartment is created and
then added to a model within a L1V2 document. Writing out the document
would seem fine as the spatialDimensions attribute is not present in
L1V2 and therefore not written out. However, software creating such a
model and then querying the compartment would get the following:
Level of Compartment: 1
SpatialDimensions of Compartment: 2
- which is not valid SBML.
We need to fix this - as Level 3 modules will only create further
problems of a similar nature :-)
Our proposed solution is
1) additional constructors for each object - taking level, version and
xml namespaces as arguments
e.g.
Compartment (unsigned int level, unsigned int version,
XMLNamespaces* xmlns = 0);
2) the setter functions for each object do not create invalid sbml
e.g.
compartment->setUnits("volt")
would have no effect on the units variable for the compartment
3) the add functions for adding components to models do not add an
object if there is a mismatch between the level/version/xmlns
e.g.
Compartment *c = new Compartment(1, 2);
Model * m = new Model(2, 3);
m->addCompartment(c);
would not add the compartment to the model
4) there is an additional validation function checkInternalConsistency
that runs a validator that specifically looks for mismatches between
levels/versions and attribute values
eg this would log an error for a compartment within an L1V2 model that
had spatialDimensions set to 2.
=====
Item 1 will happen - as it will be useful, and possibly necessary, for
modularization wrt level 3 extensions
Item 4 we think would be a useful addition to the libSBML API as the
existing validation focusses on the level and version of the document
being validated and does not specifically look at the internal
representation of each object.
However, we would appreciate feedback on the best approach to items 2
and 3.
We think it is most useful that if a set/add function fails that this is
reported to the user in some fashion. However, using exceptions is
problematic because of the need to support multiple programming
languages. There are 3 possible solutions:
A) Do nothing.
The code that allows a user to set an invalid value or add an object
with a mismatched level/version remains as it is currently.
BUT ...
we seriously encourage users to validate their internal respresentation
using the new checkInternalConsistency function.
B) No API change but set/add functionality altered
The existing API remains the same.
However, each SBase object has a flag mModificationFailed and a function
to return the value of this flag. The set/add functions reinitialize
this flag to false and then check the validity of the function to be
preformed. If the value being set is valid this is done, if setting the
value would produce invalid SBML then no change is made to the internal
value and the mModificationFailed flag is set to true.
e.g.
mModificationFailed = false;
if (value >= 0 && value <= 3)
spatialDimensions = value;
else
mModificationFailed = true;
A user could then query this flag following a set/add function to
determine whether the action was performed.
c->setSpatialDimension(4);
if ( c->modificationFailed() )
{
cerr << "Tried to set an invalid value in
Compartment::setSpatialDImension\n";
}
C) API and functionality change
All set/add functions currently return 'void'. The new API would change
the return type of all these functions to 'bool'.
e.g.
void setSpatialDimensions(int value);
would become
bool setSpatialDimensions(int value);
The code within the function becomes
if (value >= 0 && value <= 3)
{
spatialDimensions = value;
return true;
}
else
{
return false;
}
and to check the status
if ( c->setSpatialDimension(4))
{
cerr << "Tried to set an invalid value in
Compartment::setSpatialDImension\n";
}
====
There are obvious advantages and disadvantages to each of the above
solutions. Although solution A obviously requires the least work from
anyone, ourselves included, it does leave the issue outstanding.
Solution B should not impact anyone's existing code but the continued
reinitialization of the flag means that code checking this flag would
need to be extremely careful. Solution C does involve an API change;
but is consistent with the setLevelAndVersion function already within
libSBML.
We would be very grateful for any comments on the above.
Sarah, Akiya & Mike
____________________________________________________________
To manage your libsbml-development list subscription, visit
https://utils.its.caltech.edu/mailman/listinfo/libsbml-development
For a web interface to the libsbml-development mailing list, visit
http://sbml.org/Forums/
For questions or feedback about the libsbml-development list,
contact sbml-team@caltech.edu
|
|
|