Introduction to the ARTE C++ Interface

This is a short description on how to use the new ARTE C++ interface as first included in ARTE-02-04-r3. It is part of a more general concept GATE (Generic Arte Table Environment), which will be released soon.

Improvements of the Arte C++ interface

The concept of the Arte C++ interface is a match of the Arte table lines into C structures. This allows a strong typing. Since many structures are split in two by the parallel table concept of Arte 1.x this typing has often been violated by casts, which destroy the type safety. In the old C++ interface, the typing is not provided for Arte-one-to-many and many-to-many relations. This, too, required inconvenient and possibly dangerous type casts. The new version fixes this.
The idea of storing different types (i.e. structures) in similar collections as done by the Arte tables, is realised in the C++ programming language by `containers'. The part of C++, which deals with containers, is called STL (Standard Template Library). The feature of putting arbitrary objects into the containers is provided by the C++ template mechanism. This mechanism is also used to describe the Arte tables in C++. To apply the algorithms of STL, the Arte C++ interface provides a certain compatibility to STL.
This document assumes that the reader has some basic understanding of STL. A convenient reference can be found on http://www.sgi.com/Technology/STL/

Implementation

The static containers described by the Arte data definition are now from the C++ point of view the template class `ArteTable'.  A schematic description of the table and the underlying structure looks like this:
======================================================================
`public'                                           
`private'
ArteTable<TOPP>                                    
ArteVector<TOPP>

ArtePointer<TOPP>(1) = ArteTable<TOPP>::begin() ->  TOPP #1
ArtePointer<TOPP>(2)                            ->  TOPP #2
ArtePointer<TOPP>(3)                            ->  TOPP #3
ArtePointer<TOPP>(4)                            ->  TOPP #4
ArtePointer<TOPP>(5)                            ->  TOPP #5
ArtePointer<TOPP>(6)                            ->  TOPP #6
ArtePointer<TOPP>(7) = ArteTable<TOPP>::end()       invalid position 
======================================================================

Usage

The C++ interface can be accessed by
#include <arte/arte.hh>
Make sure, that you do not include any header files of the `old' C++ interface, the `four-letter' files like RTRA.hh are not part of the C++ interface as described here.

table iterators

ArteTable provides an iterator to loop over the table (e.g. print the TOPP table and the masses:):
for( ArteTable<TOPP>::iterator i = ArteTable<TOPP>::begin();
     i!=ArteTable<TOPP>::end();
     ++i ) {
  cout << *i << ":" << (*i)->mass << "  ";
}
Note that in contrast to the old interface, the dereferencation of the iterator results in an ArtePointer. This is necessary for consistency with STL.

x-to-one relations

Arte relation of the cardinality `one' are described as ArtePointer<XXXX> as before. However, for ARTE-01-0x, many of the pointers to parallel tables now point to the more important table:
cout << "mass = " << ArtePointer<MTRA>(10)->topp->mass << endl;

higher cardinality-relations

The relation entries, e.g. ArtePointer<RTRA>(i)->mtra (MC tracks for reconstructed track i) provide a begin and an end iterator, analogous to the tables.
ArtePointer<MTRA> mtra = *(ArteTable<MTRA>::begin() + 4 );
cout << "rec. tracks of MTRA " << mtra << ": ";
copy( mtra->rtra.begin(), mtra->rtra.end(),
      ostream_iterator<ArtePointer<RTRA> >( cout, ", " ) );
An iterator can be created like this:
ArteRelationIterator<MVER> i = mtra->ever.begin();
so that the copy function could be replaced by this:
for( ArteRelationIterator<RTRA> rtraIt = mtra->rtra.begin();
     rtraIt != mtra->rtra.end();
     ++rtraIt ) {
  cout << *rtraIt << ", ";
}
Note that you should avoid such loops, if possible.

adding an object to a table

since ArteTable acts very much like a static STL vector:
RTRA rtra;
rtra.pf = 10;
ArteTable<RTRA>::push_back( rtra );
which is aquivalent to
ArteTable<RTRA>::push_back( RTRA() )->pf = 10;

setting up Arte relations

There is a global function, which combines pairs of objects. It needs a member pointer of the appropriate relation entry of one of the objects, e.g. to connect HITB 20 with RTRA 10:
createRelation( ArtePointer<RTRA>( 10 ),
                ArtePointer<HITB>( 20 ),
                &RTRA::hitb );
(You can also swap the two pointers or pass the HITB::rtra member.) Do not specify a prototype for FORTRAN_ROUTINE(mmbrel), as it might clash with the prototype of ArteTable. The next version of the C++ interface will allow to skip the third parameter where possible.

other functions

static unsigned int ArteTable<T>::size() const;  // number of rows
static string ArteTable<T>::getName() const;     // name of the table (untested)

Utilities

arte/artefunc.h provides a set of classes and functions, which help to use STL in the ARTE context. It is not in a finished state and any comments are welcome. It creates function objects by the following global functions:

ArteTable-related (e.g. z of HITB):

getEntry( &HITB::z )

Class-related (examples will be provided in a different document):

getMember
compareMember
callMember
getEntry
compareEntry
These functions seem to be obsolete, as their functionality is already provided by the C++ standard library, e.g. std::mem_fun.

Examples

  1. Find the first MC-Track with mimps and print them. Create a relation to the first RSEG:
for( ArteTable<MTRA>::iterator mtra = ArteTable<MTRA>::begin();
     mtra != ArteTable<MTRA>::end(); ++mtra ) {
  if( std::distance( (*mtra)->mimp.begin(), (*mtra)->mimp.end() ) > 0 ) {
    std::cout << "mtra=" << *mtra << " ";
    std::copy( (*mtra)->mimp.begin(), (*mtra)->mimp.end(),
               std::ostream_iterator<ArtePointer<MIMP> >( std::cout, ", " ) );
    break;
  }
}
  1. Print the z positions of the hits of RSEG #1 (needs artefunc.h):
ArtePointer<RSEG> rseg = *ArteTable<RSEG>::begin();
std::transform( rseg->hitb.begin(), rseg->hitb.end(),
                std::ostream_iterator<float>( cout, " " ),
                getEntry( &HITB::z )      );
std::cout << std::endl;

Structure

The C++ interface constists of the following header files:
include/arte/arte.hh
             ArteTable.hh
             ArteTable.icc
             artefunc.h
             PointerBase.hh
             ArteProto.hh
             PointerBase.icc
include/auto/auto.hh
Note that the header files cannot be read by gcc 2.7.
The DOC++ output describing the ARTE tables, can be found in http://www.desy.de/~borg/auto/

Valid HTML 4.0! 21 Mar 2000 Up   (mailto C.B.)