Extracting Library Statistics using OPTIMICA Compiler Toolkit APIChristian Winther
Have you ever wondered how many components, functions and models are in your library? Modelon’s OPTIMICA Compiler Toolkit has the capability to enable users to retrieve any essential information using the compiler API.
This blog introduces the OPTIMICA API – along with its purpose, functionality, and highlights how it can be used to compute library statistics.
OPTIMICA API Introduction
The OPTMICA API is a set of methods which are designed for users to interact with Modelica models and libraries. The purpose of the API is to: 1) support extensions on top of OPTMICA, such as editors, and 2) support customizations and exclusive use cases where there is necessary to directly interact with a Modelica compiler.
Through the API, a user can browse through the variables and components in a model or library, compile FMUs, browse through annotations and connect equations, render icons and much more. The API can additionally handle authentication and authorization for using together with encrypted libraries.
OPTMICA is written in Java and thus the native interface, using the API, is through Java. It can be used in other languages through Java interfaces that are commonly available.
Using OPTIMICA API
So how does it work? To start working with the API we need to create a new instance of the API class which we then use to load Modelica libraries (or single models).
Once the library is loaded we can start working on the library, retrieve the models, browse through the packages etc. Compiling an FMU can be easily achieved by,
This will compile the model to an FMU in the current directory. The returned object can be used to retrieve specific data and information that was generated during the compilation process, such as log messages and paths to the FMU.
One key feature is to start from a Modelica class (package or model for instance) and investigate what it contains. Consider a Modelica package outlined as follows,
To investigate this package, there are two different “trees” that can be used, the source tree and the instance tree. It is important to understand the difference between the two and in which situations the respective tree should be used.
- The source tree, reflects the structure of the parsed Modelica file and very little semantic interpretation has been done. It is not possible to resolve variable references nor compute the value of expressions in this tree. Instead the intent is that this tree will be used to retrieve structural information about Modelica files and libraries.
- The instance tree, enables a large amount of semantic interpretation to be done and can resolve variable references and determine the value of expressions. It also handles and resolves modifications and redeclares. Because it supports these operations, the instance tree also allows exploration of components and its contents, e.g. it is possible to list the subcomponents in a non-primitive component. This makes this tree ideal for retrieving information about a specific model.
To access either the source or instance tree and start investigating the model, either of the below can be used.
To view the children of the source class, we list them using (source/instance)Class.getElements() and from there we can continue to dig deeper down in the model.
Computing Library Statistics
So, what about the statistics? To compute the statistics, we need to loop over all the elements in a package and recursively go deeper down in the hierarchy and count all occurrences of packages, models, functions and blocks. We start from the top-level package, which in this case is MSL.
The top-level packages are retrieved using,
These are then iterated over using,
The method countStructureRecursive is a method that contains this loop, the map libraryStatistics contains the statistics about the library and is populated before the loop for each specialization (model, function, block etc).
Essentially, this is all that is necessary to compute the statistics of a library. For all details I refer to the provided file which contains the complete program.
So, with the above we compute for MSL (v. 3.2.2 build 3):
From the above, we note that there have been a few updates in the library since the statistics was updated on Modelica.org which lists about 1350 functions.
Want More Information?
This blog briefly touches upon what the capabilities are and what can be achieved using the compiler API. More documentation regarding the API is available in the users-guide that is included in the OCT installation.
For now, the focus of the API has been on collecting information about models and libraries, not on manipulating models. We are though continuously increasing the scope of the API and adding new functionality.