Homework 02: Runoff modelling
Deadline is 2019-12-19 13:00.
Late submission? 10% will be removed for each day that you are late.
15% of final marks
You’re allowed for this assignment to work in a group of 2 (and thus submit only one solution for both of you). If you prefer to work alone it’s also fine.
- Overview
- What you are given to start
- Help understanding the Metz et al. paper
- Data structure to use
- What if I can’t manage to implement the Metz et al. paper
- Tips
- The output files to submit
- The report to submit
- Marking
- What to submit and how to submit it
Overview
The aim of this assignment is to implement basic runoff modelling based on the LCP algorithm using a single flow direction (D8) on a grid DTM. In short, this will involve two steps:
- computing the flow direction as described in Section 2.1 of this paper;
- using the flow direction to compute the accumulated flow.
Everything should be implemented in Python, and the only external modules that you are allowed to use for your computations are rasterio, numpy and scipy. You may use matplotlib and seaborn to visualise your results and to generate figures for your report.
What you are given to start
We give you the skeleton of the Python program and an input file:
geo1015_hw02.py
is the main(). You are not allowed to modify this file!mycode_hw02.py
is where all your code should go. The functions defined there must be written/completed, and you are not allowed to change the input parameters. You are of course allowed to add any other functions you want. You are only allowed to import modules from the Python standard library (anything you installed throughpip
is thus not allowed, except rasterio, scipy, numpy, matplotlib and seaborn).tasmania.tif
: is our input grid.
Help understanding the Metz et al. paper
The standard D8 method we saw in the lesson defines the flow direction using the steepest downwards slope. This works fine in most areas, but it doesn’t give a good solution for flats or sinks.
The Metz et al. paper describes a modified version of the D8 method that solves both of these problems. It does this by:
- Visiting the cells in a very specific order, which is given by the priority queue. The priority is defined such that lower-elevation cells are visited first. If two cells have the same elevation, the cell that was added to the priority queue first is visited first.
- Allowing water to flow upstream in certain circumstances. Like in normal D8, the flow direction is set to the steepest downwards slope when possible. But when there are no neighbour cells with downwards slope, it sets the flow direction to the least steep upwards slope. Note that in practical terms, this means always selecting the lowest possible slope value. It doesn’t matter if it’s positive or negative.
Note that the method relies on both of these things! Make sure you add the cells to the priority queue exactly as described in the paper.
Data structure to use
Part of implementing the LCP algorithm involves creating a priority queue. This is a data structure that has its elements sorted by priority. In this way, you can easily get the highest priority element to be processed by checking the first (or last) element in the queue. You can implement priority queues in a variety of ways.
- Easiest super slow option: Use a standard list. Insert at the end (ie don’t keep the elements sorted). Instead, find the highest priority element every time you need it by iterating over the whole thing.
- Easy decent option: Use a standard list. When you need to insert a new element, start from the beginning and iterate over the list until you find the right place for it.
- Much faster but somewhat complex option: Also use a sorted list. Rather than iterating one by one, use heuristics to jump between elements to find the insertion point faster. See here.
- Fastest option: Use a heap rather than a list. Python has an implementation: heapq, but others can be used.
You are free to implement the priority queue in whatever way you want. It will not have any effect on your grade. It will have a large effect on how long your code takes to run though (hours vs minutes vs seconds), and very long run times might make debugging your code very frustrating.
What if I can’t manage to implement the Metz et al. paper
If you’re completely lost in this assignment, even after asking questions in the labs and/or posting in the forum, you are allowed to implement the standard D8 method. However, bear in mind that your assignment will then have a maximum grade of 7.0.
Tips
- The initial potential outlets should be all the pixels on the edges of the dataset (ie the top/bottom rows and the leftmost/rightmost columns) AND all the cells neighbouring the river (which in this dataset only has an elevation of 0.0).
- You can use the Python
sort()
function, but we think it is easier (and faster) not to. - Implementing the flow accumulation in the simplest way using recursion might result in you running against the Python recursion limit.
- Make sure you mention how and why flats and sinks can (or cannot) affect the output of your code in your report.
- You might want to choose specific values that represent the 8 possible flow directions of a pixel (eg 10 for rightwards and 30 for downwards), as well as special values for pixels at the different stages of processing. Choose sensible values to make visualisation intuitive.
- We will test your code with other input than
tasmania.tif
. You can assume that the pixels at the lowest elevation in the dataset are outlets. - rasterio allows you to clone a dataset’s properties (eg the width and height) using the profile dictionary. This is very handy when you want to create a new grid with similar properties as an existing one.
- Make sure that the raster data type you choose is able to fit the values that you want to store in it.
- matplotlib and seaborn are useful to debug your code or if you want to create figures for your report. There are minimal examples to produce plots in the commented lines in
geo1015_hw02.py
.
The output files to submit
You’ll have to deliver two GeoTIFF files:
- a grid showing the flow direction
- a grid showing the flow accumulation.
There should only be one band in each file, which should be of a type (eg float32
) that is appropriate for what you are storing in it.
The width, height, transform, and crs values should be the same as the input grid.
The report to submit
You need to submit a very simple report explaining briefly how you implemented the key parts (eg finding the initial potential outlets and computing the sums for the flow accumulation) and explaining why you chose to implement them in this manner.
We expect 3-5 pages for this (figures and graphs included!)
Marking
Marks | |
---|---|
followed all rules (names, functions, etc.) | 1 |
compiles/runs without modifications | 1 |
report quality/clarity | 3 |
implementation of LCP algorithm | 3 |
implementation of flow accumulation | 2 |
standard D8 instead of LCP | -3 |
What to submit and how to submit it
You have to submit a total of 4 files:
- The Python file
my_code_hw02.py
, where your name, and that of your colleague, is clearly identified at the top of the file. - 2 GeoTIFFs with the flow direction and flow accumulation for the sample dataset provided.
- report in PDF format (please no Word file)
Submit your files by uploading them here.
[last updated: 2019-12-13 17:49]