# Interactive Numeric Python Shell

- Introduction
- Environment
- Functions
- Commands
- Examples
- Python Shell Help

  # Introduction

  The OpenEV Python Shell provides access to image data in a Python scripting environment with built-in mathematical functions (supplied by the Numeric Python module). The OpenEV Python Shell adds a thin extra layer of interpretation to ordinary python, allowing a slightly different syntax to be used for some frequently used functions for typing convenience (no brackets). The core convenience functions (called commands) are registered automatically when the Python Shell launches, and have more argument checking infrastructure than regular python functions. To illustrate the difference between python and command syntax, the following example shows two ways of saving an array from the Python Shell environment to a file:

      Python:

      SaveArray(my_array,'my_filename')

      Command:

      save my_array my_filename

  Extension modules with other commands may be registered using the core command loadext, but commands require more overhead to implement and in most cases it is preferable to use the ordinary python syntax.

  If you're not familiar with Python or Numeric Python (NumPy) here are some references:

  - Python
  - Numerical Python

  # Environment:

  At startup (from the Edit/Python Shell menu item) the Python environment automatically imports functions from Numeric and gdalnumeric, and registers the core commands. Numeric provides Numeric Python and gdalnumeric provides functions to access OpenEV image data.

  The shell consists of a command input window (bottom) and an output window (top). Aside from the registered commands, it behaves in the same way as the Python command line interpreter. Use the up and down arrow keys to scroll through previous command history.

  ## OpenEV Functions:

  In addition to the functions imported from Numeric python, OpenEV's Python shell includes the following functions:
  - LoadFile(filename[,xoff][,yoff][,xsize][,ysize]) - returns a numpy array containing the data from filename. If xoff and yoff are specified, filename will be read starting at pixel (column) offset xoff and line (row) offset yoff. If xsize and ysize are specified, only xsize pixels and ysize lines will be read; otherwise, the remainder of the file will be read in. The returned array will have dimensions ysize x xsize if the raster is greyscale; N x ysize x xsize if the raster has N channels.

  - display(array) - appends the array to the current OpenEV view and displays it.

  - roi() - returns the Region Of Interest (ROI) drawn out by the ROI tool in the format (x, y, width, height).

  - get_roi(array) - given an array, and an ROI marked by the ROI tool, extract that region from array and return it.

  - SaveArray(array,filename[,format])- save array to file filename, using format. format must be a GDAL write-supported format, such as 'GTiff' (Geotiff). If format is not specified, it will default to 'GTiff'.

  - CopyDatasetInfo(src,dst)- copy metadata and georeferencing information from GDAL dataset src to GDAL dataset dst.

  ## Core commands:

  Commands make use of an infrastructure that simplifies usage and help access for commonly used procedures that interact with the main OpenEV application or describe the local environment. These commands are intercepted and parsed before being passed to the shell's python interpreter, and are entered with the command and arguments separated by spaces rather than by round brackets and commas. Commands cannot be loaded or used in a regular python shell; they only have meaning within the context of OpenEV.

  Core command list:

  1. newview- create a new OpenEV view.
  2. view3d- display a dem and drape in 3D mode in the current OpenEV view.
  3. get- grab data from the currently active OpenEV view/layer..
  4. show- display a Python Shell array or GvShapes variable in an OpenEV view.
  5. clearview- clear the current OpenEV view.
  6. save- save a Python Shell array or GvShapes variable to a file.
  7. loadext- register commands from an extension module (command equivalent of python's import keyword).
  8. macro- run a sequence of commands/Python statements from a text file.
  9. journal- save text entered at the Python Shell command line to a text file.
  10. locals- list this session's local variables and their type codes.
  11. help- display help for a function or command.
  12. functions- list loaded python functions, or scan a module for functions.
  13. commands- list registered commands.

  # Examples

  Here is a small tutorial that illustrates simple python usage and some of OpenEV's python functions; for a more comprehensive general tutorial, see the www.python.org tutorial.

  ## Example 1:

    Load a file into a Numeric python array:

            array1 = LoadFile(`filename.foo`)

    Display it in the current view:

            display(array1)

    To get the Region Of Interest (ROI) marked on the image:

    1. launch the Edit toolbar using the menu entry Edit/Edit toolbar.

    2. select "Draw ROI" to activate the ROI tool.

    3. use the ROI tool to mark a region (left click to start drawing, drag, release to finish)

    4. `roi()` returns the ROI in (x, y, width, height)

    Use the ROI tool to get a subarray:

    1. mark out an ROI with the tool on the image

    2. `array2 = get_roi(array1)`

    To save array2 to a new file:

        SaveArray(array2,'filename2.tif')

  Numeric python functions such as ones and array can also be used to create and manipulate arrays:

    To create a floating point array of ones with 5 rows and 6 columns:

            array3=ones([5,6],Float)

    Reset rows 1 to 4, columns 1 to 5 of the array with some values:

            array3[1:5,1:6]=array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]],Float)

    Square it:

            array3=power(array3,2)

    Display it in the current view:

            display(array3)

    Some important points to note are:

    1. Numeric python arrays are indexed from zero.

    2. In slicing a Numeric python array using index range N:M, elements N, N+1, ...M-1 are included.

  ## Example 2

  We are starting with Python shell (Edit->Python Shell... menu item). You should load some raster file into OpenEV to work with.

  - Get active layer

        layer = gview.app.sel_manager.get_active_layer()

    ...and load data array into memory:

        ds = layer.get_parent().get_dataset()
        data = DatasetReadAsArray(ds)

    Note: using the core command get with the argument data (ie. enter "get data" at the command line) will perform these three steps for you.

    If you don't want open and display your input data with OpenEV, but want load the file(s) in memory, make some calculations and display result, you can use other approach instead of previous steps:

        data = LoadFile('filename.l1b')

    (In this sample we will work with NOAA AVHRR data in L1B format).

  - Now we are ready to operate with loaded data. For example, calculate normalised difference vegetation index (NDVI) with NOAA AVHRR data. In this case NDVI is calculated as (Band2 - Band1)/(Band2 + Band1). We assume we have already calibrated data in our file.

        ndvi = (data[1] - data[0]) / (data[1] + data[0])

  - Display result and, optionally, save it into file:

        display(ndvi)
        SaveArray(ndvi,'ndvi.tif','GTiff')

    Note, that in all our computations arrays are fully loaded into memory. Be sure you have enough resources for this. For large arrays loading and calculations may take some time.

  - Another operation: let's make a RGB composite image. In general case this operation should be interactively controlled by the user, because band colors should be carefully adjusted to produce the best looking results. But we will simplify our task. NOAA AVHRR data has 10-bit depth (GDAL stores them in 16-bit integer), so we just scale input data to 8-bit and fill three-component array.

        rgb = zeros((3, ds.RasterYSize, ds.RasterXSize), UnsignedInt8)
        for i in range(3):
            rgb[i] = (data[i] * 256 / 1024).astype(UnsignedInt8)
        display(rgb)

    This code produces a RGB composite from the first three channels of the input image, but you can unroll the loop and use channels you want. Following code uses channel 5 as red, 2 as green and 3 as blue:

        rgb[0] = (data[4] * 256 / 1024).astype(UnsignedInt8)
        rgb[1] = (data[1] * 256 / 1024).astype(UnsignedInt8)
        rgb[2] = (data[3] * 256 / 1024).astype(UnsignedInt8)

  - Now we will use other data as a sample. Let load ASTER Level 1B dataset (the second band) and try to calibrate it. This dataset already reprocessed and should be calibrated with the simple linear function. Function coefficients contained in the metadata records with the appropriate number at the end (2 in case of the second band).

        layer = gview.app.sel_manager.get_active_layer()
        ds = layer.get_parent().get_dataset()
        data = DatasetReadAsArray(ds)
        incl = float(ds.GetMetadata()["INCL2"])
        offset = float(ds.GetMetadata()["OFFSET2"])
        data_cal = data * incl + offset
        display(data_cal)

  # Python Shell Help

  The python shell has three commands used to provide help on functions and commands:
  1. help- display help for a function or command.
  2. commands- list registered commands.
  3. functions- list loaded python functions, or scan a module for functions.
  These commands make use of python __doc__ strings and any help text files that are registered. Help text files should only be used when there is some reason for not updating the python __doc__ string itself (eg. if documentation were going to be available in multiple languages, or if the package is from a third party and you don't want to use the doc string), or if the python documentation is fine but it is desirable to display help for some functions/commands that are not loaded so that the user is made aware of them. In the latter case, the help text file should be regenerated from the python documentation each time one of the functions' documentation changes (at least for releases). Help text files may have entries of the following three formats:

      COMMAND_NAME=my_command
      Module: my_module
      Group: my_group
      Html: my_html.html

      documentation...

      FUNCTION_NAME=my_func
      Module: my_module
      Html: my_html.html

      documentation...

      BUILTIN_NAME=my_builtin
      Module: my_module
      Html: my_html.html

      documentation...

  where my_command, my_func, and my_builtin are a user-defined command, function, and builtin (bound C) function respectively. The Html entry is used to indicate an html file with more information, and is optional (currently, the python shell will not do anything with html information other than store the name of the link- this may be used in future though). The Module name is required to deal with the case of two modules defining different commands/functions with the same name. The COMMAND_NAME, FUNCTION_NAME, BUILTIN_NAME, Module, and Html parts of the text file are case-sensitive (ie. an error will occur if the case is not as above). See gvcorecmds.py's RegisterHelp function for how to register a help file with the interpreter (this function determines the location of gvcorecmds_help.txt assuming that it is in the same directory as gvcorecmds.py, and loads the text from it if it is present). The suggested convention for text help files is that if they are needed, they be placed in the same directory as the commands/functions they relate to, and have the same name as the command module, minus the '.py', plus '_help.txt'.

  Top