EMSC3025-6025
Assignment I — Precipitation
- / -
This assignment uses a century of gridded rainfall to ask three questions that hydrologists actually argue about: how much water falls on the Murray-Darling Basin, whether that amount is changing, and how the droughts and wet periods of the last twenty-five years compare with one another. Along the way you will meet the one geometric correction that separates a defensible basin water balance from one that is wrong by nearly a fifth.
Total: 10 marks.
For EMSC3025, Questions 1–4 total 10 marks. Question 5 is an optional one-mark bonus.
For EMSC6025, Questions 1–3 total 7 marks. Question 4 is worth 2 marks, and required Question 5 is worth 1 mark.
Complete these student notebooks before you begin the assignment. They are available in Colab and contain blank exercise cells.
Use the computer-lab page on the course website to read the executed solution notebooks after you attempt each exercise.
We use the monthly rainfall product from the Bureau of Meteorology’s Australian Water Outlook (the AWRA-L v7 model archive), served by NCI over OPeNDAP. You do not need to download anything by hand: xarray can open the remote file directly and subset it on the server.
If you use Google Colab, run %pip install --quiet xarray netCDF4 before you import xarray. netCDF4 lets xarray open the NCI OPeNDAP data service.
https://thredds.nci.org.au/thredds/dodsC/iu04/australian-water-outlook/historical/v1/AWRALv7/processed/values/month/rain_day.nc
# Run this first in Google Colab.
%pip install --quiet xarray netCDF4
# Use xr as the short name for xarray.
import xarray as xr
# Store the remote data address.
url = (
"https://thredds.nci.org.au/thredds/dodsC/"
"iu04/australian-water-outlook/historical/v1/"
"AWRALv7/processed/values/month/rain_day.nc"
)
# Use netcdf4 to open the OPeNDAP service.
ds = xr.open_dataset(url, engine="netcdf4")%pip install installs xarray and netCDF4 in the current Colab session. xarray reads and labels gridded data. netCDF4 lets xarray read the NCI OPeNDAP service.
import xarray as xr makes the xarray library available as xr. The url variable stores the data address. xr.open_dataset reads the file metadata and returns a dataset called ds.
At this stage, ds contains coordinates, variable names and attributes. It does not contain the full rainfall array in memory.
What you are getting:
rain_day, in millimetres. Despite the name and despite a long_name of “Daily Rainfall”, in this file each value is the monthly total rainfall. Ignore the long_name; trust the units and the time axis.Everything in this assignment that refers to a climatology, a long-term mean or an anomaly uses the full record from 1911 up to the last complete calendar year as its baseline. Say so in your notebook, and use the same baseline throughout so your numbers are comparable.
The Murray-Darling Basin boundary is supplied as a pair of shapefiles, north and south, in
Unzip it and take the union of MDB_north_boundary.shp and MDB_south_boundary.shp. This assignment treats the basin as a single region; the north/south split is the subject of Assignment II. Lab 2 (lab02_shapefiles_and_masks) shows how to read the shapefiles and test whether a point falls inside a polygon. A grid cell belongs to the basin if its centre does; that is accurate enough here, and you can check it by comparing your masked area against the published basin area of about 1,060,000 km².
1. The latitude axis runs backwards. Latitudes in this file are descending (-10 down to -44). A slice must be given in the same order as the axis:
# Wrong: this order does not match the axis.
ds.rain_day.sel(latitude=slice(-38, -24))
# -> latitude: 0 cells. EMPTY, and no error.
# Right: north to south, following the axis.
ds.rain_day.sel(latitude=slice(-24, -38))
# -> latitude: 281 cells. Correct.The first form raises no warning. You get an empty array, and every mean you compute downstream is nan. Print the shape of your subset before you go any further.
.sel selects data by its coordinate labels. slice selects every latitude between its two limits. The limits must follow the coordinate order in the file.
2. open_dataset returning instantly does not mean the data arrived. Opening the URL reads only the metadata and takes about a second. The transfer happens later, when you call .load(), .values, .plot() or an arithmetic reduction. Expect that step to take around a minute for the whole record over the basin.
3. Do not pull the global grid. The full record at full extent is 1386 x 681 x 841 float32, about 3.2 GB. Subset to a bounding box around the basin first, using contiguous slice() objects. Boolean or fancy indexing over OPeNDAP is turned into many small requests and is very slow.
4. The last year is incomplete. Resampling to annual totals without checking will produce a spurious low point in the final year. Drop it.
(2 marks) Plot monthly rainfall over the basin for four months, as a single figure with four panels arranged two rows by two columns:
| dry | wet | |
|---|---|---|
| October | October 2006 | October 2022 |
| December | December 2019 | December 2010 |
The layout is the point of the question. Each row holds the calendar month fixed, so the difference between the two panels in a row cannot be the seasonal cycle — it is purely interannual. Use a common colour scale across all four panels (otherwise the comparison is meaningless), show the basin outline, and label each panel with its date. Comment briefly on what the figure shows, including where in the basin the wet months put their rain.
(3 marks) Compute the total volume of rainfall falling on the basin each month, in gigalitres (1 GL = 10⁶ m³). This requires the area of every grid cell, and grid-cell area on a sphere depends on latitude. Use the exact formula derived in Lab 4 (lab04_grid_cell_areas),
with
(2 marks) Build a time series of annual basin rainfall over complete calendar years and fit a straight line to it by ordinary least squares. Report the slope together with its standard error and p-value, and then answer the question the fit was for: is the fitted trend distinguishable from the basin’s year-to-year variability? Quote the interannual standard deviation alongside the slope to support your answer.
Repeat the fit over at least two different starting years (for example 1911, 1970 and 2000) and comment on what happens to the slope. A good answer explains the behaviour you see rather than reporting a single number.
(EMSC3025: 3 marks; EMSC6025: 2 marks) Compare four periods, using the full-record baseline defined above:
For each, report the mean annual rainfall in GL and mm and its anomaly from the baseline, both in mm and as a percentage. Then discuss: what was similar and what was different between the two droughts, and between the two wet periods? Your discussion should distinguish clearly between how deep a rainfall deficit was and how long it lasted, and should say which of those two you would expect to matter more for storage in the basin’s reservoirs and soils, and why. Support the argument with the year-by-year numbers, not just the period means.
EMSC6025: required and worth 1 mark. EMSC3025: optional and worth one bonus mark.
https://crudata.uea.ac.uk/cru/data/soi/soi.dat (1866 to present; a fixed-width text file, year followed by twelve monthly values followed by the annual mean, with -99.9 as the missing-value flag); orhttps://psl.noaa.gov/data/correlation/nina34.anom.data (1948 to present; two header numbers, then year plus twelve monthly values, with -99.99 missing and a few lines of prose at the end).bom.gov.au. The Bureau blocks automated access and will return an HTTP 403 error. Its background page on El Niño and La Niña is worth reading, but it is reading, not a data source.Then:The raw time variable in these netCDF files is the number of days since 01/01/1900. xarray reads the units attribute and decodes this into proper datetimes for you, so ds.time already gives you dates. This only matters if you read the file with netCDF4 directly, in which case you must do the conversion yourself — and note that dividing by 365.25 is an approximation that drifts by days over a century-long record.