Skip to content

SWAT+ Simulation

SWAT+ simulations can be performed while modifying multiple optional input parameters. These parameters can be changed either individually or simultaneously for a simulation. Some examples are shown below:

Initializing the TxtinoutReader Class

The TxtinoutReader class is used to interact with the SWAT+ model via the TxtInOut folder generated by the QSWAT+. This folder must include the necessary files generated during a simulation using the SWAT+ Editor. The class allows you to modify input parameters and run simulations.

The TxtInOut folder must also contain the SWAT+ executable file. Its location can be found in the Run SWAT+ tab of the SWAT+ Editor. If the executable is missing, an error will occur.

import pySWATPlus

# Replace this with your actual path
txtinout_path = r"C:\Users\Username\project\Scenarios\Default\TxtInOut" 

txtinout_reader = pySWATPlus.TxtinoutReader(
    path=txtinout_path
)

A Trial Simulation with No Parameter Changes

This simple code checks whether the executable file runs the SWAT+ model correctly.

txtinout_reader.run_swat()

Instead of modifying the files in the input TxtInOut folder, it is recommended to run the SWAT+ simulation in a seperate direcotry.

# Replace this with your actual path
target_dir = r"C:\Users\Username\simulation_folder" 

reader = txtinout_reader.run_swat_in_other_dir(
    target_dir=target_dir
)

Simulation After Modified Timelines

The following example demonstrates how to run the SWAT+ model after modifying the simulation timelines.

# Set the begin and end years for the simulation
reader.set_begin_and_end_year(2012, 2016)

# Set the warm-up period in years
reader.set_warmup_year(1)

# Run the simulation
reader.run_swat()

Simulation After Enabling a Specific Print Object

Suppose the daily simulation data for channel output is required, but the file channel_sd_day.txt is missing after the simulation. The following example shows how to enable it and generate the expected output:

# Enable the 'channel_sd' object in the print.prt file
reader.enable_object_in_print_prt(
    obj='channel_sd',
    daily=True,
    monthly=True,
    yearly=True,
    avann=True,
)

# Run the simulation
reader.run_swat()

Simulation After Parameter Modifications

# Register the hydrology.hyd file
hyd_register = reader.register_file(
    filename='hydrology.hyd',
    has_units=False
)

# Get the DataFrame
hyd_df = hyd_register.df

# Modify the 'esco' parameter value
hyd_df['esco'] = 0.6

# rewrite hydrology.hyd file
hyd_register.overwrite_file()

# View the modified DataFrame (optional)
hyd_register.df

# Run the simulation
reader.run_swat()

Run Configurable Simulations in a Single Function

Instead of calling set_begin_and_end_year(), set_warmup_year(), and enable_object_in_print_prt() separately, you can pass all these options directly into a single call to run_swat_in_other_dir(). You can also modify input values in specific files prior to running a simulation.

Supported configuration options include:

  • params: Dictionary to modify one or more input files before the run.
  • begin_and_end_year: Tuple like (2012, 2016) to control the simulation period.
  • warmup: Number of years used for model warm-up.
  • print_prt_control: Dictionary to control which outputs are written.

This is recommended for batch or reproducible simulations.

# Modify parameters in the plants.plt file
params = {
    'plants.plt': {
        'has_units': False,
        'bm_e': [
            {'value': 100, 'change_type': 'absval', 'filter_by': 'name == "agrl"'},
            {'value': 110, 'change_type': 'absval', 'filter_by': 'name == "almd"'},
        ],
    }
}


txtinout_reader.run_swat_in_other_dir(
    target_dir=r"C:\Users\Username\simulation_1",
    params=params,
    begin_and_end_year=(2010, 2015),
    warmup=1,
    print_prt_control={
        'channel_sd': {'daily': True, 'monthly': False}
    }
)

⚠️ Note: The run_swat() method only supports the params argument for in-place simulations. It does not accept begin_and_end_year, warmup, or print_prt_control. To modify these settings within the original TxtInOut folder, use: set_begin_and_end_year(), set_warmup_year(), and enable_object_in_print_prt(). If you want to avoid changing the original TxtInOut directory, use run_swat_in_other_dir(), which supports all of these options in a separate working directory.

Parallel SWAT+ Simulations

To run multiple SWAT+ simulations in parallel with modified parameters, the following example provides a quick guide to get started:

import multiprocessing
import tempfile

# Define multiple parameter sets
param_sets = [
    {
        'hydrology.hyd': {
            'has_units': False,
            'epco': [
                {'value': 0.7, 'change_type': 'absval'}
            ],
        }
    },
    {
        'plants.plt': {
            'has_units': False,
            'bm_e': [
                {'value': 120, 'change_type': 'absval', 'filter_by': 'name == "agrl"'},
                {'value': 130, 'change_type': 'absval', 'filter_by': 'name == "almd"'},
            ],
        }
    },
]

# Define the function
def run_simulation(params):

    with tempfile.TemporaryDirectory() as tmp_dir:
        reader = pySWATPlus.TxtinoutReader(
            path=txtinout_path
        )
        output = reader.run_swat_in_other_dir(
            target_dir=tmp_dir,
            params=params
        )

    return output


if __name__ == '__main__':
    # Run simulations in parallel
    with multiprocessing.Pool(processes=2) as pool:
        results = pool.map(run_simulation, param_sets)
    # Print output directories
    for path in results:
        print("Simulation directory:", path)