Getting started with the CellML API
This guide provides assistance to developers who may wish to use the CellML API from their applications.
Why use the API Implementation?
Providing CellML support for your application means that saved models will be able to be used with a wide range of software, and can be shared with other groups also using CellML compliant software, and in addition, your users will be able to work with models they receive from other groups.
The CellML API provides a core API for manipulating CellML, and a number of services designed to make supporting CellML easier. Not all CellML applications will benefit from the API, but CellML can be difficult to process correctly, and so for many applications, using the API will mean that a wider range of models can be supported using less effort.
Obtaining the API Implementation
The CellML API Implementation is Free / Open Source software, and the development process is open; it is possible to see all bug reports and change requests and change history, and obtain changes as soon as they are pushed to our main repository. Therefore, if you want the very latest source code (which is not even guaranteed to compile) to test yourself, you can use Mercurial to clone the repository from http://cellml-opencell.hg.sourceforge.net/hgroot/cellml-api/cellml-api
However, many users will prefer to use a designated release version. The release cycle for the CellML API is 3 months, but can be delayed from the 3 month guideline for various reasons. When a release is made, both the source code and binaries for various platforms are packaged up. The API can be downloaded from http://www.cellml.org/tools/downloads/cellml_api/.
What platforms is the API Implementation supported on?
The API Implementation uses autoconf and aims to be portable to all POSIX systems; it is known to work on a number of different 32 and 64-bit systems.
Binaries of the API Implementation libraries are provided for x86 (32 bit) Linux, built using a recent gcc, Windows (32 bit), and Intel Mac (32 bit) in a special SDK package (which also includes the required headers).
What languages can my application that works with the API Implementation be in?
The API itself is written in C++, and so C++ applications can directly access the API. In addition, bindings provide access to the full API from Python and Java.
Because the API is described in IDL, it shouldn't be hard to write code to generate bindings to another language; if you do this, please let us know how you get on and share your code so it can be included with the API implementation!
What external dependencies are required?
Some of the external libraries used (for example, SUNDIALS) are already linked into the CellML API binaries, but others are not.
To use the CellML API, you will always need an external libxml2 implementation; most Linux users should have all the required shared libraries if they have installed the libxml2 binaries from their distribution. Mac OS X users should be to use the system libxml2. Windows users can download a suitable libxml2 DLL from http://www.cellml.org/tools/api/libxml2.dll/at_download/file. Alternatively, build libxml2 from source; you can get the source at http://xmlsoft.org/.
To run simulations, the CellML API will try to generate C code for the model and compile it with gcc, so you must have a gcc that produces working executables in the path if you want to be able to run simulations. If you don't need to run simulations, not having gcc installed won't cause any problems.
What is an example of a simple but working C++ program?
// For the CellML API 1.9, instead include Utilities.hxx
#include "cellml-api-cxx-support.hpp"
// This is the standard C++ interface for the core CellML API.
#include "IfaceCellML_APISPEC.hxx"
// This is a C++ binding specific header that defines how to get the bootstrap
// object.
#include "CellMLBootstrap.hpp"
int
main(int argc, char** argv)
{
// Fetch a bootstrap object. The bootstrap object is a special 'root' object
// from which you can get at everything else. CreateCellMLBootstrap() is a
// C++ binding specific method, which fetches the CellMLBootstrap object.
// It is the only non-OO method that you should ever call from the CellML
// API.
// Note that RETURN_INTO_OBJREF is a macro from Utilities.hxx. It is creating
// a variable called cbs, and assigning into it. CreateCellMLBootstrap
// returns iface::cellml_api::CellMLBootstrap*. We could assign this directly
// into a variable. We would then have to call cbs->release_ref() to release
// the object when we have finished with it. The ObjRef<> template does this
// for us, so there is no chance we will forget to clean up on a certain
// exit path.
RETURN_INTO_OBJREF(cbs, iface::cellml_api::CellMLBootstrap,
CreateCellMLBootstrap());
// Now would be a good time to see what methods we can call. In the
// CellML_DOM_API source, find interfaces/CellML_APISPEC.idl.
// This defines the interfaces you can call. Search down to find
// this text...
/*
interface CellMLBootstrap
: XPCOM::IObject
{
...
*/
// We want to load a model, so we want the modelLoader attribute. We fetch
// the attribute like this...
RETURN_INTO_OBJREF(ml, iface::cellml_api::DOMModelLoader, cbs->modelLoader());
// Start a try, because we might get an exception...
try
{
// We now have a DOMModelLoader, stored in ml. DOMModelLoader inherits from
// ModelLoader, which defines a loadFromURL operation (check in the IDL).
// Be warned that is a synchronous (blocking) load. In a real application,
// you are probably better to download the file using another asynchronous
// http library, and then creating the model from the serialised text.
RETURN_INTO_OBJREF(model, iface::cellml_api::Model,
ml->loadFromURL(L"http://www.cellml.org/models/beeler_reuter_1977_version04/download"));
// Fetch the models cmeta:id (there obviously lots of other things we could
// do here!)
RETURN_INTO_WSTRING(cmid, model->cmetaId());
printf("Model's cmeta:id is %S\n", cmid.c_str());
}
// Most parts of the CellML API raise this exception. The DOM/MathML API, on the
// other hand, raises iface::dom::DOMException.
catch (iface::cellml_api::CellMLException& e)
{
// Unfortunately, due to the need to support the 'lowest common
// denominator' of functionality in our bindings, exceptions can't have
// supplementary information (to suit XPCOM). However, many classes have
// a way to get the last error, e.g. lastErrorMessage on ModelLoader.
// However, threadsafety is potentially an issue with this.
RETURN_INTO_WSTRING(msg, ml->lastErrorMessage());
printf("Got a CellML Exception loading a model. Error was %S\n",
msg.c_str());
return 1;
}
return 0;
}
Save this file in a directory by itself. Extract the CellML API for Linux as well:
tar -xjf cellml-api.tar.bz2 -C /usr/share
Now, compile the program against the CellML API:
gcc -Wall -ggdb ./api_usage_example.cpp -I/usr/share/cellml-sdk/include \
-L/usr/share/cellml-sdk/lib -lcellml -o api_usage_example
If you were building a more complex program, you might also use other libraries, such as one of the extension API libraries; in this case, only libcellml.so.0 is used.
As long as this file is in the dynamic linker path, the program should run:
$ LD_LIBRARY_PATH=/usr/share/cellml-sdk/lib/ ./api_usage_example Model's cmeta:id is beeler_reuter_1977_version04
On Mac OS X, usage is similar (but make sure you use the Mac OS X SDK and not the Linux one); the last command should be:
DYLD_LIBRARY_PATH=/usr/share/cellml-sdk/lib/ ./api_usage_example
On Windows, using MSVC9, this works (from the Cygwin shell with paths to cl set up correctly - adjust for whatever environment you are using):
cl /EHsc /wd4091 ./api_usage_example.cpp /I../cellml-sdk/include/ \ /link ../cellml-sdk/lib/libcellml.lib /out:api_usage_example.exe PATH=../cellml-sdk/lib ./api_usage_example.exe
What is an example of a simple Java program?
The following example shows how to use the API from Java:
Create a directory simple_java_example, and in that directory, then create SimpleJavaExample.java with the following contents (note - for CellML API 1.9 and earlier, the System.loadLibrary call should be System.loadLibrary("cellml_java_bridge"):
import cellml_api.*;
public class SimpleJavaExample
{
public static void main(String[] args)
{
new SimpleJavaExample().doExample();
}
public void doExample()
{
System.loadLibrary("java_cellml");
CellMLBootstrap bs = cellml_bootstrap.CellMLBootstrap.createCellMLBootstrap();
DOMModelLoader dml = bs.getModelLoader();
Model m = dml.loadFromURL("http://www.cellml.org/models/beeler_reuter_1977_version04/download");
System.out.println("Model's cmeta ID: " + m.getCmetaId());
}
};
javac -cp /usr/share/cellml-sdk/lib/cellml.jar SimpleJavaExample.java LD_LIBRARY_PATH=/usr/share/cellml-sdk/lib java \ -Djava.library.path=/usr/share/cellml-sdk/lib \ -cp /usr/share/cellml-sdk/lib/cellml.jar:. \ SimpleJavaExample
All going well, the model's cmeta ID should be printed. A very similar process should work on all the other platforms if you adjust the paths to follow the expected format for that platform; instead of LD_LIBRARY_PATH, use DYLD_LIBRARY_PATH on Mac and just PATH on Windows (but make sure java stays in the PATH too).
Where can I find documentation for the exact functions that I can call on the API implementation?
Refer to http://cellml-api.sourceforge.net/ or look in the IDL files in the interfaces subdirectory of the source tree for full documentation on what all the API functions do.


