|
| 1 | +""" |
| 2 | +Script to extract and format data into Streamfall expected format/structure. |
| 3 | +""" |
| 4 | + |
| 5 | +using OrderedCollections |
| 6 | +using Glob |
| 7 | + |
| 8 | +using Statistics |
| 9 | +using CSV, DataFrames, YAML |
| 10 | +using Streamfall |
| 11 | + |
| 12 | +# Load climate data - in this case from a CSV file with data for all nodes. |
| 13 | +climate_data = CSV.read( |
| 14 | + "climate/climate_historic.csv", |
| 15 | + DataFrame; |
| 16 | + comment="#" |
| 17 | +) |
| 18 | + |
| 19 | +# Load in observation data for each gauge in network |
| 20 | +outflow_files = readdir(glob"gauges/*_outflow*.csv") |
| 21 | +all_flow_data = CSV.read.(outflow_files, DataFrame; comment="#") |
| 22 | + |
| 23 | +# Process data. Later on, flow data will be re-combined into a single dataframe |
| 24 | +ordered_flow_data = OrderedDict() |
| 25 | +for name in node_names(sn) |
| 26 | + matching_file_pos = findall(occursin.(name, outflow_files))[1] |
| 27 | + suffix = "_outflow_[ML]" |
| 28 | + |
| 29 | + if name != "406000" |
| 30 | + ordered_flow_data[name] = extract_flow(all_flow_data[matching_file_pos], name, suffix) |
| 31 | + continue |
| 32 | + end |
| 33 | + |
| 34 | + out = extract_flow(all_flow_data[matching_file_pos], name, suffix) |
| 35 | + ext = all_flow_data[matching_file_pos][:, ["Date", "406000_extractions_[ML]"]] |
| 36 | + df = DataFrame(Date=out.Date) |
| 37 | + |
| 38 | + # Note that dam releases must have "releases" in their column name. |
| 39 | + df[!, "406000_releases_[ML]"] = out[:, "406000"] .+ ext[:, "406000_extractions_[ML]"] |
| 40 | + |
| 41 | + ordered_flow_data[name*"_releases_[ML]"] = df |
| 42 | +end |
| 43 | + |
| 44 | +# Streamfall provides some convenience functions to align datasets. |
| 45 | +# In the next few lines |
| 46 | +aligned_climate, aligned_flow... = align_time_frame(climate_data, values(ordered_flow_data)...) |
| 47 | +_, extraction_data = align_time_frame(aligned_climate, ordered_flow_data["406000_releases_[ML]"]) |
| 48 | + |
| 49 | +# Read in dam levels for calibration |
| 50 | +hist_dam_levels = CSV.read( |
| 51 | + "gauges/406000_historic_levels_for_fit.csv", |
| 52 | + DataFrame; |
| 53 | + comment="#" |
| 54 | +) |
| 55 | +_, aligned_dam_levels = align_time_frame(aligned_climate, hist_dam_levels) |
| 56 | + |
| 57 | +# Combine all data into a single DataFrame |
| 58 | +calib_data = hcat( |
| 59 | + aligned_flow[1][:, [:Date]], |
| 60 | + [aligned_flow[i][:, 2:end] for i in 1:length(keys(aligned_flow))]... |
| 61 | +) |
| 62 | + |
| 63 | +# For dams, level data should be used for calibration, so we replace that here. |
| 64 | +rename!(calib_data, "406000_releases_[ML]"=>"406000") |
| 65 | +calib_data[!, "406000"] = aligned_dam_levels[!, "Dam Level [mAHD]"] |
| 66 | + |
| 67 | +# We now have a dataset for calibration (`calib_data`) and a dataset indicating the |
| 68 | +# historic dam extractions (`extraction_data`) which is added onto releases to obtain total |
| 69 | +# dam outflow. |
| 70 | +# `extraction_data` may also hold water extractions at each "reach". |
| 71 | + |
| 72 | +CSV.write("gauges/outflow_and_level.csv", calib_data) |
| 73 | +CSV.write("climate/climate.csv", aligned_climate) |
| 74 | +CSV.write("gauges/dam_extraction.csv", extraction_data) |
0 commit comments