Maps and weather data

Persefone currently requires two separate map input files: one for land cover, the other for field geometry. Additionally, a weather input file is needed. This documents describe how to obtain and process the data needed for each of these.

Land cover maps

Land cover maps for Germany at 10m resolution can be obtained from Mundialis. These are generated annually from Sentinel data and comprise the following land cover classes:

10: forest
20: low vegetation
30: water
40: built-up
50: bare soil
60: agriculture

To create a Persefone map input file, you need to crop the national Mundialis map to the extent that you want to simulate (suggestion: approx. 10x10km is a reasonable size).

To do so, download the Mundialis map and import it into QGIS. Then create a new vector layer and create a rectangle feature to delimit the extent of your region. Then go to Raster -> Extraction -> Clip Raster by Extent. Select the Mundialis map as the input layer, set the clipping extent by choosing your region vector layer under Calculate from Layer and specify the output file name before clicking Run. This will generate a TIF file that you can pass to Persefone as the landcovermap parameter.

Field ID maps

In addition to the land cover data explained above, Persefone also needs information about agricultural field boundaries in order to assign these to the farming agents. Unfortunately, getting this is rather more complicated.

In the EU, every country runs a Land Parcel Information System (LPIS) to administer CAP payments. In Germany, this is called InVeKoS and is run by the Länder. For example, you can view and download the InVeKoS data for Thüringen here. This gives you a vector layer which can be loaded into QGIS. However, it needs to be converted to a raster layer and cropped to your region extent before it can be used in Persefone.

The first thing to do is to make sure that the vector layer has a numeric (!) field with a unique identifier for each field block (check the attribute table). The Thüringen data has the FBI ("Feldblockident") field, but this is a string value and therefore not usable by the rasteriser. So, we set the vector layer to edit mode, open the field calculator, enter the information for a new field (call it "FID" and set it to a 32-bit integer), and enter @row_number in the expression field. Then save the layer and close the calculator.

Secondly, you need to filter out all non-field/non-grassland plot types. (LPIS also has data on forests and various landscape elements that are not relevant to our use case.) Assuming you're working with the Thüringen InVeKoS data (other data sets may have a different structure), right-click on the layer name in QGIS' layer overview and click on "Filter...". Then, enter this expression in the query builder: "BNK" = 'AL' OR "BNK" = 'GL' and click "OK". This will select only field and grassland plots.

Next, open the rasteriser (Raster -> Conversion -> Rasterize). Select your FID field as the "Field to use for a burn-in value", and your land cover map (as created above - this ensures the two layers match) as the output extent. Make sure the "fixed value to burn" is "Not set". Then choose "Georeferenced units" as the "Out raster size units" and set horizontal and vertical resolution to 10.0. In the advanced parameters, set the output data type to UInt32. Finally, enter an output file name and run. The resulting TIF file can be passed to Persefone as the farmfieldmap parameter.

Weather data

Currently, Persefone uses historical weather data from the closes weather station as its weather input. (In future, this may be changed to a more detailed raster input, which could then also provide future weather predictions under climate change.) Weather data can be downloaded from the German weather service (DWD). The relevant data are in the folder daily/kl/historical.

The description of this data set and the list of weather stations can be found in the Persefone repository, in the docs folder (or downloaded from the link above). Using the list of weather stations, select the one closest to the area of study. Note that not all stations were continuously in operation; make sure that the selected station covers the years of interest.

  • Region Jena: station number 02444 ("Jena (Sternwarte)")
  • Region Eichsfeld:
  • Region Thüringer Becken: station number 00896 ("Dachwig")
  • Region Hohenlohe:
  • Region Bodensee:
  • Region Nördlicher Oberrhein:

From the link above, download the ZIP file associated with the station number. Check the included meta-data if there is any important missing data, or other relevant information (e.g. the station moved position).

Then use data/extract_weather_data.R to process the data into the format needed by Persefone:

library(tidyverse)

## replace this with the correct file name
weatherfile = "produkt_klima_tag_18210101_20221231_02444.txt"

data = read.table(weatherfile, sep=";", header=T)

weather = data %>%
    ## drop values before 2000 to save space
    filter(MESS_DATUM>=20000101) %>%
    ## select relevant variables and convert place-holder values to NA
    select(MESS_DATUM, FM, RSK, SDK, VPM, TMK, TXK, TNK) %>%
    mutate(date=MESS_DATUM, MESS_DATUM=NULL,
           mean_windspeed=na_if(FM, -999), FM=NULL,
           precipitation=na_if(RSK, -999), RSK=NULL,
           sunshine_hours=na_if(SDK, -999), SDK=NULL,
           mean_vapour_pressure=na_if(VPM, -999), VPM=NULL,
           mean_temperature=na_if(TMK, -999), TMK=NULL,
           max_temperature=na_if(TXK, -999), TXK=NULL,
           min_temperature=na_if(TNK, -999), TNK=NULL)

## replace with the desired file name
write.csv(weather, file="weather_jena.csv", row.names=FALSE)

Note: for calculating the reference evapotranspiration ET_0 (needed for the AquaCrop model), use the FAO Penman-Monteith equation.