diff --git a/odc/stac/_mdtools.py b/odc/stac/_mdtools.py index 6afbe3f..e1bb64f 100644 --- a/odc/stac/_mdtools.py +++ b/odc/stac/_mdtools.py @@ -660,6 +660,7 @@ def parse_item( band2grid = template.band2grid has_proj = False if template.has_proj is False else has_proj_ext(item) _assets = item.assets + _acc_names = list(_assets.keys()) _grids: Dict[str, GeoBox] = {} bands: Dict[BandKey, RasterSource] = {} @@ -681,6 +682,9 @@ def _get_grid(grid_name: str, asset: pystac.asset.Asset) -> GeoBox: asset = _assets.get(asset_name) if asset is None: continue + # the assets that aren't bands should be accessories + if asset_name in _acc_names: + _acc_names.remove(asset_name) grid_name = band2grid.get(asset_name, "default") geobox: Optional[GeoBox] = _get_grid(grid_name, asset) if has_proj else None @@ -711,6 +715,8 @@ def _get_grid(grid_name: str, asset: pystac.asset.Asset) -> GeoBox: driver_data=driver_data, ) + accessories = {name: {"path": _assets[name].href} for name in _acc_names} + md = item.common_metadata return ParsedItem( item.id, @@ -720,6 +726,7 @@ def _get_grid(grid_name: str, asset: pystac.asset.Asset) -> GeoBox: datetime=item.datetime, datetime_range=(md.start_datetime, md.end_datetime), href=item.get_self_href(), + accessories=accessories, ) diff --git a/odc/stac/eo3/_eo3converter.py b/odc/stac/eo3/_eo3converter.py index 8ab7e6e..050a1df 100644 --- a/odc/stac/eo3/_eo3converter.py +++ b/odc/stac/eo3/_eo3converter.py @@ -220,6 +220,7 @@ def _to_dataset( "properties": dicttoolz.keymap( lambda k: STAC_TO_EO3_RENAMES.get(k, k), properties ), + "accessories": item.accessories, "lineage": {}, } diff --git a/odc/stac/model.py b/odc/stac/model.py index cc4a14c..747f9d7 100644 --- a/odc/stac/model.py +++ b/odc/stac/model.py @@ -206,6 +206,8 @@ class ParsedItem(Mapping[BandIdentifier, RasterSource]): Only includes raster bands of interest. """ + # pylint: disable=too-many-instance-attributes + id: str """Item id copied from STAC.""" @@ -227,6 +229,9 @@ class ParsedItem(Mapping[BandIdentifier, RasterSource]): href: Optional[str] = None """Self link from stac item.""" + accessories: dict[str, Any] = field(default_factory=dict) + """Additional assets""" + def geoboxes(self, bands: BandQuery = None) -> Tuple[GeoBox, ...]: """ Unique ``GeoBox`` s, highest resolution first. diff --git a/tests/test_mdtools.py b/tests/test_mdtools.py index b0bbb16..0070c9d 100644 --- a/tests/test_mdtools.py +++ b/tests/test_mdtools.py @@ -389,6 +389,19 @@ def test_parse_item_no_proj(sentinel_stac_ms: pystac.item.Item): assert _auto_load_params([xx] * 3) is None +def test_accessories_preserved(ga_landsat_stac: pystac.item.Item): + item0 = ga_landsat_stac + item = pystac.Item.from_dict(item0.to_dict()) + + md = extract_collection_metadata(item, STAC_CFG) + + xx = parse_item(item, md) + assert len(xx.accessories) == 3 + assert xx.accessories.get("thumbnail:nbart") + assert xx.accessories.get("checksum:sha1") + assert xx.accessories.get("metadata:processor") + + @pytest.fixture def parsed_item_s2(sentinel_stac_ms: pystac.item.Item): (item,) = parse_items([sentinel_stac_ms], STAC_CFG)