Quick Start Guide
Get started with SPI and SPEI calculations in 5 minutes!
Setup Python Path
Before using the package, add the src folder to your Python path:
import sys
sys.path.insert(0, 'src') # Or use absolute pathBasic Usage
Calculate SPI
Calculate the Standard Precipitation Index (SPI) for your precipitation data:
import sys
sys.path.insert(0, 'src')
import xarray as xr
from indices import spi, save_index_to_netcdf
# Load your precipitation data
ds = xr.open_dataset('your_precip_data.nc')
precip = ds['precip'] # or 'precipitation', 'prcp', 'pr'
# Calculate SPI-12 (12-month scale)
spi_12 = spi(
precip,
scale=12,
periodicity='monthly',
calibration_start_year=1991,
calibration_end_year=2020
)
# Save results
save_index_to_netcdf(spi_12, 'spi_12_output.nc')Calculate SPEI
Calculate the Standardized Precipitation Evapotranspiration Index (SPEI):
from indices import spei
# Load precipitation and temperature
precip = ds['precip']
temp = ds['temperature']
lat = ds['lat']
# Calculate SPEI-12 (auto-calculates PET from temperature)
spei_12 = spei(
precip,
temperature=temp,
latitude=lat,
scale=12,
periodicity='monthly',
calibration_start_year=1991,
calibration_end_year=2020
)
# With Pearson III distribution (recommended for SPEI)
spei_12_p3 = spei(
precip,
temperature=temp,
latitude=lat,
scale=12,
distribution='pearson3'
)
save_index_to_netcdf(spei_12_p3, 'spei_pearson3_12_output.nc')The spei() function can automatically calculate PET when you provide temperature data:
- Thornthwaite (default): Requires only mean temperature. Simple and widely used.
- Hargreaves: Requires Tmin/Tmax data. Better for arid/semi-arid regions.
# Thornthwaite (default)
spei_12 = spei(precip, temperature=temp, latitude=lat, scale=12)
# Hargreaves (requires Tmin/Tmax)
spei_12 = spei(precip, temperature=temp, latitude=lat, scale=12,
pet_method='hargreaves', temp_min=tmin, temp_max=tmax)If you have pre-computed PET values, use pet=your_pet_data instead of temperature=.
By default, all functions use the Gamma distribution. You can choose from five supported distributions via the distribution parameter:
'gamma'— Default, standard for SPI (McKee et al. 1993)'pearson3'— Recommended for SPEI (Vicente-Serrano et al. 2010)'log_logistic'— Alternative for SPEI (original R SPEI package)'gev'— For extreme value analysis'gen_logistic'— European dry/wet indices
See the Probability Distributions page for detailed guidance.
Multi-Scale Calculation
Calculate multiple time scales at once for efficiency:
from indices import spi_multi_scale
# Calculate SPI for multiple time scales at once
spi_multi = spi_multi_scale(
precip,
scales=[1, 3, 6, 12],
periodicity='monthly',
calibration_start_year=1991,
calibration_end_year=2020
)
# Access individual scales
spi_1 = spi_multi['spi_gamma_1_month']
spi_3 = spi_multi['spi_gamma_3_month']
spi_12 = spi_multi['spi_gamma_12_month']Multi-scale calculation is more efficient than calculating each scale separately, especially for large datasets.
Save and Reuse Parameters
Speed up repeated calculations by saving and reusing fitted distribution parameters:
from indices import save_fitting_params, load_fitting_params
# Calculate SPI and save parameters
spi_12, params = spi(precip, scale=12, return_params=True)
# Save parameters for future use
save_fitting_params(
params,
'spi_params.nc',
scale=12,
periodicity='monthly',
index_type='spi'
)
# Later: Load and reuse parameters (much faster!)
params = load_fitting_params('spi_params.nc', scale=12, periodicity='monthly')
spi_12_fast = spi(new_precip, scale=12, fitting_params=params)Customizing Output Metadata
By default, output NetCDF files include minimal metadata (source, CF conventions). You can customize the metadata attributes in two ways:
Modify DEFAULT_METADATA at the start of your script. All subsequent outputs will use these values:
from config import DEFAULT_METADATA
# Set your organization's metadata
DEFAULT_METADATA['institution'] = 'My University, Department of Geography'
DEFAULT_METADATA['source'] = 'precip-index package v2026.1'
DEFAULT_METADATA['references'] = 'McKee et al. (1993)'
DEFAULT_METADATA['comment'] = 'Drought monitoring project'
# All subsequent outputs will include these attributes
spi_12 = spi(precip, scale=12)Pass global_attrs to override metadata for specific outputs:
spi_ds = spi_multi_scale(
precip,
scales=[3, 12],
global_attrs={
'institution': 'ACME Research Lab',
'project': 'Regional Drought Monitor',
}
)
# Also works with save_fitting_params, spi_global, spei_global, etc.
save_fitting_params(
params, 'spi_params.nc',
scale=12, periodicity='monthly', index_type='spi',
global_attrs={'institution': 'My Organization'}
)The default metadata fields are: institution, source, Conventions, references, and comment. You can also add any custom fields via global_attrs (e.g., project, contact, license).
Climate Extremes Event Analysis
Identify and analyze complete extreme events using run theory:
from runtheory import identify_events
from visualization import plot_events
# Identify dry (drought) events (negative threshold)
spi_location = spi_12.isel(lat=50, lon=100)
dry_events = identify_events(spi_location, threshold=-1.2, min_duration=3)
print(f"Found {len(dry_events)} dry events")
print(dry_events[['start_date', 'end_date', 'duration', 'magnitude', 'peak']])
# Visualize events
plot_events(spi_location, dry_events, threshold=-1.2)# Identify wet events (positive threshold) - same function!
wet_events = identify_events(spi_location, threshold=+1.2, min_duration=3)
print(f"Found {len(wet_events)} wet events")
plot_events(spi_location, wet_events, threshold=+1.2)from runtheory import calculate_period_statistics
# Calculate gridded statistics for a time period
stats = calculate_period_statistics(
spi_12,
threshold=-1.2,
start_year=2020,
end_year=2024
)
# Plot number of events per grid cell
stats.num_events.plot(title='Number of Dry/Wet Events 2020-2024')The same functions work for both drought (negative threshold) and wet events (positive threshold). This unified approach makes analysis consistent and straightforward.
Data Requirements
Your input data must be NetCDF with (time, lat, lon) dimensions (any order — auto-transposed). SPI needs precipitation; SPEI also needs temperature or pre-computed PET. A 30-year calibration period (default 1991–2020) is recommended.
See Data Model & Outputs for the complete input contract, output schemas, calibration conventions, and zero/NaN handling details.
Understanding the Output
SPI/SPEI Classification
| Value Range | Category | Percentile band (approx.) | Interpretation |
|---|---|---|---|
| ≤ -2.00 | Exceptionally Dry | 0–2.3% | Exceptional drought |
| -2.00 to -1.50 | Extremely Dry | 2.3–6.7% | Severe drought |
| -1.50 to -1.20 | Severely Dry | 6.7–11.5% | Severe drought |
| -1.20 to -0.70 | Moderately Dry | 11.5–24.2% | Moderate drought |
| -0.70 to -0.50 | Abnormally Dry | 24.2–30.9% | Below normal |
| -0.50 to +0.50 | Near Normal | 30.9–69.1% | Normal conditions |
| +0.50 to +0.70 | Abnormally Moist | 69.1–75.8% | Above normal |
| +0.70 to +1.20 | Moderately Moist | 75.8–88.5% | Moderately wet |
| +1.20 to +1.50 | Very Moist | 88.5–93.3% | Very wet conditions |
| +1.50 to +2.00 | Extremely Moist | 93.3–97.7% | Extremely wet conditions |
| ≥ +2.00 | Exceptionally Moist | 97.7–100% | Extreme flooding risk |
Percentile bands are approximate (standard normal) and provided for intuitive frequency interpretation.
Time Scales
| Scale | Application | Use Case |
|---|---|---|
| 1-month | Meteorological | Short-term precipitation deficits |
| 3-month | Agricultural | Seasonal crop stress |
| 6-month | Agricultural/Hydrological | Medium-term water resources |
| 12-month | Hydrological | Long-term water supply |
| 24-month | Socio-economic | Multi-year water planning |
Common Issues
Solution: Make sure to add the src directory to Python path:
import sys
sys.path.insert(0, 'src')Possible causes:
- Calibration period doesn’t overlap with data
- All zero or negative precipitation values
- Check:
precip.min(),precip.max(), data year range
Solution: This was a bug in earlier versions, now fixed! The code automatically handles any dimension order.
Run the Test Script
Test with the included example data:
python tests/run_all_tests.pyThis will:
- Load TerraClimate Bali data from
input/folder - Calculate SPI-3 and multi-scale SPI
- Calculate SPEI with temperature
- Test run theory functions
- Display statistics and validation
Expected runtime: ~30 seconds
Learn More
📓 Jupyter Notebooks
Interactive tutorials with real data
📖 User Guide
Detailed methodology and usage
🔧 API Reference
Complete function documentation
Next Steps
Now that you know the basics:
- Try the tutorials - Work through interactive examples with real climate data
- Read the methodology - Understand SPI, SPEI, and run theory
- Explore visualizations - Create publication-quality plots
- Use your own data - Apply the package to your research
Support
Need help?
- Check the Tutorials for step-by-step examples
- Review the User Guide for detailed explanations
- See test results for validation examples
- Open an issue on GitHub
See Also
- Installation - Setup and dependencies
- Configuration - Customize settings
- Data Model & Outputs - Input/output contracts
- Examples - Common use cases and code snippets
Ready to dive deeper? Try the SPI Tutorial next!