Welcome to swiflow’s documentation!¶
Welcome to swiflow¶
WARNING: Swiflow is under active development on its master branch.
A python package for modeling streamflow using surface water input from iSnobal
- Free software: MIT license
- Documentation: https://swiflow.readthedocs.io
Setting up a new project¶
To setup a project you must have a vector for each subbasin representing water landing on the ground surface. In most cases this project uses aggregated Surface Water Input (SWI) from iSnobal typically generated using AWSM .
To setup a basin consider using delineate with the –streamflow flag. THis will create all the static files you need for your basin.
SWI is usually outputted as an image. To aggregate SWI to a vector, SWIFlow has a function to manage this which is used like the code below. This will produce a CSV containing the vectorized surface water input (SWI) by looping through the watersheds and the em.nc file.
prep_swi em.nc watersheds.shp SWI
Setup a config.ini that looks similar to the one in ./examples/catchment_csv/config.ini which should point to the new files you just created. For more info on the config simply use inicheck:
inicheck -m swiflow --details <section>
Once you have started a configuration file, attempt to determine the max_infiltration setting in your config file by running the following command over a whole water year. To do this you will also need provide a path to observed_streamflow in the config file.
solve_rmax config.ini
This will print out the estimated max_infiltration.
Once a max_infiltration value is determined. Use the calibrate_swi tool to estimate the upper_residence_time and lower_residence_time by running the following command over a whole water year and setting your timestep to 4 hours to speed it up:
calibrate_swi config.ini
The calibration process is still experimental so you may need to adjust values still. Attempt to use a value set that was listed in the print out from the calibration scheme will help narrow it down.
Once you have your parameters set, set the dates of interest and run:
swiflow config.ini
Credits¶
This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.
Installation¶
Stable release¶
To install swiflow, run this command in your terminal:
$ pip install swiflow
This is the preferred method to install swiflow, as it will always install the most recent stable release.
If you don’t have pip installed, this Python installation guide can guide you through the process.
From sources¶
The sources for swiflow can be downloaded from the Github repo.
You can either clone the public repository:
$ git clone git://github.com/USDA-ARS-NWRC/swiflow
Or download the tarball:
$ curl -OL https://github.com/USDA-ARS-NWRC/swiflow/tarball/master
Once you have a copy of the source, you can install it with:
$ python setup.py install
Usage¶
To use swiflow simply create a config file point to all the necessary files and
swiflow config.ini
Catchment Models¶
Catchment models describe how the inputted water leaves the subcatchment. Currently only one is implemented:
- Comola
Routing Methods¶
SWIFlow has two routing methods developed in it.
- Direct
- Muskingum-Cunge (1969)
Direct¶
Direct routing assumes that a bulk of the time water is spent on the hill slope. This is only valid for small catchments.
Muskingum-Cunge (Under Development)¶
Description of technique first provided by Cunge 1969. Numerical discretization taken from Gallice et. al 2016 and re-transcribed below.
Variables
- n - Time index [unitless]
- i - Discretize stream reach index [unitless]
- t - Time [Seconds]
- Q - Flowrate [M^3/S]
- l_i - Stream reach discretized length for stream i [m]
- w - Stream segment width [m]
- S_0 - Local bed slope []
- C_r - Wave celerity [m/s]
- Q_r - Representative discharge [m^3/s]
- n_m - Mannings coefficient ( 0.03 - 0.10 for small natural streams) [s/m^-1/3]
Assumptions
- C_r is derived from Q_r assuming rectangular channel cross section
Where
Where
Numerical stability guidance provided by the following for lumped systems as opposed to gridded discretized reaches:
Calibration Theory¶
In the SWIFlow configuration file, max_infiltration (\(R_{max}\)), lower_residence_time (\(\bar{\tau_l}\)), and upper_residence_time (\(\bar{\tau_u}\)) are all model Parameters to be set by the user. These values unfortunately are specific to a basin and thus need calibration.
Most of the following theory depends on the ability to separate the flow into two components of the observed flowrate. The current method utilizes an approach described by Eckhardt 2005 in a paper titled “How to construct recursive digital filters for baseflow separation to be used for calibration.”
Max Infiltration Theory¶
Solving for \(R_{max}\) means that the scope of the following derivation should only be performed on the lower layer equations. The storage equation is simplified by assuming the change in storage is zero on an annual basis. Using the base component of the separate flow from Eckhardt’s method our storage and infiltration equation becomes:
Substituting the infiltration equation into the storage equation, it then becomes:
\(R_{max}\) is a constant value so using the above equation allows us to iteratively estimate the value. This is performed by bisection where the solution is driving the residual to 0 in the following manner where A is always less than B:
The steps to solve for max infiltration:
- Separate the flow into direct and base flow using Eckhardt’s method
- Calculate the cumulative volumes from the Inputted SWI and the observed flowrate
- Calculate the derivative of the difference between SWI and Observed volumes
- Calculate the mean of this timeseries to estimate the infiltration value
TIP: The configuration file sets the time period for analysis. Use a time period of most importance to weight the average towards a high volume period
Residence Time Theory¶
After estimating \(R_{max}\), the next step is to solve for residence times for the upper and lower layers (\(\bar{\tau}_{L}\) and \(\bar{\tau}_{U}\)). This is performed in a similar fashion as in max infiltration.
The steps to estimate the upper and low residence times
- Separate the flow into direct and base flow using Eckhardt’s method
- Insert the separated components into the model’s states \(Q_{base} \rightarrow Q_{L}\) and \(Q_{direct} \rightarrow Q_{U}\)
- Run the model, skipping solving for \(Q\)
- Solve for \(\bar{\tau}_{L}\) and \(\bar{\tau}_{U}\)
- Use the min/max to bound an iterative solution via bisection. e.g. \(A = min(\bar{\tau}_{L})\) \(B = max(\bar{\tau}_{L})\)
- Assume \(\bar{\tau}_{U}\) is constant, and run model as in step #3 with \(\bar{\tau_C} = \frac{A + B}{2}\)
- Rerun the model as in step #3.
- Iterate on the solution picking the new bounds as described above.
- Repeat Steps 1-8 leaving the new \(\bar{\tau_L}\) constant and iterate on \(\bar{\tau_U}\)
Fair Warning¶
The calibration process is in still in development. Estimating for \(R_{max}\), \(\bar{\tau}_{L}\) and \(\bar{\tau}_{U}\) is highly interconnected and thus in these early stages of development some user intuition made need to be applied and even iterated upon. E.g. Calibrate, adjust, calibrate.
Configuration File Reference¶
The SWIFlow configuration file is described in detail below. This information is all based on the CoreConfig file stored under the top level of the package.
For configuration file syntax information please visit http://inicheck.readthedocs.io/en/latest/
setup¶
model¶
output¶
system¶
analysis¶
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
You can contribute in many ways:
Types of Contributions¶
Report Bugs¶
Report bugs at https://github.com/USDA-ARS-NWRC/swiflow/issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” and “help wanted” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “enhancement” and “help wanted” is open to whoever wants to implement it.
Adding Models¶
Adding a catchment model or adding a routing model to swiflow is as simple as
New models can easily be added to swiflow by following the steps below:
- Create a new class in the swiflow.<relevant module> module with a name containing a keyword
- Inherit from the Base<Keyword> Class and define the functions in the base class left blank
3. Add your class name (minus the word model) to the options listed under <relevant module>_type 4. Use it.
All new routing models are added to swiflow.routing_models using the keyword Routing in the class name
All new catchment models are added to swiflow.catchment_models using the keyword Model in the class name
Write Documentation¶
swiflow could always use more documentation, whether as part of the official swiflow docs, in docstrings, or even on the web in blog posts, articles, and such.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/USDA-ARS-NWRC/swiflow/issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started!¶
Ready to contribute? Here’s how to set up swiflow for local development.
Fork the swiflow repo on GitHub.
Clone your fork locally:
$ git clone git@github.com:your_name_here/swiflow.git
Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:
$ mkvirtualenv swiflow $ cd swiflow/ $ python setup.py develop
Create a branch for local development:
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
When you’re done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:
$ flake8 swiflow tests $ python setup.py test or py.test $ tox
To get flake8 and tox, just pip install them into your virtualenv.
Commit your changes and push your branch to GitHub:
$ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature
Submit a pull request through the GitHub website.
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
- The pull request should work for Python 3.5 3.6, and 3.7. Check https://travis-ci.org/USDA-ARS-NWRC/swiflow/pull_requests and make sure that the tests pass for all supported Python versions.
Deploying¶
A reminder for the maintainers on how to deploy. Make sure all your changes are committed (including an entry in HISTORY.rst). Then run:
$ bumpversion patch # possible: major / minor / patch
$ git push
$ git push --tags
Credits¶
Development Lead¶
- Ernesto Trujillo @etrujil
- Micah Johnson @micahjohnson150
Contributors¶
Want to be the first?
Comola Catchment Model¶
SWIFlow is a two layer streamflow model. There is an upper storage and a lower storage that interact. The model uses three state variables to model streamflow. The are storage of a layer, infiltration rate into the layer, and the flowrate from the layer.
This model was introduced by Comola et. al 2015 and implemented the same in swiflow as it was originally described.
Equations¶
Below are the definitions used in the model equations:
The model is described by the following equations:
For change in storage in the upper and lower layer:
The Residence time for each layer for each subbasin is:
The flowrate out of a layer is defined by:
Discretization¶
Spatially the model is split up by subwatersheds or sometimes called HRUs prior to running SWIFlow. This can be performed by basin_setup . Temporally, the change in storage equation is split up explicitly which is implemented as follows:
Algorithm¶
At the beginning of the run, SWIFlow the initial conditions for \(Q_{res_{L,U}}\) and \(S_{res_{L,U}}\), S are all zero. SWIFlow computes the state variables in the following order for each timestep.