%-----------------------------------------
%  LCIO fotran wrapper manual 
%
%  $Id: f77api.tex,v 1.17 2004-09-24 16:14:46 hvogt Exp $  $Name: not supported by cvs2svn $
%
%-----------------------------------------
\subsection{The Fortran Interface} \label{f77api}

The Fortran API of LCIO is based on a set of wrapper functions to the 
C++ implementation using "cfrotran.h" to create the correct Fortran name.

The main idea is that we use integers in Fortran to represent pointers to 
objects on the C++ side. There will be one wrapper function for every class method
of the implementation classes (namespaces IMPL and IO) plus two additional methods 
to create and delete the object respectively. All functions that operate on objects, i.e.
all functions except for the creation functions (constructors) need as a first argument 
the integer pointer to the particluar object.

By using a unique naming convention the documentation of the C++ version of the API
can be utilized for the Fortran API as well.

Moreover example code written in C++ can be translated into Fortran basically line by 
line as far as LCIO is concerned -- of course language specific control structures 
will have to be different. So even if you are only intereseted in using LCIO from Fortran 
it is probably a good idea to read the above sections on Java and C++ as well to get some 
insight into the general structure of LCIO.


\subsubsection{ Note} \label{f77note}
{\em The handling of pointers in Fortran {\bf\em must} be done carefully.
One has to ensure that pointers are always used in the right context.
Pointers of objects given back to C++ can not be checked by the language to be applicable.
In most cases of wrong pointer usage the execution of the executable will result in a
{\bf\em{ segmentation violation}}.
}


\subsubsection{Naming convention}
The following naming convention is used for the fortran wrapper functions to the 
C++ implementation of LCIO:
\begin{itemize}

\item{all function names start with {\bf lc}}

\item{{\bf lc} is followed by a three letter acronym that uniquley identifies the 
corresponding C++ class, e.g. {\bf evt} for LCEvent.} See table \ref{tab_f77} for a complete listing
(for the classes 'LCVec, STL vector' see in the {\bf first part of Appendix~\ref{ftn_summary} under utility})

\item{the function name ends on the full lowercased name of the class method, e.g. \\
 \verb$LCEventImpl::getRunNumber()$ becomes  {\bf lcevtgetrunnumber() } }

\item{the constructor and destructor of the class  end on {\bf create} and {\bf delete} 
respectively, eg. {\bf lcevtdelete()} }

\item{All constants defined in \verb$Event::LCIO$ are defined as constants in Fortran with the 
same name prepended by {\bf 'LCIO\_'}, e.g. the type name for MCParticles defined in C++ in
\verb$LCIO::MCPARTICLE$ is defined in a character constant in Fortran named
{\bf LCIO\_MCPARTICLE} (see the Fortran include file {\bf lciof77apiext.inc}).}

\end{itemize}

\begin{table}
\begin{center}
\begin{tabular}{|c|c|}
\hline
\rule[-5mm]{0mm}{10mm} C++ class  &  f77 acronym   \\ \hline \hline

 CalorimeterHitImpl         & cah \\ \hline
 ClusterImpl                & clu \\ \hline
 LCCollectionVec            & col \\ \hline
 LCEventImpl                & evt \\ \hline
 LCGenericObjectImpl        & gob \\ \hline
 MCParticleImpl             & mcp \\ \hline
 LCObject (Vector)          & obv \\ \hline
 ParticleIDImpl             & pid \\ \hline
 ReconstructedParticleImpl  & rcp \\ \hline
 LCReader                   & rdr \\ \hline
 LCRelationImpl             & rel \\ \hline
 LCRunHeaderImpl            & rhd \\ \hline
 LCRelationNavigator        & rnv \\ \hline
 SimCalorimeterHitImpl      & sch \\ \hline
 SimTrackerHitImpl          & sth \\ \hline
 TPCHitImpl                 & tph \\ \hline
 TrackerHitImpl             & trh \\ \hline
 TrackImpl                  & trk \\ \hline
 LCWriter                   & wrt \\ \hline \hline

 LCVec, STL vector          & ??? \\ \hline

\end{tabular}
\end{center}
\caption{Three letter acronyms for f77 wrapper functions.}
\label{tab_f77}
\end{table}

Additional methods to handle string, int and float vectors from Fortran are provided\\
for the user extension classes (LCIntVec, LCFloatVec, LCStringVec):\\
{\bf lcivcgetlength()}, {\bf lcivcgetintat()}  \\
{\bf lcfvcgetlength()}, {\bf lcfvcgetfloatat()} \\
{\bf lcsvcgetlength()}, {\bf lcsvcgetstringat()}  \\

and for the stl vector class:\\
{\bf intvectorgetlength()}, {\bf intvectorgetelement()}  \\
{\bf floatvectorgetlength()}, {\bf floatvectorgetelement()}  \\
{\bf stringvectorgetlength()}, {\bf stringvectorgetelement()} . \\

For strings the Fortran CHARACTER* declaration has to be large enough, otherwise the original
string is truncated.\\
A Summary of all functions in the basic Fortran API is given in the first part of {\bf Appendix~\ref{ftn_summary} }.


\subsubsection{Extension of the Base Fortran API} \label{f77ext}

An additional set of Fortran functions is provided for user convenience. These are higher level functions
that usually allow to access several attributes of data objects with one function call.
These functions are declared in \verb#$LCIO/src/f77/lciof77apiext.inc#,
%$
and are summarized in the second part of {\bf Appendix~\ref{ftn_summary} }.

Most Fortran programs for simulation use the \verb$hepevt$ common block. 
Conversion functions from the LCIO MCParticle collection to the \verb$hepevt$ common block and vice versa 
are also provided in the extended interface. See the example in \ref{rwpythia}.

The wrapper functions for the {\bf LCParametersImpl} class are provided in the extension of the base Fortran API.
This class is related to the classes\\
{\bf LCRunHeaderImpl, LCEventImpl, and LCCollectionVec}\\
 and has the methods\\
{\bf setIntValues, setFloatValues, setStringValues, getIntKeys, getFloatKeys, getStringtKeys,
getIntValues, getFloatValues, and getStringValues} .\\

The set/get methods are performed by the wrapper fuctions:
\begin{verbatim}
lcsetparameters (class_name, class_pointer, method_name, key_name, vector_pointer) 
lcgetparameters (class_name, class_pointer, method_name, key_name, vector_pointer) 
\end{verbatim}
.    \\
The vector\_pointer is given to lcsetparameters and obtained from lcgetparameters and the vector content
may be set or obtained by the stl vector wrapper fuctions.

Methods of the extended Fortran API can be used\\

to create the vectors for the user extension classes (LCIntVec, LCFloatVec, LCStringVec)\\
 {\bf lcintvectorcreate(...)} \\
 {\bf lcfloatvectorcreate(...)} \\
 {\bf lcstringvectorcreate(...)} \\

and to fetch the content of a vector\\
 {\bf lcgetintvector(...)} \\
 {\bf lcgetfloatvector(...)} \\
 {\bf lcgetstringvector(...)} \\

to create/delete the stl vectors having int, float, string, and pointer datamembers
(e.g needed for the setShape method in the ClusterImpl Class)\\
 {\bf intvectorcreate(...)} \\
 {\bf intvectordelete(...)} \\
 {\bf floatvectorcreate(...)} \\
 {\bf floatvectordelete(...)} \\
 {\bf stringvectorcreate(...)} \\
 {\bf stringvectordelete(...)} \\
 {\bf pointervectorcreate(...)} \\
 {\bf pointervectordelete(...)} \\

and to fetch the content of a vector\\
 {\bf getintvector(...)} \\
 {\bf getfloatvector(...)} \\
 {\bf getstringvector(...)} \\
 {\bf getpointervector(...)} \\

The parameters of the functions above are explained in 
the the second part of {\bf Appendix~\ref{ftn_summary} }
(The extended Fortran API to LCIO).

\subsubsection{Reading and writing LCIO files}

Examples for reading and writing LCIO files can be found in:
\begin{verbatim}
  src/f77
    simjob.F
    recjob.F
    anajob.F
\end{verbatim}
To build these examples, do:
\begin{verbatim}
   gmake -C src/f77
\end{verbatim}

These examples correspond to that provided in \verb#$LCIO/src/cpp/src/EXAMPLE# for C++. \\
                                                                                       
The complete interface is declared in the include file \verb#$LCIO/src/f77/lciof77api.inc#. 
%$
A simple example for reading an LCIO file with Fortran is:

\begin{verbatim}
 ...
#include "lciof77api.inc"
#include "lciof77apiext.inc"

      PTRTYPE reader, event, runhdr
      integer status, irun, ievent

      reader = lcrdrcreate()
      status = lcrdropen( reader, 'simjob.slcio' )
      
      if( status.eq.LCIO_ERROR) then
         goto 99
      endif

      do 
         event = lcrdrreadnextevent( reader )
         if( event.eq.0 ) goto 11 
         
         status = lcdumpevent( event )
      enddo
 11   continue
 ...
\end{verbatim}
The function \verb$lcdumpevent(event)$ is part of the extended interface described in \ref{f77ext}.
Note that all functions that operate on existing objects have as a first argument the integer pointer 
to this particluar object.
All functions that do not return a pointer to an object do return a status word instead that can be 
compared to \verb$LCIO_ERROR$ (\verb$LCIO_SUCCESS$).

An example how to write a LCIO file from Fortran is:

\begin{verbatim}
 ...
      writer = lcwrtcreate()
      status = lcwrtopen( writer, filename , LCIO_WRITE_NEW )

 ... 
      do iev = 1,nev
          
          event = lcevtcreate()

          status = lcevtsetrunnumber( event, irun ) 
          status = lcevtseteventnumber( event,  iev ) 
 
          schcol = lccolcreate( LCIO_SIMCALORIMETERHIT )

          do k=1,nhit

             hit = lcschcreate() 
             status = lcschsetcellid0( hit, 1234 ) 
             status = lcschsetenergy( hit, energy )

             status = lccoladdelement( schcol, hit ) 
          enddo

          status = lcwrtwriteevent( writer , event )
          
c------- need to delete the event as we created it
          status = lcevtdelete( event )

      enddo

      status = lcevtaddcollection(event,schcol ,'MyCalHits') 

      status = lcwrtclose( writer ) 
 ...
\end{verbatim}

Note that as in the C++ case we have to delete the event if we created it as described in \ref{cppmem}. \\

\subsubsection{Using a C++ RunEventProcessor class for LCIO files processing in Fortran}

A RunEventProcessor class is added to the Fortran API. To use it a wrapper function {\bf lcrdreventprocessor}
is provided which has to be called as:
\begin{verbatim}
...
#include "lciof77api.inc"
      integer          lcrdreventprocessor, status
      character*30     filenamesin(3)
      character*30     filenameout
      PTRTYPE          writer, pv
      common /outinfo/ writer
...
      filenamesin(1)  = 'simjob_f1.slcio'
      filenamesin(2)  = 'simjob_f2.slcio'
      filenamesin(3)  = 'simjob_f3.slcio'
      filenameout     = 'recjob_f.slcio'
***     create writer, open output file
      writer = lcwrtcreate()
      status = lcwrtopen( writer, filenameout , LCIO_WRITE_NEW )
***     create a stringvector of input file names
      pv = lcstringvectorcreate( filenamesin, 3, len (filenamesin(1))
***     create reader, open input file chain, start event loop
      status = lcrdreventprocessor( pv )
...
      subroutine processrunheader ( pheader )
      PTRTYPE pheader
***      some code if wanted, e.g.
      status = lcdumprunheader ( pheader )
      end

      subroutine modifyrunheader ( pheader )
      PTRTYPE pheader
***      some code if wanted
      end

      subroutine processevent ( pevent )
      PTRTYPE pevent
***      some code if wanted
      end

      subroutine modifyevent ( pevent )
#include "lciof77api.inc"
      PTRTYPE          pevent
      PTRTYPE          writer
      common /outinfo/ writer
...
***      some code if wanted
*
***      write event
      status = lcwrtwriteevent ( writer, pevent )
...

      end
\end{verbatim}

The 4 subroutines {\bf processrunheader, modifyrunheader, processevent, and modifyevent} must be provided if
the wrapper function {\bf lcrdreventprocessor} is used. They are called via the LCRunListener, LCEventListener classes.
As an expample the code in \verb#$LCIO/src/f77/recjob.F# may be looked at. 
The function \verb$lcdumprunheader(pheader)$ is part of the extended interface described in \ref{f77ext}.

