Skip to content

Items & collections

UmbraItem is the normalized view of one STAC item — its geometry, datetime, polarizations, product types, and downloadable assets. ItemCollection is the iterable of items a search returns.

UmbraItem dataclass

UmbraItem(id, properties=dict(), assets=dict(), geometry=None, bbox=None, href=None, raw=dict(), place=None, datetime_suspect=False, published=None)

A single Umbra SAR acquisition, parsed from a STAC item.

created property

created

When Umbra generated this STAC item (properties.created).

That is the sidecar's generation time, not tasking delivery and not when the object appeared in the public bucket (:attr:published). Legacy _METADATA.json collects do not carry created.

resolution property

resolution

(range, azimuth) resolution in metres.

description property

description

Free-text description of the acquisition, when the STAC item has one.

Checks the item's top-level description (STAC convention) and properties.description, then falls back to the description on the primary image asset (GEC) so popups can surface whatever human-readable blurb the catalog provides.

task property

task

The Umbra task (AOI campaign) this acquisition belongs to.

Umbra files every pass of a site under one sar-data/tasks/<task>/ or sar-data/task-data/<task-id>/ directory, so the task is the natural grouping for "the same place over time". We read the task component straight from the item's sidecar href (URL-decoded, e.g. "Centerfield, Utah"), since that carries the human-friendly label on named campaigns; UUID collects keep the task id. When no usable href is present we fall back to the umbra:task_id property. Returns None when neither is available.

asset_map property

asset_map

Map canonical product type -> actual STAC asset key.

When several assets share a product type (a primary SIDD and a csi_sidd, or gec and gec_2), the unsuffixed non-CSI asset is preferred. CSI is read from the key and the filename, so a normalized csi_sidd key still loses to sidd.

available_assets property

available_assets

Canonical product types present on this item (e.g. GEC, SICD).

from_dict classmethod

from_dict(data, href=None)

Build an item from a STAC feature dictionary.

asset_href

asset_href(name)

Return the download URL for one asset.

name is a product type in any case ("GEC"), a schema v2 key ("gec", "gec_2", "csi_sidd", "file_tif"), or the original filename (umbra-py:filename). "GEC" and "gec" are the primary file; "gec_2" is the next file of that product. A name that is not on the item raises :class:AssetNotFoundError listing the v2 keys. Stored keys may still be a filename or "GEC"; selection uses the same v2 key space the API serves.

Umbra's published *.stac.v2.json sidecars reference assets either with href="" or with an s3:// URL into a private processing bucket -- neither is anonymously fetchable. In both cases the public copy sits next to the sidecar in the open-data bucket, so we reconstruct a public HTTPS URL: first relative to the item's own sidecar href (which correctly handles named-task layouts like tasks/<name>/<task_id>/<acq>/), then falling back to deriving from umbra:task_id. Hrefs already pointing at http(s) are returned unchanged.

intersects_bbox

intersects_bbox(bbox)

Whether this item's footprint overlaps the given bounding box.

intersects_polygon

intersects_polygon(geometry)

Whether this item's footprint intersects the given polygon geometry.

geometry is the form returned by :func:umbra_py._geometry.parse_geometry (exterior rings, or a one-position ring for a Point). This uses the item's actual footprint polygon when it has one -- a tighter test than the bbox rectangle :meth:intersects_bbox uses -- and falls back to the footprint bbox when the geometry is missing or not understood (and matches nothing when neither is available). A query point matches when it lies inside the footprint or on its boundary.

matches_filters

matches_filters(*, polarizations=None, min_incidence=None, max_incidence=None, max_resolution=None)

Whether this item satisfies the SAR acquisition-property filters.

These are the first-class radar-discovery filters an analyst reaches for beyond geography and date -- polarization, incidence angle and spatial resolution -- read from the STAC sar:/view: properties the item already parses (:attr:polarizations, :attr:incidence_angle, :attr:resolution). Every argument is optional; a None/empty one is no constraint, so a call with no arguments always returns True.

  • polarizations: keep the item if it exposes at least one of the requested polarizations (case-insensitive), e.g. ["VV"]. This is the filter that keeps a change composite comparing like with like -- HH and VV image different scattering physics (see :data:~umbra_py.constants.POLARIZATION_CAVEAT).
  • min_incidence / max_incidence: inclusive bounds on the view incidence angle in degrees.
  • max_resolution: keep the item only if it is at least this fine -- both the range and azimuth resolution must be <= max_resolution metres.

Each filter is a hard predicate: when it is set, an item that lacks the corresponding metadata is excluded (an absent value can't be confirmed to match), matching the STAC Query-extension convention that a property predicate does not select items missing that property. This is deliberately unlike the geometric :meth:intersects_bbox / :meth:intersects_polygon filters, which fall back to a coarser datum when a footprint is missing: those have a fallback, these categorical / numeric properties do not, so "present and satisfies" is the honest test. No model is called and no new dependency is used -- pure metadata comparison, so it is fully deterministic and offline-testable.

metadata_summary

metadata_summary()

A compact, human-friendly subset of the item's metadata.

to_llm_context

to_llm_context()

A compact, explanation-rich context card for prompting a model.

Like :meth:metadata_summary but tuned for a language model rather than a human: every present product type carries a one-line explanation, the polarizations carry the change-detection caveat, and the mandatory CC-BY attribution line travels with the data. The differences from metadata_summary are exactly the things a model needs spelled out and a human already knows — so an agent can reason about the scene, and cite the right product, with no external SAR literacy. Deterministic and offline (no network, no model call).

Published as docs/schemas/item-context.schema.json -- the same card umbra info --json prints, the agent tools return, and a watch delta carries one of per new acquisition.

to_geojson

to_geojson()

Return a GeoJSON Feature representing this item.

Convenience wrapper around :func:umbra_py.viz.item_to_feature so users can call item.to_geojson() directly. The third coordinate of 3D footprints is stripped so the feature renders cleanly in standard 2D GIS tools.

summary

summary()

A one-paragraph readable description for the CLI / notebooks.

ItemCollection

ItemCollection(items=(), *, thumbnails=False, max_size=256, db=True)

Bases: list

A list of :class:UmbraItem that renders as a gallery in notebooks.

Behaves exactly like a list (it is one), so existing code that iterates search results is unaffected. The extra is a Jupyter _repr_html_ that lays the items out as a grid of metadata cards::

from umbra_py import UmbraCatalog, ItemCollection
results = ItemCollection(UmbraCatalog().search(area="rome", limit=8))
results  # -> gallery of cards (offline, no extras needed)

Pass thumbnails=True to stream a small SAR quicklook for each item (needs the viz extra). Thumbnails are fetched lazily when the collection is displayed; any item that can't be previewed falls back to its footprint card, so displaying the collection never raises.

GeoJSON helpers

item_to_feature

item_to_feature(item)

Convert one UmbraItem to a GeoJSON Feature dict.

Properties include the compact metadata summary plus the item's STAC URL (stac_href) so downstream tools can link back to the source.

items_to_featurecollection

items_to_featurecollection(items)

Convert items to a single GeoJSON FeatureCollection dict.

write_geojson

write_geojson(items, dest, *, indent=2)

Write items as a GeoJSON FeatureCollection to dest.

Product constants

PRODUCT_ASSETS module-attribute

PRODUCT_ASSETS = ('GEC', 'CSI', 'SIDD', 'SICD', 'CPHD')

DATA_LICENSE module-attribute

DATA_LICENSE = 'CC-BY-4.0'

ATTRIBUTION module-attribute

ATTRIBUTION = 'Contains Umbra open data, licensed under CC BY 4.0.'