%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

This chapter explains how to build and install the PIL library from its
source code distribution. It also provides some initial help on programming
with PIL by reviewing the sample programs that come with the PIL distribution.

\section{Building the PIL library}

\subsection{Necessary tools}

\subsubsection{Hardware}

Version 1.8.2 of PIL (May 2002) compiles on the following 
architectures :

\begin{verbatim}
  sparc-sun-solaris    (32 / 64 bit)
  intel-gnu-linux      (32 bit)
\end{verbatim}

The library may compile/run on other architectures (we have reports of
successful compilation on HP-UX, mips-sgi-irix and alpha-dec-osf machines), 
but PIL development team has access only to those aforementioned. Furthermore
ISDC officially supports only "reference platform", which is defined
as sparc-sun-solaris running Solaris 8 with Forte 6 compiler set.
Refer to :

\begin{verbatim}
   http://isdc.unige.ch/index.cgi?Software+swplatform
\end{verbatim}

for more information.

\subsubsection{Software}

Version 1.8.2 of PIL was tested with following compilers :

\begin{verbatim}
on Solaris 8 :

  Sunsoft cc C compiler version 5.0, 5.1, 6.x (aka Forte 6)
  Sunsoft CC C++ compiler version 5.0, 5.1, 6.x (aka Forte 6)
  Sunsoft f90 compiler version 5.0, 5.1, 6.x (aka Forte 6)

on Linux kernel version 2.2/2.4 :

  gcc/g++ C/C++ compiler version 2.7.*, 2.8.*, 2.95.2, 3.0.*
  Fujitsu Fortran 95 Express Version 1.0 (now Lahey ver 5+)
\end{verbatim}

PIL library may be compilable with other compilers, however 
the PIL development team have access to only those aforementioned.
Not all combinations of C/C++ and F90 compilers were tested.

Active development and debugging is done on Solaris with some
work also on Linux.

Besides compilers, one needs the following system utilities :

\begin{verbatim}
  gnu make (ver. 3.79.1) (Sun's /usr/ccs/bin/make does _NOT_ work)
  gzip
  tar (or gtar but renamed to tar)
\end{verbatim}


\subsection{Unpacking distribution file and setting up directories structure}

PIL library is usually delivered as a part of support-sw package. It is
however possible to compile it as a standalone package.

After downloading the distribution file, one has to move it to empty directory
in which she/he has read and write access rights. Then the following
should be done :

\begin{verbatim}
  gzip -d pil-1.8.2.tar.gz
  tar xvf pil-1.8.2.tar
\end{verbatim}

First line uncompresses the distribution file, the second unpacks files from
tar-file, usually creating several files and subdirectories. Main directory
should contain among the others Makefile.in, makeisdc1.in, configure.in, 
configure files and autoconf subdirectory.


\subsection{Autoconfiguring Makefiles}

Before attempting autoconfiguration the directory tree has to be set to the
clean state. This is done with the following command :

\begin{verbatim}
  make distclean
\end{verbatim}

This command deletes any existing object files, executables produced by
build process, config.cache, Makefiles produced by previous run of configure
script.

Before  running  configure one may wish to review (and probably manually
edit) files makeisdc1.in and Makefile.in. makeisdc1 and Makefile
should not be edited since their contents will be overwritten by subsequent
run of \${ISDC\_ENV}/bin/ac\_stuff/configure script.

To autoconfigure PIL library one has to run :

\begin{verbatim}
  $ISDC_ENV/bin/ac_stuff/configure
\end{verbatim}

\${ISDC\_ENV}/bin/ac\_stuff/configure script adapts Makefile to C
and F90 compilers tastes. If there is no F90 compiler available configure
script disables compilation of F90 source files. If configure script is 
unable to automatically find correct C and F90 compiler one can set CC, F90,
CFLAGS and F90FLAGS environment variables to force configure script to
choose specific compilers/options. For example configure script tends to 
favor gcc over other C compilers. So if you have gcc and other C
compiler it will always choose gcc. If you want to use C compiler other then
gcc please type : 

\begin{verbatim}
      setenv CC name_of_your_C_compiler (cc is quite common)
\end{verbatim}

before running ./configure 

\paragraph{Notes\\}
{\it
On some architectures NAG F90 compiler requires -Qpath option to be
predefined in F90FLAGS. configure script is not smart enough
to figure out where NAG F90's libraries/executables reside (usually
not in PATH). Besides, NAG F90 compiler is not supported.\\
If CFLAGS and F90FLAGS setup by ./configure script are incorrect one 
may fix them directly in Makefile/makeisdc1. For instance, some people
want to have libraries compiled with debug option turned on ("-g"), 
and configure script does not always put "-g" option in CFLAGS/F90FLAGS.
Please keep in mind that any subsequent run of configure script will
overwrite any changes.
}

\subsection{Compilation of library and demo programs}

To compile PIL library and build demo executables one has to type :

\begin{verbatim}
   make 
\end{verbatim}

This will create libpil.a file and executables :pset, plist, pilcdemo,
pilfdemo among others.


\subsection{Installation of library}

To install PIL package under \${ISDC\_ENV} directory tree one has to type :

\begin{verbatim}
   make global_install
\end{verbatim}

For more information about make files and installation procedure refer to 
makefiles-2.4.4 manual (found on ISDC web serwer) or README.make file.

\subsection{Sample programs}

A small number of sample programs is distributed together with PIL library
(and built when compiling library). They are :

\begin{itemize}
\item
pset - PIL's equivalent for IRAF/XPI pset program. Sets value of parameter
in arbitrary parameter file.
\item
pget - PIL's equivalent for IRAF/XPI pget program. Read value of parameter
in arbitrary parameter file and display it on screen.
\item
plist - PIL's equivalent for IRAF/XPI plist program. Dumps contents of
parameter file on screen.
\item
pil\_lint - program checks given parameter file and reports any errors
encountered.
\item
pil\_gen\_c\_code - given parameter file program dumps (to stdout) source
of C program which can read that parameter file.
\item
pilcdemo - sample C application (see source code for more info)
\item
pilfdemo - sample F90 application (see source code for more info)
\item
cvector - test program for vector support
\item
ISDCcopy - sample CTS compliant application (use make ISDCcopy to
build it - requires support-sw installed)
\end{itemize}

Most of those demo program are for testing purposes, and do not perform 
any useful calculations. Refer to chapters \ref{PILRefCcalling} and
\ref{PILRefF90calling} for information how to use PIL library.

\section{IRAF parameter files}\label{PILRefParFiles}

The purpose of PIL library is to enable ISDC applications access IRAF
compatible parameter files. IRAF parameter file is a text file.
Every line describes single parameter. Format is as follows : 

\begin{verbatim}
    name,type,mode,default,min,max,prompt 
\end{verbatim}

\begin{itemize}

\item
{\tt name} : name of parameter 

\item
{\tt type} : type of parameter. Allowable values: 

\begin{itemize}
\item
{\tt b} : means parameter of boolean type

\item
{\tt i} : means parameter of integer type

\item
{\tt r} : means parameter of real type

\item
{\tt s} : means parameter of string type

\item
{\tt f} : for parameter of filename type. {\tt f} may be followed
by any combination of r/w/e/n meaning test for read access, write
access, presence of file, absence of file. Thus fw means test whether
file given as a value of parameter is writable. 
\end{itemize}

\item
{\tt mode} : mode of parameter. Allowable value is any reasonable
(it is: a/h/q/hl/ql) combination of : 

\begin{itemize}
\item
{\tt a/auto} : effective mode equals to the {\it value} of parameter named
{\tt mode} in parameter file. If that parameter is not found in parameter
file or is found invalid then the effective mode is 'hidden'. 

\item
{\tt h/hidden} : No questions are asked, unless default value is invalid
for given data type. for example "qwerty" is specified as a value
for integer parameter. Note that is PILOverrideQueryMode function
was called with argument set to PIL\_QUERY\_OVERRIDE then no questions
are asked even for parameters with invalid values.

\item
{\tt l/learn} : If application changed parameter value, new value will be
written to parameter file when application terminates.
Actually this takes places when application calls either PILClose()
or PILFlushParameters() (or CommonExit() when writing ISDC's CTS
compliant software).
If this flag is not specified then any changes to the parameter 
(via PILGetXXX or PILPutXXX) are lost and are not written to disk.

\item
{\tt q/query} : Always ask for parameter. The format of the prompt is :
prompt field from parameter file (parameter name if prompt fielf
is empty) followed by allowable range (if any) in <>, followed
by default value (if any) in [], followed by colon. Pressing RETURN
key alone accepts default value. If newly entered value (or default
value in the case RETURN key alone is pressed) is unacceptable library
prompts user to reenter value. If the value is overridden by command
line argument, then the PIL library does not prompt for that parameter
(if value is valid and within boudaries if any) 
Note that is PILOverrideQueryMode function
was called with argument set to PIL\_QUERY\_OVERRIDE then no questions
are asked ever (even for parameters with invalid values).

\end{itemize}

\item
{\tt default} : default value for parameter [this field is optional]. This can be:
yes/no/y/n for booleans, integer/real literals (ie. 123, -34567 for integers, 1.23,
1234, -45.3e-5 for reals) for integers/reals, and string literals for
strings and filenames. String literals can be: abcdef, "abcdef", 'abcdef'. 

\item
{\tt min} : minimum value allowable for parameter [this field is optional].
Range checking is enabled only if both {\tt min} and {\tt max} fields
are nonempty. See also {\tt max}.
When {\tt max} field is empty then {\tt min} field can also contain pipe
symbol (vertical bar)
separated list of allowable values for given parameter. This works for
integer, real, string and filename types. For instance :

\begin{verbatim}
  OutFile,f,ql,"copy.o",/dev/null|copy.o|dest.o,,"Enter output file name"
\end{verbatim}

specifies that OutFile parameter can take only 3 distinct values, it is
/dev/null, copy.o or dest.o. Furthermore, for string (and \_ONLY\_ for string,
this does \_NOT\_ apply for filename parameter types) parameter types,
case does not matter, and string returned by PILGetString is converted
to uppercase. Note, that automatic conversion to uppercase is only done when
enum list is specified for given parameter.

\item
{\tt max} : maximum value allowable for parameter [this field is optional].
Works for integer, real string and filename data types. Both {\tt min} and 
{\tt max} must be specified for range checking to be active. Also {\tt min}
cannot be larger than {\tt max}. In case of any format error in {\tt min} or
{\tt max} PIL assumes that no range checking is requested. See also 
{\tt min} for a description of enumerated value list.

\item
{\tt prompt} : short description of parameter to be displayed whenever
library asks for value. If none is given library will display parameters name. 

\end{itemize}

As an example :

\begin{verbatim}
      pressure,r,ql,1013,,,"Enter atmospheric pressure in hPa" 
\end{verbatim}

describes parameter named pressure of type real, mode = query + learn, with
default value = 1013, no range checking and prompt

\begin{verbatim}
   "Enter atmospheric pressure in hPa" 
\end{verbatim}

Empty lines and lines beginning with '\#' are considered to be comment lines. 

\section{How parameter files are named and where are they looked for ?}\label{PILRefWhereFiles}

Typically for every executable there is a corresponding parameter file. The
name of parameter file is the name of executable file plus ".par" suffix.
Thus executable :

\begin{verbatim}
  isdc_copy
\end{verbatim}

will have parameter file named :

\begin{verbatim}
  isdc_copy.par
\end{verbatim}

Parameter files are searched for in several locations: 

\begin{itemize}
\item
PFILES enviromnent variable 

This variable is used to specify where the parameters are looked for. The
variable uses a ";" delimiter to
separate 2 types of parameter directories: 

\begin{verbatim}
<path1>;<path2>
\end{verbatim}

where path 1 is one or more user/writeable parameter directories, and
path 2 is one or more system/read-only parameter directories. When
path 1 equals path 2 one can omit path 2 and semicolon. The PIL library
allows multiple ":"-delimited directories in both portions of the
PFILES variable. The default values from path 2 are used the first
time task is run, or whenever the default values have been
updated more recently than the user's copy of the parameters. The user's
copy is created when a task terminates, and retains any learned
changes to the parameters. 

\item
Current working directory.

It is equivalent of PFILES set to ".". 
\end{itemize}

\paragraph{Notes\\}
{\it
contrary to FTOOLS/SAOrd/XPI PFILES environment variable can be left
undefined. In this can case PIL
library will look for parameter files only in current directory. FTOOLS
executables return error in this situation. 
}


\section{PIL extensions to IRAF parameter files format}\label{PILRefExtensions}

This section lists PIL extensions to IRAF parameter files.

\subsection{Parameter file line length}\label{PILRefLineLength}

PIL limits parameter file length to 2000 characters. This is much larger
that IRAF parameter file line length limit (80 or 255 depending on
application/library). Thus parameter files created by PIL may not
necessarily be readable by IRAF.

\subsection{Expansion of environment variables}\label{PILRefEnvExpansion}

If value of given parameter contains the following string :

\begin{verbatim}
      ${ANY_VAR_NAME}
\end{verbatim}

PIL expands it to the value of ANY\_VAR\_NAME environment variable. Any number
of environment variables can be specified. Also the same variable can be
specified many times. As an example, for a user joe with home directory
in /home/joe :

\begin{verbatim}
      ${HOME}/pfiles/${HOME}
\end{verbatim}

is expanded to

\begin{verbatim}
      /home/joe/pfiles/home/joe
\end{verbatim}

\subsection{Vector support}\label{PILRefVector}

PIL internally supports parameters with values with specify vectors with
either fixed or variable number of elements. This works for parameter
types: integer, real and real4. The parameter itself has
to be of type string (type stored in parameter file). Thus it can be read 
as either string (by calling PILGetString) or vector of values
(by calling PILGetxxxVector or PILGetxxxVarVector). See description of
PILGetxxxVector or PILGetxxxVarVector functions for more details.


\section{How parameters are evaluated}\label{PILRefEvaluate}

In general parameter's values are read from the parameter file. They can
however be overridden if the command line arguments are entered. 
Let's assume that we have written simple application named ISDCCopy to 
copy a file. It accepts 2 parameters, namely InFile and OutFile. 
The corresponding parameter file could be : 
  
\begin{verbatim}
InFile,s,ql,sample1.fits,,,"Enter input file name" 
OutFile,s,ql,/dev/null,,,"Enter output file name" 
\end{verbatim}

If we run that application without any arguments 

\begin{verbatim}
      ISDCCopy
\end{verbatim}

it will prompt us for these two parameters. Pressing 2 times {\bf RETURN} key
will accept default values and in this case application will attempt to copy
sample1.fits file onto /dev/null device (not a very useful function).
If we type : 

\begin{verbatim}
      ISDCCopy sample34.fits
\end{verbatim}

or 

\begin{verbatim}
      ISDCCopy InFile="sample34.fits"
\end{verbatim}

it will ask only for 2nd second parameter. The value of first parameter will
be set to sample34.fits. If we
type: 

\begin{verbatim}
      ISDCCopy sample45.fits mycopy.fits
\end{verbatim}

or 

\begin{verbatim}
      ISDCCopy InFile="sample45.fits" OutFile="mycopy.fits"
\end{verbatim}

or 

\begin{verbatim}
      ISDCCopy OutFile="mycopy.fits" InFile="sample45.fits"
\end{verbatim}

it will not ask for any parameters. If we type : 

\begin{verbatim}
      ISDCCopy OutFile="mycopy.fits"
\end{verbatim}

it will ask only for the first parameter. 

\paragraph{Notes\\}
{\it
If a call to PILOverrideQueryMode has been made and PIL\_QUERY\_OVERRIDE
mode is in effect PIL library does not prompt user when invalid or out
of range argument is encountered. Instead it returns with an error.

Bogus parameter names passed in command line (i.e. those without maching
counterpart in parameter file) may result in application returning 
with an error PIL\_BOGUS\_CMDLINE. This can happen if application calls
PILVerifyCmdline(). PILInit() itself does not call PILVerifyCmdline().
}

\subsection{Positional parameters}\label{PILRefPositionalPar}

When specifying new value for a parameter on the command line, the
simplest method is to type its value only :

\begin{verbatim}
      exename par1value par2value par2value [ ... ]
\end{verbatim}

More specifically, PIL treats n-th command line argument as new value
for n-th parameter in the parameter file (hence the name *positional*). 
That is, assuming there are no empty/comment lines, the parameter in 
the n-th line in the parameter file.

\subsection{Named parameters}\label{PILRefNamedPar}

A more flexible method to specify new value of the parameter is to use
the syntax :

\begin{verbatim}
      name=value
\end{verbatim}

Using this syntax, one can specify new value for the parameters in any
order. Thus :

\begin{verbatim}
      ISDCCopy OutFile="mycopy.fits" InFile="sample45.fits"
\end{verbatim}

and

\begin{verbatim}
      ISDCCopy InFile="sample45.fits" OutFile="mycopy.fits"
\end{verbatim}

are equivalent. Furthermore, since spaces are allowed around '=' separator,
than all the following formats are equivalent :

\begin{verbatim}
      ISDCCopy OutFile=mycopy.fits
      ISDCCopy OutFile =mycopy.fits
      ISDCCopy OutFile= mycopy.fits
      ISDCCopy OutFile = mycopy.fits
\end{verbatim}

{\it note: any positional parameters must precede parameters given 
with name=value syntax.
}
