Reference
Weather Tables
PlantMeteo.Atmosphere — Type
Atmosphere(; kwargs...)One weather timestep in PlantMeteo.
Atmosphere is the row-level object used throughout the package. A weather series is typically a Weather or TimeStepTable made of Atmosphere rows. At minimum, construct it with T, Wind, and Rh; other fields are optional or can be derived from those core variables.
Key fields
date: timestamp of the record. Defaults toDates.now().duration: timestep duration. Defaults toDates.Second(1.0).T: air temperature in degrees Celsius.Wind: wind speed in m s-1.Rh: relative humidity in 0-1 units.P: air pressure in kPa. Defaults toDEFAULTS.P.Precipitations: precipitation over the timestep in mm.Ri_SW_f: incoming short-wave radiation flux in W m-2.
Additional atmospheric variables such as e, VPD, ρ, λ, γ, ε, and Δ can be supplied explicitly or left to their default computations.
Example
using PlantMeteo, Dates
row = Atmosphere(
date = DateTime(2025, 7, 1, 12),
duration = Hour(1),
T = 24.0,
Wind = 1.8,
Rh = 0.58,
P = 101.3,
Ri_SW_f = 620.0
)PlantMeteo.Weather — Function
Weather(data[, metadata])Convenience constructor for a weather table made of Atmosphere rows.
Weather returns a TimeStepTable{Atmosphere} and is the easiest way to say "this table is weather". It accepts either a vector of Atmosphere rows or any table whose columns match the canonical PlantMeteo variable names.
Use Weather when building a small synthetic weather series by hand, converting already-clean tabular data into PlantMeteo's table type, or returning weather from a custom API backend.
Example
using PlantMeteo, Dates
weather = Weather(
[
Atmosphere(date=DateTime(2025, 7, 1, 12), duration=Hour(1), T=24.0, Wind=1.8, Rh=0.58, P=101.3),
Atmosphere(date=DateTime(2025, 7, 1, 13), duration=Hour(1), T=25.0, Wind=2.0, Rh=0.55, P=101.3),
],
(site = "demo",)
)PlantMeteo.TimeStepTable — Type
TimeStepTable(data[, metadata])General timestep-indexed table type used throughout PlantMeteo.
TimeStepTable stores one row per timestep and implements the Tables.jl interface, which makes it usable with downstream tabular tooling while preserving efficient row and column access inside PlantMeteo. Weather is simply TimeStepTable{Atmosphere}.
Use TimeStepTable directly when you want PlantMeteo's table behavior without necessarily framing the data as weather, or when building custom timestep tables backed by your own row type.
Example
using PlantMeteo, Dates
table = TimeStepTable(
[
Atmosphere(date=DateTime(2025, 7, 1, 12), duration=Hour(1), T=24.0, Wind=1.8, Rh=0.58, P=101.3),
Atmosphere(date=DateTime(2025, 7, 1, 13), duration=Hour(1), T=25.0, Wind=2.0, Rh=0.55, P=101.3),
],
(site = "demo",)
)
table[:T]
table[1]
table[1:2, :T]PlantMeteo.Constants — Type
Physical constants
The definition and default values are:
K₀ = -273.15: absolute zero (°C)R = 8.314: universal gas constant ($J\ mol^{-1}\ K^{-1}$).Rd = 287.0586: gas constant of dry air ($J\ kg^{-1}\ K^{-1}$).Dₕ₀ = 21.5e-6: molecular diffusivity for heat at base temperature, applied in the integrated form of the Fick’s Law of diffusion ($m^2\ s^{-1}$). See eq. 3.10 from Monteith and Unsworth (2013).Cₚ = 1013.0: Specific heat of air at constant pressure ($J\ K^{-1}\ kg^{-1}$), also known as efficiency of impaction of particles. See Allen et al. (1998), or Monteith and Unsworth (2013). NB: bigleaf R package uses 1004.834 intead.ε = 0.622: ratio of molecular weights of water vapor and air. See Monteith and Unsworth (2013).λ₀ = 2.501: latent heat of vaporization for water at 0 degree ($J\ kg^{-1}$).σ = 5.670373e-08Stefan-Boltzmann constant in ($W\ m^{-2}\ K^{-4}$).Gbₕ_to_Gbₕ₂ₒ = 1.075: conversion coefficient from conductance to heat to conductance to water vapor.Gsc_to_Gsw = 1.57: conversion coefficient from stomatal conductance to CO₂ to conductance to water vapor.Gbc_to_Gbₕ = 1.32: conversion coefficient from boundary layer conductance to CO₂ to heat.Mₕ₂ₒ = 18.0e-3(kg mol-1): Molar mass for water.J_to_umol = 4.57: Conversion factor from radiation in Joules m-2 s-1 (or W m-2) to μmol m-2 s-1.PAR_fraction = 0.48: Fraction of shortwave radiation that is photosynthetically active radiation (PAR).
References
Allen, Richard G., Luis S. Pereira, Dirk Raes, et Martin J Fao Smith. 1998. « Crop evapotranspiration-Guidelines for computing crop water requirements-FAO Irrigation and drainage paper 56 » 300 (9): D05109.
Monteith, John, et Mike Unsworth. 2013. Principles of environmental physics: plants, animals, and the atmosphere. Academic Press.
PlantMeteo.get_index_raw — Function
Get row from TimeStepTable in its raw format, e.g. as a NamedTuple or Atmosphere of values.
Data Ingestion And Export
PlantMeteo.read_weather — Function
read_weather(file, args...; kwargs...)Read a local weather file and convert it into a Weather table.
Use this when you already have station data, project CSV files, or archived meteorology that needs to be mapped into PlantMeteo's canonical variables. Input files may include a commented YAML header for metadata, and column transformations follow the familiar source => transform => target style.
Transform patterns
:source => :target: rename a column.:source => (x -> f.(x)) => :target: transform and rename a column.:source: keep a column as-is.
Important behavior
- file variables are used as provided unless you transform them
- units must already match PlantMeteo's canonical units
- if
durationis absent, PlantMeteo can infer it fromdate,hour_start, andhour_end - legacy files with sparse date columns can be handled with
forward_fill_date=true
Example
using PlantMeteo, Dates
file = joinpath(dirname(dirname(pathof(PlantMeteo))), "test", "data", "meteo.csv")
weather = read_weather(
file,
:temperature => :T,
:relativeHumidity => (x -> x ./ 100) => :Rh,
:wind => :Wind,
:atmosphereCO2_ppm => :Cₐ,
date_format = DateFormat("yyyy/mm/dd")
)PlantMeteo.write_weather — Function
write_weather(file, weather; vars=setdiff(propertynames(weather), ATMOSPHERE_COMPUTED), duration=Dates.Minute)Write a PlantMeteo weather table to disk.
Use this after standardizing a local file, downloading weather from an API, or preparing a cleaned weather table that should be reused later. By default, variables that can be recomputed from the core atmospheric inputs are omitted from the exported file.
Example
using PlantMeteo, Dates
file = joinpath(dirname(dirname(pathof(PlantMeteo))), "test", "data", "meteo.csv")
weather = read_weather(
file,
:temperature => :T,
:relativeHumidity => (x -> x ./ 100) => :Rh,
:wind => :Wind,
:atmosphereCO2_ppm => :Cₐ,
date_format = DateFormat("yyyy/mm/dd")
)
write_weather("weather_out.csv", weather)PlantMeteo.row_datetime_interval — Function
row_datetime_interval(
row;
index=0,
date_cols=(:date,),
start_cols=(:hour_start, :hour),
end_cols=(:hour_end,),
duration_cols=(:step_duration, :duration),
default_date=Date(2000, 1, 1),
default_duration_seconds=1.0,
allow_end_rollover=false,
)Return (start_dt, end_dt) for one timestep row.
start_dt is built from date_cols + start_cols. end_dt is taken from end_cols, or derived from duration_cols, or from default_duration_seconds when no explicit end is available.
PlantMeteo.check_non_overlapping_timesteps — Function
check_non_overlapping_timesteps(rows; kwargs...)Validate that each timestep starts at or after the previous timestep end. Throws an error on the first overlap.
PlantMeteo.select_overlapping_timesteps — Function
select_overlapping_timesteps(rows, start_dt, end_dt; closed=true, kwargs...)Return rows whose timestep interval overlaps [start_dt, end_dt] (closed=true) or (start_dt, end_dt) (closed=false).
API Retrieval
PlantMeteo.AbstractAPI — Type
AbstractAPIAbstract supertype for weather-download backends used by get_weather.
Implement a subtype of AbstractAPI plus a corresponding get_forecast method when you want to plug a custom weather provider into PlantMeteo without changing the downstream workflow.
PlantMeteo.DemoAPI — Type
DemoAPI()Offline weather backend bundled with PlantMeteo for documentation, tests, and examples.
DemoAPI is not a real weather provider. It returns a deterministic synthetic hourly weather series from latitude, longitude, and date range inputs so examples can be copied into a REPL and run without network access. For real weather downloads, use OpenMeteo(), which remains the default live backend for get_weather.
PlantMeteo.get_weather — Function
get_weather(lat, lon, period; api=OpenMeteo(), sink=TimeStepTable, kwargs...)Download weather for a location and date range through a PlantMeteo API backend.
This is usually the first function to use when you have coordinates and dates but no cleaned weather file yet. The result is a weather table that can then be inspected, aggregated with to_daily, sampled with sample_weather, or written to disk with write_weather.
Arguments
lat: latitude in degrees.lon: longitude in degrees.period: date range asStepRange{Date,Day}orVector{Date}.api: backend implementingget_forecast. Defaults toOpenMeteo().sink: output sink. Defaults toTimeStepTable, but any compatible sink can be used.kwargs...: forwarded to the backend.
Notes
- The documentation site uses
DemoAPI, a built-in offline backend for tests and demos. - Real Open-Meteo calls require network access and should be treated as live external requests.
Example
using PlantMeteo, Dates
period = Date(2025, 7, 1):Day(1):Date(2025, 7, 3)
weather = get_weather(48.8566, 2.3522, period; api=OpenMeteo())PlantMeteo.OpenMeteoUnits — Type
OpenMeteoUnits(...)Unit configuration passed to OpenMeteo.
Use this when you want to control how temperature, wind speed, and precipitation are requested from Open-Meteo before PlantMeteo converts the result into a weather table.
PlantMeteo.OpenMeteo — Type
OpenMeteo(; kwargs...)Built-in PlantMeteo backend for the Open-Meteo API.
Use OpenMeteo() with get_weather when you want the fastest path from coordinates and dates to a usable weather table. PlantMeteo uses Open-Meteo's forecast endpoint for recent/future periods, a historical forecast endpoint for recent past periods, and its ERA5-based archive endpoint for older periods. That makes the same interface practical for both short-term forecasts and retrospective runs.
Why it is useful
- no API-specific glue code in your modeling project
- hourly weather variables behind one backend
- recent forecast data and older historical data through the same interface
Important caveats
- calls require network access
- forecast, historical forecast, and archive data may differ in source and resolution
- usage terms should be checked for your real use case, especially commercial use
Key arguments
vars: Open-Meteo hourly variables to request.start_archive: cutoff deciding when PlantMeteo switches to the archive endpoint.units: unit configuration, seeOpenMeteoUnits.timezone: timezone requested from Open-Meteo.models: forecast models exposed by Open-Meteo.
Example
using PlantMeteo, Dates
api = OpenMeteo(timezone="UTC", models=["best_match"])
period = Date(2025, 7, 1):Day(1):Date(2025, 7, 3)
weather = get_weather(48.8566, 2.3522, period; api=api)PlantMeteo.get_forecast — Function
get_forecast(params::OpenMeteo, lat, lon, period; verbose=true, kwargs...)Live Open-Meteo request used internally by get_weather.
This method returns a TimeStepTable{Atmosphere} built from Open-Meteo responses. Most users should call get_weather rather than invoking get_forecast directly.
Daily Aggregation
PlantMeteo.to_daily — Function
to_daily(weather, args...)Aggregate sub-daily weather to one row per civil day.
Use to_daily when the source weather is hourly or sub-hourly and the model expects a standard daily weather table. The function applies sensible defaults for common variables: it averages state-like variables, sums precipitation, computes Tmin and Tmax, and integrates radiation fluxes over the day.
User-supplied transformations can add new daily variables or override those defaults.
Example
using PlantMeteo, Dates
hourly = Weather([
Atmosphere(date=DateTime(2025, 7, 1, h), duration=Hour(1), T=18.0 + h, Wind=1.0, Rh=0.60, P=101.3)
for h in 0:23
])
daily = to_daily(hourly, :T => mean => :Tmean)Sampling
PlantMeteo.AbstractTimeReducer — Type
AbstractTimeReducerAbstract supertype for reducers used by MeteoTransform.
Reducer implementations are expected to be callable with either:
(vals)(vals, durations)
See MeanWeighted, SumReducer, and RadiationEnergy.
PlantMeteo.MeanWeighted — Type
MeanWeighted()Duration-weighted mean reducer. When durations are not provided, falls back to a plain mean.
PlantMeteo.MeanReducer — Type
MeanReducer()Arithmetic mean reducer.
PlantMeteo.SumReducer — Type
SumReducer()Sum reducer.
PlantMeteo.MinReducer — Type
MinReducer()Minimum reducer.
PlantMeteo.MaxReducer — Type
MaxReducer()Maximum reducer.
PlantMeteo.FirstReducer — Type
FirstReducer()Reducer returning first value in the window.
PlantMeteo.LastReducer — Type
LastReducer()Reducer returning last value in the window.
PlantMeteo.DurationSumReducer — Type
DurationSumReducer()Integrate values over durations (seconds) with no unit conversion. Returns sum(values .* durations).
PlantMeteo.RadiationEnergy — Type
RadiationEnergy()Integrate flux values (W m-2) over durations (seconds) into MJ m-2.
PlantMeteo.AbstractSamplingWindow — Type
AbstractSamplingWindowAbstract supertype for weather window selectors used by sample_weather.
PlantMeteo.RollingWindow — Type
RollingWindow(dt=1.0)Trailing sampling window for sample_weather.
Use RollingWindow when the model needs the aggregation of the last dt source timesteps, such as the previous 24 hourly records at the current simulation step.
PlantMeteo.CalendarWindow — Type
CalendarWindow(period; anchor=:current_period, week_start=1, completeness=:strict)Calendar-based sampling window for sample_weather.
Use CalendarWindow when sampling should follow civil periods such as day, week, or month rather than a fixed trailing number of source timesteps.
period: one of:day,:week, or:monthanchor: sample the:current_periodor the:previous_complete_periodweek_start: first day of week whenperiod == :weekcompleteness: require a full period with:strictor accept incomplete ones with:allow_partial
PlantMeteo.MeteoTransform — Type
MeteoTransform(target; source=target, reducer=MeanWeighted())Variable-wise sampling rule used by sample_weather.
target is the name written to the sampled row, source is the variable read from the source weather, and reducer defines how values over the selected window are combined.
PlantMeteo.PreparedWeather — Type
PreparedWeather(weather; transforms=default_sampling_transforms(), lazy=true)Internal sampler container storing source weather, normalized transforms, and optional caches.
Most users should build this through prepare_weather_sampler and then pass it to sample_weather or materialize_weather.
PlantMeteo.prepare_weather_sampler — Function
prepare_weather_sampler(weather; transforms=default_sampling_transforms(), lazy=true)Prepare a weather series for repeated sampling.
Use this once before repeated calls to sample_weather when a model repeatedly queries rolling or calendar windows from the same fine-step weather table.
PlantMeteo.sample_weather — Function
sample_weather(prepared, step; window=RollingWindow(1.0), transforms=nothing)Sample one aggregated weather row from prepared fine-step weather.
This is the main entry point for model-aligned weather sampling. It selects a window around step, reduces source variables according to the configured transforms, and returns one sampled Atmosphere row.
Use it instead of to_daily when you need rolling windows, calendar windows, or custom reducers per variable.
PlantMeteo.materialize_weather — Function
materialize_weather(prepared; windows, transforms=nothing)Precompute sampled weather tables for one or more sampling windows.
Use this when the same sampled weather tables will be reused many times, for example across long simulation loops, calibration runs, or repeated scenarios.
PlantMeteo.default_sampling_transforms — Function
default_sampling_transforms(; radiation_mode=:both)Default weather sampling rules.
radiation_mode controls how radiation targets are emitted:
:flux_mean: duration-weighted mean flux (same units as source):energy_sum: integrated quantity in MJ m-2 over the sampling window:both: keepRi_*_fas weighted-mean flux and also emitRi_*_qquantities
Arguments
radiation_mode::Symbol: one of:flux_mean,:energy_sum,:both.
Returns
Vector{MeteoTransform} used by PreparedWeather and sample_weather.
PlantMeteo.normalize_sampling_transforms — Function
normalize_sampling_transforms(transforms)Normalize user-provided weather transform definitions into Vector{MeteoTransform}.
Accepted inputs are:
Vector{MeteoTransform}(copied as-is)NamedTuplewhere each key is the target variable and each value is either:- a reducer (
AbstractTimeReducerinstance/type, or callable), or - a named tuple with optional
sourceandreducerfields
- a reducer (
AbstractVectorcontaining onlyMeteoTransformentries
This is the canonical parser used by PreparedWeather and sample_weather to validate and materialize transform rules.
Arguments
transforms: user transform specification (named tuple or vector forms).
Returns
Vector{MeteoTransform}.
Atmosphere Computations
PlantMeteo.atmosphere_emissivity — Function
atmosphere_emissivity(Tₐ,eₐ)Emissivity of the atmoshpere at a given temperature and vapor pressure.
Arguments
Tₐ(°C): air temperatureeₐ(kPa): air vapor pressureK₀(°C): absolute zero
Examples
Tₐ = 20.0
VPD = 1.5
atmosphere_emissivity(Tₐ, vapor_pressure(Tₐ,VPD))References
Leuning, R., F. M. Kelliher, DGG de Pury, et E.-D. SCHULZE. 1995. Leaf nitrogen, photosynthesis, conductance and transpiration: scaling from leaves to canopies ». Plant, Cell & Environment 18 (10): 1183‑1200.
PlantMeteo.vapor_pressure — Function
vapor_pressure(Tₐ, Rh; check=true)Vapor pressure (kPa) at given temperature (°C) and relative hunidity (0-1).
Arguments
Tₐ(Celsius degree): air temperatureRh(0-1): relative humiditycheck(Bool): if true, check thatRhis between 0 and 1
Examples
vapor_pressure(25.0, 0.4)PlantMeteo.e_sat — Function
e_sat(T)Saturated water vapour pressure (es, in kPa) at given temperature T (°C). See Jones (1992) p. 110 for the equation.
PlantMeteo.air_density — Function
air_density(Tₐ, P; check=true)
air_density(Tₐ, P, Rd, K₀; check=true)ρ, the air density (kg m-3).
Arguments
Tₐ(Celsius degree): air temperatureP(kPa): air pressureRd(J kg-1 K-1): gas constant of dry air (see Foken p. 245, or R bigleaf package).K₀(Celsius degree): temperature in Celsius degree at 0 Kelvincheck(Bool): check if P is in the 85-110 kPa earth range
Note
Rd and K₀ are Taken from Constants if not provided.
References
Foken, T, 2008: Micrometeorology. Springer, Berlin, Germany.
PlantMeteo.latent_heat_vaporization — Function
latent_heat_vaporization(Tₐ,λ₀)
latent_heat_vaporization(Tₐ)λ, the latent heat of vaporization for water (J kg-1).
Arguments
Tₐ(°C): air temperatureλ₀: latent heat of vaporization for water at 0 degree Celsius. Taken fromConstants().λ₀
if not provided (see Constants).
PlantMeteo.psychrometer_constant — Function
psychrometer_constant(P, λ, Cₚ, ε; check=true)
psychrometer_constant(P, λ; check=true)γ, the psychrometer constant, also called psychrometric constant (kPa K−1). See Monteith and Unsworth (2013), p. 222.
Arguments
P(kPa): air pressureλ($J\ kg^{-1}$): latent heat of vaporization for water (seelatent_heat_vaporization)Cₚ(J kg-1 K-1): specific heat of air at constant pressure ($J\ K^{-1}\ kg^{-1}$)ε(Celsius degree): temperature in Celsius degree at 0 Kelvincheck(Bool): check if P is in the 85-110 kPa earth range
Note
Cₚ, ε and λ₀ are taken from Constants if not provided.
Tₐ = 20.0
λ = latent_heat_vaporization(Tₐ, λ₀)
psychrometer_constant(100.0, λ)References
Monteith, John L., et Mike H. Unsworth. 2013. « Chapter 13 - Steady-State Heat Balance: (i) Water Surfaces, Soil, and Vegetation ». In Principles of Environmental Physics (Fourth Edition), edited by John L. Monteith et Mike H. Unsworth, 217‑47. Boston: Academic Press.
PlantMeteo.rh_from_vpd — Function
rh_from_vpd(VPD,eₛ)Conversion between VPD and rh.
Examples
eₛ = e_sat(Tₐ)
rh_from_vpd(1.5,eₛ)PlantMeteo.rh_from_e — Function
rh_from_e(VPD,eₛ)Conversion between e (kPa) and rh (0-1).
Examples
rh_from_e(1.5,25.0)PlantMeteo.vpd — Function
vpd(Rh,Tₐ)Compute vapor pressure deficit (kPa) from the air relative humidity (0-1) and temperature (°C).
The computation simply uses vpd = eₛ - e.
Examples
vpd(0.4,25.0)PlantMeteo.vpd_from_e — Function
vpd_from_e(e,Tₐ)Compute vapor pressure deficit (kPa) from the air vapor pressure (kPa) and temperature (°C).
The computation simply uses vpd = eₛ - e.
Examples
vpd_from_e(1.5,25.0)PlantMeteo.duration_seconds — Function
duration_seconds(x; field_name="duration", allow_nan=true)Convert a duration-like value into seconds.
Accepted values are:
- numeric values (already in seconds),
Dates.Period,Dates.Time,Dates.DateTime,- strings formatted as
HH:MM[:SS], - strings parseable as numbers.
When parsing fails, the function returns NaN if allow_nan=true, otherwise it throws.
PlantMeteo.positive_duration_seconds — Function
positive_duration_seconds(x; field_name="duration")Convert a duration-like value to seconds and ensure it is finite and strictly positive.
Index
PlantMeteo.AbstractAPIPlantMeteo.AbstractSamplingWindowPlantMeteo.AbstractTimeReducerPlantMeteo.AtmospherePlantMeteo.CalendarWindowPlantMeteo.ConstantsPlantMeteo.DemoAPIPlantMeteo.DurationSumReducerPlantMeteo.FirstReducerPlantMeteo.LastReducerPlantMeteo.MaxReducerPlantMeteo.MeanReducerPlantMeteo.MeanWeightedPlantMeteo.MeteoTransformPlantMeteo.MinReducerPlantMeteo.OpenMeteoPlantMeteo.OpenMeteoUnitsPlantMeteo.PreparedWeatherPlantMeteo.RadiationEnergyPlantMeteo.RollingWindowPlantMeteo.SumReducerPlantMeteo.TimeStepTablePlantMeteo.WeatherPlantMeteo.air_densityPlantMeteo.atmosphere_emissivityPlantMeteo.check_non_overlapping_timestepsPlantMeteo.default_sampling_transformsPlantMeteo.duration_secondsPlantMeteo.e_satPlantMeteo.get_forecastPlantMeteo.get_index_rawPlantMeteo.get_weatherPlantMeteo.latent_heat_vaporizationPlantMeteo.materialize_weatherPlantMeteo.normalize_sampling_transformsPlantMeteo.positive_duration_secondsPlantMeteo.prepare_weather_samplerPlantMeteo.psychrometer_constantPlantMeteo.read_weatherPlantMeteo.rh_from_ePlantMeteo.rh_from_vpdPlantMeteo.row_datetime_intervalPlantMeteo.sample_weatherPlantMeteo.select_overlapping_timestepsPlantMeteo.to_dailyPlantMeteo.vapor_pressurePlantMeteo.vpdPlantMeteo.vpd_from_ePlantMeteo.write_weather