Tags:
not added yet
Model development using OMS 3.0 (NGMF)This document describes a core concept and a reference implementation of a "Next Generation Modeling Framework" NGMF. This is a working title! The result of this research will be merged into the next generation of the Object Modeling System to provide a as the core runtime and execution environment. Keywords Modeling Framework, Non-invasive Framework, OMS Table of Contents
MotivationUsing frameworks for the development of scientific environmental simulation models became an important ???
Concepts
ComponentsThe concept of a component refersWhat is expected from a component modeling framework.
All of those functions have to be as easy as possible for a model developer. A first component example import ngmf.ann.*; @Description("Daylength computation.") (1) @Author(name="Joe Scientist") public class Daylen { (2) private static final int[] DAYS = { 15, 45, 74, 105, 135, 166, 196, 227, 258, 288, 319, 349 }; @In public java.util.Calendar currentTime; (3) @Role("Parameter") (4) @Range(min=-90, max=90) (5) @In public double latitude; @Range(min=9, max=15) @Out public double daylen; (6) @Execute (7) public void execute() { (8) int month = currentTime.get(java.util.Calendar.MONTH); double dayl = DAYS[month] - 80.; if (dayl < 0.0) dayl = 285. + DAYS[month]; double decr = 23.45 * Math.sin(dayl / 365. * 6.2832) * 0.017453; double alat = latitude * 0.017453; double csh = (-0.02908 - Math.sin(decr) * Math.sin(alat)) /(Math.cos(decr) * Math.cos(alat)); daylen = 24.0 * (Math.PI/2 - Math.asin(csh)) / Math.PI; } } Component MetadataAnnotations are being utilized to specify resources in a class that relate to its use as a component for NGMF. Such annotations might have different importance and relevance to different aspects of the use of the component within the framework. The same Annotations can also play different roles depending in the context use.
Why Annotations? Annotations are a Java feature since 1.5. They are an addon to the java language to allow for custom and domain specific markups of language elements. "They do not affect directely the class semantics, but they do affect the way classes are treated by tools" (??). Annotations allow for the extension of the Java programs with meta information that can be picked up from sources, classes, or at runtime. They respect also scopes and and are supported by Java IDE's with code completion and syntax higlighting. Meta Data Overview
@DescriptionThe description annotations takes a String argument that provides component description information, such as a brief abstract about its purpose, scientific background, etc.
@Description(“Circle Area Calculation.”) public class CircleArea { @Description (“Radius”) @In public double r; ... } The @Documentation annotation is being used for automatic capturing the purpose of a component for archiving, online presentation, database integration, and component selection during the process of model building. This is optional meta data. @AuthorThe optional Author annotation provides information about the authorship of the component. The annotation fields name, org, and contact will give more details. Author elements
@Author( name="Joe Scientist", org="Research Org", contact="joe.scientist@research-org.edu") public class HamonET ... } @BibliographyAttach a @Bibliography annotation to a component to refer to Literature background, Web sites that contain detailed documentation, etc. This annotation does have the same purpose like a Bibliography list in a scientific paper.Each reference is a separate string, multiple references are comma separated. This is optional metadata and can be used to document components. @Description(“Circle Area Calculation.”) @Bibliography(“Journal of Geometry, Vol.1, p..”) public class CircleArea { ... } @StatusComponent with status information. A status is a component quality indicator.@Description(“Circle Area Calculation.”) @Status(Status.TESTED) public class CircleArea { ... } Component have an optional status. A developer can specify the level of completeness or maturity of a component with this tag. Predefined values DRAFT, SHARED, TESTED, VALIDATED, CERTIFIED This is optional metadata and can be used to classify, verify stored components in a repository @VersionInfoThe VersionInfo annotation takes one string argument that represents the version of this component. A developer might use version control supported keyword substitution for this. The example below shows the use of the Subversion keyworks $Id to provide revision number, modification time, and committer name as version information. @VersionInfo(“$Id: ET.java 20 2008-07-25 22:31:07Z od $”) public class ET { } @VersionInfo might contain more than just a number. Version control systems such as CVS, Subversion, or Mercurial provide keyword substitution that present revision number, last modification time, or developer id. @VersionInfo is optional but is good practice. Component repositories can use and present this information @SourceInfoThe SourceInfo annotation captures information about the source. This should be some hint about aource availability, maybe the source location or some contact information. The example below shows the use of subversion's keyword substitution for the head Url of a source file. This can also point to a specific tagged version with a repository.@SourceInfo(“$HeadURL: http://www.test.org/repo/ET.java $”) public class ET { } @SourceInfo provides some link to the source. Version control systems such as CVS, Subversion, or Mercurial provide keyword substitution that fills in the Repository URL. @SourceInfo is optional. Component repositories can use and present this information @KeywordsTag the Component with the @Keywords annotation to characterize it. This annotation does have the same purpose like a Keyword list in a scientific paper. This is optional metadata and can be used to index, search, and retrieve archived and stored components. It is optional meta data.@Description(“Circle Area Calculation.”) @Keywords(“Geometry, 2D”) public class CircleArea { ... } @LabelSimple Example component with label information. Labels relate to ontologies (label is an OWL annotation)public class Calc { @Label(“latitude”) @In public double lat; ... } Labeling a field or component offers alternative names. Labels might be used to relate components or fields to ontologies. Labels are optional. @InThe In annotation on a field specifies it as input to the component. The field has to be public as noted earlier. This that within the Execute method there is read access to the field.... @In public double latitude; ... @OutThe Out annotation on a field specifies it as output of the component. The field has to be public and the Execute method will write to this. NGMF used uses this field annotation to connect to another In field of another component.@Out public double daylen; @RangeThe Range annotation is supporting meta data for an In or an Out field. If present it defines a min/max range in wich the value of the field is valid. It is up to the execution runtime to handle the range information. Violating ranges might lead to execution abortion or just a warning message. Another use of the range information would be in component testing.@Range(min=-90, max=90) @In public double latitude; In the example above the latitude value can only be in the range of -90 to +90. @RoleThe Role annotation gives an In or Out tagged field a certain meaning within the modeling domain. This allows someone who reads the component source code or is using a builder tool that respect this annotation to present categorized views on field data. Such categories might be "Parameter", "Variable", "Output", "Input", and others. The Role annotation takes the category as a String parameter. categories can be freely defined.@Role("Parameter") @Range(min=0, max=90) @In public double latitude; Now the latitide field is "tagged" as Parameter. @UnitA @Unit annotation attached information about a physical unit to a component field that is tagged as In or Out.public class Calc { @Unit(“degree”) @In public double latitude; ... } Unit information for IO fields Usually used for scalars and arrays. Allows frameworks to support unit checking/validation and conversion Optional Meta data. @BoundA bound defines a binding to another field. This could be a dimension for an array. public class ET { @Bound(“nsim”) @In public double[] jh_coeff; @In public int nsim; ... } A Bound annotation takes a string argument. It allows a GUI to present dependencies between fields. This is optional meta data. Jh_coeff has the named dimension nsim. @ExecuteThis method provides the implementation logic of the component where the input is being transformed to output.public class Component { @Execute public void executemethod() { // execute code here } } Name the execution method any name you want, but annotate it with @Execute The execute methods has to be non-static, public, void, no arguments. This is required meta data! @InitializeIn this method the internal state of a component should be initialized. (e.g. opening a file for reading) public class Component { @Initialize public void start() { // initialization code } } Name the execution method any name you want, but annotate it with @Initialize The init methods has to be non-static, public, void, and has no arguments. This method gets called once after Component instantiation and before the first execution. This is optional meta data. @FinalizeThis method provides the notion of a final cleanup after model execution (e.g. closing a DB connection) public class Component { @Finalize public void cleanup() { // execute code here } } Name the finalization method any name you want, but annotate it with @Finalize The method has to be non-static, public, void, and has no arguments. Finalize overlaps with Java’s finalize() method that gets called from the garbage collector. This is optional meta data Metadata RepresentationThe following sections introduce Embedded Metadata using Annotationsimport ngmf.ann.*; public class Daylen { static final int[] DAYS = { 15, 45, 74, 105, 135, 166, 196, 227, 258, 288, 319, 349 }; @Range(min=6, max=18) @Out public double daylen; @In public Calendar currentTime; @Role(“Parameter”) @Range(min=-90, max=90) @In public double latitude; @Execute public void execute() { int month = currentTime.get(Calendar.MONTH); double dayl = DAYS[month] - 80.; if (dayl < 0.0) dayl = 285. + DAYS[month]; double decr = 23.45 * Math.sin(dayl/365.*6.2832)*0.017453; double alat = latitude*0.017453; double csh = (-0.02908 - Math.sin(decr) * Math.sin(alat)) /(Math.cos(decr) * Math.cos(alat)); daylen = 24.0 * (Math.PI/2 - Math.asin(csh)) / Math.PI; } } Attached MetaData using AnnotationsThe following Listing show a alternative implementation of the Daylen component. It was split into two parts, (i) a pure computational component class Daylen.java and (ii) the component metadata class DaylenCompInfo.java . Only the latter one now has meta data dependencies to NGMF. DaylenCompInfo.java import ngmf.ann.*; public abstract class DaylenCompInfo { @Out @Range(min=6, max=18) public double daylen; @In public Calendar currentTime; @In @Role(“Parameter”) @Range(min=-90, max=90) public double latitude; @Execute public abstract void execute(); } As a rule, an attached component metadata class has the same name like the compoment but ends with CompInfo. This class has to be public and abstract. It duplicates all the relevant fields and methods that should be annotated for NGMF. The methods should all be abstract. It is important to use the same spelling for fields and methods. Daylen.java public class Daylen { static final int[] DAYS = { 15, 45, 74, 105, 135, 166, 196, 227, 258, 288, 319, 349 }; public double daylen; public Calendar currentTime; public double latitude; public void execute() { int month = currentTime.get(Calendar.MONTH); double dayl = DAYS[month] - 80.; if (dayl < 0.0) dayl = 285. + DAYS[month]; double decr = 23.45 * Math.sin(dayl/365.*6.2832)*0.017453; double alat = latitude*0.017453; double csh = (-0.02908 - Math.sin(decr) * Math.sin(alat)) /(Math.cos(decr) * Math.cos(alat)); daylen = 24.0 * (Math.PI/2 - Math.asin(csh)) / Math.PI; } } There are pro and cons for using embedded and attached component metadata. External meta data enables clean and neutral computational components parts with no framework dependency. However, two separate files have to be managed and have to kept in sync while doing component development. Attached meta data using XML@Range(min=10, max=20) <xmlns:temp="http://oms/tmp"> <xmlns:latitude="http://oms/tmp"> <temp:Range min='10' max='20'/> <temp:Description> Temperature </temp:Description> Execution Concepts and ListeningUnit ConversionExecution LoggingIntegrationsRunning the model as a Webservice (JAX)Modeling Framework interoperability (OpenMI, OMS)Cluster Execution (Terracotta)Running the model in a Compute Cloud (EC2)Component Testing (JUnit)Accessing native code in Fortran/C (JNA)This sections demonstrates the integration and access of libraries written in languages other than Java into the system. In the scientific community common languages are C/C++/Fortran; Python is emerging. The approach used here is using the JNA library (Java Native Interface). It does not belong to NGMF, however it offers an appealing simplicity and transparency for its use in a framework.The Example below shows a Fortran implementation of HamonET. It is actually using the Fortran 2003 BIND and VALUE keyword. ! ! File: ftest.f90 ! Author: od ! FUNCTION potET(daylen, temp, days) BIND(C, name='hamon') REAL*8,VALUE :: daylen,temp INTEGER*4,VALUE :: days REAL*8 :: potET REAL*8 :: Wt,D2 Wt = 4.95 * exp(0.062 * temp) / 100.0 D2 = (daylen / 12.0) * (daylen / 12.0) potET = 0.55 * days * D2 * Wt print *, Wt if (potET <= 0.0) then potET = 0.0 endif if (temp <= -1.0) then potET = 0.0 endif potET = potET * 25.4 END A Java Component is still required. But it now more lightweight and proxies ot the Fortran function only. As defined by JNA the Java code binds directely to a Dynamic Linked Library (Dynamic Shared Object) on any major OS with a simple Java interface. No JNI source generation or some othere source bridge building is required. You need to create the DLL with your favorite IDE or just a makefile. import com.sun.jna.Library; import com.sun.jna.Native; import ngmf.ann.Execute; import ngmf.ann.In; import ngmf.ann.Out; import java.util.Calendar; public class HamonET { // the number of days per months final static int[] DAYS = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; @In public double temp; @In public double daylen; @In public Calendar currentTime; @Out public double potET; // Interface binding interface ETLib extends Library { (1) double hamon(double daylen, double temp, int days); } // mapping the ETLib interface to "libF_ETLib.so" or "F_ETLib.dll" ETLib etlib = (ETLib) Native.loadLibrary("F_ETLib", ETLib.class); (2) @Execute public void executeNative() { int month = currentTime.get(Calendar.MONTH); potET = etlib.hamon(daylen, temp, DAYS[month]); (3) } }
The C version of the very same HamonET is shown below. Within the HamonET Java component, only the name of the Library needs to be changes, the binding interface and its use in Java will remain the same. /* * File: testc.c */ double hamon(double daylen, double temp, int days) { double Wt = 4.95 * exp(0.062 * temp) / 100.; double D2 = (daylen / 12.0) * (daylen / 12.0); double potET = 0.55 * days * D2 * Wt; if (potET <= 0.0) { potET = 0.0; } if (temp <= -1.0) { potET = 0.0; } potET *= 25.4; return potET; } For further details on how to manage Java and DLL/Shared Objects see this manual. Conclusions
References and Further Reading
|
Navigation Bar for Object Modeling System
Resources:
Downloads You must login to see this link. Register now, if you have no user account yet. OMS API Javadoc Publications & Presentations Annotation Reference DSL Reference Handbook 3.0 (Draft) Frequently Asked Questions (FAQ) OMS License (LGPL 2.1) New Users: 1. Get an ALM account 2. Join the OMS project Contact Us: Jack Carlson Coordinator, OMS Laboratory OMS Laboratory Jack.Carlson@colostate.edu (970) 492-7323 Olaf David Director, OMS Laboratory odavid (at) colostate.edu (970) 491-8026 |