\chapter{Utility Routines}\label{chap:utility-routines}
Here is a brief description of the utility routines
supplied with the ASCA\_ANL.
With the utility routines,
you can access many kinds of information
required in programming a new module.
Some functions can be realized without using the utility routines,
however, you are recommended to use the utility routines.

In this section
we briefly introduce functions of the utility routines.
All the utility routines here are supplied in a library {\tt libANL\_UTIL.a}.
The library are automatically created by installing the ASCA\_ANL
(see \S \ref{sec:install}).\\

The following functions are supplied.
\begin{center}
\begin{tabular}{lll} \hline
Name & Function & Ref. \\ \hline
{\tt ANL\_readHK\_register} & register HK items & \S\ref{sec:ANL_readHK} \\
{\tt ANL\_readHK} & get an HK value from HK files or FRF& \S\ref{sec:ANL_readHK} \\
{\tt ANL\_readGISmoni} & count up GIS/RBM monitor counts in a specified time interval & \S\ref{sec:ANL_readGISmoni} \\
{\tt ANL\_orbit}  & get orbital and attitude information & \S\ref{sec:ANL_orbit} \\
{\tt ANL\_GETLUN} & get an unoccupied logical unit number & \S\ref{sec:ANL_getlun_freelun}\\
{\tt ANL\_FREELUN} & set free the occupied logical unit number & \S\ref{sec:ANL_getlun_freelun} \\
{\tt ANL\_GET\_CHAIN\_INFO} & get module names in an analysis chain & \S\ref{sec:ANL_get_chain_info} \\
{\tt ANL\_CURRENT\_CALL} & get the order of a module called currently in an analysis chain & \S\ref{sec:ANL_get_chain_info} \\ \hline
\end{tabular}   
\end{center}

\section{ANL\_readHK}\label{sec:ANL_readHK}
{\tt ANL\_readHK} is a function to get HK values from HK files or FRF.

First,
if you get HK values from HK files,
set a name of a directory in which HK files are stored
to an environment variable {\tt FHKDIR}.
If you have HK files in several directories,
you can set names of the directories separated by a delimiter ':'.
If you set nothing to {\tt FHKDIR},
HK files are searched from the current directory.
If you get HK values from FRF, you need not set {\tt FHKDIR}
but must include {\tt GISREAD} or {\tt SISREAD} in an analysis chain.

Second,
call {\tt ANL\_readHK\_register} to register HK items.
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
int ANL_readHK_register(char *HKitem);
\end{verbatim}\end{quote}
{\tt HKitem} is a name of HK item you want.
{\tt ANL\_readHK} returns an ID for the HK item.
If a error occurs, {\tt ANL\_readHK\_register} returns a negative value. 

Third,
call {\tt ANL\_readHK} with {\tt ascatime} and {\tt HKid}
to get a HK value you need.
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
int ANL_readHK(int HKid, double ascatime, double mtime[2]);
\end{verbatim}\end{quote}
{\tt HKid} is an integer value which {\tt ANL\_readHK\_register} returned.
{\tt ANL\_readHK} returns a HK value at {\tt ascatime}
which corresponds to {\tt HKid}.
Also,
{\tt ANL\_readHK} returns the reference times in an array {\tt mtime}.
{\tt mtime[0]} is a time stamp of the latest HK value
before specified {\tt ascatime} in a HK file
and {\tt mtime[1]} is a time stamp of the first HK value
appeared after {\tt ascatime} in a HK file.
%{\tt ANL\_readHK} returns HK value that is calculated between {\tt mtime[0]} and {\tt mtime[1]}.
If a error occurs, {\tt ANL\_readHK} returns a negative value.
Notice that it may not work well if you call {\tt ANL\_readHK\_register} after calling {\tt ANL\_readHK}.

\section{ANL\_readGISmoni}\label{sec:ANL_readGISmoni}
{\tt ANL\_readGISmoni} is a function to count up
GIS and/or RBM monitor counts in a specified time interval.
Following shows the sample call of {\tt ANL\_readGISmoni}.
You have to set integration times for {\bf ALL} monitor counts individually.
If you set zero to an integration time of a certain monitor count,
{\tt ANL\_readGISmoni} does not count up the monitor count.
In the following sample, 
RBM, H0 and H2 of GIS2/3 will be counted up each four seconds.

\begin{quote}\baselineskip 3.2mm\begin{verbatim}
#incldue "anl_gismoni.h"

    double ascatime;    /* ASCATIME of interest */
    struct ANL_GISmoni gm;
    
    gm.rb.dt = 4;       /* RBM count */
    
    gm.g2.ld.dt = 0;    /* GIS2 LDHIT */
    gm.g2.l0.dt = 0;    /* GIS2 L0 */
    gm.g2.l1.dt = 0;    /* GIS2 L1 */
    gm.g2.l2.dt = 0;    /* GIS2 L2 */
    gm.g2.h0.dt = 4;    /* GIS2 H0 */
    gm.g2.h1.dt = 0;    /* GIS2 H1 */
    gm.g2.h2.dt = 4;    /* GIS2 H2 */
    gm.g2.ci.dt = 0;    /* GIS2 CPUIN */
    gm.g2.co.dt = 0;    /* GIS2 CPUOUT */
    gm.g2.to.dt = 0;    /* GIS2 TLMOUT */
    
    gm.g3.ld.dt = 0;    /* GIS3 LDHIT */
    gm.g3.l0.dt = 0;    /* GIS3 L0 */
    gm.g3.l1.dt = 0;    /* GIS3 L1 */
    gm.g3.l2.dt = 0;    /* GIS3 L2 */
    gm.g3.h0.dt = 4;    /* GIS3 H0 */
    gm.g3.h1.dt = 0;    /* GIS3 H1 */
    gm.g3.h2.dt = 4;    /* GIS3 H2 */
    gm.g3.ci.dt = 0;    /* GIS3 CPUIN */
    gm.g3.co.dt = 0;    /* GIS3 CPUOUT */
    gm.g3.to.dt = 0;    /* GIS3 TLMOUT */
        
    ANL_readGISmoni(ascatime, &gm);

\end{verbatim}\end{quote}

\noindent
Return values for RBM counts are, for example, stored in following variables:

\begin{center}
\begin{tabular}{lll}
	{\tt double gm.rb.t0} & & Start time of integration \\
	{\tt double gm.rb.t1} & & End time of integration \\
	{\tt double gm.rb.dt} & & ({\tt gm.rb.t1} $-$ {\tt gm.rb.t0}) \\
	{\tt int gm.rb.count} & & RBM counts in the integration time \\
\end{tabular}
\end{center}

\noindent
An instantaneous counting rate (c/s)
of RBM counts at {\tt ascatime}
can be calculated by {\tt (gm.rb.count/gm.rb.dt)}.
Note that {\tt gm.rb.dt} is set to 0.0
when {\tt ascatime} is out of bounds.

At present,
{\tt ANL\_readGISmoni} works only in a limited condition.
Also, you have to pay careful attention to its usage.
As a summary, you should note that following points in using
{\tt ANL\_readGISmoni}:

\begin{itemize}
\item	{\tt ANL\_readGISmoni} must be used with GISREAD or SISREAD.\\
	This function does not work with FITSREAD.
\item	{\tt ANL\_readGISmoni} can be called only from a C module.
\item	{\tt ANL\_readGISmoni} does not check that GIS or RBM are
	in the proper state \\
	(GIS/RBM/HV/CPU ON/OFF, HV level, etc).
\item	GIS monitor counts are not set in PCAL mode.
\item	TLMOUT is not set in MPC mode.
\item	It's no use to set integration time longer than 16 SF
	(64 s in bit-H),\\
	because GISREAD or SISREAD hold only 16 SF data in the memory.
\item	Most of monitor counts are output once in 4 frames
	which correspond to 4 s in bit-L. \\
	(RBM and TLMOUT 1 frame, and LDHIT 2 frames)
\item	Integration start and end are ({\tt ascatime}$-${\tt dt}/2)
	and ({\tt ascatime}$+${\tt dt}/2) in principle,\\
	but it can be shifted if corresponding SF are not in the memory.
\end{itemize}

\section{ANL\_orbit}\label{sec:ANL_orbit}
{\tt ANL\_orbit} is a function
to get orbital and attitude information,
such as rigidity, elevation, and so on.
A user can get the information by calling a function {\tt ANL\_orbit}
with the ascatime.
Note that {\tt ANL\_orbit} can be called only from a C module at present.

\begin{quote}\baselineskip 3.2mm\begin{verbatim}
#include <anl_orbit.h>
   ...
   ANL_orbit(ascatime, &asca);
\end{verbatim}\end{quote}

The function {\tt ANL\_orbit} calls atFunctions through functions in ascatool
and the information is supplied by a structure variable, {\tt $\ast$asca}.
The types of variables are shown in Table~\ref{tab:orbit-parameter}
and, Table~\ref{tab:struct-ANLorbit}.
If no error occurred,
{\tt ANL\_orbit} returns {\tt ANL\_ORBIT\_OK}.
Otherwise,
{\tt ANL\_orbit} returns {\tt ANL\_ORBIT\_ERROR}.

\begin{table}[htb]
\caption{ANL\_orbit parameter}
\label{tab:orbit-parameter}
\begin{center}
\begin{tabular}{|l|c|c|c|} \hline
parameter    & unit & I/O    & type   \\ \hline
ascatime     & sec  & Input  & double \\
$\ast$asca   & ---  & Output & ANLorbit \\ \hline
\end{tabular}   
\end{center}
\end{table}
 
\begin{table}[htb]
\caption{structure member of ANLorbit}
\label{tab:struct-ANLorbit}
\begin{center}
\begin{tabular}{|l|l|c|l|} \hline
variable name & unit   & type    & remark \\    \hline
phi           & degree & double  & Z-Y-Z first Euler angle \\
theta         & degree & double  & Z-Y-Z second Euler angle \\
psi           & degree & double  & Z-Y-Z third Euler angle \\
RA            & degree & double  & Right Ascension of Target (J2000) \\
DEC           & degree & double  & Declination of Target (J2000) \\
height        & km     & double  & altitude of the satellite from the earth surface\\ 
longitude     & degree & double  & longitude of the satellite on the earth surface, $0\leq\mbox{longitude} < 360$ \\
latitude      & degree & double  & latitude of the satellite on the earth surface, $-90\leq\mbox{latitude}\leq 90$\\
rigidity      & GeV/c  & float   & cutoff rigidity \\ 
elevation     & degree & double  & elevation angle from the earth edge \\
earth         & ---    & int & 0:Sky 1:NightEarth 2:BrightEarth \\
day\_night    & ---    & int & 1:Night else Day on the satellite \\
saa           & ---    & int & 1:in 0:out SAA\\ \hline
\end{tabular}   
\end{center}
\end{table}

\section{ANL\_GETLUN/ANL\_FREELUN}\label{sec:ANL_getlun_freelun}
If your module needs a logical unit number for a file I/O,
use subroutines {\tt ANL\_GETLUN} and {\tt ANL\_FREELUN}.
The subroutine {\tt ANL\_GETLUN} gives us an unoccupied logical unit number,
and the subroutine {\tt ANL\_FREELUN} releases the logical number.

{\bf DO NOT} use your favorite number for a logical unit number.
That may cause fatal errors in file I/O.
This means you may destroy data in science FITS file in such a case.

Followings are examples of calling these subroutines.
In the example
you get or release a logical unit number through an integer variable {\tt lun}.

\subsubsection{In FORTRAN}
To get a logical unit number,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
   Integer*4 lun
   ...
   Call ANL_getlun(lun)
\end{verbatim}\end{quote}

To release the logical unit number,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
   Integer*4 lun
   ...
   Call ANL_freelun(lun)
\end{verbatim}\end{quote}

\subsubsection{In C}
To get a logical unit number,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
#include <anl_misc.h>
   ...
   int lun;
   ...
   ANL_GETLUN(lun);
\end{verbatim}\end{quote}

To release the logical unit number,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
#include <anl_misc.h>
   ...
   int lun;
   ...
   ANL_FREELUN(lun);
\end{verbatim}\end{quote}

Notice that
an argument {\tt lun} is NOT a pointer to an integer
but an integer variable itself.
This is
because we use "cfortran" to interface C and FORTRAN.
See a manual of "cfortran"\cite{cfortran} for details.

\section{ANL\_GET\_CHAIN\_INFO/ANL\_CURRENT\_CALL}\label{sec:ANL_get_chain_info}
You can get information on an analysis chain
by calling a subroutine {\tt ANL\_GET\_CHAIN\_INFO}
or a function {\tt ANL\_CURRENT\_CALL}.
The subroutine {\tt ANL\_GET\_CHAIN\_INFO}
returns an array of character strings
which contains module names in an analysis chain currently defined.
The function {\tt ANL\_CURRENT\_CALL}
returns an integer
which indicates the module currently called by the ASCA\_ANL system.
The number corresponds to the order of calling modules
in a defined analysis chain\footnote{
For example,
if you defined an analysis chain
which includes three modules "A", "B", "C" in this order,
{\tt ANL\_CURRENT\_CALL} returns 2
while the system is calling the module "B".
}.

Followings are examples of calling these subroutines.
In the example
you pass {\tt MAXSIZE},
or a size of an array of character strings {\tt chain}.
The array {\tt chain} is used to get module names.
You also get {\tt defined},
or the number of modules currently defined in the analysis chain,
and {\tt registered},
or the number of modules currently registered to the ASCA\_ANL system.

\subsubsection{In FORTRAN}
To get information on the analysis chain,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
   Integer MAXSIZE
   Parameter (MAXSIZE=10)
   character*16 chain(MAXSIZE)
   Integer defined, registered
   ...
   Call ANL_get_chain_info(MAXSIZE, chain, defined, registered)
\end{verbatim}\end{quote}

To know which module is currently called,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
   Integer current
   Integer ANL_current_call
   ...
   current = ANL_current_call
\end{verbatim}\end{quote}

\subsubsection{In C}
To get information on the analysis chain,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
#define MAXSIZE 10
   ...
   char chain[MAXSIZE][16];
   int defined, registered;
   ...
   ANL_GET_CHAIN_INFO(MAXSIZE, chain, defined, registered);
\end{verbatim}\end{quote}

Notice that
arguments {\tt defined} and {\tt registered} are NOT pointers to an integer
but integer variables themselves.
This is
because we use "cfortran" to interface C and FORTRAN.
See a manual of "cfortran"\cite{cfortran} for details.

To know which module is currently called,
\begin{quote}\baselineskip 3.2mm\begin{verbatim}
   int current;
   ...
   current = ANL_CURRENT_CALL();
\end{verbatim}\end{quote}
