# Presentation: 672516

## Using a Code Generator for the Calibration API

- Paolo Calafiura, LBL

## Motivation

- Calibration API insulates the framework from DBMS-specific code
- Still DBManager requires one “Streamer”  per Calibration class and per DBMS
- With 50+ calibration  classes and at least two DBMS systems (Oracle and MSQL) plenty of error prone cut-and-paste code to write
- generate the Streamer code starting from a description of the calibration data

## Components

- A formal description of the “channel” class(assume each subdetector to be a vector<channel>)
- A parser that builds an abstract representation of the class syntax into some internal structure
- A back-end that, using this representation, or better an API to access it, generates the code

- Parser

- Class
- Description

- Syntax
- Representation

- Generator

## The Front-End

- C++ header file seems the obvious choice for the description...
- But good C++ parsers are difficult to find/write and tend to became unwieldy (cint). Other “but”s...
- We choose the CORBA Interface Description Language (IDL)
- simple C++ like syntax
- industry-standard, used also in HENP (e.g. STAR)
- many tools available adopted Sun CFE parser: free, reliable, existing HEP tool
- only rudimentary interface available to code the backend

## The Code Generator

- Our backend is based on D. Quarrie’s Fidle, (a prototype of a multi-language data access package).
- The core class is an abstract **emitter** with template methods such as *emit_attributes*, abstract methods such as *emit_attribute* and concrete methods such as *is_perst*
- There is a specialized emitter per template file, plus a fairly complete -untested- CORBA emitter
- Only small(ish) **code tokens** are generated, inserted using a Perl script  in matching **template files**

## An example: the IDL description

- typedef long Chid;
- interface Ped
- {
-   readonly attribute boolean is_perst;
-   attribute Chid channel;
-   attribute double offset;
-   attribute double error;
- };

## An example: the generated tokens

- table_Name =>
-   "Ped",
- table_tabhh_rawstruct =>
-   "struct Raw
- {
-   Raw():channel(0) , offset(0) , error(0)  { }
-   Raw(long achannel, double aoffset, double aerror):
-  channel(achannel), offset(aoffset), error(aerror) { }
-   ~Raw() { }
-   long   channel;
-   double   offset;
-   double   error;
- };",

## An example: the template file

- class $gen{table_Name}
- {
- public:
-         $gen{table_tabhh_rawstruct}
-         .........
-         bool operator<(const $gen{table_Name}& p) const { return true; }
-         .........
- }

## An example: the resulting file

- class Ped
- {
- public:
-         struct Raw
- {
*  **Raw():channel(0) , offset(0) , error(0)  { }*
-   Raw(long achannel, double aoffset, double aerror):
-  channel(achannel), offset(aoffset), error(aerror) { }
-   ~Raw() { }
-   long   channel;
-   double   offset;
-   double   error;
- };

## An example: the code generator (CFE version)

-   //
-   //generate table_tabhh_rawstruct ----------------
-   //
-   ost.str("");
-   skip_to_indent(ost);
-   ost << "struct Raw" << endl;
-   skip_to_indent(ost);
-   ost << "{" << endl;
-   increase_indent();
-   //default constructor
-   skip_to_indent(ost);
-   ost << "Raw():";
-   first = I_TRUE;
-   i = new UTL_ScopeActiveIterator(str,
-        UTL_Scope::IK_decls );

-  while ( !(i->is_done( )) ) {
-     d = i->item( );
-     if ( d->in_main_file( ) ) {
-       if ( AST_Decl::NT_field == d->node_type( ) ) {
-         field = be_field::narrow_from_decl( d );
-         if ( NULL != field ) {
-           if (I_FALSE == first) {   ost<< ", "; }
-           first = I_FALSE;
-           ost << field->local_name()->get_string()<< "(0) ";
-         } else {
-           cerr << "narrow failed on NT_field!" << endl;
-         }
-       }
-     }
-     i->next( );
-   }
-   ost << " { }"  << endl;
-   delete i;

## Summary

- IDL is a compact language to describe DB tables and simple classes
- Specialized CFE backends written for MSQL, iODBC
- Working prototype integrated in DBObjects package.
- Interfacing your calibration code to MSQL, Oracle and root “n-tuples” will be as easy as writing an IDL description of channel data.(exceptions for large/peculiar sub-detectors?)

## What next?

- Generate the (CORBA) interface to access calibrations in a distributed fashion.
- (Try to) generate rootcint files. Require coordination with the ROOT team.
- CFE is not an easy tool. Backend code may quickly turn into a monster.
- I am testing Java as an alternative:
- comes with a built-in parser and a library for back-end coding (generator code is smaller by X2 and much more readable)
- Java allow to mark classes and fields as persistent/transient
- jdbc + java.idl promising to implement a portable, distributed database-independent package to access calibrations

## An example: the Java description

-   public class ped implements Serializable {
-   float slope;
-   double error;
-   transient long myid;
- }

## An example: the code generator (Java version)

-   Field f[] = fileClass.getDeclaredFields();
-  //
-   //generate table_tabhh_rawstruct ----------------
-   //
- 	String rawstr="";
- 	skip_to_indent(rawstr);
- 	rawstr += "struct Raw {";
- 	endl(rawstr);
- 	increase_indent();
- 	//default constructor
- 	skip_to_indent(rawstr);
- 	rawstr+="Raw():";
- 	for (i=0; i<f.length; i++) {
- 	    if (i>0) rawstr+=", ";
- 	    rawstr += f[i].getName() + "(0)";
- 	}
- 	rawstr += " {}";
- 	endl(rawstr);

## And after that?

- Use code generation for Event data:
- Help root cint (out?),
- provide/enforce module-to-module communication protocol in AC++
- Need a richer description language than IDL. Java is certainly an option to evaluate.
- ODL looks even better on paper, not really used, would require substantial work (no parser, no back-end library available)