Skip to content

Commit

Permalink
DAS-2146 - select correct asset from stac Item (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
flamingbear authored May 30, 2024
1 parent 84e154e commit bad8970
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 13 deletions.
29 changes: 25 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
## v1.1.0 - 2024-04-30
# Changelog

HyBIG follows semantic versioning. All notable changes to this project will be
documented in this file. The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/).


## [v1.2.0] - 2024-05-28

### Added
Adds functionality to retrieve '`visual`' asset for multi-file
granules. Harmony creates this type of asset when the UMM-G is correctly
configured with a "BROWSE IMAGE SOURCE" subtype.

## [v1.1.0] - 2024-04-30

### Changed
Changes the computation for an output image's default scale extent. Previously
Expand All @@ -8,17 +22,17 @@ and uses that transformed boundry as the default region to make a scale extent f

Upgraded harmony-service-lib to v1.0.26

## v1.0.2 - 2024-04-05
## [v1.0.2] - 2024-04-05

This version of HyBIG correctly handles missing/bad input data marked by _FillValue or NoData.
Anytime a bad value occurs in the input raster, the output png image will set to transparent.

## v1.0.1 - 2024-04-05
## [v1.0.1] - 2024-04-05

This version of HyBIG updates the repository to use `black` code formatting
throughout. There should be no functional change to the service.

## v1.0.0 - 2024-01-22
## [v1.0.0] - 2024-01-22
This version of the Harmony Browse Image Generator (HyBIG) contains all
functionality previously released internally to EOSDIS as
sds/harmony-browse-image-generator:0.0.11.
Expand All @@ -28,3 +42,10 @@ outlined by the NASA open-source guidelines.

For more information on internal releases prior to NASA open-source approval,
see legacy-CHANGELOG.md.

[unreleased]:https://github.com/nasa/harmony-browse-image-generator/compare/1.2.0..HEAD
[v1.2.0]: https://github.com/nasa/harmony-browse-image-generator/compare/1.1.0..1.2.0
[v1.1.0]: https://github.com/nasa/harmony-browse-image-generator/compare/1.0.2..1.1.0
[v1.0.2]: https://github.com/nasa/harmony-browse-image-generator/compare/1.0.1..1.0.2
[v1.0.1]: https://github.com/nasa/harmony-browse-image-generator/compare/1.0.0..1.0.1
[v1.0.0]: https://github.com/nasa/harmony-browse-image-generator/compare/0.0.11-legacy..1.0.0
13 changes: 11 additions & 2 deletions bin/extract-release-notes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@
###############################################################################

CHANGELOG_FILE="CHANGELOG.md"
VERSION_PATTERN="^## v"

## captures versions
## >## v1.0.0
## >## [v1.0.0]
VERSION_PATTERN="^## [\[]v"

## captures url links
## [unreleased]:https://github.com/nasa/harmony-browse-image-generator/compare/1.2.0..HEAD
## [v1.2.0]: https://github.com/nasa/harmony-browse-image-generator/compare/1.1.0..1.2.0
LINK_PATTERN="^\[.*\].*\.\..*"

# Read the file and extract text between the first two occurrences of the
# VERSION_PATTERN
result=$(awk "/$VERSION_PATTERN/{c++; if(c==2) exit;} c==1" "$CHANGELOG_FILE")

# Print the result
echo "$result" | grep -v "$VERSION_PATTERN"
echo "$result" | grep -v "$VERSION_PATTERN" | grep -v "$LINK_PATTERN"
2 changes: 1 addition & 1 deletion docker/service.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ WORKDIR "/home"
# Create Conda environment:
COPY conda_requirements.txt conda_requirements.txt
RUN conda create --yes --name hybig --file conda_requirements.txt \
python=3.10 --channel conda-forge --channel defaults -q && \
python=3.11 --channel conda-forge --channel defaults -q && \
conda clean --all --force-pkgs-dirs --yes

# Install additional Pip dependencies
Expand Down
2 changes: 1 addition & 1 deletion docker/service_version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.0
1.2.0
31 changes: 26 additions & 5 deletions harmony_browse_image_generator/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,39 @@ def validate_message(self):
'Harmony ScaleExtents must be in order [xmin,ymin,xmax,ymax].'
)

def get_asset_from_item(self, item: Item) -> Asset:
"""Returns the correct browse asset from a stac Item.
This is used to select which asset is used by HyBIG to generate
the browse image following these steps:
1. If found, return the first asset with 'visual' in any of the item's values' roles.
2. If found, return the first asset that has 'data' in its item's values' roles.
3. Raise a StopIteration error.
"""
try:
return next(
item_asset
for item_asset in item.assets.values()
if 'visual' in (item_asset.roles or [])
)
except StopIteration:
return next(
item_asset
for item_asset in item.assets.values()
if 'data' in (item_asset.roles or [])
)

def process_item(self, item: Item, source: HarmonySource) -> Item:
"""Processes a single input STAC item."""

try:
working_directory = mkdtemp()
results = item.clone()
results.assets = {}

asset = next(
item_asset
for item_asset in item.assets.values()
if 'data' in (item_asset.roles or [])
)
asset = self.get_asset_from_item(item)

color_palette = get_color_palette_from_item(item)

Expand Down
60 changes: 60 additions & 0 deletions tests/unit/test_adapter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from datetime import datetime
from unittest import TestCase
from unittest.mock import Mock

from harmony.message import Message
from harmony.util import config
from pystac import Asset, Item

from harmony_browse_image_generator.adapter import BrowseImageGeneratorAdapter
from harmony_browse_image_generator.exceptions import HyBIGInvalidMessageError
Expand Down Expand Up @@ -152,3 +155,60 @@ def test_create_output_stac_items(self):
self.assertEqual(
output_stac_item.assets['auxiliary'].title, 'browse.png.aux.xml'
)


class TestAdapterAssetFromItem(TestCase):
"""A class testing get_asset_from_item function."""

def setUp(self):
self.adapter = BrowseImageGeneratorAdapter({}, {})
self.visual_asset = Asset(Mock(), roles=['visual'])
self.data_asset = Asset(Mock(), roles=['data'])
self.none_asset = Asset(Mock(), roles=[])
self.other_asset = Asset(Mock(), roles=['other'])

def item_fixture(self, assets: dict) -> Item:
item = Item(Mock(), None, None, datetime.now(), {})
item.assets = assets
return item

def test_get_asset_from_item_with_visual_role(self):
with self.subTest('data asset first'):
item = self.item_fixture(
{'data': self.data_asset, 'visual': self.visual_asset}
)
expected = self.visual_asset

actual = self.adapter.get_asset_from_item(item)

self.assertEqual(expected, actual)

with self.subTest('visual asset first'):
item = self.item_fixture(
{'visual': self.visual_asset, 'data': self.data_asset}
)
expected = self.visual_asset

actual = self.adapter.get_asset_from_item(item)

self.assertEqual(expected, actual)

def test_get_asset_from_item_with_data_role(self):
item = self.item_fixture({'data': self.data_asset, 'other': self.other_asset})
expected = self.data_asset

actual = self.adapter.get_asset_from_item(item)

self.assertEqual(expected, actual)

def test_get_asset_from_item_no_roles(self):
item = self.item_fixture({'none': self.none_asset})
with self.assertRaises(StopIteration):
self.adapter.get_asset_from_item(item)

def test_get_asset_from_item_no_matching_roles(self):
item = self.item_fixture(
{'first': self.other_asset, 'second': self.other_asset}
)
with self.assertRaises(StopIteration):
self.adapter.get_asset_from_item(item)

0 comments on commit bad8970

Please sign in to comment.