Python implementation of the Tank Hydrological model by Sugawara and Funiyuki (1956), based on the original code from tank-model by hckaraman.
To install the package, run:
pip install tj_hyd_tank
Your dataset should contain the following columns: Date, Precipitation, Evapotranspiration, and **Discharge **. The column names are customizable.
Example:
Date | Q | P | E |
---|---|---|---|
10/9/2016 | 0.25694 | 0 | 2.79 |
10/10/2016 | 0.25812 | 0 | 3.46 |
10/11/2016 | 0.30983 | 0 | 3.65 |
10/12/2016 | 0.31422 | 0 | 3.46 |
10/13/2016 | 0.30866 | 0 | 5.64 |
10/14/2016 | 0.30868 | 0 | 3.24 |
10/15/2016 | 0.31299 | 0 | 3.41 |
... | ... | ... | ... |
Ensure the time intervals between dates are consistent (e.g., 24 hours) for accurate model performance.
Use a HEC-HMS basin file.
import pandas as pd
from tj_hyd_tank import TJHydTANK, TANKColNames, TANKConfig
df = pd.read_csv('assets/data_example.csv')
tank_cols_name = TANKColNames(
date='Date',
precipitation='P',
evapotranspiration='E',
discharge='Q'
)
tank_config = TANKConfig(
start_date=None,
end_date=None,
interval=24.0
)
tank = TJHydTANK(
basin_file='assets/CedarCreek.basin',
df=df,
tank_col_names=tank_cols_name,
tank_config=tank_config
)
from tj_hyd_tank import Subbasin, Reach
for basin_def in tank.basin_defs:
print(basin_def.name, basin_def.type)
print(basin_def.stats)
if isinstance(basin_def, (Subbasin, Reach)):
print(basin_def.params)
from tj_hyd_tank import Subbasin, Reach
for root_node in tank.root_node:
print(root_node.name, root_node.type)
print(root_node.stats)
if isinstance(root_node, (Subbasin, Reach)):
print(root_node.params)
outlet1 = tank.get_basin_def_by_name('Outlet1')
if outlet1 is not None:
tank.show_discharge(outlet1)
from tj_hyd_tank import SubbasinParams
w170 = tank.get_basin_def_by_name('W170')
if w170 is not None:
if isinstance(w170, Subbasin):
tank.reconfig_subbasin_params(
w170,
SubbasinParams(
t0_is=0.02,
t0_soc_uo=80.0
)
)
print('Q_tank_0', w170.Q_tank_0.tolist())
print('Q_tank_1', w170.Q_tank_1.tolist())
print('Q_tank_2', w170.Q_tank_2.tolist())
print('Q_tank_3', w170.Q_tank_3.tolist())
print('bottom_outlet_flow_tank_0', w170.bottom_outlet_flow_tank_0.tolist())
print('bottom_outlet_flow_tank_1', w170.bottom_outlet_flow_tank_1.tolist())
print('bottom_outlet_flow_tank_2', w170.bottom_outlet_flow_tank_2.tolist())
tank.reconfig_tank(
TANKConfig(
start_date=pd.to_datetime('09/10/2016', dayfirst=True, utc=True),
end_date=pd.to_datetime('20/10/2016', dayfirst=True, utc=True)
)
)
outlet1_df = tank.to_dataframe(outlet1)
outlet1_df
print(tank.logs)
tank = TJHydTANK(
basin_file='not important',
df=df,
tank_col_names=tank_cols_name,
tank_config=tank_config,
basin_defs=other_tank.basin_defs,
root_node=other_tank.root_node
)
- Params:
SubbasinParams
- Params:
BasinDefParams
- Params:
BasinDefParams
- Params:
ReachParams
Raised when a basin file is invalid, possibly due to incorrect format or corrupted data.
Raised when a specified file cannot be located. The missing file's name is included for easy identification.
Raised when required columns are missing from the dataset. The exception specifies which column is absent.
Raised when a specified column contains empty data, ensuring all necessary fields are populated.
Raised for invalid datetime entries, such as incorrect formatting or out-of-range values.
Raised when the provided datetime interval is invalid, ensuring consistency in date ranges or intervals.
Raised for invalid start dates, particularly for time-based events or ranges.
Raised for invalid end dates, handling errors related to the conclusion of time-based events or ranges.
Raised when the date range is invalid, such as when the start date is after the end date. An optional message may provide additional context.