Skip to content

Semantic variable loaders

In plain English:
Semantic loaders give you common variables (temperature, precipitation, NDVI) without memorizing provider field names. They now return VirtualCubes automatically for large AOIs or long time ranges so you can request decades of data safely.

What this page helps you do:
- Pick the right semantic loader for climate or NDVI - See how loaders behave when streaming activates - Debug tile settings when you want to peek under the hood

Simple semantic requests

import cubedynamics as cd
from cubedynamics import pipe, verbs as v

ndvi = cd.ndvi(lat=40.0, lon=-105.25, start="1985", end="2024")
pipe(ndvi) | v.mean(dim=("y", "x"))

The code above streams automatically if the span is large. You do not need to change the verb chain.

Working With Large Datasets (New in 2025)

CubeDynamics can now work with extremely large climate or NDVI datasets — even decades of data or very large spatial areas — without loading everything into memory at once.

It does this using a new system called VirtualCube, which streams data in small 'tiles'. You can think of these tiles as puzzle pieces. CubeDynamics processes each piece, keeps track of running statistics, and never holds the whole puzzle in memory.

Loader tips for streaming

  • Add streaming_strategy="virtual" to force streaming.
  • Use time_tile="5y" or similar if you want to control time slices.
  • Large bounding boxes may trigger spatial tiles; call .debug_tiles() to see the layout.

Example: NDVI z-scores at scale

ndvi_z = cd.ndvi_zscore(
    bbox=[-125, 24, -66.5, 49],
    start="1984",
    end="2024",
)

# Streamed anomaly over space
anomaly_ts = pipe(ndvi_z) | v.anomaly(dim="time") | v.mean(dim=("y", "x"))

Debugging semantic loaders

  • print(loader_output) shows whether you received a VirtualCube.
  • .debug_tiles() prints time and spatial slices used for streaming.
  • .materialize() turns the virtual object into an in-memory cube; use only for small AOIs.

Legacy Technical Reference (kept for context)

Semantic variable loaders

In plain English:
These helpers give you common climate variables like temperature or NDVI without remembering provider-specific codes. You ask for "temperature" and CubeDynamics calls the right loader under the hood.

You will learn:
- How to request temperature cubes with one function call - How to grab anomalies and z-scores without custom code - How to fall back to raw loaders when you need full control

What this is

Semantic loaders are small wrappers around the PRISM, gridMET, and Sentinel-2 helpers. They turn friendly names such as temperature or ndvi into the correct provider variables and return standard (time, y, x) cubes.

Why it matters

Remembering that gridMET uses pr while PRISM uses ppt is error-prone. Semantic helpers smooth that friction so new researchers can focus on questions instead of variable catalogs. They also encourage consistent naming when you share notebooks with students or community partners.

How to use it

import cubedynamics as cd
from cubedynamics import pipe, verbs as v

# Daily mean temperature (gridMET by default)
temp = cd.temperature(
    lat=40.0,
    lon=-105.25,
    start="2000-01-01",
    end="2020-12-31",
)

# Minimum and maximum temperature with explicit sources
tmin = cd.temperature_min(
    lat=40.0, lon=-105.25,
    start="2000-01-01", end="2020-12-31",
    source="gridmet",
)

tmax = cd.temperature_max(
    lat=40.0, lon=-105.25,
    start="2000-01-01", end="2020-12-31",
    source="prism",
)

# An anomaly cube using the same API
tanom = cd.temperature_anomaly(
    lat=40.0,
    lon=-105.25,
    start="2000-01-01",
    end="2020-12-31",
    source="gridmet",
    kind="mean",
)

pipe(tanom) | v.show_cube_lexcube(title="GridMET temperature anomaly")

These calls delegate to the provider-specific loaders, so you keep the convenience without losing accuracy.

A second example shows NDVI:

ndvi = cd.ndvi(
    lat=40.0,
    lon=-105.25,
    start="2018-01-01",
    end="2020-12-31",
    source="sentinel2",
)

ndvi_z = pipe(ndvi) | v.zscore(dim="time")

cd.ndvi now returns raw NDVI; standardize explicitly with v.zscore. The as_zscore flag is deprecated and will be removed in a future release.


Original Reference (kept for context)

Semantic variable loaders

CubeDynamics now provides a thin "semantic" layer on top of the sensor-specific loaders so you can work with common variables like temperature and NDVI with a single function call.

Temperature cubes

Use cd.temperature, cd.temperature_min, and cd.temperature_max to request mean, minimum, or maximum daily temperature from PRISM or gridMET without memorizing provider-specific variable names:

import cubedynamics as cd
from cubedynamics import pipe, verbs as v

temp = cd.temperature(
    lat=40.0,
    lon=-105.25,
    start="2000-01-01",
    end="2020-12-31",
    # default: gridMET
)

tmin = cd.temperature_min(
    lat=40.0, lon=-105.25,
    start="2000-01-01", end="2020-12-31",
    source="gridmet",
)

tmax = cd.temperature_max(
    lat=40.0, lon=-105.25,
    start="2000-01-01", end="2020-12-31",
    source="prism",
)

Behind the scenes, these helpers delegate to cd.load_prism_cube and cd.load_gridmet_cube with the appropriate variable names.

Temperature anomalies

cd.temperature_anomaly wraps the temperature loaders and the v.anomaly verb to compute anomalies along the time axis:

tanom = cd.temperature_anomaly(
    lat=40.0,
    lon=-105.25,
    start="2000-01-01",
    end="2020-12-31",
    source="gridmet",
    kind="mean",
)

pipe(tanom) | v.show_cube_lexcube(title="GridMET temperature anomaly")

NDVI cubes

For greenness dynamics, use cd.ndvi:

ndvi_z = cd.ndvi(
    lat=40.0,
    lon=-105.25,
    start="2018-01-01",
    end="2020-12-31",
    source="sentinel2",
    as_zscore=True,
)

When as_zscore=True, this calls cd.load_sentinel2_ndvi_zscore_cube and returns an NDVI z-score cube. When as_zscore=False, it computes raw NDVI from Sentinel-2 bands using v.ndvi_from_s2.

As always, you can fall back to the sensor-specific loaders when you need full control over band selection, cloud filtering, or temporal aggregation.