\documentclass[11pt]{article}

% GILDAS specific definitions
\include{gildas-def}

\def\Num{{\tt Numeric}}                                          
\def\Numa{{\tt Numeric.array}}
\def\NP{{\tt NumPy}}
\def\NPa{{\tt numpy.ndarray}}
\def\Pc{{\tt PYTHON}}
\def\SV{{\tt SicVar}}
\def\SS{{\tt SicStructure}}
\def\sd{{\tt \_\_sicdata\_\_}}
\def\sn{{\tt \_\_sicname\_\_}}
\def\sl{{\tt \_\_siclevel\_\_}}
\def\main{{\tt \_\_main\_\_}}

\title{PYGILDAS: Interleaving Python and GILDAS\\
       \large{End-user and developer documentation}}
\author{S\'ebastien Bardeau, Emmanuel Reynier,\\
        J\'er\^ome Pety and St\'ephane Guilloteau}
\date{24-apr-2018}
\makeindex{}

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

\begin{document}

\maketitle

\begin{center}
  Version 0.8
\end{center}

\begin{rawhtml}
  Note: this is the on-line version of the Introduction to the Python port
  of GILDAS.
  A <A HREF="../../pdf/gildas-python.pdf"> PDF version</A>
  is also available.
\end{rawhtml}

\begin{rawhtml}
  Related information is available in:
  <UL>
  <LI> <A HREF="../greg-html/greg.html"> GREG:</A> Grenoble Graphics
  <LI> <A HREF="../sic-html/sic.html"> SIC:</A> Simple Interpretor of Commands
  </UL>
\end{rawhtml}

\section{Context}

Goal: to create an inter-operable environment in which a SIC driven program can also
use all Python facilities and vice-versa: a Python code could import a SIC-based
program.\\
Method: first create a common space in which SIC and Python communicates by their
respective ``objects'': SIC variables and Python \NP\ arrays.\\
Content: description of the SIC variable to Python object mapping.\\


% --- End-user documentation ------------------------------------------------

\section{End-user documentation}

\subsection{Prerequisites {\it (what you have to know)}}

{\it If you wonder how to compile Gildas with the Python binding activated,
please refer to section \ref{txt:installation}.}

\subsubsection{Python basics}
\label{txt:pythonbasics}

\paragraph{Identifiers}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Identifiers}}
To the opposite to SIC, Python (like C) is case sensitive. SIC variables will be
imported in Python variables with names arbitraryly lowercased. There are also a
few forbidden characters in Python identifiers, especially '\%' and '\$'. The dot
'.' is reserved for a special purpose. See subsection \ref{txt:getfunc} for more
details.

\paragraph{Multidimensional-array arrangement in memory}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Multidimensional-array arrangement in memory}}
Multidimensional arrays in C (and thus Python) are stored in row-major order; in
Fortran they are in column-major order. For a 2-dimensional array (matrix), this
means that C stores each row contiguously in memory, while Fortran stores each
column contiguously. More generally, for an N-dimensional array, in C the last
dimension is contiguous in memory, while in Fortran the first dimension is
contiguous. This means that for the same area allocated in memory, Fortran and C
indices are transposed:
\begin{center}
\begin{math}
a_{Fortran}(d_1,...,d_N) \leftrightarrow a_C[d_N,...,d_1]
\end{math}
\end{center}
where $N$ is the number of dimensions and $d_i$ the $i^{th}$ dimension.\\
Remember also that first element through one dimension has index 1 in Fortran, and
index 0 in C. Finally, we can write:
\begin{center}
\begin{math}
a_{Fortran}(i,j,...,k) \equiv a_C[k-1,...,j-1,i-1]
\end{math}
\end{center}
This element is the same but accessed from Fortran or from C respectively.

\paragraph{The {\tt vars()} built-in function}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt vars()}}
With no arguments, displays the dictionary\footnote{a Python dictionary is an {\it
associative array}: a set of couples keys + items.} of the current name area. Thus
{\tt vars().keys()}\footnote{the {\tt .keys()} (resp. {\tt .values()}) method
returns the keys (resp. the values) list of any dictionary.} is a list of all
variables defined in the current name area. With a variable as argument, displays
the attributes list of this variable.

\paragraph{The {\tt dir()} built-in function}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt dir()}}
With no arguments, displays the whole list of variables, functions or other objects
defined in the current name area. With a variable as argument, displays the list of
attributes but also methods and other objects associated to this variable.

\paragraph{The {\tt \_\_doc\_\_} attribute}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt \_\_doc\_\_ }}
Each Python object (functions, classes, variables,...) provides (if programmer has
filled it) a short documentation which describes its features. You can access it
with commands like {\tt print myobject.\_\_doc\_\_}. You can provide a
documentation for your own objects (functions for example) in the body of their
definition as a string surrounded by three double-quotes:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> def myfunc():
...    """'myfunc' documentation."""
...    pass
...
>>> print myfunc.__doc__
'myfunc' documentation.
\end{verbatim}
\end{minipage}
\end{center}

\paragraph{Global/local variables and module name spaces}
\addcontentsline{toc}{paragraph}{\hspace{1.6cm}{Global or local variables and name spaces}}
Python has the usual notion of global and local variables. A variable may be either
visible in all the main code (it is {\it global}) or only in the function which
defines it (it is {\it local}). When a variable is called in a function, Python
searches it in the local name space and if not found, it searches it in the global
name space.\\

When a module is imported, it has its own global and locals name spaces, which it
does not share with the main ones. Thus, if a variable is defined as global in a
module, it can only be accessed as an element of the module. Let us assume we want to
import a module named {\tt mymodule} which provides an {\tt execute()} function. This
function executes command lines in the module global name space\footnote{it may be coded
this way: {\tt def execute(string): exec(string) in globals()}}.
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> import mymodule
>>> mymodule.execute('a = 0')
>>> mymodule.a
0
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> a # is not defined (or visible) in the main name space.
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'a' is not defined
\end{verbatim}
\end{minipage}
\end{center}
Note that importing all module objects in the main name space does not give a
solution:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> from mymodule import execute
>>> # 'execute()' is now a member of the main name space
>>> execute('a = 0')
>>> a # is not defined...
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'a' is not defined
>>> execute('print a') # but seems defined 'somewhere'...
0
>>> print __name__ # Prints the current module name
__main__
>>> execute('print __name__') # Prints the module name the
...                           # 'execute()' function works in
mymodule
\end{verbatim}
\end{minipage}
\end{center}
{\tt execute()} function still works in {\tt mymodule} (and defines variables as
members of it) although there is no '{\tt mymodule}' module visible in the main name
space.\\

Finally you will have to import the brand new created variable if you want to make
it visible in the main name space:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> from mymodule import a
>>> a
0
\end{verbatim}
\end{minipage}
\end{center}
Note that the two objects {\tt a} (imported from {\tt mymodule}) and
{\tt mymodule.a} are the same object (not a copy):
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> execute('b = [0, 0, 0]')
>>> from mymodule import b
>>> b
[0, 0, 0]
>>> b[0] = 1
>>> b # the one imported into 'main' from 'mymodule'
[1, 0, 0]
>>> execute('print b') # the one in 'mymodule'
[1, 0, 0]
\end{verbatim}
\end{minipage}
\end{center}

\subsubsection{\NP\ basics}
\label{txt:numabasics}
\index{\NP}

 Array handling is provided to Python by the optional package \NP. \NP\ derives
from the older module \Num\ which documentation is available at
{\tt http://nume ric.scipy.org/numpydoc/numdoc.htm}. You will have to pay for the
\NP\ documentation\footnote{see {\tt http://www.tramy.us}}, but the \Num\ one
may be sufficient to begin handling arrays with Python. You can also find an
extensive list of the \NP\ functions, methods and attributes at {\tt
http://www.scipy.org/Numpy\_Example\_List\_With\_Doc }.\\
 The type {\tt ndarray} provided by \NP\ module has a large set of attributes and
methods which can help to deal with these objects. This module also brings many
useful functions.
\addcontentsline{toc}{paragraph}{\hspace{2cm}{Accessing array elements}}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> from numpy import array, reshape
>>> a = reshape(array(range(1,25)),(2,3,4))
>>>     # integers from 1 to 24 rearranged in a 2x3x4 data cube
>>> a
array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]],
       [[13, 14, 15, 16],
        [17, 18, 19, 20],
        [21, 22, 23, 24]]])
>>> type(a)
<type 'numpy.ndarray'>
\end{verbatim}
\end{minipage}
\end{center}

Basic array elements access may be summarized as follows:

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> a[0] # First subarray through first dimension
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> a[0][1] # Second subarray through first dimension of subarray 'a[0]'
array([5, 6, 7, 8])
>>> a[0][1][2]
7
>>> a[0,1,2] # Same as above
7
>>> j = (0,1,2)
>>> a[j] # Tuples are valid indices
7
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}
>>> a[:] # All subarrays through first dimension, thus 'a' itself
array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]],
       [[13, 14, 15, 16],
        [17, 18, 19, 20],
        [21, 22, 23, 24]]])
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}
>>> a[0:1] # lower limit is included, upper limit excluded,
           # thus only a[0]
array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]]])
>>> a[:,1:,:2] # All elements through 1st dimension,
               # all elements except 1st one (0) through 2nd dimension,
               # 1st two elements (0 and 1) through 3rd dimension:
array([[[ 5,  6],
        [ 9, 10]],
       [[17, 18],
        [21, 22]]])
\end{verbatim}
\end{minipage}
\end{center}


\paragraph{Attributes}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Attributes}}
Attributes come with any \NPa. Among others we can mention:
\begin{itemize}
\item The {\tt .shape} built-in attribute: is a Python tuple storing the dimensions
      of the input array.

\item The {\tt .dtype} built-in attribute: a \NPa\ brings its datatype in a special
      object called {\tt dtype}, which can be retrieved with the {\tt .dtype}
      attribute. Default type is {\tt dtype('<i4')} ({\it standard integer}) for
      integers, and {\tt '<f8'} ({\it double precision}) for floats. We will import
      different kind of numbers from SIC (different memory size allocated per
      element), so the dtypes will be one of {\tt '<f8'} ({\it double precision
      float}), {\tt '<f4'} ({\it single precision float}), {\tt '<i4'} ({\it
      integers}), or {\tt '|S1'} ({\it single characters}).

\item The {\tt .itemsize} built-in attribute: is the size allocated in memory (in
      bytes) for each array element (see dtypes above).

\end{itemize}

\paragraph{Methods}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Methods}}
Methods come with any \NPa. Among others:
\begin{itemize}
\item The {\tt .flatten()} built-in method: returns a {\it flat} (rank 1) vector compound
      with a copy of all input array elements.

\item The {\tt .tostring()} built-in method: returns a string representation of the
      data portion of the array it is applied to. It can be used to concatenate
      elements of a character ('{\tt |S1}') array.
\end{itemize}

\paragraph{Functions}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Functions}}
Functions must be imported from \NP\ module. Among others:
\begin{itemize}
\item The {\tt array()} built-in function: returns a \NPa\ from a list of elements
      (or list of lists,...), from a tuple (or tuple of tuples,...), or even from
      any valid \NPa. The array constructor also takes an optional {\tt dtype} (see
      above), an optional {\tt savespace} argument, and an optional {\tt copy}
      argument (see below).\\
      Try also {\tt ones()} or {\tt zeros()} with a tuple containing dimensions as
      argument to create new arrays.

\item The {\tt size()} built-in function: displays the number of elements of the
      input array.

\item The {\tt rank()} built-in function: displays the number of dimensions of the
      input array (0 = scalar, 1 = vector, etc).

\item The {\tt len()} built-in function: displays the number of elements of the
      input array along the first dimension.

\item See also: {\tt reshape()}.
\end{itemize}

\paragraph{Subarrays and derivates}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Subarrays and derivates}}
An important feature is that arrays that derive from \NPa\ are not copies: they
still point to the memory area of the initial array.
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> from numpy import zeros
>>> a = zeros((2,3))
>>> a
array([[0, 0, 0],
       [0, 0, 0]])
>>> b = a[0] # Subarray
>>> b
array([0, 0, 0])
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> c = reshape(a,(6,)) # 1D version of 'a'
>>> c
array([0, 0, 0, 0, 0, 0])
>>> a[0,0] = 1
>>> b[1] = 2
>>> c[2] = 3
>>> a
array([[1, 2, 3],
       [0, 0, 0]])
>>> b
array([1, 2, 3])
>>> c
array([1, 2, 3, 0, 0, 0])
\end{verbatim}
\end{minipage}
\end{center}

The array constructor (built-in function) {\tt array()} can take an optional
boolean argument {\tt copy} which indicates if the above feature applies or not
to the derived array:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> a = array((0,0,0))
>>> a
array([0, 0, 0])
>>> b = array(a,copy=True)  # A copy: does not share its data with 'a'
>>> c = array(a,copy=False) # Not a copy: shares its data with 'a'
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> a[0] = 1
>>> b[1] = 2
>>> c[2] = 3
>>> a
array([1, 0, 3])
>>> b
array([0, 2, 0])
>>> c
array([1, 0, 3])
\end{verbatim}
\end{minipage}
\end{center}


\newpage
\subsection{Using Python from SIC}

\subsubsection{The SIC command \Pc}
If Python and the \NP\ module was detected, SIC provides the command
\Pc\ with various behaviors depending on what follows (or not) on
command line:
\begin{itemize}
\item {\bf Starting Python}: in all cases, the first call to the command
      starts the Python interpreter in the background if it was not already
      launched. This is done only once:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}
SIC> PYTHON
Python 2.5 (r25:51908, Nov 14 2006, 22:44:28)
[GCC 4.1.1 20061011 (Red Hat 4.1.1-30)] on linux2
Entering interactive session. Type 'Sic()' to go back to SIC.
>>>
\end{verbatim}
\end{minipage}
\end{center}

The SIC variables are not yet available at this stage, assuming the
user may not need them. You have to invoke the {\tt .get()} method
(with no arguments) to import them (see section \ref{txt:import} for
details):

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}
>>> pysic.get()
Importing all SIC variables into Python...
... done.
>>>
\end{verbatim}
\end{minipage}
\end{center}

\item {\bf Switching to Python}: by default, if no argument follows, an
      interactive session is launched (see above). It has the same
      behavior as the standard interactive Python mode: multiline
      definition for functions and classes, and command history. To exit
      both SIC and Python, type {\em CTRL-D} as usual. The {\tt exit()}
      function is also available. To go back to SIC, call the {\tt Sic}
      object with {\tt Sic()}.

\item {\bf Executing a Python script}: if the first argument which follows
      the command \Pc\ is a string ending with the three characters
      `{\tt .py}', SIC assumes that you gave it a Python filename. SIC
      will look in all the {\tt MACRO\#DIR:} directories it usually looks
      in for its own procedures. SIC also solves the logical names if any.
      If the file is found, it will be executed by the Python interpreter
      in the current name space:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> TYPE test.py
print "Hello world!"
a = 1
a
print "a value is", a

# This line is a comment
for i in xrange(1,4):
   print i

if True:
   print "True"
else:
   print "False"
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> PYTHON test.py
Hello world!
a value is 1
1
2
3
True
SIC>
\end{verbatim}
\end{minipage}
\end{center}
Note that the command {\tt a = 1} does not print any output. You have to
explicitely request a print to see any value. After the execution you
fall back to the SIC prompt. If the {\tt SIC\%VERIFY} flag is set to
{\tt ON}, commands are printed before execution:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> SIC VERIFY ON
I-SIC,  VERIFY       is ON
SIC> PYTHON test.py
>>> print "Hello world!"
Hello world!
>>> a = 1
>>> a
>>> print "a value is", a
a value is 1
>>> for i in xrange(1,4):
...    print i
1
2
3
>>> if True:
...    print "True"
... else:
...    print "False"
True
SIC>
\end{verbatim}
\end{minipage}
\end{center}

\item {\bf Passing arguments to Python scripts}: You can pass
  arguments to the Python script after its name. They will be
  available in the {\tt sys.argv} list as usually when you launch
  Python scripts from shell:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> TYPE test2.py
import sys
for i in sys.argv:
  print i, type(i)
SIC> PYTHON test2.py 1 qwerty "ABCD"
test2.py <type 'str'>
1 <type 'str'>
qwerty <type 'str'>
"ABCD" <type 'str'>
SIC>
\end{verbatim}
\end{minipage}
\end{center}
Arguments are also parsed by SIC before being sent to Python:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> DEFINE DOUBLE A
SIC> LET A 1.234
SIC> py test2.py A "A" 'A'
test2.py <type 'str'>
A <type 'str'>
"A" <type 'str'>
1.234 <type 'str'>
SIC>
\end{verbatim}
\end{minipage}
\end{center}

\item {\bf Parsing Python script arguments}: Sic does NOT interpret
  arguments starting by a slash as options of the command. This can be
  useful to simulate a Sic-like calling sequence, but implemented in
  Python. The Gildas-Python module {\tt sicparse.py} can help you to
  parse such options in Python:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> type test3.py
import sicparse
parser = sicparse.OptionParser()

# Declare 1 known option:
parser.add_option(
  "-m",           # Short name
  "--myopt",      # Full name
  dest="optval",  # Variable name where option value will be stored
  nargs=1,        # Number of arguments expected
  type="float",   # Kind of arguments
  default=1.23)   # Default value if option is absent

# Call again add_options to declare more options

# Parse:
try:
  (options, args) = parser.parse_args()
except:
  raise StandardError,"Invalid option"

print "Success"
print "Command arguments: ",args
print "Options: ",options
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> python test3.py ABCD
Success
Command arguments:  ['ABCD']
Options:  {'optval': 1.23}
SIC> python test3.py ABCD /myopt 4.56
Success
Command arguments:  ['ABCD']
Options:  {'optval': 4.56}
SIC>
\end{verbatim}
\end{minipage}
\end{center}
But of course, as in Sic, arguments starting with a slash must be then
double-quoted:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> python test3.py /home/me
Usage: test3.py [options]

test3.py: error: no such option: /home/me
Traceback (most recent call last):
  File "./test3.py", line 19, in <module>
    raise StandardError,"Invalid option"
StandardError: Invalid option
SIC> python test3.py "/home/me"
Success
Command arguments:  ['"/home/me"']
Options:  {'optval': 1.23}
\end{verbatim}
\end{minipage}
\end{center}

\item {\bf Raising errors in Python scripts}: There are typically 3
  ways to raise errors in Python scripts:
\begin{enumerate}
\item let Python raise its own errors, e.g.
\begin{verbatim}
SIC> type test4.py
print 1/0
SIC> python test4.py
Traceback (most recent call last):
  File "./test4.py", line 1, in <module>
    print 1/0
ZeroDivisionError: integer division or modulo by zero
SIC>
\end{verbatim}
\item {\tt raise} your own Python error, e.g.
\begin{verbatim}
SIC> type test5.py
arg = 0
if (arg==0):
  raise StandardError, "Argument must not be null"
else:
  print 1/arg
SIC> python test5.py
Traceback (most recent call last):
  File "./test5.py", line 3, in <module>
    raise StandardError, "Argument must not be null"
StandardError: Argument must not be null
SIC>
\end{verbatim}
\item turn ON the error status of the {\tt SIC$\backslash$PYTHON}
  command, such as it behaves correctly when hand is given back to
  Sic. For example:
\begin{verbatim}
SIC> type test6.py
def main():
  try:
    print 1/0
  except:
    print "E-SIC, Some error when printing 1/0"
    pysic.sicerror()  # Set the SIC\PYTHON command error
    return            # Leave the function and the script

if __name__ == "__main__":
    main()

SIC> py test6.py
E-SIC, Some error when printing 1/0
SIC>
\end{verbatim}

Note that these 3 methods raise an error in Sic, i.e. the flag {\tt
  SIC\%ERROR} is true on return, and that procedures will stop in such
a case (if {\tt ON ERROR} is {\tt PAUSE}).

The last syntax gives the best integration in Sic, because in
particular it hides the Python error traceback. However, this requires
1) to catch the error with a {\tt try/except} clause, 2) to tell Sic
an occured thanks to the method {\tt sicerror()}, and 3) to leave the
script right after. This last point can only be achieved by putting
the whole code in a (top) function, from which you can {\tt return}
when required. {\tt exit} is not satisfying because it performs too
much cleaning, nor {\tt raise} since a traceback would be back.

\end{enumerate}

\item {\bf Sending Sic-formatted messages to Sic}: the method {\tt
  message()} can be used to send messages to Sic. They will be
  formatted and filtered by the standard Sic messaging mechanism,
  e.g.:
\begin{verbatim}
>>> pysic.message(pysic.seve.i,"FOO","Hello world!")
I-FOO,  Hello world!
\end{verbatim}
The {\tt seve} instance contains the usual elements ({\tt f, e, w, r,
  i, d, t, c}) which have to be used to indicate the message severity.

\item {\bf Executing a single-line Python command}: if any other character
      string follows the \Pc\ command, it will be sent to the Python
      interpreter as a single line command. Multiline feature can not be
      used in this case:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> PYTHON print "Hello world!"
Hello world!
SIC>
\end{verbatim}
\end{minipage}
\end{center}
The command line sent after the \Pc\ command is executed by the Python interpreter.
It is also printed after a {\tt >>>} prompt if the {\tt SIC\%VERIFY} flag is
{\tt ON}:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> SIC VERIFY ON
I-SIC,  VERIFY       is ON
SIC> PYTHON print "Hello world!"
>>> print "Hello world!"
Hello world!
SIC>
\end{verbatim}
\end{minipage}
\end{center}
Take care that what you type at SIC prompt after \Pc\ command is now case sensitive! There
will be no reformatting, except for single-quoted strings:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> PYTHON print 'Hello world?'
>>> print 'Helloworld?'
Helloworld?
SIC>
\end{verbatim}
\end{minipage}
\end{center}
 Please use double-quotes instead for commands sent by SIC to Python.

\end{itemize}

\subsubsection{Calling Python functions}
The Python community has developped a large set of additional modules for many
purposes. Some functions that SIC does not provide can be imported from an
external Python module. User can also define its own functions written with Python.

 The numerical functions can be called from SIC formulas. When SIC does not find a
function in its own builtin or user-defined ones, it will have a look in the
Python main namespace area (if Python interpreter is launched!). If one object name 
matches and is callable, it will call this Python function with the arguments you 
provided:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> PYTHON from scipy.special import jn
>>> from scipy.special import jn
SIC> PYTHON print jn.__doc__
>>> print jn.__doc__
y = jn(n,x) returns the Bessel function of integer order n at x.
SIC> DEF REAL A
SIC> A = JN(0,1)
SIC> EXA A
A               =   0.7651977                ! Real    GLOBAL
SIC>
\end{verbatim}
\end{minipage}
\end{center}
{\tt jn}\footnote{{\tt scipy} and its subpackages provide a large set of
mathematical functions for scientific computing. See project webpage for more
informations: {\tt http://www.scipy.org}} is the Bessel function, called here at
order 0 with {\tt x = 1}. Always take care to import (or create) your Python
functions in the main namespace. Note that function names are fully lowercased
before trying to match them with Python names.


\newpage
\subsection{Using SIC from Python}

\subsubsection{PyGildas modules}
Most of the Gildas packages can be directly imported as Python modules:
\begin{itemize}
\item {\tt import pysic}
\item {\tt import pygreg}
\item {\tt import pyastro}
\item {\tt import pyclass}\footnote{the current Class was called Class90
      before Feb '08}
\item {\tt import pyclic}
\item {\tt import pymapping}
\end{itemize}

During the import, 3 steps are executed:
\begin{itemize}
\item SIC (resp. GreG) is initialized as a background process,
\item the {\tt Sic} object is instantiated into Python \main\ (see
      subsection \ref{txt:Sicobject}),
\item all SIC variables are imported into Python \main\ (see
      subsection \ref{txt:import}).
\end{itemize}
From this point, you can use the (shared) variables, jump to SIC prompt, and use any
of the methods the module defines (see hereafter).


\subsubsection{Special commands}
\label{txt:specialcommands}

A set of special functions has been written for user convenience. They are provided
as methods of the modules {\tt pysic, pygreg, ...} if SIC is launched from
Python, and also in every case as methods of an instance called {\tt Sic} in
the Python \main\ (see subsection \ref{txt:Sicobject}):

\begin{itemize}
\item {\tt comm(string)}:
      \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt comm()}}
      takes a string as argument and sends it to the SIC interpreter, which will
      execute it. If SIC fails to interpret the command, or if the command
      itself returns an error, {\tt comm} will raise an error in
      Python\footnote{Please note that the {\tt @} command in SIC will not raise
      any error even if a command fails in the procedure executed. User is
      expected to correct it on-the-fly, or to tune the error handling with
      the {\tt ON ERROR} command in SIC.}. As usual in Python, it can be catched
      with the {\tt try} and {\tt except} couple of directives.

% \item {\tt enter()}:
%       \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt enter()}}
%       takes no arguments. Jumps to the prompt of the current SIC (or GreG) process.
%       Type \Pc\ to go back to Python. This is only provided in the case you
%       use Python which imports SIC.

\item {\tt setgdict(dictionary)}:
      \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt setgdict()}}
      define input dictionary as the area where Gildas variables will be
      imported, and automatically import these into the input dictionary. If a
      dictionary was already defined, it  is  first  cleaned  before filling
      the new one given in input.\\
      A call to this function is required if user wants to access the
      imported variables. This avoids polluting name areas because of
      uncontroled default. In interactive mode, the most common usage is to use
      the current name area, e.g. {\tt setgdict(globals()); print pi}. In script
      mode, prefer using a custom dictionary, e.g.
      {\tt d = dict(); setgdict(d); print d['pi']}, or even better the
      {\tt gdict} container (see subsection \ref{txt:gdict}).

\item {\tt get([string[,integer[,boolean]]])}:
      \label{txt:getfunc}
      \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt get()}}
      Takes a string as argument, which must be a valid SIC name (in
      SIC format, thus not case sensitive). Variable can be a scalar,
      an array, a structure, an header, a table, or an image. The
      second argument may be the level of the variable to be imported
      (0 = global, 1 = 1-local, and so on). It defaults to the current
      execution level. A third argument indicates if the function
      should be verbose ({\tt True}, default), or not ({\tt
        False}).\\
      `{\tt get()}' creates a \SV\ or a \SS\ instance
      sharing its data with the corresponding variable in SIC. Its
      name is the original SIC name, but lowercased, and converted in
      respect with the Python name conventions (see table
      \ref{tbl:conversion}). '{\tt \$}' can not appear in Python
      names: it is converted to `{\tt \_}'. `{\tt \%}' (structures in
      SIC) has a special treatment and is converted to `{\tt .}'  (see
      subsection \ref{SicStructure}). All structures elements are
      linked to the corresponding \SS\ as \SV\ (or \SS) attributes,
      and all header components of the images are linked to the
      corresponding \SV\ as \SV\
      attributes.\\
      `{\tt get()}' fails to import variable into Python when its
      converted name is a Python reserved keyword (such as `{\tt
        def}', `{\tt del}', `{\tt import}', `{\tt as}', ...), or a
      built-in function name (such as
      `{\tt type}', `{\tt range}', `{\tt min}', `{\tt max}', ...).\\
      With no argument, `{\tt get()}' imports all SIC variables by
      iteratively calling `{\tt get()}' itself with their names as
      argument.

\begin{table}[h!]
\begin{center}
\caption{SIC to Python names conversion}
\medskip
\begin{tabular}{cc}
SIC & Python\\
\noalign{\medskip}
\hline
\noalign{\medskip}
{\tt "ABC"}      & {\tt "abc"} \\
% {\tt "ABC.DEF"}  & {\tt "abc\_def"} \\
{\tt "ABC\$DEF"} & {\tt "abc\_def"} \\
{\tt "ABC\%DEF"} & {\tt "abc.def"} \\
% {\tt "ABC\_DEF"} & {\tt "abc\_\_def"} ???\\
\end{tabular}
\label{tbl:conversion}
\end{center}
\end{table}

\item {\tt exa([var1[,var2[,...]]])}:
      \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt exa()}}
      with one or more \SV\ or \SS\ instances as argument, displays one line per instance
      with the corresponding SIC variable name, details on its type, dimensions,...
      With no argument, displays this line for the full list of the SIC variables.
      Example:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> exa(pi)
PI               is a        REAL*8, 0D            (GLOBAL,RO) -> pi
\end{verbatim}
\end{minipage}
\end{center}

\item {\tt define(string[,boolean])}:
      \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt define()}}
      takes one string as argument and defines one or more variables in both SIC
      and Python. First keyword must be the type (one of {\tt real}, {\tt double},
      {\tt integer}, {\tt character} or {\tt structure}, or a non-ambiguous
      truncated form of them), followed by one or more valid variable-creator SIC
      name (e.g. `{\tt A}', `{\tt B*8}', `{\tt C[2]}', `{\tt D\%E}' or even
      `{\tt F\%G*8[2,3]}'). All  variables created this way are read-and-write. By
      default they are local to the current execution level, but you can provide a
      second optional argument set to {\tt True} to make the variables global. For
      images, give the command line you would give to the SIC interpreter, but
      without the {\tt define} keyword. {\tt exa()} is finally called on the
      newly created instance(s). Examples:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> define('real a')
 A               is a        REAL*4, 0D            (GLOBAL,RW) -> a
>>> define('double b c[2] d[2,3]')
 B               is a        REAL*8, 0D            (GLOBAL,RW) -> b
 C               is a        REAL*8, 1D (2x0x0x0)  (GLOBAL,RW) -> c
 D               is a        REAL*8, 2D (2x3x0x0)  (GLOBAL,RW) -> d
>>> define('structure e')
 E               is a   <structure>, 0D            (GLOBAL,RW) -> e
>>> define('character e%f e%g*6[2,3]')
 E%F             is a   CHARACTER*1, 0D            (GLOBAL,RW) -> e.f
 E%G             is a   CHARACTER*6, 2D (2x3x0x0)  (GLOBAL,RW) -> e.g
>>> define('image h centaurus.gdf read')
 H               is a (image)REAL*4, 2D (512x512x1x1) (GLOBAL,RO) -> h
\end{verbatim}
\end{minipage}
\end{center}

\item {\tt delete(var1[,var2[,...]])}:
      \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt delete()}}
      takes one or more \SV\ or \SS\ instances as arguments. Tries to delete the
      corresponding variable in SIC. On success, also deletes the input instance.

\item {\tt getlogical(string)}:
      \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt getlogical()}}
      takes one Python string as argument. The method translates a SIC
      logical and returns it as a Python string. Input name is
      case insensitive. An empty string is returned if no such SIC
      logical exists (no error is raised).

% \item {\tt pexecfile(string[,dict])}:
%       \addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{\tt pexecfile()}}
%       takes a Python file name as argument. Does the same as the
%       `{\tt execfile()}' standard Python function (which executes the file in
%       current name area), but also prints the command lines or full command
%       blocks before execution. The global dictionary used as name area can be
%       passed as second argument. \main\ dictionary is used by default (NOT the
%       current `{\tt globals()}' one).

\end{itemize}

\subsubsection{The {\tt gdict} container}
\label{txt:gdict}
 Modules have a special attribute named {\tt gdict} (actually, a class instance)
from which all Gildas variables can be easily retrieved and defined:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> import pysic
>>> pysic.get()
Importing all SIC variables into Python...
... done.
>>> g = pysic.gdict
>>> g
Container for imported Gildas variables. Variables are accessed as
   attributes of this object.
>>> dir(g)         # List of all imported variables
['__builtins__', 'debug_recursive', 'gildas_node', 'linedb', 'no', 'pi',
'run_window', 'sic', 'type_dble', 'type_inte', 'type_logi', 'type_long',
'type_real', 'yes']
>>> g.pi           # Get Gildas variable PI
3.14159265359
>>> g.a = (1,2,3)  # Set a new Gildas variable A
A               is a      INTEGER*4, 1D (3x0x0x0)   (GLOBAL,RW) -> a
>>> pysic.comm('exa a')
A               is an integer Array      of dimensions      3
            1            2            3
\end{verbatim}
\end{minipage}
\end{center}
Whatever the name area has been defined by user with {\tt setgdict}, any
{\tt gdict} instance will allways find the Gildas
dictionary\footnote{Technically, {\tt gdict} instances have no attributes. They
only have the methods {\tt \_\_getattr\_\_} and {\tt \_\_setattr\_\_} which
dynamically retrieve or define the \SV\ instances.}. The variable handling can
be found easier than the dictionary equivalent {\tt d['pi']}.

\subsubsection{The {\tt Sic} object in Python \main}
\label{txt:Sicobject}

 This object is obsolescent.
Whatever is the way you launched SIC and Python through the Pygildas features, an
object named {\tt Sic} will be created at initialization time in the Python \main.
It is used for these purposes:
\begin{itemize}
\item It stores (as attributes) aliases of commands documented at subsection 
      \ref{txt:specialcommands}. If user called Python from SIC, he can only access 
      them from the {\tt Sic} object. If user called Gildas from Python (e.g. by
      importing {\tt pysic} or {\tt pygreg}), he can either call these commands
      with the {\tt pysic}/{\tt pygreg} or {\tt Sic} prefix. Calling {\tt Sic()}
      switches to the SIC prompt.

\item It stores as an attribute the array of 10 instances named {\tt localspaces} and
      used to save local variables (see subsection \ref{txt:localspaces}).

\item It stores a logical flag named {\tt warnings} which activate/deactivate
      warnings (printed when importing a variable failed for example). It is set to 
      {\tt True} by default, but user can switch it to {\tt False}.

\end{itemize}


\newpage
\subsection{Importing SIC objects}
\label{txt:import}
{\it Importing} SIC objects (more precisely {\it making them visible from Python})
is quite easy and all the trick is based on the \NP\ package and its {\tt ndarray}
type object. All SIC variables are imported through instances of two special
classes: \SV\ and \SS\ which implements \NPa\ features.

\subsubsection{SIC arrays}
SIC arrays are imported as \SV\ instances. Let us define\footnote{the {\tt comm()}
method of the {\tt Sic} object or the {\tt pysic, pygreg, ...} modules (depending
of the calling method) sends its string argument as a command line to SIC. See
subsection \ref{txt:specialcommands} for all the usefull methods.} a 1D array
{\tt A} in SIC:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}
>>> Sic.setgdict(globals())
Importing all SIC variables into Python...
... done.
>>> Sic.comm('DEFINE INTEGER A[3]')
\end{verbatim}
\end{minipage}
\end{center}

Defining a variable in SIC automatically imports it in Python \main. Here {\tt A} 
is imported into a \SV\ instance with name '{\tt a}':
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> a
[0 0 0]
>>> print a
<SicVar instance>
array([0, 0, 0])
>>> type(a)
<type 'instance'>
>>> print a.__doc__
A SicVar instance.
\end{verbatim}
\end{minipage}
\end{center}

 All of the \NPa\ attributes, methods or functions should apply to the \SV\
instances, because almost all these instances behaviors are redirected to their
\NPa\ component.
% \footnote{nevertheless, if something goes wrong, try to deal with the 
% {\tt {\it varname}.\_\_sicdata\_\_} attribute which {\it is} the real \NPa.}
Their elements can be accessed with standard \NP\ indexing syntax:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> a[0]
0
>>> a[1:] # Elements 1 and subsequents
[0 0]
>>> a += 1 # Adds 1 to all elements
>>> a
[1 1 1]
\end{verbatim}
\end{minipage}
\end{center}
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}
>>> a[:] = 0 # Sets all elements to 0
>>> a
[0 0 0]
>>> len(a) # Length
3
>>> a.shape
(3,)
\end{verbatim}
\end{minipage}
\end{center}

Remember that data pointed to by \SV\ instances is not a copy: if you
modify it in Python it will be modified in SIC:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> a[0] = 1
>>> a
[1 0 0]
>>> Sic.comm('EXA A')
A               is an integer Array      of dimensions      3
            1            0            0
\end{verbatim}
\end{minipage}
\end{center}

 Remember also that derived arrays share their data with the initial array:

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> b = a[0:2] # First two elements (upper limit is excluded)
>>> print b.__doc__
A SicVar instance.
>>> b
[1 0]
>>> b += 1 # Adds 1 to all elements
>>> b
[2 1]
>>> a
[2 1 0]
\end{verbatim}
\end{minipage}
\end{center}

Note that {\tt b}, as a derived array, {\bf is} itself a \SV\ instance, but is only visible 
in Python. And remember the different memory arrangement between SIC (Fortran) and C 
(Python) for multidimensionnal arrays (see subsection \ref{txt:pythonbasics}):
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('DEFINE INTEGER C[2,3,4]')
>>> c.shape
(4, 3, 2)
>>> c[0,0,0] = 1  # First element
>>> c[3,2,1] = 2  # Last element
>>> Sic.comm('EXAMINE C')
C     is an integer Array    of dimensions      2     3     4
     1          0          0          0          0          0
     0          0          0          0          0          0
     0          0          0          0          0          0
     0          0          0          0          0          2
\end{verbatim}
\end{minipage}
\end{center}


\subsubsection{SIC scalars}
\label{txt:SicVar}

Particular \NPa's which have no (0) dimension have a special treatment: they still
have \NPa\ type, but their representation and handling is similar to standard Python
scalars. SIC scalars are imported in Python as \NPa\ scalars through \SV\ instances:

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('DEF REAL D')
>>> d
0.0
>>> print d.__doc__
A SicVar instance.
\end{verbatim}
\end{minipage}
\end{center}

You have to take care that you cannot modify scalars (and, actually, any \SV\
or \SS\ instance) with commands such as {\tt d = 1}, because this
unbounds {\tt d} to its corresponding \SV\ instance (which is lost and
deleted if no other variable uses it), and bounds it to integer 1. If it happens,
you can {\tt get('D')} again: \SV\ instance is recreated and all the
previous changes will not be lost because {\tt D} have not been deleted in SIC.

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('LET D 1.')
>>> d
1.0
>>> d = 2.            # ooops... 'd' instance is lost!
>>> type(d)
<type 'float'>        # 'd' is bound to a standard float,
>>> Sic.comm('EXA D') # but 'D' remains unchanged in SIC.
D          =   1.000000              ! Real    GLOBAL
>>> Sic.get('D')      # Reincarnates d.
>>> d
1.0
\end{verbatim}
\end{minipage}
\end{center}

 Thus, to modify scalars from Python, you have to access its data through its
unique element:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> d[0] = 2.
>>> d
2.0
>>> print d.__doc__
A SicVar instance.
\end{verbatim}
\end{minipage}
\end{center}


\subsubsection{SIC structures}
\label{SicStructure}

SIC structures are imported in Python into instances of the special class named {\tt
SicStructure}:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('DEFINE STRUCTURE E')
>>> e
<pgutils.SicStructure instance at 0xb7f00bcc>
\end{verbatim}
\end{minipage}
\end{center}

SIC structure elements are stored in attributes of \SS\ instances, and these
attributes are themselves \SV\ instances. Call the {\tt print} statement to
print all (and only) \SV\ (or \SS) attributes, and some details on them.

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('DEFINE INTEGER E%A')
>>> Sic.comm('DEFINE REAL E%B[2]')
>>> Sic.comm('DEFINE DOUBLE E%C[2,3]')
>>> e
<sicutils.SicStructure instance at 0xb7f009cc>
>>> print e # Detailed printing
<SicStructure instance>
a = 0                                 INTEGER*4 0D
c = [[ 0.  0.] [ 0.  0.] [ 0.  0.]]      REAL*8 2D (2x3x0x0)
b = [ 0.  0.]                            REAL*4 1D (2x0x0x0)
>>> print e.c # 'c' attribute is a SicVar instance
<SicVar instance>
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])
\end{verbatim}
\end{minipage}
\end{center}

Nested structures can be recursively imported:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('DEFINE STRUCTURE E%D')
>>> Sic.comm('DEFINE INTEGER E%D%A')
>>> print e
<SicStructure instance>
a = 0                                 INTEGER*4 0D
c = [[ 0.  0.] [ 0.  0.] [ 0.  0.]]      REAL*8 2D (2x3x0x0)
b = [ 0.  0.]                            REAL*4 1D (2x0x0x0)
d = <SicStructure>
>>> print e.d
<SicStructure instance>
a = 0                                 INTEGER*4 0D
\end{verbatim}
\end{minipage}
\end{center}

\SS\ instances can be added new attributes and these attributes are automatically
instantiated in the SIC structure\footnote{if possible. The destination value
must be caste-able by the {\tt numpy.array} method into a {\tt numpy.ndarray}}:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> e.e = 1
E%E             is a      INTEGER*4, 0D             (GLOBAL,RW) -> e.e
>>> Sic.comm('EXA E%E')
E%E             =            1               ! Integer GLOBAL
>>>
>>> e.f = (1,2,3)
E%F             is a      INTEGER*4, 1D (3x0x0x0)   (GLOBAL,RW) -> e.f
>>> Sic.comm('EXA E%F')
E%F             is an integer Array      of dimensions      3
            1            2            3
>>>
>>> import numpy
>>> e.g = numpy.zeros((3,3))  # Create a 3x3 real numpy array
E%G             is a         REAL*8, 2D (3x3x0x0)   (GLOBAL,RW) -> e.g
>>> Sic.comm('EXA E%G')
E%G             is a double precision Array      of dimensions      3     3
   0.00000000000000000       0.00000000000000000       0.00000000000000000
   0.00000000000000000       0.00000000000000000       0.00000000000000000
   0.00000000000000000       0.00000000000000000       0.00000000000000000
\end{verbatim}
\end{minipage}
\end{center}

\subsubsection{SIC images}
\label{txt:sicimages}
Standalone headers or tables are imported like any other structure or array
respectively. SIC images, which combines a header with a table, are also
imported in \SV\ instances. Thus, image elements are accessed through standard
indexing to the instance itself, and header components through attributes of this
instance:

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('DEFINE IMAGE F centaurus2.gdf WRITE')
PygildasWarning: 'max' is a ndarray attribute, could not overwrite it.
PygildasWarning: 'min' is a ndarray attribute, could not overwrite it.
PygildasWarning: 'ndim' is a ndarray attribute, could not overwrite it.
\end{verbatim}
\end{minipage}
\end{center}
You have to take care that \NPa's provide a large set of attributes and methods,
and some of them have name identicals to headers components: they are not imported
and only a warning is printed.

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> f
[[ 0.01676085  0.0141144   0.0194073   0.0141144   0.0105858 ]
 [ 0.02911095  0.01852515  0.0141144   0.01323225  0.0123501 ]
 [ 0.09968295  0.0264645   0.          0.0141144   0.01499655]
 [ 0.035286    0.0141144   0.01676085  0.01499655  0.01323225]
 [ 0.0229359   0.017643    0.0123501   0.0158787   0.0158787 ]]
>>> f[0,0]
0.0167608503252
>>> print f
<SicVar instance>
array([[ 0.01676085,  0.0141144 ,  0.0194073 ,  0.0141144 ,  0.0105858 ],
       [ 0.02911095,  0.01852515,  0.0141144 ,  0.01323225,  0.0123501 ],
       [ 0.09968295,  0.0264645 ,  0.        ,  0.0141144 ,  0.01499655],
       [ 0.035286  ,  0.0141144 ,  0.01676085,  0.01499655,  0.01323225],
       [ 0.0229359 ,  0.017643  ,  0.0123501 ,  0.0158787 ,  0.0158787 ]], dtype=float32)
rms       = 0.0                                        REAL*4 0D
major     = 0.0                                        REAL*4 0D
blan      = 8                                       INTEGER*4 0D
ptype     = 3                                       INTEGER*4 0D
system    = 'EQUATORIAL  '                       CHARACTER*12 0D
... (and so on for all header elements)
>>> print f.rms # 'rms' is an attribute of 'f', and a SicVar itself.
<SicVar instance>
array(0.0, dtype=float32)
\end{verbatim}
\end{minipage}
\end{center}


\subsubsection{Handling character strings}

 Character strings are imported in a \SV\ instance as any other SIC
variable:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.comm('DEFINE CHARACTER G*8')
>>> Sic.comm('LET G "ABCDEFGH"')
>>> g
'ABCDEFGH'
>>> print g
<SicVar instance>
array('ABCDEFGH',
      dtype='|S8')
>>> len(g)
8
\end{verbatim}
\end{minipage}
\end{center}

Remember that \NPa 's provide the {\tt .tostring()} method which returns a Python
string resulting of the concatenation of elements of a character array ('{\tt |S*}'
dtypes). This can be useful to handle SIC strings in Python. Nevertheless string
concatenation and multiplication is already implemented in \SV\ instances:

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> h = 'xyz' + g + 'ijk'
>>> h
'xyzABCDEFGHijk'
>>> type(h)
<type 'str'> # A standard Python string
>>> h = 2*g
>>> h
'ABCDEFGHABCDEFGH'
\end{verbatim}
\end{minipage}
\end{center}

 These \SV\ strings can also be easily modified\footnote{whereas real Python
strings are {\it immutable} objects: you can not modify them inplace and have
to make copies for such handlings.}:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> g[0] = "qwerty"
>>> g
'qwerty  ' # note 'g' has been automatically blank filled
>>> Sic.comm('EXA G')
G     = qwerty             ! Character* 8 GLOBAL
\end{verbatim}
\end{minipage}
\end{center}

% Substring assignment not available anymore (to be fixed)
% >>> g[4:8] = 'xyz'
% >>> g
% 'qwerxyz ' # substring assignment + auto blank filling


\newpage
\subsection{Object status in SIC:}

\paragraph{Read-only or read-and-write?}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Read-only or read-and-write?}}
 Read or write status is preserved when variables are imported in Python, and
 trying to modify their values will raise an error:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> pi
3.14159265359
>>> print pi.__doc__ # pi was imported from SIC
A SicVar instance.
>>> pi[0] = 0
Traceback (most recent call last):
  File "<STDIN>", line 1, in <module>
  File "/home/bardeau/gildas/gildas-src-dev/pc-fedora6-ifort/kernel/
python/pgutils.py", line 204, in __setitem__
    raise PygildasValueError, "Variable is read-only in SIC."
pgutils.PygildasValueError: Variable is read-only in SIC.
\end{verbatim}
\end{minipage}
\end{center}

The protection of \SV\ intances against deletion or re-definition (ie using
{\tt pi = 1} instead of {\tt pi[0] = 1}) is not implemented. See considerations in
subsection \ref{txt:SicVar}.

\paragraph{Global or local variable (in the SIC sense)?}
\label{txt:localspaces}
\addcontentsline{toc}{subsubsection}{\hspace{1.6cm}{Global or local variable?}}
\SV\ and \SS\ instances have a \sl\ attribute which is an integer
set to the level of the corresponding variable in SIC (0 for global, 1 for first
local level, and so on).

When SIC defines any variable, it automatically imports it in the Python \main\ 
name space\footnote{This is subject to changes as long as the Gildas-Python
binding is in a beta development status.}. When this variable is SIC-local (when
executing procedures for example), importing it in Python may overwrite a lower
level instance which has the same name. To prevent this, the {\tt Sic} object in
Python \main\ provides an array of 10 instances (one per level) which are used
to temporarily store object which would have been erased. This array is named
{\tt localspaces} and objects are saved as attributes of its 10 elements.
Consider these SIC procedures:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}
SIC> type localtest1.sic
define integer a
let a 123
pause
@localtest2.sic
SIC> type localtest2.sic
define real a[3]
pause
\end{verbatim}
\end{minipage}
\end{center}
They will define local variables named `{\tt A}' at different local levels. Let's define
a global `{\tt A}' variable and execute these procedures:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC> define char a*8
SIC> let a "qwertyui"
SIC> @localtest1.sic
SIC_2> define integer a
SIC_2> let a 123
SIC_2> pause
SIC_3> python
Entering interactive session. Type 'Sic()' to go back to SIC.
>>> a
123
>>> a.__siclevel__
1
>>> Sic.localspaces[0].a
'qwertyui'
>>> Sic.localspaces[0].a.__siclevel__
0
\end{verbatim}
\end{minipage}
\end{center}
`{\tt a}' object currently in Python \main\ is the level-1 SIC object. The SIC-global 
`{\tt A}' variable has been saved as an attribute of the {\tt Sic.localspaces[0]}
element.\\
Let's go deeper:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC_3> continue
SIC_2> @localtest2.sic
SIC_3> define real a[3]
SIC_3> pause
SIC_4> python
Entering interactive session. Type 'Sic()' to go back to SIC.
>>> a
[ 0.  0.  0.]
>>> a.__siclevel__
2
>>> vars(Sic.localspaces[0])
{'a': 'qwertyui'}
>>> vars(Sic.localspaces[1])
{'a': 123}
\end{verbatim}
\end{minipage}
\end{center}
Now we find the level-2 object in the Python \main, and the 2 lower-level variables with the
same name are saved in the {\tt Sic.localspaces} array. At any stage, user can access its
current-level variables in the Python \main, but also any lower level ones through
the {\tt Sic.localspaces} array.\\
Let's end procedures:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}SIC_4> continue
SIC> python
Entering interactive session. Type 'Sic()' to go back to SIC.
>>> a
'qwertyui'
>>> vars(Sic.localspaces[0])
{}
>>> vars(Sic.localspaces[1])
{}
\end{verbatim}
\end{minipage}
\end{center}
In an automatic cascading mechanism, the lower-level variables are moved back to the
Python \main\ when the current level one is deleted. The {\tt Sic.localspaces} array is
cleaned at the same time so their is no double reference for any object. Thus at the end 
of the procedures, the SIC-global variables are back in the Python \main, and the 
{\tt Sic.localspaces} array has no more attributes.\\

Remember that an object is saved in the {\tt Sic.localspaces} array if and only if an
upper level variable is defined with the same name. Thus, at any time, the Python
\main\ may contain objects from different levels. User does not have to care about the
saving and unsaving mechanism: all is automatic and goes back as it was after procedure
execution. He only has to know that he can access any lower level variable in the
{\tt Sic.localspaces} array.


% --- Programmer documentation ----------------------------------------------
\newpage
\section{Programmer documentation}

\subsection{Installing PyGILDAS}

\subsubsection{Prerequisites}
\label{txt:installation}

Before compiling, Gildas administrative scripts\footnote{i.e. when executing
{\tt source admin/gildas-env.sh}} try to detect your Python installation. It
retrieves the version number of the python executable visible from your shell
({\tt python -V}) and searches for associated {\tt libpython}{\it version}{\tt .*}
and {\tt Python.h}. The latter header file is not always shipped with default
system installations, but it is required to compile the Python binding for
Gildas. If not found, you should consider to install the Python development
package for your installation.\\

WARNING: if your Python is the one installed on your system, try only to install
the development package for it. NEVER try to upgrade it! Python is deeply used
in modern Linux systems and you might break it definitely.\\

Additionally, Gildas-Python binding rely on the extended array-support
module \NP. It must be importable in Python in order to activate the
compilation of the binding.\\

Versions: PyGILDAS is known to work with Python from versions 2.6.* up
to 3.4.*, and with \NP\ version 1.4.* to 1.7.*.

\subsubsection{How to build your own Python version}
\label{txt:ownpython}

You can easily build your own Python binaries and libraries by
following the steps below:

\begin{enumerate}
\item Retrieve the sources from the official website:
      {\tt http://www.python.org/download/}

\item Unpack, compile and install Python (any version, here with
      Python 2.7):
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}cd <compilation-directory>
tar jvzf Python-2.7.tar.bz2
cd Python-2.7
./configure --enable-shared [--prefix=/your/custom/installation/path]
make
make test
make install
\end{verbatim}
\end{minipage}
\end{center}
      The {\tt --enable-shared} option ensures to build both static
      and dynamic Python libraries. This option is \emph{mandatory}
      for a correct behaviour of the Gildas-Python binding.  The {\tt
      --prefix} option allows you to install Python in a custom
      location (instead of {\tt /usr/local}). This is useful in
      particular if you do not have administrative priviledges.
      Finally you should refer to section~\ref{txt:readline} if you
      want to enable the command line history in the Gildas-Python
      binding.

\item Make your new Python available. Fill the binary and library
      location in the corresponding environment variables:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}export PATH=/your/custom/installation/path/bin:$PATH
export LD_LIBRARY_PATH=/your/custom/installation/path/lib:$LD_LIBRARY_PATH
\end{verbatim}
\end{minipage}
\end{center}
You can make your custom Python the permanent default for yourself
(i.e. overriding the system Python), or you can make it a transient
default to be used only for Gildas compilation. This depends on your
needs, see post-compilation instructions in
section~\ref{txt:custompython}.

\item Check your installation:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}which python
python -V
python -c "import sqlite3"
\end{verbatim}
\end{minipage}
\end{center}
{\tt sqlite3} Python module is optional, needed only for the extension
named Weeds for Class. If {\tt import sqlite3} fails, install (or ask
your system administrator) sqlite3 headers on your system (system
package providing {\tt sqlite3.h} i.e. sqlite3-devel), and restart
from step 2.
\end{enumerate}

Then you are ready to install \NP\ (see below).

\subsubsection{Python module {\tt readline} for command history}
\label{txt:readline}

 The Python interpreter launched from SIC provides the command line history if and
only if the Python module {\tt readline} is imported. This is done automatically when
the interpreter is launched. If this module can not be imported, an {\tt ImportError}
will be raised and you will not have the command history at the Python prompt.

 The {\tt readline} module is a Python builtin module. In most case it has been compiled 
and installed during your Python installation. Nevertheless, in case of a new
compilation and installation of Python, it may not be available. You can check this
by trying to import it in a standard Python session: 
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> import readline
\end{verbatim}
\end{minipage}
\end{center}

 If an {\tt ImportError} raises, here is what you (or your system
administrator) have to do. The basic idea is that the {\tt readline}
Python module is compiled from a {\tt readline.c} in Python
source. Your system must provide the libraries {\tt libreadline.a} and
{\tt libtermcap.a} to compile it successfully.
\begin{enumerate}
\item Check the {\tt config.log} file (the output of the {\tt
      ./configure} command) in the directory used to compile
      Python. Search for {\tt readline} occurences and look for errors
      that did not allow to find {\tt readline} on your system.
\item It may appear that some symbols where undefined. They are
      provided by the two system libraries {\tt libreadline.a} and
      {\tt libtermcap.a}. Check if you have them, install them if
      not. Launch {\tt ./configure} command again.
\item If the {\tt readline} Python module still not compiles, try fo
      force {\tt ./configure} to link against one or two of the above
      system libraries:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}./configure --with-libs='-ltermcap'
\end{verbatim}
\end{minipage}
\end{center}
      The module should now compile. {\tt make} and {\tt make install}
      your Python with its new module.
\end{enumerate}

\subsubsection{Install \NP\ module for Python}

\NP\ is mandatory for the Gildas-Python binding. Building and
installing it requires some specific options and setting a correct
environment. You can follow these steps:
\begin{enumerate}
\item Download \NP\ from: {\tt http://www.scipy.org/Download}

\item Unpack and compile \NP. You can build \NP\ either for the Python
      installed on your system or for a custom one: the build will be
      done for the Python which is seen from your shell ({\tt which
      python}).
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}cd <compilation-directory>
tar xvzf numpy-1.3.0.tar.gz
cd numpy-1.3.0
python setup.py build --fcompiler=<compiler>
\end{verbatim}
\end{minipage}
\end{center}
      Usually {\tt gnu95} is the correct argument for the {\tt
      --fcompiler} option. Else (or if your want to know more), you
      should consider the following point:
\begin{verbatim}
  The two most popular open source fortran compilers are g77 and gfortran.
Unfortunately, they are not ABI compatible, which means  that  concretely
you should  avoid  mixing  libraries  built  with  one  with  another. In
particular, if your blas/lapack/atlas is built with g77, you  *must*  use
g77 when building numpy and scipy; on the  contrary,  if  your  atlas  is
built with gfortran, you *must* build numpy/scipy with gfortran.

* Choosing the fortran compiler
  - To build with g77:
    python setup.py build --fcompiler=gnu
  - To build with gfortran:
    python setup.py build --fcompiler=gnu95

* How to check the ABI of blas/lapack/atlas?
  One relatively simple and reliable way to check for the  compiler  used
to build a library is to use ldd  on  the  library.  If  libg2c.so  is  a
dependency, this means that g77 has been used.  If  libgfortran.so  is  a
dependency, gfortran has been used. If both are dependencies, this  means
both have been used, which is almost always a very bad idea.
\end{verbatim}
      In other words, for standard users, \NP\ has a linear algebra
      module ({\tt linalg}) which is linked with the system's
      blas/lapack/atlas libraries. This implies that the Fortran
      sources of \NP\ must be compiled with the same compiler which
      was used for the libraries. Check e.g. with {\tt ldd
      /usr/lib(64)/lapack.so} which compiler you will have to
      use.

\item Install \NP:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}python setup.py install [--prefix=/some/custom/installation/prefix]
\end{verbatim}
\end{minipage}
\end{center}
      The installation prefix ({\tt --prefix}) is required \emph{only}
      if you want to install \NP\ in a location different from your
      Python installation directory (e.g. you are using the default
      Python executable provided by your system but you do not have
      root permissions). In this case (only), you will have to fill
      the {\tt \$PYTHONPATH} environment variable to indicate where
      Python can find \NP.\\
      In the other cases, Python will install the module into its own
      installation directory, which is fine in particular when you are
      using a custom installation of Python. In this case you will
      also not have to augment the {\tt \$PYTHONPATH} since the module
      is installed in a standard location known by Python.

\item Check the installation. Launch Python and type:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}import numpy
numpy
numpy.__version__
\end{verbatim}
\end{minipage}
\end{center}
      You should recognize the installation path and the correct \NP\
      version.
\end{enumerate}

% Actually this is not true...
% WARNING: you must compile \NP\ with the same {\em version} Fortran
% compiler than the one used for the system libraries. If you plan to
% use another {\em version} of the same compiler (e.g. gfortran) to
% build Gildas, you will encounter troubles because you will mix
% dependencies on several versions of libgfortran for example.
% 
% On the other hand you {\em can} compile Gildas with {\em another}
% Fortran compiler, e.g. Ifort.

\subsubsection{Install {\tt scipy} module for Python (optional)}

The module named {\tt scipy} ({\it Scientific Python}) is not
necessary for the Gildas-Python binding, but it provides useful
functionalities you may want. The build and installation process is
exactly the same as for \NP:

\begin{enumerate}
\item Download {\tt scipy} from: {\tt http://www.scipy.org/Download}

\item Unpack and compile {\tt scipy}:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}cd <compilation-directory>
tar xvzf scipy-0.7.1.tar.gz
cd scipy-0.7.1
python setup.py build --fcompiler=<compiler>
\end{verbatim}
\end{minipage}
\end{center}

\item Install:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}python setup.py install [--prefix=/some/custom/installation/prefix]
\end{verbatim}
\end{minipage}
\end{center}
      If you provide a custom installation path ({\tt --prefix}), use
      the same as for \NP: you will not have to augment again the {\tt
      \$PYTHONPATH} for this second module.

\item Check the installation:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}import scipy
scipy
scipy.__version__
from scipy.special import jn
\end{verbatim}
\end{minipage}
\end{center}
      (the last line tries to import the Bessel functions named {\tt
      jn}).
\end{enumerate}

\subsubsection{Compiling Gildas with your custom Python (if any)}
\label{txt:custompython}

If you compiled and installed a custom version of Python and the
needed modules, then you can run the usual Gildas administrative
scripts:
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}cd <installation-directory>
tar xvzf gildas-src-jul14.tgz
cd gildas-src-jul14
source admin/gildas-env.sh [-c <compiler>]
# read carefully the messages (in particular those for Python)
make
make install
# read the last instructions
\end{verbatim}
\end{minipage}
\end{center}

\vspace{0.5cm}
If you followed correctly the installation of your custom Python and
the compilation of Gildas, Gildas is now binded to your custom Python
libraries. You have then 2 possibilities:
\begin{itemize}
\item if you use Python inside Gildas (i.e. SIC$\backslash$PYTHON
  commands), you can safely revert the {\tt python} command to its
  original state. Gildas will use your custom Python libraries,
  including its specific syntax and rules.
\item if you use the Gildas-Python modules (e.g. pygreg, pyclass) in
  Python, then you must import them from your custom Python
  executable. Either you keep it permanently in your \$PATH, either
  you call it explictly by a custom name (e.g. {\tt python34}) before
  importing the modules. Here also this means you have to use the
  correct syntax and rules.
\end{itemize}

\subsection{How SIC variables are imported}

\subsubsection{Comments on the strategy}

 Concerning variables handling from both SIC and Python, the first priority was to
manage the same data in memory from the two processes, e.g. a modification of a
variable in one process should be instantaneously visible in the other with no
particular resynchronization.

 Another consideration is that Python does not natively handle multi-dimensionnal
arrays. This feature can be easily added, but we need the \NP\ package.\\

It appeared quite naturally that the solution was to use the {\tt
  PyArray\_SimpleNewFromData()} function of the \NP\ C-API: it can
construct a \NPa\ from the memory address of an array, its dimensions
and its datatype.\\

With this feature the strategy can be summarized as follow:
\begin{itemize}
\item \NP\ freezes its {\tt array} definition (attributes, size in
  memory and so on) at compilation time. We can not add to it more
  interesting features, especially new attributes or write protection
  for read-only variables.
\item an overlay had to be created with one purpose: defining a set of features like
      \begin{itemize}
      \item the ability to define attributes to variables,
      \item the protection of read-only variables,
      \item a special treatment for character string variables (concatenation),
      \item ...
      \end{itemize}
      and all this must keep unmodified all the \NPa\ features (indexing, array
      handling, special functions and attributes, and so on)
\item this overlay was created as a Python class named \SV. It has three
      attributes: a string named \sn, which is the SIC name of the variable,
      a \NPa\ named \sd, which shares its data with the SIC variable, and its
      SIC-level (global or local) stored as an integer named \sl. All
      \NPa-like requests on a \SV\ are redirected to the \sd\ attribute: with
      this, \SV\ instances behaves like any other \NPa.
\end{itemize}

\subsubsection{The \SV\ class}

\SV\ instances should be automatically initialized with the {\tt get()}
function. When importing a variable, {\tt get()} calls the instance creator
{\tt SicVar()} with three arguments: SIC variable name (as a Python string), its level
(as an integer), and memory address of its descriptor (Python integer). It is the own 
responsibility of the {\tt get()} function to assign this instance to the correct 
Python variable name.\\
 During the initialization, {\tt SicVar()} defines three attributes to the instance:
\sn, \sl, and \sd. By convention the '{\tt \_\_}' delimiters denote objects that are
hidden to the user, but still accessible. \sn\ and \sl\ are a Python string and an integer,
and are used to keep a trace of what the original SIC variable is. \sd\ is a \NPa\
initialized with the informations provided by the descriptor (data address, dimensions,
type,...).

\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> Sic.define('real a')
 A               is a        REAL*4, 0D            (RW) -> a
>>> vars(a)    # vars() displays attributes names and values
{'__sicdata__': array(0.0, dtype=float32), '__sicname__': 'A', '__siclevel__': 0}
>>> type(a.__sicdata__)
<type 'numpy.ndarray'> # A NumPy array
>>> type(a.__sicname__)
<type 'str'>   # A Python string
>>> type(a.__siclevel__)
<type 'int'>   # A Python integer 
\end{verbatim}
\end{minipage}
\end{center}

\SV\ instances are used to import SIC standard variables (scalars or arrays). Due
to its class type, it can also accept new attributes, and thus be used to import
images (for example in an instance named {\tt ima}). In this case, the image (the
array component) is imported through the \sd\ attribute ({\tt ima.}\sd), and can be
directly accessed from {\tt ima} ({\tt ima[0,0]}). Header variables are imported
into other attributes ({\tt ima.naxis1}, {\tt ima.naxis2},...), provided they do
not attempt to overwrite a \NPa\ attribute or method. As any other imported SIC
variables, these header attributes are themselves \SV\ instances. See subsection
\ref{txt:sicimages} for details and example on importing SIC images.\\

 All attributes of a \SV\ instance are write-protected against deletion or
overwriting. This is a first importance for \sd, because deleting it would be
dramatic. Remember that the command {\tt a.}\sd\ {\tt = 0} do not modify its content
but bounds it to the 0 integer, loosing data and all information about the
corresponding SIC variable. But end-user should never have to deal with the \sd\
attribute, and have to work on the instance itself instead (for example
{\tt a[0] = 0}).\\
 These warnings also apply to images attributes: do not try {\tt ima.naxis1 = 0}
but {\tt ima.naxis1[0] = 0} instead.\\

 \SV\ instances come with a set of methods and attributes, for one part inherited
from the \NPa\ type, and for the other part (re)defined at instance initialization.
For example the addition ({\tt \_\_add\_\_} and {\tt \_\_radd\_\_}) is redefined to
add numbers or concatenate character strings.
\begin{center}
\begin{minipage}[t]{13cm}\small
\begin{verbatim}>>> dir(a) # All attributes and methods.
['__add__', '__copy__', '__deepcopy__', '__delattr__', '__div__',
'__doc__', '__eq__', '__ge__', '__getattr__', '__getitem__',
'__gt__', '__iadd__', '__idiv__', '__imul__', '__init__', '__int__',
'__isub__', '__le__', '__len__', '__lt__', '__module__', '__mul__',
'__ne__', '__nonzero__', '__radd__', '__rdiv__', '__repr__',
'__rmul__', '__rsub__', '__setattr__', '__setitem__', '__sicdata__',
'__sicname__', '__str__', '__sub__', 'astype', 'byteswapped',
'copy', 'iscontiguous', 'itemsize', 'resize', 'savespace',
'spacesaver', 'tolist', 'toscalar', 'tostring', 'typecode']
\end{verbatim}
\end{minipage}
\end{center}


\subsubsection{The \SS\ class}
 The only purpose of the \SS\ instances is to be objects that accept
user-defined attributes (as for SIC structures actually). The definition of the
{\tt SicStructure} class is rather simple. It is instantiated by the
{\tt SicStructure()} creator with the SIC structure name and level as only arguments,
which are stored in its \sn\ and \sl\ attributes.\\

 This empty instance in then filled by the {\tt get()} function: it loops through all
SIC variable dictionary and searches for all names which begin with the structure
name. For each valid variable it {\tt get()}'s it as a \SV\ attribute of the \SS\
instance. \SS s support nested structures, as user or program can define any kind
of attributes (\SV, \SS, or even standard Python objects).\\

%  As the only relation between a structure and its elements is its name and their
% prefix, user has to {\tt get()} it again to reloop through all SIC variable
% dictionary to synchronize the \SS\ instance to the SIC structure.\\

 For user convenience, the {\tt \_\_str\_\_()} method (called by {\tt
print myinstance} or {\tt str(myinstance)}) of the \SS\ class is redefined to
print all (and only) \SV\ and \SS\ attributes, with some details on them.

\newpage
\subsection{Array elements types}

As mentionned earlier (see subsection \ref{txt:numabasics}), \NPa\ elements can be
of different kind, precision, and thus memory size. This is reflected through the
{\tt .dtype} attribute of any \NPa. By default, integer elements are created
with the '{\tt <i4}' datatype (standard integer), and floats with the '{\tt <f8}'
one (double precision float). Nevertheless, not all SIC elements follows these
types. Attention have been paid to import SIC data into the correct type (see
table \ref{tbl:typecodes}).\\

\begin{table}[h!]
\begin{center}
\caption{OBSOLETE TABLE. SEE NUMPY DOCUMENTATION. SIC to \Num\ type conversion (for a 32-bit architecture)}
\medskip
\begin{tabular}{lcl}
SIC type & \Num\ typecode & \# of bytes\\
\noalign{\medskip}
\hline
\noalign{\medskip}
{\tt INTEGER*4} & {\tt 'i'} & {\tt sizeof(int) = 4} \\
{\tt REAL*4}    & {\tt 'f'} & {\tt sizeof(float) = 4} \\
{\tt REAL*8}    & {\tt 'd'} & {\tt sizeof(double) = 8} \\
{\tt LOGICAL*4} & {\tt 'i'} & {\tt sizeof(int) = 4} \\
{\tt CHARACTER} & {\tt 'c'} & {\tt sizeof(char) = 1}
\end{tabular}
\label{tbl:typecodes}
\end{center}
\end{table}

 Mixing arrays in Python formulas with element size different from the default
Python behavior is not problematic. \NP\ deals with all these types and applies
coercion to the adequate type, and all is completely transparent for the user.

% .. except in one case.
% When using augmented assignments (inplace addition for example), \Num\ tries to
% modify {\it inplace} the data. But if the second argument is of different type, an
% error is raised:
%
% \begin{center}
% \begin{minipage}[t]{13cm}\small
% \begin{verbatim}>>> from Numeric import array
% >>> a = array((1.,2.,3.),'f') # Single precision floats
% >>> a += 1. # 1. is a double precision float
% Traceback (most recent call last):
%   File "<stdin>", line 1, in ?
% TypeError: return array has incorrect type
% \end{verbatim}
% \end{minipage}
% \end{center}
%
% In this unique case (inplace operations), we have to manually coerce
% the argument to the correct array type with the {\tt .astype()} method:
% \begin{center}
% \begin{minipage}[t]{13cm}\small
% \begin{verbatim}>>> a += array(1.).astype('f')
% >>> a
% array([ 2.,  3.,  4.],'f')
% \end{verbatim}
% \end{minipage}
% \end{center}
%
%  Inplace operations have been redefined in \SV\ to prevent these errors. But this
% may be a source of errors for example if user incarnates a subarray of a \SV\
% instance into a standard \Numa.

\newpage
\section{Python 3K}
\label{txt:python3}

As of mid-october 2014, the Gildas-Python binding supports Python
3. This is implies more or less transparent changes depending on how
far you are involved in this topic.

\subsection{References}

Before switching to Python 3K, you might want to have a closer look to
what this implies. You may find the following documents helpful:
\begin{itemize}
\item Python 2 or Python 3? {\tt
    https://wiki.python.org/moin/Python2orPython3}
\item What's new in Python 3K: {\tt
    http://docs.python.org/py3k/whatsnew/3.0.html}
\item Porting to Python 3: {\tt
    https://wiki.python.org/moin/PortingPythonToPy3k}
\item Strings are now Unicode in Python 3K: {\tt
    https://docs.python.org/3.0/howto/ unicode.html}

\end{itemize}

\subsection{Standard end-user}

As a standard user, you are of course exposed to all the changes
implied by Python 3. You can use the {\tt 2to3} tool shipped with
Python 3 to translate your Python scripts. Note also that some Python
3 syntaxes and behaviors are backward compatible with Python 2.6 and
2.7, you should prefer them when possible.\\

Regarding the Gildas-Python binding itself, you should consider that:
\begin{itemize}
\item the support for Python 2.5 and lower has been removed (this,
  because Python offers some Python 3 pre-compatibility of our
  Gildas-Python internal code starting from Python 2.6),
\item the default Python strings are now Unicode strings, while Sic
  characters strings (and their representation as a {\tt SicVariable}
  in Python) remain ASCII strings (1 byte per character). We tried to
  deal with this as transparently as possible for you, so that you can
  still perform the usual actions on the {\tt SicVariable}
  strings. Unfortunately, this implies many hidden conversions between
  ASCII and Unicode.
\end{itemize}

\subsection{Developers using the Python binding}

If you are in charge of a Python module or package integrated in
Gildas, you should be aware of the following:
\begin{itemize}
\item as Gildas supports both Python 2 and 3, you are asked to provide
  your scripts with Python 2 syntax only. If needed, the scripts will
  be processed by the {\tt 2to3} Python tool at compilation time. Try
  also to use Python 3 syntax backported to Python 2 as much as
  possible in order to limit the differences between both syntaxes.
\item if your scripts are part of a Python module, they will be
  implicitly Python-compiled\footnote{see {\tt
      https://docs.python.org/3/library/py\_compile.html}} at
  compilation time. This pre-compilation is always done sooner or
  later by Python at first use of the module. Our intent is to offer
  this compilation for users who do not have write-access to the
  module installation path (e.g. shared installations of Gildas). See
  link for details.
\item designing the hierarchy of your Python package and (sub)modules
  is less trivial than it seems. Check carefully the \emph{relative
    imports} guidelines as described e.g. in {\tt
    https://docs.python.org/2/faq/programming.html\#what-are-the-best-practices-
    for-using-import-in-a-module}
\end{itemize}

\subsection{Developers of Fortran GILDAS packages}

As a pure Gildas developer (Fortran), the Gildas-Python binding offers
to you the possibility to make your library importable from
Python. This is done with the rule {\tt IMPORT\_FROM\_PYTHON = yes} in
the Makefile. Say, if your package is named \emph{foo}, you should be
aware that:
\begin{itemize}
\item the Python binary module \emph{pyfoo.so} is not anymore a
  symbolic link to \emph{libfoo.so}. Since symbolic links are not
  portable, the module \emph{pyfoo.so} has been made a real binary
  file.
\item the file \emph{foo-pyimport.c} (which provides the Python entry
  points) should not be compiled anymore into the Gildas library
  \emph{libfoo.so}. It is now the responsibility of Python to compile
  it implicitly and to put it in the binary module \emph{pyfoo.so}.
\end{itemize}


\newpage{}
\appendix{}

\section{What's new?}

\begin{itemize}
\item 2018-apr-24
\begin{itemize}
\item Removed support for \Num\ obsolete python package.
\end{itemize}

\item 2018-apr-09
\begin{itemize}
\item The {\tt \_\_dir\_\_} method of the {\tt gdict} container (see
  section \ref{txt:gdict}) is now redefined to return the list of
  Gildas-Python shared variables.
\end{itemize}

\item 2014-oct-13
\begin{itemize}
\item Added support for Python 3 (see details in
  section~\ref{txt:python3}). Removed support for Python 2.5 and
  lower. Python 2.6 and 2.7 still supported.
\end{itemize}

\item 2013-may-31
\begin{itemize}
\item Added argument {\tt verbose=True|False} to the method {\tt
    get()} (indicate if the method should be verbose or not when
  importing Sic variables).
\end{itemize}

\item 2013-may-30
\begin{itemize}
\item Document how to build Gildas with Python 2, when Python 3 is the
  default on the system. Waiting for Python 3 support in the
  Gildas-Python binding, currently under development.
\end{itemize}

\item 2012-may-14
\begin{itemize}
\item The method {\tt .sicerror()} is added to the Gildas-Python modules
      (e.g. pysic, pygreg, etc). It is intended to set the error status
      ON in Sic when executing a Python script, in order to raise custom
      errors from Python.
\item The method {\tt .message()} is added to the Gildas-Python modules,
      in conjuction to the object {\tt seve}. They should be used to print
      messages like Sic does, including on-screen and/or to-file
      redirection, and application of filtering rules.     
\end{itemize}

\item 2012-mar-06
\begin{itemize}
\item{Double quotes surrounding character strings arguments in SIC are
now preserved when they are passed to the sys.argv list in Python.
This is a change of behavior as they were implicitely removed up to
now, but could lead to problems on some cases, e.g. for Python commands
using a leading ``/'' for options as Sic does.}
\end{itemize}

\item 2010-sep-07
\begin{itemize}
\item{SIC aliases created from the SIC side are now automatically
imported to the Python side, like any other variables. SIC aliases
were already supported, but not imported by default.}
\end{itemize}

\item 2010-jul-08
\begin{itemize}
\item{Python 2.7 and \NP\ 1.4.1 are supported.}
\end{itemize}

\item 2010-mar-03
\begin{itemize}
\item{Added automatic creation of booleans (SIC logicals) when they
are attached to a \SS.}
\end{itemize}

\item 2010-jan-11
\begin{itemize}
\item{When executing a Python script from Gildas, 'sys.argv' is now a list
(and not a tuple anymore). This conforms the standard Python behavior.}
\end{itemize}

\item 2010-jan-07
\begin{itemize}
\item{Improved retrieving of the arguments passed to a Python script
through the SIC PYTHON command. Make sure that double quoted strings
with arbitrary number of blanks are not split nor modified.}
\end{itemize}

\item 2009-nov-18
\begin{itemize}
\item{Nested structures could not be correctly imported into Python in
some cases. Fixed.}
\end{itemize}

\item 2009-oct-06
\begin{itemize}
\item{Added method 'getlogical' which translates a SIC logical and returns it in a
      Python string.}
\end{itemize}

\item 2009-apr-27
\begin{itemize}
\item{Fixed a recursive call at initialization time of SicVar instances.}
\item{Ensure support for Python 2.6.2}
\end{itemize}

\item 2008-aug-01
\begin{itemize}
\item{Ensure support for Python 2.5.2}
\end{itemize}

\item 2008-jun-02
\begin{itemize}
\item{Gildas packages are available with a {\tt py*} prefix: {\tt pysic},
      {\tt pygreg}, {\tt pyastro}, {\tt pyclass} and {\tt pymapping}.}
\item{Enhanced support of string (scalar) variables: they are imported as
      a single element, i.e. characters are not splitted anymore in a
      subarray.}
\item{Enhanced support of \SS: adding an attribute to a \SS\ in Python
      automatically augments the corresponding structure in SIC.}
\end{itemize}

\item 2008-mar-06
\begin{itemize}
\item{New beta release, still under development. As of the current date, {\tt
      pysic} and {\tt pygreg} modules are obsolescent. They are replaced by a
      direct import of Gildas libraries which have been made
      Python-importable. This can be done by import commands such as {\tt
      import libgreg}. Please consider that the prefix {\tt lib} will soon
      disappear, and {\tt pysic} and {\tt pygreg} modules will not be
      available anymore at this point.}
\item{Thanks to the point above, some of the Gildas programs are now also
      importable from Python: {\tt libastro}, {\tt libclass}. More will
      come soon.}
\end{itemize}

\item 2006-mar-13
\begin{itemize}
\item Python modules {\tt pysic} and {\tt pygreg} are now provided to users. Importing
      one of them into a Python script launches the SIC (resp. GreG) process and
      imports its variables into the Python \main.
\item {\tt Sic.localspaces}: to prevent overwriting a variable when a deeper-level
      one is created in SIC with the same name, a saving and unsaving automatic
      mechanism of the \SV\ and \SS\ instances into a 10-dimensional array (one
      per level) is now available. To achieve this, the \SV\ and \SS\ instances
      now have a \sl\ attribute.
\item {\tt Sic.warnings} logical flag activates/deactivates {\tt PygildasWarning}'s.
\item Improvement of the \Num\ 24.2 retrocompatibility.
\item Enforced variable write-protection (if any) by setting the `writeable' flag of
      the \NPa 's. For compatibility with \Num, read-and-write or read-only status in
      SIC is still checked each time array elements are attempted to be modified.
\item {\tt define()} command can now be passed a second optional boolean argument
      which describes if the variable will be global or not. By default it is not,
      e.g. it is local to the current execution level.
\item Images are now automatically imported into Python at creation time. The
      {\tt get()} command is now also able to import images, thus the
      {\tt getimage()} command is not available anymore for users.
\item {\tt pexecfile()} function is provided to user. It does the same as the {\tt
      execfile()} Python function (execute a Python script in current name space),
      but also prints the commands during execution.
\item {\tt SIC$\backslash$PYTHON PythonCommandLine} and {\tt SIC$\backslash$PYTHON
      PythonProcedureName.py} functionalities now print or not the command lines
      depending on the {\tt SIC\%VERIFY} flag value.
\item {\tt SIC$\backslash$PYTHON PythonProcedureName.py} functionality now allows
      to be passed arguments. They can be retrieved in the '{\tt sys.argv}' list
      from Python. Arguments are parsed by SIC before calling the script. SIC now
      also searches in the {\tt MACRO\#DIR:} directories to find the Python script.
      Logical names are parsed if any.
\item Exit behavior is now the same whatever is the master process. To quit both
      SIC and Python, use {\em CTRL-D} (or {\tt exit()}) from Python, or {\tt
      EXIT} from SIC. As a consequence, use \Pc\ (from SIC) and {\tt Sic()} (from
      Python) to switch to the other command-line interpreter.
\item 64 bits support.
\end{itemize}

\item 2006-oct-12
\begin{itemize}
\item{First beta release.}
\end{itemize}

\item 2006-sep-13
\begin{itemize}
\item Python embedding into SIC. Python interpreter is started with new SIC
      command {\tt 'PYTHON'}, and can execute Python command-lines, Python
      scripts, or even jump to interactive mode.
\item Python (numerical) functions can now be called in SIC formulas, provided
      Python interpreter is started and function exists in Python \main.
\item Support for both \Num\ and \NP\ modules: \sd\ attribute is a \NPa\ if \NP\
      is installed, or a \Numa\ if not.
\end{itemize}

\item 2006-jul-07
\begin{itemize}
\item Loss of the {\tt sicarray} type. \SV\ instances have now two elements:
      \sn\ (the SIC variable name) and \sd\ (a \NPa). Previously \sd\ was a {\tt
      sicarray} with itself a \Numa\ attribute.
\item \NP\ support: SIC variables (arrays and scalars) are now imported as \NPa,
      using the same C-API function from \Num\ that \NP\ still supports.
\item Adaptation of the adequates methods of the \SV\ class to handle the unique
      element of the \NPa\ scalars through {\tt [0]} indexing (\NP\ only provides
      indexing for its scalars through {\tt [()]} index).
\item Attempting to define an image attribute which name is already used for a
      native method or attribute of the \NPa's will not raise an error anymore but
      will only warn the user.
\item \SV\ strings now support concatenation ({\tt +}) and duplication ({\tt *}).
\item Automatic blank filling when assigning a Python string to a \SV\ string
      (\Num\ provides this feature but \NP\ does not: it requires the two strings
      to have the same length).
\item A \SV\ subarray is now also a \SV\ with the same \sn\ attribute and with a
      \sd\ sharing its data with the original array, and thus with the SIC variable
      (previously a \SV\ subarray was a \Numa). Such subarrays inherit the \SV\
      specific methods, such as string handling or write protection if any.
\item Usefull functions such as {\tt get()}, {\tt comm()} or {\tt exa()} are now
      methods of the {\tt Sicfunctions} class, and are visible through the {\tt sic}
      instance created during the process initialization.
\item Creation of the {\tt sic()}, {\tt greg()}, {\tt define()} and {\tt delete()}
      methods of the {\tt Sic functions} class.

\end{itemize}

\item 2006-jun-21
\begin{itemize}
\item{First unofficial release.}
\end{itemize}

\end{itemize}

\newpage
\tableofcontents

\printindex{}

\end{document}

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