Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feedback #1

Open
wants to merge 63 commits into
base: feedback
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
d6b9bac
Setting up GitHub Classroom Feedback
github-classroom[bot] Jan 21, 2021
bf1d6b1
Fixed error
woody-lam-cwl Jan 23, 2021
a379eae
Completed Task1D
woody-lam-cwl Jan 23, 2021
26b0448
Fixed errors
woody-lam-cwl Jan 23, 2021
a616736
Completed Task1E
woody-lam-cwl Jan 23, 2021
ed4851b
Fixed flake8
woody-lam-cwl Jan 23, 2021
59a8175
Expanded pytest to coverage testing
woody-lam-cwl Jan 23, 2021
3f585b3
Fixed coverage issue
woody-lam-cwl Jan 23, 2021
ecd5fe1
Fixed flake8
woody-lam-cwl Jan 23, 2021
c47745c
Extension: Property decorators added
woody-lam-cwl Jan 24, 2021
f602cb9
git commit
Ckh31 Jan 24, 2021
efb66e2
git commit -m "Complete Task 1B"
Ckh31 Jan 24, 2021
84b352f
Merge branch 'main' of https://github.com/cued-ia-computing/flood-ckh…
Ckh31 Jan 24, 2021
01b749a
git commit
Ckh31 Jan 24, 2021
28a5835
git commit
Ckh31 Jan 24, 2021
2aae5d1
git commit
Ckh31 Jan 24, 2021
f7249ff
Completed Task 1B
Ckh31 Jan 24, 2021
26f8e76
Removed old gitlab file
woody-lam-cwl Jan 25, 2021
eadb1df
Completed Task B
Ckh31 Jan 27, 2021
86e9b2c
Completed Task C
Ckh31 Jan 27, 2021
95fe13b
Merge branch 'main' of https://github.com/cued-ia-computing/flood-ckh…
Ckh31 Jan 27, 2021
bf30fd4
Completed Task1B
Ckh31 Jan 27, 2021
affd660
Completed Task1F
Ckh31 Jan 27, 2021
327f410
Completed Task1C
Ckh31 Jan 28, 2021
70f6c59
Completed Task1C
Ckh31 Jan 28, 2021
8e9ce19
Completed Task1F
Ckh31 Jan 28, 2021
3e04a9a
Completed Task1B
Ckh31 Jan 28, 2021
cfbbaa5
Completd Task1C
Ckh31 Jan 28, 2021
47fd39e
Completed Task1F
Ckh31 Jan 28, 2021
7a2138d
Fixed issue with Task1B and Task1C
woody-lam-cwl Jan 28, 2021
03b97fe
Included haversine installation in workflow
woody-lam-cwl Jan 28, 2021
9ba97a3
Completed map extension
woody-lam-cwl Jan 28, 2021
5a36fd0
Installed missing plotly module
woody-lam-cwl Jan 28, 2021
bd898c3
Expanded attributes of MonitoringStation objects
woody-lam-cwl Jan 28, 2021
a0a739a
Completed Task1F
Ckh31 Feb 6, 2021
309258f
Added pytest and fixed bugs
woody-lam-cwl Feb 7, 2021
b01ad99
Fixed stations_within_radius bug
woody-lam-cwl Feb 9, 2021
1af8f8c
Completed Task2B
Ckh31 Feb 24, 2021
d2b750c
Merge branch 'main' of https://github.com/cued-ia-computing/flood-ckh…
Ckh31 Feb 24, 2021
85023e5
Completed Task2B
Ckh31 Feb 24, 2021
d2c81dd
Completed Task2C
Ckh31 Feb 24, 2021
b8e6bfb
Completed Task2C
Ckh31 Feb 24, 2021
401d429
Completed Task2C
Ckh31 Feb 24, 2021
603f94f
Added update_water_levels to Task2 B and C
Ckh31 Feb 25, 2021
0c7a752
Completed Task2C
Ckh31 Feb 25, 2021
59a22a6
Removed unused variable
Ckh31 Feb 25, 2021
19bd83d
Completed Task2C
Ckh31 Feb 25, 2021
2fd7148
Changes to ratio variable
Ckh31 Feb 25, 2021
7048c0f
Completed Task2C
Ckh31 Feb 25, 2021
7514c34
Clean codes
woody-lam-cwl Feb 25, 2021
21f28e9
Flake8 corrections and debugging
woody-lam-cwl Feb 25, 2021
35a5e19
FIxed pytest
woody-lam-cwl Feb 25, 2021
5f49ce0
Fixed bugs in datafetcher
woody-lam-cwl Feb 25, 2021
cf528f7
Added pytest
woody-lam-cwl Feb 25, 2021
1a1c92d
Completed task 2E and 2F
woody-lam-cwl Feb 25, 2021
0048501
Resolved issue with matplotlib on CI
woody-lam-cwl Feb 25, 2021
216a1c5
Completed map extension
woody-lam-cwl Feb 26, 2021
bbe30ce
Completed Task2G
Ckh31 Mar 3, 2021
80d30c9
Commit
Ckh31 Mar 3, 2021
a4cc99c
Completed Task2G
Ckh31 Mar 3, 2021
535001e
Changes Made to Task2C and 2G
Ckh31 Mar 3, 2021
5f96bef
Completed Task2G
woody-lam-cwl Mar 3, 2021
9294127
Updated CI testing
woody-lam-cwl Mar 3, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .coverage
Binary file not shown.
16 changes: 13 additions & 3 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,29 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 matplotlib pytest requests
pip install flake8 matplotlib haversine plotly pytest-cov requests

- name: Lint with flake8
run: flake8 --statistics *.py

- name: Run unit tests using pytest
run: pytest -v
- name: Run unit tests using pytest (coverage)
run: pytest --cov=floodsystem --cov-report term-missing

- name: Run Deliverable 1 code
run: |
python Task1A.py
python Task1B.py
python Task1C.py
python Task1D.py
python Task1E.py

- name: Run Deliverable 2 code
run: |
python Task2A.py
python Task2B.py
python Task2C.py
python Task2D.py
python Task2E.py
python Task2Eext.py
python Task2F.py
python Task2G.py
19 changes: 0 additions & 19 deletions .gitlab-ci.yml

This file was deleted.

18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,21 @@ Engineering, University of Cambridge.
The activity is documented at
https://cued-partia-flood-warning.readthedocs.io/. Fork this repository
to start the activity.

Criteria for flood warnings issued are as follows:
- Each MonitoringStation will have a risk index, which is derived from its
current water level and 6 predicted water levels 15 minutes, 1 hour, 2 hours,
6 hours, 12 hours and 24 hours after the previous measurement.
- Risk indice take discrete values from 0 to 7 which counts the total number
of the 7 water levels aforementioned exceeding the relative level of 0.8.
- Flood warnings are issued for towns. Each town has a risk index calculated
by the average risk index of all stations in the town, which has continuous
values from 0 to 7.
- Warnings are then issued according to the town's risk index. Risk indices
above or equal to 6 are classified as "severe"; those below 6 but above or
equal to 4 are classified as "high"; those below 4 but above or equal to 2
are classified as "moderate"; the rest of the towns with valid risk indices
are classified as "low"
- If none of the stations in the town can provide a valid risk index,
the town has invalid risk index. This may be due to inconsistent typical range,
no available latest level or no available past levels.
18 changes: 18 additions & 0 deletions Task1B.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from floodsystem.stationdata import build_station_list
from floodsystem.geo import stations_by_distance


def run():

stations = build_station_list()
p = (52.2053, 0.1218)

List = stations_by_distance(stations, p)

print(List[:10])
print(List[-10:])


if __name__ == "__main__":
print("*** Task 1B: CUED Part IA Flood Warning System ***")
run()
18 changes: 18 additions & 0 deletions Task1C.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from floodsystem.stationdata import build_station_list
from floodsystem.geo import stations_within_radius


def run():

stations = build_station_list()
centre = (52.2053, 0.1218)
r = 10

ListC = stations_within_radius(stations, centre, r)

print(ListC)


if __name__ == "__main__":
print("*** Task 1C: CUED Part IA Flood Warning System ***")
run()
22 changes: 22 additions & 0 deletions Task1D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from floodsystem.stationdata import build_station_list
from floodsystem.geo import rivers_with_station, stations_by_river


def run():
"""Requirements for Task 1D"""

stations = build_station_list()

rivers = rivers_with_station(stations)

print(len(rivers))
print(rivers[:10])

print(sorted([station.name for station in stations_by_river(stations)['River Aire']]))
print(sorted([station.name for station in stations_by_river(stations)['River Cam']]))
print(sorted([station.name for station in stations_by_river(stations)['River Thames']]))


if __name__ == "__main__":
print("*** Task 1D: CUED Part IA Flood Warning System ***")
run()
15 changes: 15 additions & 0 deletions Task1E.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from floodsystem.stationdata import build_station_list
from floodsystem.geo import rivers_by_station_number


def run():
"""Requirements for Task 1E"""

stations = build_station_list()

print(rivers_by_station_number(stations, 9))


if __name__ == "__main__":
print("*** Task 1E: CUED Part IA Flood Warning System ***")
run()
16 changes: 16 additions & 0 deletions Task1F.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from floodsystem.stationdata import build_station_list
from floodsystem.station import inconsistent_typical_range_stations


def run():

stations = build_station_list()

W = inconsistent_typical_range_stations(stations)

print(W)


if __name__ == "__main__":
print("*** Task 1F: CUED Part IA Flood Warning System ***")
run()
19 changes: 19 additions & 0 deletions Task2B.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from floodsystem.flood import stations_level_over_threshold
from floodsystem.stationdata import build_station_list, update_water_levels


def run():

stations = build_station_list()
update_water_levels(stations)
tol = 0.8

v = stations_level_over_threshold(stations, tol)

for station in v:
print("{} {}".format(station[0].name, station[1]))


if __name__ == "__main__":
print("*** Task 2B: CUED Part IA Flood Warning System ***")
run()
19 changes: 19 additions & 0 deletions Task2C.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from floodsystem.flood import stations_highest_rel_level
from floodsystem.stationdata import build_station_list, update_water_levels


def run():

stations = build_station_list()
update_water_levels(stations)
N = 10

b = stations_highest_rel_level(stations, N)

for station in b:
print("{} {}".format(station.name, station.relative_water_level()))


if __name__ == "__main__":
print("*** Task 2C: CUED Part IA Flood Warning System ***")
run()
28 changes: 28 additions & 0 deletions Task2E.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (C) 2018 Garth N. Wells
#
# SPDX-License-Identifier: MIT

import datetime
from floodsystem.stationdata import build_station_list, update_water_levels
from floodsystem.datafetcher import fetch_measure_levels
from floodsystem.flood import stations_highest_rel_level
from floodsystem.plot import plot_water_levels


def run():
# Build list of stations
stations = build_station_list()

# Update latest level data for all stations
update_water_levels(stations)
dt = 10

# Identify stations with relative water level over threshold
for station in stations_highest_rel_level(stations, 5):
dates, levels = fetch_measure_levels(station.measure_id, dt=datetime.timedelta(days=dt))
plot_water_levels(station, dates, levels)


if __name__ == "__main__":
print("*** Task 2E: CUED Part IA Flood Warning System ***")
run()
37 changes: 37 additions & 0 deletions Task2Eext.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (C) 2018 Garth N. Wells
#
# SPDX-License-Identifier: MIT

import datetime
from floodsystem.stationdata import build_station_list, update_water_levels
from floodsystem.datafetcher import fetch_measure_levels
from floodsystem.flood import stations_highest_rel_level
from floodsystem.plot import plot_water_levels_ext, plot_water_levels_web


def run():
# Build list of stations
stations = build_station_list()

# Update latest level data for all stations
update_water_levels(stations)

dt = 10
p = 4

# Identify stations with relative water level over threshold
stations = stations_highest_rel_level(stations, 9)
datess, levelss = [], []

for station in stations[:9]:
dates, levels = fetch_measure_levels(station.measure_id, dt=datetime.timedelta(days=dt))
datess.append(dates)
levelss.append(levels)

plot_water_levels_web(stations[:9], datess, levelss, p)
plot_water_levels_ext(stations[:6], datess[:6], levelss[:6], p)


if __name__ == "__main__":
print("*** Task 2E extension: CUED Part IA Flood Warning System ***")
run()
30 changes: 30 additions & 0 deletions Task2F.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (C) 2018 Garth N. Wells
#
# SPDX-License-Identifier: MIT

import datetime
from floodsystem.stationdata import build_station_list, update_water_levels
from floodsystem.datafetcher import fetch_measure_levels
from floodsystem.flood import stations_highest_rel_level
from floodsystem.plot import plot_water_level_with_fit


def run():
# Build list of stations
stations = build_station_list()

# Update latest level data for all stations
update_water_levels(stations)

dt = 2
p = 4

# Identify stations with relative water level over threshold
for station in stations_highest_rel_level(stations, 5):
dates, levels = fetch_measure_levels(station.measure_id, dt=datetime.timedelta(days=dt))
plot_water_level_with_fit(station, dates, levels, p)


if __name__ == "__main__":
print("*** Task 2F: CUED Part IA Flood Warning System ***")
run()
33 changes: 33 additions & 0 deletions Task2G.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from floodsystem.flood import update_stations_risk, update_flood_warnings
from floodsystem.stationdata import build_station_list, update_water_levels


def run():

# List truncated to shorten runtime for testing
stations = build_station_list()[:50]
update_water_levels(stations)
update_stations_risk(stations)

towns = update_flood_warnings(stations)

severe_list = sorted([town for town in towns if towns[town] == "severe"])
high_list = sorted([town for town in towns if towns[town] == "high"])
moderate_list = sorted([town for town in towns if towns[town] == "moderate"])
low_list = sorted([town for town in towns if towns[town] == "low"])

print("{} Towns with Severe Warning".format(len(severe_list)))
print("{} Towns with High Warning".format(len(high_list)))
print("{} Towns with Moderate Warning".format(len(moderate_list)))
print("{} Towns with Low Warning".format(len(low_list)))
print("Severe Warnings:")
for town in severe_list:
print(town)
print("High Warnings:")
for town in high_list:
print(town)


if __name__ == "__main__":
print("*** Task 2G: CUED Part IA Flood Warning System ***")
run()
40 changes: 40 additions & 0 deletions floodsystem/analysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
""" This module contains functions to computer least-square fit
of a polynomial to water level data.

"""

from matplotlib import dates as mpldates
import numpy as np
import datetime


def polyfit(dates, levels, p):
"""Take lists of dates and levels, and an integer p as the
degree of polynomial. Compute least-square fit of a polynomial
for the water level data supplied. Return a NumPy.poly1D object
and shift in date axis.

"""

d0 = dates[-1]
mpl_dates = np.array(mpldates.date2num(dates)) - mpldates.date2num(d0)
coeff = np.polyfit(mpl_dates, levels, p)
poly = np.poly1d(coeff)
return poly, d0


def prediction(poly, dates, d0):
"""Take a fitted Numpy.poly1D object, a list of dates and shift
in date axis. Return a list of predicted water level data 15 minutes,
1 hour, 2 hours, 6 hours, 12 hours and 24 hours ahead with values arranged
in chronological order.

"""

dates.sort()
date = dates[-1]
times = [15, 60, 120, 360, 720, 1440]

prediction_time = [date + datetime.timedelta(minutes=time) for time in times]
mpl_dates = np.array(mpldates.date2num(prediction_time)) - mpldates.date2num(d0)
return poly(mpl_dates)
Loading