Skip to content

Analysis

Climate statistics

Available as climate_toolkit.analyze_climate_statistics.

climate_toolkit.climate_statistics.statistics.analyze_climate_statistics

analyze_climate_statistics(
    location_coord,
    start_year,
    end_year,
    source,
    fixed_season=None,
    model=None,
    scenario=None,
    extra_months=6,
    precip_source=None,
    temp_source=None,
    crop_name=None,
    calendar_source=None,
    calendar_system="rf",
    spei_scale_months=None,
    spei_fit="ub-pwm",
    spei_ref_start=None,
    spei_ref_end=None,
    spi_scale_months=None,
    spi_fit="ub-pwm",
    spi_ref_start=None,
    spi_ref_end=None,
    custom_station_file=None,
    custom_station_variables=None,
    custom_station_name=None,
    custom_temp_unit="c",
    custom_precip_unit="mm",
    livestock_type=DEFAULT_LIVESTOCK_TYPE,
    livestock_climate_profile=DEFAULT_LIVESTOCK_CLIMATE_PROFILE,
    livestock_elevation_override_m=None,
    include_period_raw_summary=True,
    include_season_raw_summary=True,
    include_season_overall_statistics=True,
    include_ltm_season_summary=True,
    ee_project_id=None,
    workers=1,
    verbose=False,
)

Run the full seasonal climate-statistics pipeline for one location.

Single entrypoint that fetches daily climate data for a point, derives reference evapotranspiration (ET0, Hargreaves) and a daily water balance, detects growing seasons (automatically from rainfall, or from a fixed/crop-calendar window), and reduces everything to per-season, per-period, and long-term-mean (LTM) statistics, optionally adding monthly SPEI/SPI drought indices.

Pipeline steps 1. Validate source/period/calendar options; resolve the livestock THI profile and human-heat (humidex) source bundle. 2. Fetch all daily climate variables for start_year-01-01 through end_year-12-31 plus a tail (up to extra_months in auto mode, or a full extra year for year-crossing fixed seasons) so late/cross-year seasons are captured. 3. Add ET0 (Hargreaves) and daily water balance columns. 4. Detect seasons: automatic onset/cessation detection from rainfall, or fixed windows from fixed_season / crop_name + calendar_source (GGCMI crop-calendar preset). If auto detection is unreliable and a calendar preset was requested, the preset is applied as a fallback. 5. Compute per-season statistics (rainfall, temperature, dry spells, water balance, livestock THI, humidex, ET0 sub-seasons), period-wide summaries, LTM season summaries, and optional SPEI/SPI monthly series.

Progress and warnings are printed to stdout as the pipeline runs. Recoverable input/validation problems are returned as {"error": "..."} rather than raised.

Parameters:

Name Type Description Default
location_coord tuple of float

(lat, lon) in decimal degrees (WGS84), e.g. (-1.286, 36.817) for Nairobi.

required
start_year int

First calendar year of the analysis period (inclusive).

required
end_year int

Last calendar year of the analysis period (inclusive). A baseline of at least 20 years is recommended for LTM output; a shorter span triggers coverage_warning.

required
source str

Daily climate data source. Common choices:

  • 'agera_5' : AgERA5 (recommended single-source historical).
  • 'era_5' : ERA5.
  • 'nasa_power' : NASA POWER (no credentials required).
  • 'nex_gddp' : NEX-GDDP-CMIP6 projections; use with model and scenario.
  • 'chirps_v2', 'chirps_v3_daily_rnl' : CHIRPS precipitation (precipitation-only; temperature is filled or must come from a paired source).
  • 'chirps_v2+chirts' : merged CHIRPS precip + CHIRTS temp.
  • 'auto' : tries chirps_v3_daily_rnl + agera_5, then agera_5, then era_5, then chirps_v2+chirts.
  • 'paired' : combine explicit precip_source + temp_source.

Earth Engine-backed sources (agera_5, era_5, chirps_v2, chirps_v3_daily_rnl, nex_gddp, ...) require prior earthengine authenticate and a GCP_PROJECT_ID environment variable (or ee_project_id); nasa_power needs no credentials.

required
fixed_season str

Fixed season window(s) as "MM-DD:MM-DD" (onset:cessation), e.g. "03-01:08-31". Up to two comma-separated windows are allowed (e.g. "03-01:05-31,10-01:12-31"). A cessation earlier than the onset means the season crosses the year boundary. Default None (automatic season detection).

None
model str

Climate model name for source='nex_gddp' (e.g. 'ACCESS-ESM1-5'). Default None.

None
scenario str

Scenario for source='nex_gddp': 'historical' or an SSP such as 'ssp245'/'ssp585'. Default None.

None
extra_months int

In automatic season-detection mode, how many months of tail data past end_year-12-31 to fetch so seasons that end after the final year are captured. Set 0 to disable the tail.

6
precip_source str

Precipitation source for paired mode (e.g. 'chirps_v3_daily_rnl', 'chirps_v2', 'imerg', 'tamsat'). Must be provided together with temp_source.

None
temp_source str

Temperature source for paired mode (e.g. 'agera_5', 'era_5'). Must be provided together with precip_source.

None
crop_name str

Crop name used to look up a crop-calendar season preset (e.g. 'maize'). Requires calendar_source. Default None.

None
calendar_source str

Crop-calendar dataset used with crop_name. Only 'ggcmi' is supported. When given without fixed_season, the preset window is applied directly; it is also used as a fallback when auto detection is unreliable. Default None.

None
calendar_system str

GGCMI calendar system: 'rf' (rainfed), 'ir' (irrigated), or 'both'.

'rf'
spei_scale_months int

Accumulation scale in months for monthly SPEI (e.g. 3 for SPEI-3). Default None (SPEI is not computed).

None
spei_fit str

SPEI distribution-fitting method. 'ub-pwm' fits the log-logistic distribution per calendar month using unbiased probability-weighted moments (canonical SPEI practice); 'empirical' uses an empirical-quantile fallback.

'ub-pwm'
spei_ref_start str

Reference (calibration) period bounds for SPEI fitting, e.g. '1991-01-01' / '2020-12-31'. Default None (fit on the full analysis period).

None
spei_ref_end str

Reference (calibration) period bounds for SPEI fitting, e.g. '1991-01-01' / '2020-12-31'. Default None (fit on the full analysis period).

None
spi_scale_months int

Accumulation scale in months for monthly SPI. Default None (SPI is not computed).

None
spi_fit str

SPI fitting method: 'ub-pwm' or 'empirical' (see spei_fit).

'ub-pwm'
spi_ref_start str

Reference period bounds for SPI fitting. Default None.

None
spi_ref_end str

Reference period bounds for SPI fitting. Default None.

None
custom_station_file str

Path to a station CSV/JSON whose observations override the gridded values on matching dates (gridded data fills gaps). Default None.

None
custom_station_variables list of str

Variables to take from the station file, e.g. ['precipitation', 'max_temperature', 'min_temperature']. Default None (all supported variables present in the file).

None
custom_station_name str

Label for the custom station in logs/metadata. Default None.

None
custom_temp_unit str

Temperature unit in the station file: 'c', 'f', or 'k'.

'c'
custom_precip_unit str

Precipitation unit in the station file: 'mm', 'inch', or 'tenth_mm'.

'mm'
livestock_type str

Livestock profile for temperature-humidity-index (THI) heat stress statistics. One of 'cattle_dairy', 'cattle_general', 'cattle_beef', 'goats', 'sheep', 'pigs', 'poultry_broilers', 'poultry_layers', 'poultry_general'.

'cattle_dairy'
livestock_climate_profile str

THI threshold climate adjustment: 'auto' (inferred from latitude/elevation), 'temperate', or 'tropical'.

'auto'
livestock_elevation_override_m float

Site elevation in metres used when inferring the livestock climate profile; overrides automatic elevation lookup. Default None.

None
include_period_raw_summary bool

Include the period-wide raw climate summary ('raw_climate_summary' key) in the result.

True
include_season_raw_summary bool

Include a raw climate summary inside each season entry.

True
include_season_overall_statistics bool

Include full overall statistics inside each season entry.

True
include_ltm_season_summary bool

Include the long-term-mean summary across years per season window ('ltm_season_summary' key).

True
ee_project_id str

Google Cloud project ID for Earth Engine, overriding the GCP_PROJECT_ID environment variable. Default None.

None
workers int

Number of parallel workers for data fetching.

1
verbose bool

Print extra diagnostic detail during fetching and season detection.

False

Returns:

Type Description
dict

On validation or fetch failure, {'error': '<message>'}. Otherwise a dictionary with these top-level keys:

  • 'location' : dict with 'lat' and 'lon'.
  • 'period' : dict with 'start_year' and 'end_year'.
  • 'source', 'model', 'scenario', 'precip_source', 'temp_source' : echo of the data request (source names normalized).
  • 'mode' : 'auto' or 'fixed' season detection as actually applied.
  • 'fixed_season' : the applied fixed-season string, or None in auto mode.
  • 'human_heat_bundle' : provenance of variables feeding the humidex (human heat) metrics.
  • 'thi_profile' : resolved livestock THI profile and thresholds.
  • 'crop_name', 'calendar_source', 'calendar_system', 'calendar_preset_requested', 'calendar_preset_used', 'calendar_preset_fallback', 'calendar_preset' : crop-calendar request and what was actually applied.
  • 'raw_climate_summary' : list of per-variable summary rows for the whole period (empty if disabled).
  • 'overall_statistics' : dict of period-wide statistics (temperature, rainfall, water balance, THI, humidex, ...).
  • 'xclim_references' : xclim-based reference indicators for the period.
  • 'season_statistics' : list of dicts, one per detected season per year, each with 'year', 'season_number', 'onset', 'cessation', 'regime', 'season_identity', rainfall/dry-spell metrics, and (when enabled) nested 'raw_climate_summary', 'overall_statistics', and 'eto_sub_seasons'.
  • 'ltm_season_summary' : long-term means across years per season window (dict with 'mode' and 'windows').
  • 'spei', 'spi' : None, or dicts with 'config', 'summary', 'metadata', and 'monthly_series' (list of monthly records including the index values).
  • 'season_slot_warning', 'coverage_warning' : warning strings or None.
  • 'annual_summary' : per-year detection summary rows.
  • 'season_detection_status', 'season_detection_reasons', 'human_review_recommended', 'calendar_override_recommended', 'season_detection_guidance', 'season_detection' : season-detection reliability diagnostics.
  • 'timing' : dict of elapsed seconds per pipeline stage.
  • 'analysis_date' : ISO timestamp of the run.
  • 'methodology' : short methodology note.

Examples:

Seasonal climatology for maize in Nairobi, Kenya from AgERA5 (requires earthengine authenticate and GCP_PROJECT_ID; use source='nasa_power' for a credential-free run):

>>> import climate_toolkit as ct
>>> result = ct.analyze_climate_statistics(
...     location_coord=(-1.286, 36.817),
...     start_year=2000,
...     end_year=2020,
...     source="agera_5",
...     crop_name="maize",
...     calendar_source="ggcmi",
...     spei_scale_months=3,
... )
>>> sorted(result["ltm_season_summary"].keys())
['mode', 'windows']
>>> result["season_statistics"][0]["year"]
2000

Hazards

Available as climate_toolkit.evaluate_hazards.

climate_toolkit.calculate_hazards.hazards.calculate_hazards

calculate_hazards(
    crop_name,
    location_coord,
    date_from,
    date_to,
    season_start=None,
    season_end=None,
    fixed_season=None,
    source="auto",
    precip_source=None,
    temp_source=None,
    custom_thresholds=None,
    gap_days=30,
    min_season_days=30,
    soilcp=DEFAULT_SOILCP,
    soilsat=DEFAULT_SOILSAT,
    spinup_days=DEFAULT_SPINUP_DAYS,
    water_balance_window=FULL_WINDOW_WATER_BALANCE,
    calendar_source=None,
    calendar_system="rf",
    livestock_type=DEFAULT_LIVESTOCK_TYPE,
    livestock_climate_profile=DEFAULT_LIVESTOCK_CLIMATE_PROFILE,
    livestock_elevation_override_m=None,
    ee_project_id=None,
    workers=1,
)

Assess growing-season climate hazards for a crop at a point location.

Fetches daily climate data (precipitation, temperature, humidity) for one or more growing seasons, runs a daily soil water-balance model, and scores each season against crop-specific hazard thresholds. Hazards assessed:

  • Seasonal precipitation total versus crop rainfall requirements
  • Mean season temperature versus crop temperature tolerance
  • Extreme heat: NTx35 / NTx40 (days with Tmax above 35 / 40 deg C)
  • Drought: NDD (dry days, < 1 mm), dry-spell statistics (>= 7 consecutive dry days), NDWS (water-stress days from the soil water-balance model), and WRSI (water requirement satisfaction index)
  • Waterlogging: NDWL0 (days with soil water above field capacity)
  • Livestock heat stress: THI (temperature-humidity index) for the chosen livestock type and climate profile
  • Human heat stress: Humidex screening (mean/max, high and extreme days)

The growing-season window is resolved in one of three ways:

  1. Explicit window -- pass season_start and season_end together.
  2. Fixed calendar window(s) -- pass fixed_season (e.g. '03-01:06-30'), applied to every year between date_from and date_to.
  3. Auto-detection (default) -- rainfall-based onset/cessation detection per year; if detection is unreliable and calendar_source='ggcmi' was given, falls back to the GGCMI crop-calendar preset window.

This function is exported as climate_toolkit.evaluate_hazards.

Parameters:

Name Type Description Default
crop_name str

Crop to assess (case-insensitive). Crops with built-in hazard thresholds: 'beans', 'maize', 'millet', 'groundnuts', 'sorghum', 'cassava', 'rice'. Other crops require custom_thresholds.

required
location_coord tuple of float

(latitude, longitude) in decimal degrees, e.g. (-1.286, 36.817) for Nairobi.

required
date_from str

Analysis window as ISO dates 'YYYY-MM-DD'. In fixed-season and auto-detect modes, every calendar year in this range is analysed.

required
date_to str

Analysis window as ISO dates 'YYYY-MM-DD'. In fixed-season and auto-detect modes, every calendar year in this range is analysed.

required
season_start str

Explicit season window (ISO dates 'YYYY-MM-DD'). Must be supplied together; takes precedence over fixed_season and auto-detection. Default None.

None
season_end str

Explicit season window (ISO dates 'YYYY-MM-DD'). Must be supplied together; takes precedence over fixed_season and auto-detection. Default None.

None
fixed_season str

Fixed calendar window(s) as 'MM-DD:MM-DD', comma-separated for two seasons per year (e.g. '03-01:05-31,10-01:12-15'). Year-crossing windows such as '11-01:02-28' are supported. Default None.

None
source str

Climate dataset: 'auto', 'agera_5', 'era_5', 'chirps_v2+chirts' (alias 'chirps+chirts'), 'nasa_power', or 'paired'. 'auto' tries chirps_v3_daily_rnl + agera_5, then agera_5, then era_5, then chirps_v2+chirts. Precipitation-only sources ('chirps_v3_daily_rnl', 'imerg', 'tamsat') are rejected here -- use them through source='paired'. 'chirps_v2+chirts' only covers years up to 2016.

'auto'
precip_source str

Required together when source='paired': explicit precipitation and temperature datasets, e.g. precip_source='chirps_v3_daily_rnl' with temp_source='agera_5'. Default None.

None
temp_source str

Required together when source='paired': explicit precipitation and temperature datasets, e.g. precip_source='chirps_v3_daily_rnl' with temp_source='agera_5'. Default None.

None
custom_thresholds dict

Per-metric threshold overrides merged over the built-in crop and hazard-index thresholds. Shape {metric: {band: (low, high)}}, where metric is one of 'Total Precip', 'TAVG', 'NDD', 'NTx35', 'NTx40', 'NDWS', 'NDWL0', 'THI', 'HUMIDEX'. Band names are e.g. 'no_stress', 'moderate_stress', 'severe_stress', 'extreme_stress' (crop 'Total Precip' / 'TAVG' use 'moderate_stress_low' / 'moderate_stress_up' / 'severe_stress_low' / 'severe_stress_up'); None in a (low, high) tuple means open-ended. Metrics omitted keep package defaults. Supplying this also allows assessing crops without built-in thresholds. Default None.

None
gap_days int

Intended dry-gap (days) that ends an auto-detected season. Currently accepted for CLI parity but not forwarded to the season detector, which uses its own default.

30
min_season_days int

Intended minimum auto-detected season length (days). Same caveat as gap_days.

30
soilcp float

Plant-available soil water capacity (mm) between wilting point and field capacity, used by the water-balance model (NDWS/NDWL0/WRSI). When both soilcp and soilsat are left at their defaults, site-specific values are derived from gridded soil data (SoilGrids/HWSD) where available; pass explicit values to override.

100.0
soilsat float

Additional soil water storage (mm) between field capacity and saturation; governs waterlogging (NDWL0). See soilcp for the automatic site-specific derivation.

100.0
spinup_days int

Days of climate data fetched before season onset so the soil water balance starts from a realistic moisture state.

60
water_balance_window (full_window, crop_active)

How NDWS/NDWL0 are counted within fixed-season runs: 'full_window' uses the whole fixed window; 'crop_active' restricts counting to detected ETO sub-season(s) inside the window when available.

'full_window'
calendar_source ggcmi

Crop-calendar preset source used as a fallback when auto season detection is unreliable. Default None (no fallback).

'ggcmi'
calendar_system (rf, ir, both)

GGCMI crop-calendar system when calendar_source is used: rainfed ('rf'), irrigated ('ir'), or both.

'rf'
livestock_type str

Livestock THI profile, e.g. 'cattle_dairy', 'cattle_general', 'cattle_beef', 'goats', 'sheep'. See climate_toolkit.climatology.heat_stress.list_thi_livestock_profiles for the full list.

'cattle_dairy'
livestock_climate_profile (auto, temperate, tropical)

THI climate context. 'auto' selects from latitude plus highland elevation when available.

'auto'
livestock_elevation_override_m float

Site elevation (metres above sea level) used by the 'auto' THI climate-context selection instead of an automatic elevation lookup. Default None.

None
ee_project_id str

Google Cloud project ID for Earth Engine-backed climate sources. Overrides the GCP_PROJECT_ID environment variable. Default None.

None
workers int

Bounded worker count for chunked historical Earth Engine fetches.

1

Returns:

Type Description
dict

On failure: {'error': <message>}, optionally with 'available_crops' (unknown crop) or 'season_detection' (season-detection diagnostics).

When exactly one season is resolved, a flat assessment dict with keys 'crop', 'location' ({'latitude', 'longitude'}), 'season_info' (onset/cessation dates, length, detection method, data source), 'thi_profile', 'soil_parameters', 'water_balance_parameters', 'water_balance_methodology', 'season_statistics' (precipitation and temperature summaries, dry-spell statistics, NDD, NTx35, NTx40, NDWS, NDWL0, WRSI, Humidex and THI metrics), 'hazard_evaluation' (per-hazard value and status such as 'no_stress' / 'moderate_stress' / 'severe_stress'), plus 'season_detection', 'calendar_source', 'calendar_system', 'calendar_preset_requested', 'calendar_preset_used', and 'calendar_preset'.

When multiple seasons are resolved (multi-year range and/or two seasons per year), a wrapper dict with 'assessments' (list of per-season dicts shaped as above), 'thi_profile', 'soil_parameters', 'water_balance_parameters', 'water_balance_methodology', 'season_detection', the calendar keys above, 'baseline_ltm' (long-term mean baseline across seasons, or None), and 'baseline_ltm_comparisons' (per-year deltas versus that baseline). A 'warning' key is included when the baseline is suppressed (e.g. inconsistent auto-detected season counts across years).

Notes

Earth Engine-backed sources ('agera_5', 'era_5', 'chirps_v2+chirts', 'chirps_v3_daily_rnl', and the default 'auto' chain) require a one-time earthengine authenticate and a Google Cloud project ID, supplied via the GCP_PROJECT_ID environment variable or the ee_project_id argument. The 'nasa_power' source needs no credentials.

Progress messages are printed to stdout during data fetching. Use climate_toolkit.calculate_hazards.hazards.print_hazard_results to pretty-print the returned dict.

Examples:

Maize near Nairobi for the 2020 long-rains season, explicit window:

>>> import climate_toolkit as ct
>>> result = ct.evaluate_hazards(
...     crop_name='maize',
...     location_coord=(-1.286, 36.817),
...     date_from='2020-01-01',
...     date_to='2020-12-31',
...     season_start='2020-03-01',
...     season_end='2020-06-30',
...     source='agera_5',
... )
>>> result['hazard_evaluation']['NTx35']['status']
'no_stress'

Period comparison

Available as climate_toolkit.compare_climate_periods.

climate_toolkit.compare_periods.periods.compare

compare(
    location,
    baseline_start,
    baseline_end,
    focal_year,
    source,
    fixed_season=None,
    precip_source=None,
    temp_source=None,
    crop_name=None,
    livestock_type=DEFAULT_LIVESTOCK_TYPE,
    livestock_climate_profile=DEFAULT_LIVESTOCK_CLIMATE_PROFILE,
    livestock_elevation_override_m=None,
    calendar_source=None,
    calendar_system="rf",
    spei_scale_months=None,
    spei_fit="ub-pwm",
    spei_ref_start=None,
    spei_ref_end=None,
    spi_scale_months=None,
    spi_fit="ub-pwm",
    spi_ref_start=None,
    spi_ref_end=None,
    workers=1,
)

Compare a focal year's climate against a multi-year baseline climatology.

Runs the full climate-statistics workflow twice for a single point location -- once for the baseline period (baseline_start to baseline_end) and once for the focal year -- then differences the four main report sections between the two runs:

  1. raw_climate_summary : per-variable daily statistics (Mean/Min/Max/Std for rainfall, temperature, etc.).
  2. overall_statistics : period totals and derived metrics, with baseline values annualised (divided by the number of baseline years) so they are comparable to a single year.
  3. season_statistics : growing-season metrics, aggregated across baseline seasons (per fixed-season window when fixed_season is given, otherwise across auto-detected seasons).
  4. annual_summary : annual rainfall and humid-year status (focal year vs the baseline average / humid-year frequency).

Each diffed metric reports the focal value, the baseline value (or baseline average), the absolute difference diff and, where meaningful, the percent change pct. Supplementary comparison blocks for xclim reference indices and (when requested) SPEI/SPI are also included.

Most sources are fetched via Google Earth Engine and require prior Earth Engine authentication plus a Google Cloud project id in the GCP_PROJECT_ID environment variable (GOOGLE_CLOUD_PROJECT or EE_PROJECT_ID also work). The nasa_power source needs no authentication.

Parameters:

Name Type Description Default
location tuple of float

(latitude, longitude) in decimal degrees, e.g. (-1.286, 36.817) for Nairobi.

required
baseline_start int

First year of the baseline period (inclusive).

required
baseline_end int

Last year of the baseline period (inclusive). Must be greater than or equal to baseline_start.

required
focal_year int

Single year to compare against the baseline climatology.

required
source str

Climate data source. One of 'agera_5', 'era_5', 'nasa_power', 'chirps', 'chirps_v2', 'chirps_v3_daily_rnl', 'chirts', 'chirps+chirts', 'chirps_v2+chirts', 'terraclimate', 'imerg', 'tamsat', 'auto', or 'paired'. Precipitation-only sources (chirps variants, imerg, tamsat) skip temperature-based metrics. 'paired' combines separate precipitation and temperature sources and requires precip_source and temp_source.

required
fixed_season str

Season window(s) as 'MM-DD:MM-DD', comma-separated for multiple windows, e.g. '03-01:05-31' (single), '03-01:05-31,10-01:12-15' (two seasons), or '11-01:02-28' (year-crossing). Default None (automatic rainfall-based season detection).

None
precip_source str

Precipitation source when source='paired', e.g. 'chirps_v2', 'chirps_v3_daily_rnl', 'imerg', or 'tamsat'. Default None.

None
temp_source str

Temperature source when source='paired', e.g. 'agera_5', 'era_5', or 'nasa_power'. Default None.

None
crop_name str

Crop name used when requesting external crop-calendar presets (e.g. GGCMI) via calendar_source, e.g. 'maize'. Default None.

None
livestock_type str

Livestock THI (temperature-humidity index) heat-stress profile, e.g. 'cattle_dairy' (default), 'cattle_beef', 'cattle_general'. See :func:climate_toolkit.climatology.heat_stress.list_thi_livestock_profiles for the full list.

DEFAULT_LIVESTOCK_TYPE
livestock_climate_profile str

THI climate context: 'auto' (default; uses latitude plus highland elevation when available), 'temperate', or 'tropical'.

DEFAULT_LIVESTOCK_CLIMATE_PROFILE
livestock_elevation_override_m float

Site elevation in metres above sea level, overriding the automatically fetched elevation used for THI climate-context selection. Default None.

None
calendar_source str

Crop-calendar preset source to use when automatic season detection is not reliable. Currently only 'ggcmi'. Default None.

None
calendar_system str

Crop-calendar system when calendar_source is used: 'rf' (rainfed, default), 'ir' (irrigated), or 'both'.

'rf'
spei_scale_months int

SPEI accumulation scale in months (e.g. 3, 6, 12). When given, SPEI is computed and compared alongside the other statistics. Default None (SPEI skipped).

None
spei_fit str

SPEI distribution-fitting method: 'ub-pwm' (unbiased probability-weighted moments, default) or 'empirical'. Ignored unless spei_scale_months is set.

'ub-pwm'
spei_ref_start str

SPEI reference-period start date as 'YYYY-MM-DD', e.g. '1991-01-01'. Default None.

None
spei_ref_end str

SPEI reference-period end date as 'YYYY-MM-DD', e.g. '2020-12-31'. Default None.

None
spi_scale_months int

SPI accumulation scale in months. When given, SPI is computed and compared alongside the other statistics. Default None (SPI skipped).

None
spi_fit str

SPI distribution-fitting method: 'ub-pwm' (default) or 'empirical'. Ignored unless spi_scale_months is set.

'ub-pwm'
spi_ref_start str

SPI reference-period start date as 'YYYY-MM-DD'. Default None.

None
spi_ref_end str

SPI reference-period end date as 'YYYY-MM-DD'. Default None.

None
workers int

Number of parallel workers for chunked Earth Engine data fetches. Default 1.

1

Returns:

Type Description
dict

On success, a dictionary with:

  • Run metadata echoing the request: 'focal_year', 'baseline_period' ('YYYY-YYYY' string), 'baseline_years', 'source', 'fixed_season', 'precip_source', 'temp_source', 'crop_name', livestock settings ('livestock_type', 'livestock_label', 'livestock_climate_profile', 'livestock_climate_profile_applied'), calendar settings ('calendar_source', 'calendar_system' and preset-usage flags), SPEI/SPI settings, and 'temperature_excluded' (True for precipitation-only sources).
  • 'season_detection' : diagnostics on season detection for both periods.
  • 'raw_climate_summary' : {variable: {stat: {'focal', 'baseline', 'diff', 'pct'}}}.
  • 'overall_statistics' : {category: {metric: {'focal_year', 'baseline_avg', 'diff', 'pct'}}} with annualised baseline values.
  • 'season_statistics' : seasonal comparison; with fixed_season a {'windows': [...]} list with one entry per window, otherwise a single block with season counts, water-balance methodology notes, and a metric 'diff' block.
  • 'annual_summary' : 'annual_rain_mm' (focal vs baseline average) and 'humid_status' (humid-year classification).
  • 'xclim_references' : comparison of xclim reference indices.
  • 'spei', 'spi' : drought-index comparisons (None-like when the corresponding scale was not requested).

On failure, a dictionary with an 'error' key describing the problem (invalid arguments, fetch failure, or unreliable season detection), possibly alongside 'season_detection' diagnostics. Check for 'error' before using the result.

Examples:

Compare 2023 against a 1991-2020 baseline for Nairobi, Kenya, using AgERA-5 with a GGCMI maize calendar (requires Earth Engine authentication and GCP_PROJECT_ID set):

>>> import climate_toolkit as ct
>>> result = ct.compare_climate_periods(
...     location=(-1.286, 36.817),
...     baseline_start=1991,
...     baseline_end=2020,
...     focal_year=2023,
...     source="agera_5",
...     crop_name="maize",
...     calendar_source="ggcmi",
... )
>>> if "error" not in result:
...     rain = result["annual_summary"]["annual_rain_mm"]
...     print(rain["focal"], rain["baseline_avg"], rain["pct"])