# How does gdal_calc numpy operators work?

### Gdal_calc manual

Gdal_calc is introduced as :

``````gdal_calc.py - Command line raster calculator with numpy syntax
gdal_calc.py [-A <filename>] [--A_band] [-B...-Z filename] [other_options]
OPTIONS:
--calc=CALC           calculation in gdalnumeric syntax using +-/* or any
numpy array functions (i.e. logical_and())
DESCRIPTION
Command line raster calculator with numpy syntax. Use any basic arithmetic
supported by numpy arrays such as +-*/ along with logical operators such as >.
EXAMPLE
gdal_calc.py -A input1.tif -B input2.tif --outfile=result.tif --calc="A+B"
average of two layers
gdal_calc.py -A input.tif -B input2.tif --outfile=result.tif --calc="(A+B)/2"`
set values of zero and below to null
gdal_calc.py -A input.tif --outfile=result.tif --calc="A*(A>0)" --NoDataValue=0
``````

### Unexpected results

I made some good uses of gdal_calc in the past, yet, recent results makes no sences to me. I have 3 input files `hillshades_A.tmp.tif`, `hillshades_B.tmp.tif`, `hillshades_C.tmp.tif` and one output `composite.tif`. I want to make calculations with these inputs. I will follow pixel x=10 y=10 with values are A=`222`, B=`220`, C=`224` to check the correctness of the output. Let's start.

Example:

`````` # ASSIGN VALUE. Expect: 300.
--calc="300" --NoDataValue=-1
\$gdallocationinfo ./composite.tif 10 10 -valonly
>255          # Ergh? Ok, as it's a grey scale [0-255], such auto-correction is ok
``````

Then the fun start !

``````# SUM: A+B or (A+B), when A=222, B=220. Expect: 442 or 255.
--calc="(A+B)" --NoDataValue=-1
\$gdallocationinfo ./composite.tif 10 10 -valonly
>186          # Ergh? This is A+B-256=442-256=186

# AVERAGE: (A+B)/2, when A=222, B=220. Expect: 221 or 255.
--calc="(A+B)/2" --NoDataValue=-1
\$gdallocationinfo ./composite.tif 10 10 -valonly
>93           # Ergh? ok, per previous 186/2=93.
# must use (A/2)+(B/2) => 221

# MULTIPLY: A*B, when A=222, B=220. Expect: 48840 or 255
--calc="A*B" --NoDataValue=-1
\$gdallocationinfo ./composite.tif 10 10 -valonly
>200           # Ergh? ok, it's modulo: 222*220 % 256=200

# MULTIPLY+SCALE BACK: A*B/255, when A=222, B=220. Expect: 191.5 rounded to 191 or 192.
--calc="A*B/255" --NoDataValue=-1
\$gdallocationinfo ./composite.tif 10 10 -valonly
>0             # Ergh? Maybe A*B/255=200/255 (per previous point) being <0 it get rounded to 0 firt. It confirms: Ergh?
``````

And I may go again and yet again. These are not simple basic arithmetic [...] such as `+-*/` .

### Question

How does gdal_calc operators works ? and... Is there a comprehensive manual for this gdal_calc / numppy syntaxes equations ? (I didn't find any solid one via google)

EDIT: may this behavior be the byproduct of [0-255] greyscale hillshade as input.

``````\$gdalinfo ./hillshades_A.tmp.tif -mm
Driver: GTiff/GeoTIFF
Size is 1920, 1950
Coordinate System is `'
Origin = (66.991666666666674,37.508333333333354)
Pixel Size = (0.016666666666667,-0.016666666666667)
INTERLEAVE=BAND
Corner Coordinates:
Upper Left  (  66.9916667,  37.5083333)
Lower Left  (  66.9916667,   5.0083333)
Upper Right (  98.9916667,  37.5083333)
Lower Right (  98.9916667,   5.0083333)
Center      (  82.9916667,  21.2583333)
Band 1 Block=1920x4 Type=Byte, ColorInterp=Gray
Computed Min/Max=1.000,255.000
NoData Value=0
``````

Gdal_calc's numpy seems to have more operators :

``````+ addition
- subtraction
/ division
* multiplication
= equals to
< less than
> larger than
! not equal to
? if clause
M maximum of two values
m minimum of two values
B bit level operator
``````

I haven't found clear and proper examples for how the exotic operators should be used. If you have something, feel free to share.

• I'll guess the datatype of your inputs is `Byte`? Can you reproduce the same errors when you change your inputs to `Float`? – Kersten May 13 '15 at 11:04
• Maybe someone at the GDAL-Dev Mailinglist can help osgeo-org.1560.x6.nabble.com/GDAL-Dev-f3742093.html You could also take a look at this repository, maybe you will find some answers github.com/gbb/gbb_gdal_calc – bennos May 13 '15 at 14:53
• @kersen: how to change that? Any quick command? – Hugolpz May 16 '15 at 8:09
• `gdal_translate -ot {Byte|Flot32|Float64}` should be the easiest way to change the datatype. Depending on you input you might also need the `-a_nodata` parameter. – Kersten May 18 '15 at 7:42