Skip to content

Python implementation of the Tank Hydrological model by Sugawara and Funiyuki (1956)

License

Notifications You must be signed in to change notification settings

duynguyen02/HydTANK

Folders and files

NameName
Last commit message
Last commit date

Latest commit

33344ec · Dec 22, 2024

History

13 Commits
Nov 27, 2024
Dec 22, 2024
Nov 27, 2024
Nov 27, 2024
Nov 27, 2024
Dec 22, 2024
Dec 22, 2024
Nov 27, 2024

Repository files navigation

HydTANK

PyPI - Version

Python implementation of the Tank Hydrological model by Sugawara and Funiyuki (1956), based on the original code from tank-model by nzahasan.

Installation

pip install hydtank

Getting Started

1. Prepare the Dataset

The dataset must include the following columns: Date, Precipitation, Evapotranspiration, and Discharge. Additionally, ensure that:

  • The time intervals between dates are consistent (e.g., 24 hours) for accurate model performance.

Example dataset:

Date Discharge Precipitation Evapotranspiration
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
... ... ... ...

2. Prepare the HEC-HMS Basin File

In addition to the dataset, ensure you have the required HEC-HMS basin file. This file contains the hydrological and geographical configuration needed for the TANK model.

3. Initialize the Model

3.1 Directly from a dataset file and a basin file:

from hydtank import build_hydtank

with open('data.csv') as file1, open('NuiLe_GiaUi.basin') as file2:
    tank = build_hydtank(
        dataset_content=file1.read(),
        basin_content=file2.read(),
        interval=24.0,
        start=None,
        end=None
    )

3.2 From a Dataset and a basin file:

import pandas as pd
from hydtank import build_hydtank_from_dataset, Dataset, TIME_SERIES, PRECIPITATION, EVAPOTRANSPIRATION, DISCHARGE

df = pd.read_csv('data.csv')

_dataset = Dataset(
    time_series=df[TIME_SERIES].tolist(),
    precipitation=df[PRECIPITATION].tolist(),
    evapotranspiration=df[EVAPOTRANSPIRATION].tolist(),
    discharge=df[DISCHARGE].tolist(),
)

tank = build_hydtank_from_dataset(
    basin_content=open('NuiLe_GiaUi.basin').read(),
    _dataset=_dataset,
    interval=24.0,
    start=None,
    end=None
)

3.3 From an existing model:

from hydtank import build_hydtank, HydTANK

with open('data.csv') as file1, open('NuiLe_GiaUi.basin') as file2:
    tank = build_hydtank(
        file1.read(),
        file2.read()
    )

    # Avoid using the original model directly!
    # Always make a copy before creating a new model
    tank_copy = tank.copy()

    tank2 = HydTANK(
        tank_copy.dataset,
        tank_copy.basin_defs,
        tank_copy.root_node,
        tank_copy.interval,
        tank_copy.start,
        tank_copy.end
    )

4. Retrieve BasinDef Information by Name

from hydtank.bsd_junction import Junction
from hydtank.bsd_reach import Reach
from hydtank.bsd_sink import Sink
from hydtank.bsd_subbasin import Subbasin

...

try:
    nui_le: Subbasin = tank.get_basin_def_by_name('NuiLe')
    giaui_local: Subbasin = tank.get_basin_def_by_name('GiaUi_Local')
    reach1: Reach = tank.get_basin_def_by_name('Reach1')
    junction1: Junction = tank.get_basin_def_by_name('Junction1')
    sink: Sink = tank.get_basin_def_by_name('Sink1')
except ValueError:
    # BasinDef not found
    pass

5. Plotting

tank.plot_basin_network().save('GiaUi_NuiLe_Basin_Network.png')
tank.plot_headwater_q().save('GiaUi_NuiLe_Headwater.png')
tank.plot_q().save('GiaUi_NuiLe_Qsim.png')
tank.plot_subbasin(nui_le).save('GiaUi_NuiLe_NuiLe_Subbasin.png')
tank.plot_subbasin(giaui_local).save('GiaUi_NuiLe_GiaUiLocal_Subbasin.png')

6. Reconfigure Parameters for a BasinDef

from hydtank.parameters import SubbasinParameters, ReachParameters

...

params = reach1.parameters.copy()
params.k = 0.9235288521736096
tank.reconfig_parameters(reach1.name, params)
tank.reconfig_parameters(reach1.name, ReachParameters())

tank.reconfig_parameters(nui_le.name, SubbasinParameters())

7. Auto-Optimize Parameters for Subbasin and Reach

7.1 Optimize Specific Subbasin and Reach

tank.optimize([nui_le, reach1, giaui_local])

7.2 Optimize All

Note: This process can take significant time as it involves optimizing parameters for all Subbasin and Reach elements in the model.

tank.optimize_all()

8. Export Calculation Results as a pandas.DataFrame

r_df = tank.to_dataframe()

9. Set a New Dataset

df = pd.read_csv('new_data.csv')

_dataset = Dataset(
    time_series=df[TIME_SERIES].tolist(),
    precipitation=df[PRECIPITATION].tolist(),
    evapotranspiration=df[EVAPOTRANSPIRATION].tolist(),
    discharge=df[DISCHARGE].tolist(),
)

tank.reset_dataset(_dataset, interval=24.0)

10. Configure Time Range

from datetime import datetime

...

tank.set_timeseries_range(start=datetime(...), end=datetime(...))

License

This library is released under the MIT License.

Contact

For any questions or issues, please open an issue on GitHub or email us at [email protected].


About

Python implementation of the Tank Hydrological model by Sugawara and Funiyuki (1956)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages