PrepIFS GUI client

 

Graphical user interface functionality.

Description of features for defining configurations.

Version 1.0

Revision History

Date

Version

Description

Author

25 Apr 2002 1.0 Draft C. Larsson
19 Apr 2005 1.0 Main C. Larsson
15 Oct 2005 1.1 Main C. Larsson

Table of contents

  1. Introduction
  2. Terminology
  3. Input to the system
  4. Output from the system
  5. Composition Constraints
  6. How to write checks, internal representation and addressing
  7. Existing Dynamic libraries
  8. Existing Static libraries
  9. Writing your own libraries
  10. Making it work

Introduction

This document is intended as an introduction for a model developer in how to use PrepIFS to configure his model. It explains the hierarchy of experiments at ECMWF and how the tool can help the modeller and the user to compose a correct setup.

Terminology

The general hierarchy of an experiment is as follows:


Experiment
   !
   !--- ExperimentType X  (forecast, analysis  etc)
   !
   !--- ExperimentType Y
   !
   !--- ExperimentType Z
             !
             !
             !---NameList A  (Archiving, post-processing etc)
             !
             !---NameList B
             !
             !---NameList C
                    !
                    !
                    !---------Configurable variable I (Archive name, days2run, etc)
                    !
                    !---------Configurable variable J
                    !
                    !---------Configurable variable K
                    !
                    !---------Configurable variable L

		  
The word ``variable'' refers to an object in the GUI applications data model representing any configurable variable in the experiment. Also referred to as making up the fact base

The word ``namelist'' refers to a collection of variables with related functionality.

The word ``experimenttype'' refers to a collection of name lists representing a configuration of a type of experiment such as a forecast model.

A ``check'' and ``checking'' means the interpretation of a series of rules by the Verifier engine returning the result as 0 or 1, true or false.

The ``Verifier'' is the software component responsible for translating and executing the rules of the check, the rules engine.

By ``defaults'' we mean the set of configurable variables created by the modeller/author for his model and the values they are given initially. These values together with a rule definition file makes up a valid configuration, i.e. one that will deploy correctly.

The experiment hierarchy is subject to change in the PRISM project.

Input to the system

The PrepIFS application reads files specifying the variables to configure(A) and the values the user specified for these variables(B). The PrepIFS application writes files with the values specified by the user (B) and files needed for deployment of the model (C).

PrepIFS input and output files
PrepIFS input and output files
Figure 1


In the document the person that creates the files (A) specifying the variables to configure is the author and the person who configures the variables,i.e. the user, is termed the composer.

PrepIFS composition
PrepIFS composition
Figure 2


The file A contains information on every variable to configure. The information is declared as elements in the XML file. A special element guiattribute is optional and can add a specific behaviour for the variable. In the GUI each variable is treated as an object and the properties are the object attributes.

An example from a defaults file is given below:
<?xml version = "1.0"?>
<?xml-stylesheet href="./namelist-html.xsl" type="text/xsl"?>
<?cocoon-process type="xslt"?>
<?xml-stylesheet type="text/css" href="../namelist.css"?>
<modelnamelist
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns="http://www.ecmwf.int/services/prepifs/"
  xsi:schemaLocation="http://www.ecmwf.int/services/prepifs/   ../NameListSchema.xsd"
  name= "Archiving">
        <!-- -->
<description>Archive parameters
</description>
         <!--  -->
<dependency><xhtml:a xhtml:href="VariationalAnalysis.xml"> Variational Analysis<
/xhtml:a>,<xhtml:a xhtml:href="Forecast.xml"> Forecast</xhtml:a>
</dependency>
         <!-- -->
<info>Unless data is archived to MARS, it cannot be accessed once it has been deleted from
thefields data base.
</info>
         <!-- -->
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<ionamelist>
   <type>STRING</type>
   <name>FILEFORMAT</name>
   <default>Archiving</default>
<label><![CDATA[Archiving]]></label>
 <description>FILEFORMAT</description>
 <dependency> any depend </dependency>
       <guiattribute key="COMMENT">Archive parameters</guiattribute>
      <guiattribute key="FILEOUT">config.h</guiattribute>
      <guiattribute key="FORMAT">ShellFormat</guiattribute>
      <guiattribute key="VIS">false</guiattribute>
      <guiattribute key="WRITE">false</guiattribute>
</ionamelist>
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<ionamelist>
   <type>BOOLEANWORD</type>
   <name>DO_ARCHIVE</name>
   <default>true</default>
<label><![CDATA[Archive fields to MARS]]></label>
 <description>DO_ARCHIVE is the highest level archiving control switch.
If DO_ARCHIVE=false,no MARS archiving will be done, even if the other archiving switches
are set to true. DO_ARCHIVE also controls all the data assimilation archiving, apart
from the long forecasts, ie <xhtml:a xhtml:href="Forecast.xml#FCLENGTH"> 
FCLENGTH</xhtml:a> > <xhtml:a xhtml:href="VariationalAnalysis.xml#PERIOD_4D"> 
PERIOD_4D</xhtml:a>
</description>
 <dependency> any depend </dependency>
       <guiattribute key="FILEOUT">config.h/sms_def</guiattribute>
      <guiattribute key="FORMAT">ShellFormat/SMSFormat</guiattribute>
</ionamelist>
<check><![CDATA[(this.sizeOfVector("PPSTEPS")<=1)?(BRF=PPFRQ)]]></check>
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
</modelnamelist>
		
All variables have a name and a type. The types of variables are matched to how we like them to be displayed in the gui.All variables of the same type are displayed the same, the author has no control over how the variable is displayed. This ensures that the composers will encounter a uniform user interface.

The current set of objects used to configure the variables are linked to the use of the variables: FORTRAN,shell and SMS configurations. The following types exists:

Table of data types
Type Displayed as
BOOLEAN Basic boolean displayed as true false
BOOLEANINT Boolean displayed as 1/0
BOOLEANTF Boolean displayed as On/Off
BOOLEANTFDOT Boolean displayed with dot delimiters
BOOLEANWORD Boolean displayed as a choice of two strings
DATE Date displayed as string
FLOAT Decimal value displayed as string
FORMSTRING Strings displayed as checkboxes
INTEGER Integer displayed as string
LONG Double precision displayed as text field
SELECTNUMBER Select between a range of numbers
SELECTSTRING Select between a range of strings
STRING String as text field
STRUCT Allows composition of any variables into a table row as in excel
STRUCTLIST Allows composition of any variables into a 2 d table as in excel
ARRAY Appending this to a basic type will make an array of the type,e.g. STRINGARRAY
Table 1


The types are rendered as in the figure below:

Displayed types in prepIFS
Displayed types in prepIFS
Figure Summary Displayed types in prepIFS


The file used to render the above configuration looks like this

Specific variations of a basic type such as INTEGER is made by extending the basic type with the required behaviour.

New types can be added by providing a java class with the required interface. The importance of the type lies in how basic validity checking is performed automatically, how values are assigned internally and how they are displayed on the screen. The output of a value is decoupled from the type and explained in the next section.

Other properties of a variable that are not required are:

Table of variable properties
Property Description
FILEOUT Which file(s) is the variable written to.
CHANGEABLE Can the user change change the variable?
COLUMNSIZE Size if variables are displayed in a table.
COMMENT The extended help text in the user interface
DEFAULT The default value of the variable
ENFORCE The variable will have any assignment rule from the check enforced.
FORMAT Specific output format for a variable in a file.
HIGHRANGE The highest value a variable is allowed.
HTML An explicit html href to be displayed if the variable is clicked.
LABEL The Short text for the variable in the GUI
LOWRANGE The lowest value a variable is allowed.
PRIORITY Flags the namelist name background in blue
RANGE A discrete range of values the variable can take.
RANGELABEL How the above ranges are displayed in the GUI.
READONLY This variable is never saved with the experiment.
SAVEONLY This variable is not visible but always saved with the experiment
STRLEN The maximum length of a string to be displayed
VIS Is variable visible to the user?
Table 2

Output from the system

Output of variables to files is directed by a special variable in the namelist, i.e. grouping of variables named FILEFORMAT. This variable defines the default file and format of all variables in the namelist and also the heading displayed in the GUI for the namelist.
Here is an example:

 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<ionamelist>
   <type>STRING</type>
   <name>FILEFORMAT</name>
   <default>Archiving</default>
<label><![CDATA[Archiving]]></label>
 <description>FILEFORMAT</description>
 <dependency> any depend </dependency>
      <guiattribute key="FILEOUT">config.h</guiattribute>
      <guiattribute key="FORMAT">ShellFormat</guiattribute>
      <guiattribute key="VIS">false</guiattribute>
      <guiattribute key="WRITE">false</guiattribute>
</ionamelist>
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
		
As short explanation of the attributes:
  • FILEOUT - Output file name for variables
  • FORMAT - Variables are written in Unix Shell format
  • LABEL - Heading displayed on GUI screen for this namelist
  • VIS - Don't show this variable to the user (=FALSE)
  • WRITE - We dont want the values of the variable written anywhere (=FALSE)


If other variables needs to go to other files or to more than one file these can be specified by adding the FILEOUT and FORMAT properties to the variable in question.

All formats implement the interface FormatTypeInterface. Currently the following formats are implemented:FORTRANFormat,SMSFormat and SHELLFOrmat. An example of a real file used at ecmwf is here: Dates.xml

Composition constraints

The GUI tries to limit the user input at composition time in two ways:

  1. In the GUI representation, for example a text field, checks are made on characters entered for integer types, dates etc.
  2. When a the composer leaves a hiearachy, such as a model component he can activate a constraints check on the values he has entered. This check will be activated automatically when he tries to submit the experiment but it is available as a manual option always.

To make sure that the experiment later submitted does not have conflicting options or simple typographical errors we apply consistency checking routines. These routines tests the validity of the configuration of the experiment as a whole.

The enforcement of constraints takes the form of an execution of a number of rules that the developer or administrator has designed to make sure that the configuration is consistent and correct at every level in the hierarchy.

Definition of constraints for the composition

The rule base

The constraints, we call them checks, are defined in files named ``*.check'',i.e. an.check. They are partitioned on the hierarchy level which is associated with the activation strategy for a rule but also to allow the separation of rules for different types, cycles etc. There is a rule file for the the cycle, experiment type and the Namelist.xml file as can be seen here.In the namelist files the declaration format is enclosed in xml markup but in the hierarchy files a simpler format is used. Their location is defined by the property DEFAULTSHOME (see the property table). The rules consist of a left hand side (LHS), the "if" part and a right hand side (RHS), the "then" part. The rules in PrepIFS are forward-chained, i.e. they are executed sequentially with the RHS firing if the LHS is true. The rules engine does not try to fire rules actively. An important aspect of rule writing is to make the rules reentrant so that no matter how many times they are activated the resulting composition will always be correct. Constraints are called checks in PrepIFS.

At ECMWF the rule base today consists of around 1000 rules.

The fact base

PrepIFS's working memory contains the facts on which the rules operate. The facts in this case is what makes up the composition, i.e. all the variables and their values in all namelists for all experiment types. This can be, for a forecast type for example, around 700 variables. For a full experiment roughly 4000 variables. Added to this there is a dictionary for storing messages in different languages, see the property table The addressing scheme for the facts is explained later, in addressing.

Below are examples of checks that will be referred to throughout this text.


Line numbers are inserted for later reference.


1 (($STATUS=-1)&&($ERR=$AN_FC_INCONSISTENT_RESOLWARN));
2 (an@Forecast@RUN_GFC=="true")?((fc@namnmi@LNMIRQ="false")&&(fc@namini@NEINI="0"));
3 (an@Forecast@RUN_GFC=="true")?((an@Archiving@LRHLP=fc@archive@LRHLP)&&
4 (an@Archiving@LRPLP=fc@archive@LRPLP)&&
5 (an@Archiving@LRSUP=fc@archive@LRSUP)&&
6 (an@Archiving@LRPVP=fc@archive@LRPVP)&&
7 (an@Archiving@LRPTP=fc@archive@LRPTP));
8 (fc@wavgeneral@WAVE != an@wavgeneral@WAVE)?(this.addCheckWarning($AN_FC_INCONSISTENT_WAVE));
9 ( ppgeneral@ETA = ecmwf.pifs.checkPrepIFS.CheckUtils.makeList(1.0,general@LEVELS,1.0));


		  
Checks are specified using the PrepIFS check language which is very similar to writing expressions in C or Java as can be seen above.

Syntax of the language

The syntax of the language is :


  ( expr1 )  ? (expr2) [ : (expr3) ] ;

  { expr1 }  ? (expr2) ;

  or in words :

  if expr1 then expr2 else expr3

  or

  while expr1 do expr2
 
		  
  • Note: The semicolon must be there to indicate end of statement
  • Note: The else clause can be left out
  • Note: The expr1 in the while clause should be deterministic. Make sure it is ...

Expressions

The expression is an expression as in Java or C supporting the following operators:

Table of operators
Symbol Operator
+ UNARY ADD
+ BINARY ADD
- UNARY SUB
- BINARU SUB
* MUL
% REMAINDER
/ DIV
>= GREATER EQUAL
> GREATER
<= LESS EQUAL
< LESS
== EQUAL
= ASGN
!= NOT EQUAL
! NOT
|| RELATIONAL OR
&& RELATIONAL AND
Table 3


Added to the operators is the ability to call functions in the experiment object or from static libraries.

How to write checks, internal representation and addressing

Writing checks you have access to two kinds of symbols.

  • Variables in namelists. These are type safe.
  • Variables in the property table. These are all untyped (strings).

Experiment values

Variables in the namelists are the ones you want to check. Internally all variables are typed to numeric ones (floats) or texts (strings). The typing mechanism prevents assignments between the two. The types mapped are the following :

Table of type assignments
Type Representation
boolean text
integer float
long float
string text
Table 4


All types support vector arithmetic automatically and checks are performed on the existence of indices. Indices start at 0. Operations involving vectors of different size are not permitted. When setting a value for a vector each index is separated with a slash (/).

       Example with integer array IA.
       IA=2/4                        -> 2/4
       IA=IA+IA                      -> 4/8
       IA[1]=1                       -> 2/1
       IA=this.MakeListOfFiveVariables() -> 1/2/3/4/5
       IA=IA+3                       -> 5/7
		

Property table

Table of client properties
Name Default Description Use
USERLEVEL "novice" Level of experience of the user Read only
WARN "" Warning message Write
ERR "" Error message Write
STATUS 0 Check status Write
INFO "" Info message Write
DEBUGCHECKS 0 Debug on/off Write for testing
DEFAULTSHOME /home/rd/rdx/defaults Defaults dir System use
system@BINPATH /home/rd/rdx/bin/prepifs Path to bin System use
GUISETTINGS .gui_settings.properties GUI settings System use
SAVEXTENSION /prepifs/saves Saves dir System use
SAVEFILE setup.save File name System use
BUFFER /tmp/.pifsSaves Tmp diff directory System use
OUTPUTFILE setup.listing Outfile System use
DBMETAPATH /cc/share/prepIFS/dbmeta Meta dir System use
HTMLROOT /PrepIFSdocs Document root System use
HTMLSOURCE /source Source root System use
HTMLIFS /ifs/source/namelist IFS documentation directory System use
HTMLEXTENSION .h.html html extension for documentation pages System use
DATE_WAVE 1998012012 Date with specific meaning for setup System use
DATE_IFS 1994030112 Date with specific meaning for setup System use
DATE_3DVAR 1996013012 Date with specific meaning for setup System use
DATE_GPQ 1995040312 Date with specific meaning for setup System use
DATE_48 1993080412 Date with specific meaning for setup System use
DATE_NEWCLIM1 1998040112 Date with specific meaning for setup System use
DATE_L50 1999030912 Date with specific meaning for setup System use
DATE_L60 1999101212 Date with specific meaning for setup System use
Table 5

Property table values are loaded with the client interface and define values with special meanings. The above variables are defined.

User level property

Setting the USERLEVEL changes the way assignments are done and should not be done from the checks. The variable is there to help you write your checks so that different users get the right kind of support. The possible values are novice or expert. The assignments are carried out according to :

Table of user profiles
Level Action
novice Assignments are always carried out in checks
expert Assignments becomes recommendations only
Table 6
Experience has shown that most users prefer to use the override on the individual items that let them be "experts" on one item only. Being an expert on everything can sometimes have "unexpected" results. Unless you can design from a clear line between experts and novice it is best to assume everyone a novice and allow for the individual override on items to resolve problems.The use of the "enforce" guiattribute allows the check writer the last word...

Showing messages to the user and signalling errors

Showing messages in the user interface check window is done by calling functions with predefined error messages.

Table of message reporting functions
Function Action
this.addCheckWarning($WARNTYPE) Warning message displayed
this.addCheckInfo($INFOTYPE) Info message displayed
Table 7

The $WARNTYPE is a predefined message that will be displayed in the language set by the client. To halt the checks and signal an error you set the STATUS and ERR as shown on line 1 in the example.

Defining messages to the user

Messages are defined in property files and loaded with the client GUI. There is one file for each language. Currently only one language has been implemented:English.

The file name is ``.Messages_en.properties''. For other languages _lang (_en in this case) would be substituted. The file is located in the place pointed to by the property DEFAULTSHOME (see table in previous section). In our example on line 1 the error $AN_FC_INCONSISTENT_RESOLWARN was raised. The definition of this error (in English) looks like this:


AN_FC_INCONSISTENT_RESOLWARN: \
WARNING: Inconsistent setting of the horizontal resolution in 'an' and 'fc'.

The syntax being:

<ERRORNAME> ``:'' <Text to be shown>

		  

Addressing variables using namespaces

Each hierarchy in the experiment defines a namespace. This means that variables with the same name can coexist in different places without a conflict because they have different scope, i.e. they belong to different namespaces. PrepIFS determines the namespace and addressing as follows:

Table of addressing modes
Level Data Model Format Example
2 Namelist Name Variables in same namelist, e.g. LRLP
3 Experimenttype namelist@name Namelists in same experiment,i.e climate@CLMSST
4 Experiment experimenttype@namelist@name Across experiment types,an@Dates@INITIME
Table 8


For example, when a rule is declared in the namelist file the scope is set to the namelist and all variables declared in the namelist can be addressed with their name only.Variables in other namelist or experiment types are prefixed as described by the format in the table above. Addressing property table values is done by prefixing with a dollar sign $.

Function calls

Function calls can be static or dynamic.

  • Static Needs the full path to the library where the function can be called.
  • Dynamic Refers to the particular instance of the experiment. Prefixed by ``this''.

      Example Static call

      ecmwf.pifs.checkPrepIFS.CheckUtils.compareDates(inidata@INITIME[0],$DATE_WAVE)
      +---------------------path--------++-function-++parameters-------------------+

      This also demonstrate the use of property values and experiment values.

      Example Dynamic Call

      this.addValueToVector("148","ppgeneral@SFCFIELDS"))

      The above call adds value 148 to variable SFCFIELDS in namelist ppgeneral.
      The experiment type is determined by context.


		  

Special array example

The while statement was introduced in 1.6 to allow for proper array and structlist support. It was primarily a question of supporting structlists which are the "table" type in prepIFS. I will illustrate with an example from the GEMS project:
1  // GEMS 
2  //($DEBUGCHECKS="1");
3  // diagnostic extra fields from YGRG_NL to D3GGFIELDSS
4  // Add to MFP3DFSSet and add extra ppfields converted 
5  {Gems@NGRGTEMP < ecmwf.pifs.checkPrepIFS.CheckUtils.toFloat(Gems@NGRG) } ? 
6  (Gems@NGRGTEMP2=this.getSTRUCTLISTValueAt("Gems@YGRG_NL",Gems@NGRGTEMP,1) &&
7  (this.addValueToVector(Gems@NGRGTEMP2,"namfpc@MFP3DFS")) && 
8  (Gems@NGRGTEMP=Gems@NGRGTEMP+1) );
        

The full namelist is available here for reference to let you see how the different variables are declared. The two temporary variables are also declared in the namelist as there is currently no way of declaring variables in the check.

Here follows a line by line comment to the example. The purpose of the code is to loop over all rows in YGRG_NL retrieving the value in column 1 and adding it to a vector MFP3DFS

  1. Comment
  2. Shows how to switch on/off checks dynamically to reduce the output to the actual constraints of interest.
  3. Comment
  4. Comment
  5. The while statement, notice the curly braces
  6. Retrieves the first item in YGRG_NL in row and assigns it to NGRGTEMP2
  7. Adds NGRGTEMP2 to the vector namfpc@MFP3DFS
  8. Increments NGRGTEMP in order to access next row and terminate the loop

To support initialisation of STRUCTLISTS to other values than the ones declared as components of the STRUCT two new attributes have been introduced:

<guiattribute key="INITIALISE">CO2/210061/true/false/false/CH4/210062/true/false/false</guiattribute>
<guiattribute key="NAMING">TYPEDEF</guiattribute>
		
See here for an example.

Existing Dynamic libraries

Table of functions
Name Description
void truncateVector(String nameofvector, String nameofsize) Truncate nameofvector to size nameofsize
int addCheckInfo(String message) Add info to message area
boolean valueInVector(String value , String nameofvector) Is v in vector?
void checkInitialData(String user, String binPath, Specific IFS initialisation check.
void getFDB( String RMIFunction , String binPath , String user, String param) Get fdb..
void execRMI( String RMIFunction , String A , String B) Execute RMI call
boolean typeLoaded(String type) Exptype loaded?
boolean typeExists(String type) ExpType exists ?
int sizeOfVector(String nameofvector) Size of vector
String mergeVectorToVector(String nameofvectorOne,String nameofvectorTwo) Merge to v.
String catVectorToVector(String nameofvectorOne,String nameofvectorTwo) cat two v.
boolean checkAllDatesAfter(String checkDate, String nameofvector) Are all dates in a vector later than checkDate?
boolean checkAllDatesBefore(String checkDate, String nameofvector) Are all dates in a vector earlier than checkDate?
boolean checkAllDatesInVector(String nameofvector) Are all dates in vector in valid date format?
void addValueToVector(String value , String nameofvector) Add v to name
void addValueToVector(Float value , String nameofvector) Add v to name
int setDatesGroup(String targetvector,String resultvector, Float nloops, \\ Float currentGroup) d> Create a series of values with nloop difference, 12 24 36 ..
void printAttributeOfItem(String itemname ,String attr) Print att a
void setAttributeOfItem(String itemname ,String attr , String value) Set att a
void removeValueInVector(String value , String nameofvector) Remove val in v
void removeAllElements(String nameofvector) Clear v
void removeValueInVector(Float value , String nameofvector) Remove val in v
boolean valueInVector(Float value , String nameofvector) Is val in v?
int addCheckWarning(String message) Add warning to messagearea
BasicItem getItemFromName(String nameofvalue ) Get an item with name n
BasicNameList getNameListFromName( String nameofvalue ) Get a nl from name n
Table 9

Existing Static libraries

Table of functions
Name Description
boolean debugOut(String var, String s) Print value of variable
boolean debugOut(String var, Float s) Print value of variable
boolean echo(String s) Echo string to output
boolean echo(Float s) Echo float to output
boolean isDigit(String s) Test if string is a digit
boolean isAlpha(String s) Test if string contains only letters
String toWord(Float value) Convert float to string
Float toFloat(String value) Convert string to float
boolean checkDate(String date) Check if string contains a valid date
String addToDate(String date, int field, Float amount) Add time to a date
Float diffDates(String date1, String date2) Calculate difference between two dates
Float compareDates(String date1, String date2) Compare dates and return as classic stringcompare
Float compareAnalysisDates(String date1, String date2) Compare dates in special format and return as classic stringcompare
String makeDates(String begindate, String enddate, Create vector of dates from to
Float byhours) interval by hours
String makeAnalysisDates(String begindate, String enddate, Create vector of dates in special
Float byhours) format from to interval by hours
String makeList(Float begin, Float end, Float by) Create vector of values from to interval by hours
String actualDate() Return todays date
String newDateAddHours(String date, Float hours) Return new date date + hours
String newDateAddDays(String date, Float days) Return new date with days added.
Float getFromDate(int field,String date) Get field from date (such as DD or YY)
Float YYYYMMDD(String date) Get YYYYMMDD as float from date
Float Hours(String date) Get hours field from date
Float Days(String date) Get day field from date
Float Month(String date) Get month field from date
Float Year(String date) Get year field from date
Float createWaveFreq( Float freq_wave_call, Float tstep ) Computes call frequency of wave model.
Table 10

Writing your own libraries

Adding dynamic functions is done by adding methods to the class ecmwf.datacontainers.ExpVer. This is straightforward as this implements the data model of the experiment and you will have access to all variables in the experiment through this class. Adding static function means adding methods to the class ecmwf.checkPrepIFS.CheckUtils. This is a static class and so all references to variables in the experiment will have to be done as input parameters.

Static functions are used when you for example want to check a variable for a special interval or compute something based on the variable.Static functions operate on variables only.

Dynamic functions are used when you need access to the internal structures of the experiment to for example adjust all variables in the experiment relating to dates or when you need to search or reorganise the structures.

Making it work

It is not practical to test that your checks are operating as intended by starting the GUI every time as this is time consuming. Before doing that you can run the ``Verifier'' that will run each check and make sure it works with the default configuration.

Debug and printing

Running the verifier is done as follows:

$java ecmwf.pifs.checkPrepIFS.Verifier

U S A G E :
serverurl    : http://xxx.xx.xxx  OR XX (run local)
userid       : name of prepifs user
lang         : en or other langugage that you have implemented
defaultpath  : path to location of default files
    at ecmwf = /home/rd/rdx/defaults
    at prism = $DEFAULTSLOCATION from system.h
userpath    : where your save files are stored
    at ecmwf = /home/rd/$USER/prepifs/saves
cycle       : name of cycle to load
    at ecmwf = ex 29r1
    at prism = ex prismV1
experimentid : Name of the experimentid to load
       ex em58
type         : Type of experiment to load
    at ecmwf = ex fc
    at prism = ex toyclim
configdir    : location of configfiles
    at ecmwf = run ~rdx/bin/prepIFS local and use the
    output 'arguments: configdir'
    at prism = run $PRISM_HOME/bin/prepIFS local and use the
    output 'arguments: configdir'
All arguments needs to be supplied always.

		  
An actual run could look like:

+ java ecmwf.pifs.checkPrepIFS.Verifier XX\
nal\
en\
/home/rd/rdx/defaults\
/home/rd/nal/prepifs/saves\
29r1\
em58\
fc\
/tmp



arguments: XX
arguments: nal
arguments: en
arguments: /home/rd/rdx/defaults
arguments: /home/rd/nal/prepifs/saves
arguments: 29r1
arguments: em58
arguments: fc
arguments: /tmp
%INFO #Apr 22 11:04:26 BST 2005#fjorgyn/136.156.112.141# PID:0 # in DawnConfigure.java#189
Server[136.156.112.141] Configuring from /tmp/ecmwf.pifs.rmi.PifsServer.ini
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
reading ... /home/rd/rdx/defaults/29r1
reading ... /home/rd/nal/prepifs/saves
Simplechecks are:true
ET::VERIFY[fc@Description]------------------------------------------------
Parse line:( DESCRIPTION == "" )?(($STATUS=-1)&&($ERR=$NODESCRIPTION))
verifyline instance=em58
( DESCRIPTION == "" ) => FALSE
NO ELSE part
VERYFYLINE *** Status -> 0
ET::VERIFY[fc@inidata]------------------------------------------------
Parse line:((INIPATH=="")&&(INIORIG=="ecfs"))?(($STATUS=-1)&&($ERR=$INIORIGERR))
verifyline instance=em58
((INIPATH=="")&&(INIORIG=="ecfs")) => FALSE
NO ELSE part
VERYFYLINE *** Status -> 0
Parse line:( USE_DATES_LIST=="false" )?
( INITIME = ecmwf.pifs.checkPrepIFS.CheckUtils.makeDates(INIBEGINDATE,INIENDDATE,INIBY) )
verifyline instance=em58
( USE_DATES_LIST=="false" ) => TRUE
Doing then part...
THEN ->( INITIME = ecmwf.pifs.checkPrepIFS.CheckUtils.makeDates(INIBEGINDATE,INIENDDATE,INIBY) ) => TRUE
VERYFYLINE *** Status -> 0
Parse line:( USE_DATES_LIST=="true" )?( INIENDDATE=INITIME[0] )
verifyline instance=em58
( USE_DATES_LIST=="true" ) => FALSE
NO ELSE part
VERYFYLINE *** Status -> 0
Parse line:( ecmwf.pifs.checkPrepIFS.CheckUtils.compareDates(INIBEGINDATE,INITIME[0]) != 0 )?
( INIBEGINDATE = INITIME[0] )
verifyline instance=em58
( ecmwf.pifs.checkPrepIFS.CheckUtils.compareDates(INIBEGINDATE,INITIME[0]) != 0 ) => FALSE
NO ELSE part
VERYFYLINE *** Status -> 0
Parse line:( INIBEGINSECONDS = ecmwf.pifs.checkPrepIFS.CheckUtils.Hours(INIBEGINDATE)*3600 )
verifyline instance=em58
( INIBEGINSECONDS = ecmwf.pifs.checkPrepIFS.CheckUtils.Hours(INIBEGINDATE)*3600 ) => TRUE

etc,etc
		
If an error is detected execution stops:
+ java -version
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
+ java ecmwf.pifs.checkPrepIFS.Verifier XX nal en /home/rd/rdx/defaults \
/home/rd/nal/prepifs/saves 29r1 em58 fc /tmp
arguments: XX
arguments: nal
arguments: en
arguments: /home/rd/rdx/defaults
arguments: /home/rd/nal/prepifs/saves
arguments: 29r1
arguments: em58
arguments: fc
arguments: /tmp
%INFO #Apr 22 11:09:51 BST 2005#fjorgyn/136.156.112.141# PID:0 # in DawnConfigure.java#189
Server[136.156.112.141] Configuring from /tmp/ecmwf.pifs.rmi.PifsServer.ini
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
reading ... /home/rd/rdx/defaults/29r1
reading ... /home/rd/nal/prepifs/saves
Simplechecks are:true
ET::VERIFY[fc@Description]------------------------------------------------
Parse line:( DESCRIPTION == "" )?(($STATUS=-1)&&($ERR=$NODESCRIPTION))
verifyline instance=em58
( DESCRIPTION == "" ) => TRUE
Doing then part...
THEN ->(($STATUS=-1)&&($ERR=$NODESCRIPTION)) => TRUE
VERYFYLINE *** Status -> -1
ecmwf.pifs.datacontainers.DatacontainersExceptions$CheckFailedException:
( DESCRIPTION == "" )?(($STATUS=-1)&&($ERR=$NODESCRIPTION))
        at ecmwf.pifs.datacontainers.ExpVer.verify(ExpVer.java:788)
        at ecmwf.pifs.checkPrepIFS.Verifier.main(Verifier.java:760)
		
The error is indicated by VERYFYLINE having the value -1 and the offending expression is reported as an exception.


 

 
            © ECMWF  
shim shim