DPUSER - The Next Generation: Python and GDL bridges
Author: Thomas Ott

# Python and GDL bridges

DPUSER can be compiled to offer the ability to call Python and/or GDL code.

## Python setup

Python support is loaded dynamically when the first python code is executed. In order to do so, DPUSER must know where to find the python dynamic link library.
If you are using the DPUSER terminal application, the library will be loaded from whereever the `DPUSER_PYTHONLIB` environment variable is pointing. This environment variable can be either set in your `.bashrc` or similar, or within DPUSER itself with the setenv procedure:
`setenv "DPUSER_PYTHONLIB", "/usr/lib/x86_64-linux-gnu/libpython3.5m.so"`
In QFitsView, you set the location within the Preferences Dialog, under the Paths tab.

## GDL setup

GDL is included statically, so in order to use GDL commands, there is nothing to be done. As with GDL itself, you need to set the `GDL_PATH` environment variable so it knows where to look for its `*.pro` files. On Linux and MacOS, you set the GDL_PATH as follows (note the '+' with will expand the path):
`export GDL_PATH="/path/to/gdl/pro:+/path/to/your/codes"`
On Microsoft Windows, since the colon is used to specify drive letters, use the following (separator is semicolon, forward slashes, no quotes):
`set GDL_PATH=c:/path/to/gdl/pro;+c:/path/to/your/codes`

# Variable conversion

The python and GDL bridges convert between the following variable types:

DPUSER | Python | GDL
--- | --- | ---
integer | PyLong | Long
float | PyFloat | Double
complex | PyComplex | complex
string | String | String
fits | numpy.ndarray | array
fits list | tuple | list | struct

# Calling sequences

## Calling python code

There are three ways implemented how to call python code from within DPUSER:

- The python procedure takes a string as argument, which will execute the string within a python interpreter:
  `DPUSER> python "print(10)"
  `
  will exactly do that, within python.
- The same can be achieved calling the python procedure without argument. The `DPUSER>` prompt will change to `>>>`, and all entered text will be passed to the python interpreter:
  `DPUSER> python
  >>>ivar=10
  >>>print(ivar)
  >>>exit
  DPUSER>
  `
  You exit the python mode by typing `exit`. This will, actually, not exit the python interpreter, but change the prompt again back to `DPUSER>` and pass all input to the DPUSER interpreter.
  It is possible to access variables created within the python interpreter:
  `hhh = pyvar("ivar")
  `
  This will create a deep copy of the python variable `ivar`. Note that changing the DPUSER variable does not change the corresponding python variable, since it is a deep copy.
- You can use python code inline DPUSER code. If this code resides within a python module, it will be loaded automatically. The calling syntax for such functions is module.submodule.function, e.g.:
  `DPUSER> hhh = numpy.zeros(100)
  `
  Inline calling of python code expands to locally stored functions, i.e. any function defined in python mode can be called from within DPUSER:
  `DPUSER> python
  >>>def add(a,b):
  ... return a+b
  >>>exit
  DPUSER> print add(2,2)
  `

## Calling GDL code

For calling GDL code, only the inline method is supported. Of course, you can write procedures and functions in `*.pro` files and execute these. The included GDL interpreter will search for these using the `GDL_PATH` environment variable. Another small trick: If you want to make sure that a GDL procedure or function is called, capitalize the function name (since GDL is case insensitive, but DPUSER is, it will then call the GDL function):
`DPUSER> print sin(10)
DPUSER> print Sin(10)
`
Arguments and keywords will be updated when calling GDL procedures and functions.