Tip
Need help? Please let us know in the SUEWS Community.
Please report issues with the manual on GitHub Issues (or use Report Issue for This Page for page-specific feedback).
Please cite SUEWS with proper information from our Zenodo page.
SUEWSSimulation Tutorial#
This tutorial demonstrates how to use the simplified SUEWSSimulation interface for running SUEWS simulations.
Introduction#
The SUEWSSimulation class provides a clean, intuitive interface for SUEWS with:
Simple configuration management
Flexible forcing data loading
Straightforward simulation execution
Multiple output formats via OutputConfig
Easy configuration updates
Getting Started#
1. Basic Simulation#
The simplest way to run a SUEWS simulation:
from supy import SUEWSSimulation
# Create simulation from YAML configuration
sim = SUEWSSimulation('config.yml')
# Update forcing data
sim.update_forcing('forcing_data.txt')
# Run the simulation
sim.run()
# Save results
sim.save('output_dir/')
2. Using Benchmark Data#
Run with the provided benchmark data:
from pathlib import Path
from supy import SUEWSSimulation
# Use benchmark configuration and forcing
config_path = Path('test/benchmark1/benchmark1.yml')
forcing_path = Path('test/benchmark1/forcing/Kc1_2011_data_5.txt')
# Create and run simulation
sim = SUEWSSimulation(config_path)
sim.update_forcing(forcing_path)
sim.run()
# Access results directly
results = sim.results
print(f"Simulation complete! {len(results)} timesteps processed")
Working with Results#
3. Accessing Output Variables#
Results are returned as multi-level pandas DataFrames with columns organised by (group, variable):
# Access results property
results = sim.results
# Method 1: Use get_variable() (recommended for simple access)
qh = sim.get_variable('QH') # Sensible heat flux
qe = sim.get_variable('QE') # Latent heat flux
# Method 2: Direct access using (group, variable) syntax
qs = results[('SUEWS', 'QS')] # Storage heat flux
t2 = results[('SUEWS', 'T2')] # 2m air temperature
# Calculate daily averages using pandas
qh_daily = qh.resample('D').mean()
# Plot energy balance
import matplotlib.pyplot as plt
energy_vars = ['QH', 'QE', 'QS', 'QF']
for var in energy_vars:
sim.get_variable(var).plot(label=var)
plt.legend()
plt.ylabel('Energy flux (W/m²)')
plt.show()
Handling variables in multiple groups:
Some variables appear in multiple output groups (e.g., AlbSnow in both SUEWS and DailyState, Kup in both SUEWS and SPARTACUS). The get_variable() method handles this safely:
# For ambiguous variables, specify the group
try:
albedo = sim.get_variable('AlbSnow') # Raises error if ambiguous
except ValueError as e:
print(e) # "Variable 'AlbSnow' appears in multiple groups: SUEWS, DailyState..."
# Resolve by specifying group
albedo_suews = sim.get_variable('AlbSnow', group='SUEWS')
albedo_daily = sim.get_variable('AlbSnow', group='DailyState')
# Alternative: direct MultiIndex access
kup_suews = results[('SUEWS', 'Kup')]
kup_spartacus = results[('SPARTACUS', 'Kup')]
4. Saving Results#
Save results according to OutputConfig settings:
# Save using default settings from config
sim.save() # Saves to current directory
# Save to specific directory
sim.save('my_output_dir/')
# The format (txt or parquet) is determined by OutputConfig in YAML:
# output_file:
# format: parquet # or txt
# freq: 3600 # output frequency in seconds
Configuration Management#
5. Updating Configuration#
Update configuration parameters without reloading:
# Update timestep
sim.update_config({'model': {'control': {'tstep': 600}}})
# Update multiple parameters
sim.update_config({
'model': {
'control': {'tstep': 300},
'physics': {'stabilitymethod': 2}
}
})
# Reset and re-run with new configuration
sim.reset()
sim.run()
6. Loading Different Configurations#
Switch between configurations:
# Start with one configuration
sim = SUEWSSimulation('config_summer.yml')
sim.update_forcing('forcing_summer.txt')
summer_results = sim.run()
# Switch to different configuration
sim.update_config('config_winter.yml')
sim.update_forcing('forcing_winter.txt')
sim.reset()
winter_results = sim.run()
Forcing Data Options#
7. Multiple Forcing Files#
Load forcing data from multiple files:
# List of forcing files (concatenated in order)
forcing_files = [
'forcing_2023_jan.txt',
'forcing_2023_feb.txt',
'forcing_2023_mar.txt'
]
sim.update_forcing(forcing_files)
8. DataFrame Forcing#
Use pandas DataFrame as forcing:
import pandas as pd
# Load or create forcing DataFrame
df_forcing = pd.read_csv('my_forcing.csv', index_col=0, parse_dates=True)
# Use DataFrame directly
sim.update_forcing(df_forcing)
Advanced Usage#
9. Accessing Configuration#
Inspect and modify the configuration object:
# Access configuration
config = sim.config
# Check current timestep
print(f"Timestep: {config.model.control.tstep}")
# Check sites
for site in config.sites:
print(f"Site: {site.name}, Grid ID: {site.gridiv}")
10. Forcing Fallback#
The simulation automatically loads forcing from config if specified:
# In config.yml
model:
control:
forcing_file: forcing/data.txt # Relative to config file
# No need to call update_forcing if forcing_file is in config
sim = SUEWSSimulation('config.yml')
sim.run() # Uses forcing from config
Best Practices#
Always check results: Verify simulation completed successfully
Use relative paths in config: Makes projects portable
Save frequently: Use OutputConfig to control format and frequency
Reset between runs: Use
sim.reset()when changing parametersCheck forcing data: Ensure forcing covers simulation period
Error Handling#
Common issues and solutions:
try:
sim = SUEWSSimulation('config.yml')
sim.run()
except FileNotFoundError:
print("Configuration file not found")
except RuntimeError as e:
if "No forcing data" in str(e):
print("Remember to load forcing data with update_forcing()")
else:
raise
Further Reading#
SUEWSSimulation Class - Full API reference
YAML Configuration Format - YAML configuration guide
df_output variables - Understanding output structure