# Generate Geotiff from Rainbow file with wradlib

**URL:** <https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231>\
**Category:** Retrievals\
**Tags:** wradlib\
**Created:** [April 30, 2023, 4:56am UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231 "2023-04-30T04:56:16Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![d-siden](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/d-siden/32/95_2.png) [@d-siden](https://openradar.discourse.group/u/d-siden)\
**Post date:** [April 30, 2023, 4:56am UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/1 "2023-04-30T04:56:16Z")

</div>

Hi,

I’m trying to follow [this tutorial](https://docs.wradlib.org/en/latest/notebooks/fileio/wradlib_gis_export_example.html) in order to get data from a Rainbow (.vol) file and export it to a Geotiff file. However the tutorial refers to RADOLAN dataset, and I’m having difficulties in figuring out how to proceed to do the same with my file.  
How exactly should this tutorial be adapted for a Rainbow file?

Thanks in advance,  
Danilo

---

<div class="post-metadata">

**Author:** ![kmuehlbauer](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/kmuehlbauer/32/439_2.png) [@kmuehlbauer](https://openradar.discourse.group/u/kmuehlbauer)\
**Post date:** [May 2, 2023, 9:18am UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/2 "2023-05-02T09:18:31Z")

</div>

Hi Danilo,

The example you are referring works on cartesian data. Sou you would have to interpolate your polar data to cartesian before.

There is no combined example (cartesian interpolation and output to GIS) so far. It’s on my todo-list, but not as immediate priority. If you are up to it, I’ll gladly assist.

---

<div class="post-metadata">

**Author:** ![d-siden](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/d-siden/32/95_2.png) [@d-siden](https://openradar.discourse.group/u/d-siden)\
**Post date:** [May 10, 2023, 2:48pm UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/3 "2023-05-10T14:48:04Z")

</div>

UPDATE: First try

In my first attempt I exported the values to a .csv file with their projected coordinates.  
This file is loaded into QGIS, then made into a points vector layer, which is converted into raster layers with different resolutions.

Drawbacks:

1. The raster layer has a equally dimensioned area of value validity (like a square), which does not represent the actual shape of coverage of a radar bin.
2. A raster layer has fixed resolution, which again does not represent the variable resolution of a radar sweep data (decreasing with range).
3. Data loss: The value of the pixel comes from a single point inside it, other values are discarded.

To ‘fix’ drawback no. 2, the resolution is lowered until the pixels cover the entire area of the desired region.

This first image show the points vector layer loaded in QGIS.

 ![Captura de tela de 2023-05-10 11-37-19](https://global.discourse-cdn.com/free1/uploads/openradar/original/1X/5ef93a74b82938bced371465069c7008f381da6a.png)

This one shows the previous layer rasterized to range resolution, the inner points become an uniform layer, but outer points still miss data between them.

 ![Captura de tela de 2023-05-10 11-36-41](https://global.discourse-cdn.com/free1/uploads/openradar/original/1X/e062713b851a404c702d582607090304613082e5.png)

This one show the layer rasterized to 10 times the range resolution, the filled area reaches outer as the resolution becomes poorer.

 ![Captura de tela de 2023-05-10 11-36-54](https://global.discourse-cdn.com/free1/uploads/openradar/original/1X/a355e49f92892cc993a3035da84dd5d06547e91b.png)

I’ll be trying new methods and keeping the community updated.

---

<div class="post-metadata">

**Author:** ![d-siden](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/d-siden/32/95_2.png) [@d-siden](https://openradar.discourse.group/u/d-siden)\
**Post date:** [May 21, 2023, 8:15pm UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/4 "2023-05-21T20:15:25Z")

</div>

UPDATE: Second try

The second method I’m trying is to save an black and white PPI plot without any extra borders or image elements to PNG format, alongside a World File (.pngw), which QGIS can load to georreference the image.

The positive effect is that the plotted image has a good representation of the area that a bin represents.

Unfortunately the PNG seems to be somewhat misaligned when seen under the point layer in QGIS.

The points come from wradlib’s [`spherical_to_centroids`](https://docs.wradlib.org/en/latest/generated/wradlib.georef.polar.spherical_to_centroids.html), as described in the First Try Update above.

 ![Captura de tela de 2023-05-21 17-03-32](https://global.discourse-cdn.com/free1/uploads/openradar/original/1X/738d64453e4bd0dd1c0c195146df5ea564507988.png)  
Red and blue color scale shows the points.

 ![Captura de tela de 2023-05-21 17-03-55](https://global.discourse-cdn.com/free1/uploads/openradar/original/1X/b983890c329d5126ce4b41061c2f3775d84cf39e.png)  
Zoomed in image shows raster (PNG, black and white) under points. Notice that both layers show the same variations on their respective colors.

 ![Captura de tela de 2023-05-21 17-04-46](https://global.discourse-cdn.com/free1/uploads/openradar/original/1X/c3f6b5da032c4dbd067922ef4262687e0b0ef8eb.png)  
But looking closer at the bins, the point (centroid) does not lay on the center of the area. Radar is located to the lower right side. Points are always closer to the radar than a pixelated area in any direction.

---

<div class="post-metadata">

**Author:** ![d-siden](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/d-siden/32/95_2.png) [@d-siden](https://openradar.discourse.group/u/d-siden)\
**Post date:** [May 23, 2023, 2:52pm UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/5 "2023-05-23T14:52:32Z")

</div>

This misalignment was fixed by subtracting half of the range from the range ndarray when plotting.  
The next step is saving the values in png, because python png saving functions only support saving 8 bit integer values, whose range is between 0 and 255. So, rounding the number and adding the minimum value can temporarily solve the issue (if the data is reflectivity, whose range is between -31.5 and ~100 dBZ). Just remember to subtract again when reading.

---

<div class="post-metadata">

**Author:** ![d-siden](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/d-siden/32/95_2.png) [@d-siden](https://openradar.discourse.group/u/d-siden)\
**Post date:** [March 5, 2025, 2:19am UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/6 "2025-03-05T02:19:30Z")

</div>

Update: Still haven’t found a way to achieve this.

I’m currently using Wradlib 2.1.0 and I still haven’t managed to make it work.  
I’m trying this function:

```auto
wradlib.io.gdal.write_raster_dataset("geotiff.tif", dados, driver="GTiff")

```

Where “dados” comes from a correct implementation of:

```auto
wradlib.georef.create_xarray_dataarray(...)

```

Followed by

```auto
dados = wradlib.georef.georeference(dados, crs=epsg_to_osr(4326))

```

An attempt of writing the dataset gives

> TypeError: in method ‘Driver\_CreateCopy’, argument 3 of type ‘GDALDatasetShadow \*’

I still can’t find a solution for this, Is there an actual way to solve it?

---

<div class="post-metadata">

**Author:** ![kmuehlbauer](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/kmuehlbauer/32/439_2.png) [@kmuehlbauer](https://openradar.discourse.group/u/kmuehlbauer)\
**Post date:** [March 5, 2025, 7:07am UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/7 "2025-03-05T07:07:31Z")

</div>

Hi @d-siden,

Danilo, would it be possible for you to create a MCVE ([How to create a Minimal, Reproducible Example - Help Center - Stack Overflow](https://stackoverflow.com/help/minimal-reproducible-example)) showing the problem? It would help tremendously in getting to the bottom of the issue here, if people can start out from working with the code.

Thanks,  
Kai

---

<div class="post-metadata">

**Author:** ![d-siden](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/d-siden/32/95_2.png) [@d-siden](https://openradar.discourse.group/u/d-siden)\
**Post date:** [March 5, 2025, 2:46pm UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/8 "2025-03-05T14:46:36Z")

</div>

Of course! Here is the code:

```auto
import wradlib # 2.1.0
from os import environ
from numpy import arange # numpy 2.0.1

environ["WRADLIB_DATA"] = "/home/danilo/Documentos/Python/radar"
sample_file = environ["WRADLIB_DATA"]+"/outros-dados/2025030100000400dBZ.vol"
output_file = environ["WRADLIB_DATA"]+"/geotiff.tif"

content = wradlib.io.read_rainbow(sample_file)
azi = content["volume"]["scan"]["slice"][0]["slicedata"]["rayinfo"][0]["data"]
azi_bits = float(content["volume"]["scan"]["slice"][0]["slicedata"]["rayinfo"][0]["@depth"])
n_rays = float(content["volume"]["scan"]["slice"][0]["slicedata"]["rayinfo"][0]["@rays"])
angstep = float(content["volume"]["scan"]["slice"][0]["anglestep"])
azi = (azi * n_rays / 2 ** azi_bits) * angstep

maxrange = float(content["volume"]["scan"]["slice"][0]["stoprange"])
rangstep = float(content["volume"]["scan"]["slice"][0]["rangestep"])
# convert range from kilometers to meters
radar_range = arange(rangstep * 1000, maxrange * 1000 + rangstep * 1000, rangstep * 1000)

data = content["volume"]["scan"]["slice"][0]["slicedata"]["rawdata"]["data"]
data_bits = float(content["volume"]["scan"]["slice"][0]["slicedata"]["rawdata"]["@depth"])
mindata = float(content["volume"]["scan"]["slice"][0]["slicedata"]["rawdata"]["@min"])
maxdata = float(content["volume"]["scan"]["slice"][0]["slicedata"]["rawdata"]["@max"])
data = mindata + data * (maxdata - mindata) / 2 ** data_bits

elevation = float(content["volume"]["scan"]["slice"][0]["posangle"])

lat_radar = float(content["volume"]["sensorinfo"]["lat"])
lon_radar = float(content["volume"]["sensorinfo"]["lon"])
alt_radar = float(content["volume"]["sensorinfo"]["alt"])

data = wradlib.georef.create_xarray_dataarray(data, r=radar_range, phi=azi, theta=elevation,
                                              site=(lon_radar, lat_radar, alt_radar))
data = wradlib.georef.georeference(data, crs=wradlib.georef.epsg_to_osr(4326))

wradlib.io.gdal.write_raster_dataset(output_file, data, driver="GTiff")

```

And the [sample file](https://drive.google.com/drive/folders/1K0oJY11ir40IAI47l4uWZVCsW12oxXlc?usp=sharing).

Thanks in advance,  
Danilo

---

<div class="post-metadata">

**Author:** ![kmuehlbauer](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/kmuehlbauer/32/439_2.png) [@kmuehlbauer](https://openradar.discourse.group/u/kmuehlbauer)\
**Post date:** [March 5, 2025, 3:07pm UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/9 "2025-03-05T15:07:11Z")

</div>

@d-siden Try this as starting point

```python
import numpy as np
import wradlib as wrl
import xarray as xr

sample_file = "/home/kai/data/daten/daten/2025030100000400dBZ.vol"
output_file = "geotiff.tif"

# use xarray plus xradar engine
ds = xr.open_dataset(sample_file, engine="rainbow", group="sweep_0")

# georeference (might use some more fitting projection!)
crs = wrl.georef.epsg_to_osr(4326)
ds = ds.set_coords("sweep_mode").wrl.georef.georeference(crs=crs)

# create grid (better use a fitting projection above) this is just to showcase
xgrid = np.linspace(ds.x.min().values, ds.x.max().values, 1000)
ygrid = np.linspace(ds.y.min().values, ds.y.max().values, 1000)
cart = xr.Dataset(coords={"x": (["x"], xgrid), "y": (["y"], ygrid)})

# use nearest neighbour gridder
gridded = ds.DBZH.wrl.comp.togrid(cart, radius=200000.0, center=(0,0), interpol=wrl.ipol.Nearest)

# output to raster file, needs rasterio/rioxarray packages
gridded.rio.to_raster(output_file)

```

---

<div class="post-metadata">

**Author:** ![d-siden](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/d-siden/32/95_2.png) [@d-siden](https://openradar.discourse.group/u/d-siden)\
**Post date:** [March 5, 2025, 3:55pm UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/10 "2025-03-05T15:55:16Z")

</div>

That works!

I’ll be studying this method, I thought that the rainbow tutorial steps were the only way to get those files read.

Thank you so much!

---

<div class="post-metadata">

**Author:** ![kmuehlbauer](https://yyz2.discourse-cdn.com/free1/user_avatar/openradar.discourse.group/kmuehlbauer/32/439_2.png) [@kmuehlbauer](https://openradar.discourse.group/u/kmuehlbauer)\
**Post date:** [March 7, 2025, 6:42am UTC](https://openradar.discourse.group/t/generate-geotiff-from-rainbow-file-with-wradlib/231/11 "2025-03-07T06:42:24Z")

</div>

Hi @d-siden,

great it works for you. And yes, we could improve the documentation over at wradlib. All polar radar data related code which existed in wradlib has been ported over to [xradar — xradar 0.9.0 documentation](https://docs.openradarscience.org/projects/xradar/en/stable/). There is a section on [rainbow](https://docs.openradarscience.org/projects/xradar/en/stable/notebooks/Rainbow.html), too.

Would you mind opening an issue over at [GitHub - wradlib/wradlib: weather radar data processing - python package](https://github.com/wradlib/wradlib) with some details how the particular part of the documentation could be improved?

Thanks,  
Kai
