diff --git a/CHANGELOG.md b/CHANGELOG.md index 07de048e6..deb380d66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ media type value for these types and new media types COPC and VND_PMTILES ([#1554](https://github.com/stac-utils/pystac/pull/1554)) +### Fixed + +- `extensions.mlm` various fixes [#1556](https://github.com/stac-utils/pystac/pull/1556) + - Fixed ResizeType typos `interpolation-nearest` and `interpolation-linear` + - Fixed displaying the correct property in error message for `ResultStructure.data_type` + - Fixed `ValueScaling.maximum` setter to pop when None is given + - Fixed `ModelInput.value_scaling` to be `list[ValueScaling]` instead of `ValueScaling` + - Fixed missing version migrations + ## [v1.13.0] - 2025-04-15 ### Added diff --git a/pyproject.toml b/pyproject.toml index 74bf4d847..7d741bb35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,7 @@ dev = [ "types-jsonschema>=4.23.0.20240813", "types-orjson>=3.6.2", "types-python-dateutil>=2.9.0.20241003", + "types-requests>=2.32.0.20250328", "types-urllib3>=1.26.25.14", "virtualenv>=20.26.6", ] diff --git a/pystac/extensions/ext.py b/pystac/extensions/ext.py index 84f60c39d..fd2c7a646 100644 --- a/pystac/extensions/ext.py +++ b/pystac/extensions/ext.py @@ -406,7 +406,7 @@ def file(self) -> FileExtension[Asset]: @property def mlm(self) -> AssetGeneralMLMExtension[Asset] | AssetDetailedMLMExtension: - if "mlm:name" in self.stac_object.extra_fields: + if "mlm:architecture" in self.stac_object.extra_fields: return AssetDetailedMLMExtension.ext(self.stac_object) else: return AssetGeneralMLMExtension.ext(self.stac_object) diff --git a/pystac/extensions/mlm.py b/pystac/extensions/mlm.py index b3f53935c..781b3b0f9 100644 --- a/pystac/extensions/mlm.py +++ b/pystac/extensions/mlm.py @@ -8,6 +8,7 @@ from __future__ import annotations +import warnings from abc import ABC from collections.abc import Iterable from typing import Any, Generic, Literal, TypeVar, cast @@ -123,7 +124,7 @@ class TaskType(StringEnum): PANOPTIC_SEGMENTATION = "panoptic-segmentation" SIMILARITY_SEARCH = "similarity-search" GENERATIVE = "generative" - IAMGE_CAPTIONING = "image-captioning" + IMAGE_CAPTIONING = "image-captioning" SUPER_RESOLUTION = "super-resolution" @@ -148,8 +149,8 @@ class ResizeType(StringEnum): CROP = "crop" PAD = "pad" - INTERPOLATION_NEAREST = "interpolate-nearest" - INTERPOLATION_LINEAR = "interpolate-linear" + INTERPOLATION_NEAREST = "interpolation-nearest" + INTERPOLATION_LINEAR = "interpolation-linear" INTERPOLATION_CUBIC = "interpolation-cubic" INTERPOLATION_AREA = "interpolation-area" INTERPOLATION_LANCZOS4 = "interpolation-lanczos4" @@ -160,7 +161,7 @@ class ResizeType(StringEnum): class ValueScalingType(StringEnum): """ - An enumeratino of Value Scaling operations supported by the extension + An enumeration of Value Scaling operations supported by the extension """ MIN_MAX = "min-max" @@ -562,7 +563,7 @@ def maximum(self, v: int | float | None) -> None: if v is not None: self.properties[MAXIMUM_VALUE_SCALING_PROP] = v else: - self.properties.get(MAXIMUM_VALUE_SCALING_PROP, None) + self.properties.pop(MAXIMUM_VALUE_SCALING_PROP, None) @property def mean(self) -> int | float | None: @@ -785,7 +786,7 @@ def apply( bands: list[ModelBand] | list[str], input: InputStructure, description: str | None = None, - value_scaling: ValueScaling | None = None, + value_scaling: list[ValueScaling] | None = None, resize_type: ResizeType | None = None, pre_processing_function: ProcessingExpression | None = None, ) -> None: @@ -836,7 +837,7 @@ def create( bands: list[ModelBand] | list[str], input: InputStructure, description: str | None = None, - value_scaling: ValueScaling | None = None, + value_scaling: list[ValueScaling] | None = None, resize_type: ResizeType | None = None, pre_processing_function: ProcessingExpression | None = None, ) -> ModelInput: @@ -951,18 +952,18 @@ def description(self, v: str | None) -> None: self.properties.pop(DESCRIPTION_INPUT_OBJECT_PROP, None) @property - def value_scaling(self) -> ValueScaling | None: + def value_scaling(self) -> list[ValueScaling] | None: """ Gets or sets the value_scaling property of this ModelInput object """ - v = self.properties.get(VALUE_SCALING_INPUT_OBJECT_PROP) - return ValueScaling(v) if v is not None else v + v_list = self.properties.get(VALUE_SCALING_INPUT_OBJECT_PROP) + return [ValueScaling(v) for v in v_list] if v_list is not None else None @value_scaling.setter - def value_scaling(self, v: ValueScaling | None) -> None: + def value_scaling(self, v: list[ValueScaling] | None) -> None: # add None to properties dict and do not pop it, according to specification self.properties[VALUE_SCALING_INPUT_OBJECT_PROP] = ( - None if v is None else v.to_dict() + None if v is None else [v_entry.to_dict() for v_entry in v] ) @property @@ -1097,7 +1098,7 @@ def data_type(self) -> DataType: return get_required( self.properties.get(DATA_TYPE_RESULT_STRUCTURE_PROP), self, - DIM_ORDER_RESULT_STRUCTURE_PROP, + DATA_TYPE_RESULT_STRUCTURE_PROP, ) @data_type.setter @@ -1181,7 +1182,7 @@ def create( Creates a new Output Args: - name:Name of the output variable defined by the model. If no explicit name + name: Name of the output variable defined by the model. If no explicit name is defined by the model, an informative name (e.g.: "CLASSIFICATION") can be used instead. tasks: Specifies the Machine Learning tasks for which the output can be used @@ -1191,6 +1192,7 @@ def create( from one model head. description: Additional details about the output such as describing its purpose or expected result that cannot be represented by other properties. + description: Description of output. classes: A list of class objects adhering to the Classification Extension. post_processing_function: Custom postprocessing function where normalization, rescaling, or any other significant operations takes @@ -1339,156 +1341,68 @@ def to_dict(self) -> dict[str, Any]: return self.properties -class MLMExtension( - Generic[T], - PropertiesExtension, - ExtensionManagementMixin[pystac.Item | pystac.Collection], -): - """An abstract class that can be used to extend to properties of an - :class:`pystac.Item` or :class:`pystac.Collection` with properties from the - :stac-ext:`Machine Learning Model Extension `. - - This class can be used to extend :class:`pystac.Item`, :class:`pystac.Collection` - and :class:`pystac.ItemAssetDefinition`. For extending :class:`pystac.Asset`, use - either :class:`~AssetGeneralMLMExtension`: or :class:`AssetDetailedMLMExtension`. - """ - - name: Literal["mlm"] = "mlm" +class _ExcludedFromAssetProps(PropertiesExtension): properties: dict[str, Any] - def apply( - self, - name: str, - architecture: str, - tasks: list[TaskType], - input: list[ModelInput], - output: list[ModelOutput], - framework: str | None = None, - framework_version: str | None = None, - memory_size: int | None = None, - total_parameters: int | None = None, - pretrained: bool | None = None, - pretrained_source: str | None = None, - batch_size_suggestion: int | None = None, - accelerator: AcceleratorType | None = None, - accelerator_constrained: bool | None = None, - accelerator_summary: str | None = None, - accelerator_count: int | None = None, - hyperparameters: Hyperparameters | None = None, - *args: Any, - **kwargs: Any, - ) -> None: + @property + def mlm_name(self) -> str: """ - Sets the properties of a new MLMExtension - - Args: - name: name for the model - architecture: A generic and well established architecture name of the model - tasks: Specifies the Machine Learning tasks for which the model can be - used for - input: Describes the transformation between the EO data and the model input - output: Describes each model output and how to interpret it. - framework: Framework used to train the model - framework_version: The ``framework`` library version - memory_size: The in-memory size of the model on the accelerator during - inference (bytes) - total_parameters: Total number of model parameters, including trainable and - non-trainable parameters. - pretrained: Indicates if the model was pretrained. If the model was - pretrained, consider providing ``pretrained_source`` if it is known - pretrained_source: The source of the pretraining. - batch_size_suggestion: A suggested batch size for the accelerator and - summarized hardware. - accelerator: The intended computational hardware that runs inference - accelerator_constrained: Indicates if the intended ``accelerator`` is the - only accelerator that can run inference - accelerator_summary: A high level description of the ``accelerator`` - accelerator_count: A minimum amount of ``accelerator`` instances required to - run the model - hyperparameters: Additional hyperparameters relevant for the model - *args: Unused (no effect, only here for signature compliance with apply - method in derived classes - **kwargs: Unused (no effect, only here for signature compliance with apply - method in derived classes + Get or set the required (mlm) name property. It is named mlm_name in this + context to not break convention and overwrite the extension name class property. """ - self.mlm_name = name - self.architecture = architecture - self.tasks = tasks - self.input = input - self.output = output - self.framework = framework - self.framework_version = framework_version - self.memory_size = memory_size - self.total_parameters = total_parameters - self.pretrained = pretrained - self.pretrained_source = pretrained_source - self.batch_size_suggestion = batch_size_suggestion - self.accelerator = accelerator - self.accelerator_constrained = accelerator_constrained - self.accelerator_summary = accelerator_summary - self.accelerator_count = accelerator_count - self.hyperparameters = hyperparameters + return get_required(self.properties.get(NAME_PROP), self, NAME_PROP) - @classmethod - def get_schema_uri(cls) -> str: - """ - Retrieves this extension's schema URI + @mlm_name.setter + def mlm_name(self, v: str) -> None: + self._set_property(NAME_PROP, v) - Returns: - str: the schema URI + @property + def input(self) -> list[ModelInput]: """ - return SCHEMA_URI_PATTERN.format(version=DEFAULT_VERSION) - - @classmethod - def ext(cls, obj: T, add_if_missing: bool = False) -> MLMExtension[T]: + Get or set the required input property """ - Extend a STAC object (``obj``) with the MLMExtension - - Args: - obj: The STAC object to be extended. - add_if_missing: Defines whether this extension's URI should be added to - this object's (or its parent's) list of extensions if it is not already - listed there. + return [ + ModelInput(inp) + for inp in get_required( + self._get_property(INPUT_PROP, list[dict[str, Any]]), self, INPUT_PROP + ) + ] - Returns: - MLMExtension[T]: The extended object + @input.setter + def input(self, v: list[ModelInput]) -> None: + self._set_property(INPUT_PROP, [inp.to_dict() for inp in v]) - Raises: - TypeError: When a :class:`pystac.Asset` object is passed as the - `obj` parameter - pystac.ExtensionTypeError: When any unsupported object is passed as the - `obj` parameter. If you see this extension in this context, please - raise an issue on github. + @property + def output(self) -> list[ModelOutput]: """ - if isinstance(obj, pystac.Item): - cls.ensure_has_extension(obj, add_if_missing) - return cast(MLMExtension[T], ItemMLMExtension(obj)) - elif isinstance(obj, pystac.Collection): - cls.ensure_has_extension(obj, add_if_missing) - return cast(MLMExtension[T], CollectionMLMExtension(obj)) - elif isinstance(obj, pystac.ItemAssetDefinition): - cls.ensure_owner_has_extension(obj, add_if_missing) - return cast(MLMExtension[T], ItemAssetMLMExtension(obj)) - elif isinstance(obj, pystac.Asset): - raise TypeError( - "This class cannot be used to extend STAC objects of type Assets. " - "To extend Asset objects, use either AssetGeneralMLMExtension or " - "AssetDetailedMLMExtension" + Get or set the required output property + """ + return [ + ModelOutput(outp) + for outp in get_required( + self._get_property(OUTPUT_PROP, list[dict[str, Any]]), self, OUTPUT_PROP ) - else: - raise pystac.ExtensionTypeError(cls._ext_error_message(obj)) + ] + + @output.setter + def output(self, v: list[ModelOutput]) -> None: + self._set_property(OUTPUT_PROP, [outp.to_dict() for outp in v]) @property - def mlm_name(self) -> str: + def hyperparameters(self) -> Hyperparameters | None: """ - Get or set the required (mlm) name property. It is named mlm_name in this - context to not break convention and overwrite the extension name class property. + Get or set the hyperparameters property """ - return get_required(self.properties.get(NAME_PROP), self, NAME_PROP) + prop = self._get_property(HYPERPARAMETERS_PROP, dict[str, Any]) + return Hyperparameters(prop) if prop is not None else None - @mlm_name.setter - def mlm_name(self, v: str) -> None: - self._set_property(NAME_PROP, v) + @hyperparameters.setter + def hyperparameters(self, v: Hyperparameters | None) -> None: + self._set_property(HYPERPARAMETERS_PROP, v.to_dict() if v is not None else None) + + +class _IncludedInAssetProps(PropertiesExtension): + properties: dict[str, Any] @property def architecture(self) -> str: @@ -1638,49 +1552,140 @@ def accelerator_count(self) -> int | None: def accelerator_count(self, v: int | None) -> None: self._set_property(ACCELERATOR_COUNT_PROP, v) - @property - def input(self) -> list[ModelInput]: - """ - Get or set the required input property - """ - return [ - ModelInput(inp) - for inp in get_required( - self._get_property(INPUT_PROP, list[dict[str, Any]]), self, INPUT_PROP - ) - ] - @input.setter - def input(self, v: list[ModelInput]) -> None: - self._set_property(INPUT_PROP, [inp.to_dict() for inp in v]) +class MLMExtension( + Generic[T], + _ExcludedFromAssetProps, + _IncludedInAssetProps, + ExtensionManagementMixin[pystac.Item | pystac.Collection], +): + """An abstract class that can be used to extend to properties of an + :class:`pystac.Item` or :class:`pystac.Collection` with properties from the + :stac-ext:`Machine Learning Model Extension `. - @property - def output(self) -> list[ModelOutput]: + This class can be used to extend :class:`pystac.Item`, :class:`pystac.Collection` + and :class:`pystac.ItemAssetDefinition`. For extending :class:`pystac.Asset`, use + either :class:`~AssetGeneralMLMExtension`: or :class:`AssetDetailedMLMExtension`. + """ + + name: Literal["mlm"] = "mlm" + properties: dict[str, Any] + + def apply( + self, + name: str, + architecture: str, + tasks: list[TaskType], + input: list[ModelInput], + output: list[ModelOutput], + framework: str | None = None, + framework_version: str | None = None, + memory_size: int | None = None, + total_parameters: int | None = None, + pretrained: bool | None = None, + pretrained_source: str | None = None, + batch_size_suggestion: int | None = None, + accelerator: AcceleratorType | None = None, + accelerator_constrained: bool | None = None, + accelerator_summary: str | None = None, + accelerator_count: int | None = None, + hyperparameters: Hyperparameters | None = None, + ) -> None: """ - Get or set the required output property + Sets the properties of a new MLMExtension + + Args: + name: name for the model + architecture: A generic and well established architecture name of the model + tasks: Specifies the Machine Learning tasks for which the model can be + used for + input: Describes the transformation between the EO data and the model input + output: Describes each model output and how to interpret it. + framework: Framework used to train the model + framework_version: The ``framework`` library version + memory_size: The in-memory size of the model on the accelerator during + inference (bytes) + total_parameters: Total number of model parameters, including trainable and + non-trainable parameters. + pretrained: Indicates if the model was pretrained. If the model was + pretrained, consider providing ``pretrained_source`` if it is known + pretrained_source: The source of the pretraining. + batch_size_suggestion: A suggested batch size for the accelerator and + summarized hardware. + accelerator: The intended computational hardware that runs inference + accelerator_constrained: Indicates if the intended ``accelerator`` is the + only accelerator that can run inference + accelerator_summary: A high level description of the ``accelerator`` + accelerator_count: A minimum amount of ``accelerator`` instances required to + run the model + hyperparameters: Additional hyperparameters relevant for the model """ - return [ - ModelOutput(outp) - for outp in get_required( - self._get_property(OUTPUT_PROP, list[dict[str, Any]]), self, OUTPUT_PROP - ) - ] + self.mlm_name = name + self.architecture = architecture + self.tasks = tasks + self.input = input + self.output = output + self.framework = framework + self.framework_version = framework_version + self.memory_size = memory_size + self.total_parameters = total_parameters + self.pretrained = pretrained + self.pretrained_source = pretrained_source + self.batch_size_suggestion = batch_size_suggestion + self.accelerator = accelerator + self.accelerator_constrained = accelerator_constrained + self.accelerator_summary = accelerator_summary + self.accelerator_count = accelerator_count + self.hyperparameters = hyperparameters - @output.setter - def output(self, v: list[ModelOutput]) -> None: - self._set_property(OUTPUT_PROP, [outp.to_dict() for outp in v]) + @classmethod + def get_schema_uri(cls) -> str: + """ + Retrieves this extension's schema URI - @property - def hyperparameters(self) -> Hyperparameters | None: + Returns: + str: the schema URI """ - Get or set the hyperparameters property + return SCHEMA_URI_PATTERN.format(version=DEFAULT_VERSION) + + @classmethod + def ext(cls, obj: T, add_if_missing: bool = False) -> MLMExtension[T]: """ - prop = self._get_property(HYPERPARAMETERS_PROP, dict[str, Any]) - return Hyperparameters(prop) if prop is not None else None + Extend a STAC object (``obj``) with the MLMExtension - @hyperparameters.setter - def hyperparameters(self, v: Hyperparameters | None) -> None: - self._set_property(HYPERPARAMETERS_PROP, v.to_dict() if v is not None else None) + Args: + obj: The STAC object to be extended. + add_if_missing: Defines whether this extension's URI should be added to + this object's (or its parent's) list of extensions if it is not already + listed there. + + Returns: + MLMExtension[T]: The extended object + + Raises: + TypeError: When a :class:`pystac.Asset` object is passed as the + `obj` parameter + pystac.ExtensionTypeError: When any unsupported object is passed as the + `obj` parameter. If you see this extension in this context, please + raise an issue on github. + """ + if isinstance(obj, pystac.Item): + cls.ensure_has_extension(obj, add_if_missing) + return cast(MLMExtension[T], ItemMLMExtension(obj)) + elif isinstance(obj, pystac.Collection): + cls.ensure_has_extension(obj, add_if_missing) + return cast(MLMExtension[T], CollectionMLMExtension(obj)) + elif isinstance(obj, pystac.ItemAssetDefinition): + cls.ensure_owner_has_extension(obj, add_if_missing) + return cast(MLMExtension[T], ItemAssetMLMExtension(obj)) + elif isinstance(obj, pystac.Asset): + raise TypeError( + "This class cannot be used to extend STAC objects of type Assets. " + "To extend Asset objects, use either AssetGeneralMLMExtension or " + "AssetDetailedMLMExtension" + ) + else: + raise pystac.ExtensionTypeError(cls._ext_error_message(obj)) def to_dict(self) -> dict[str, Any]: """ @@ -1885,7 +1890,11 @@ def __repr__(self) -> str: return f"" -class AssetDetailedMLMExtension(_AssetMLMExtension, MLMExtension[pystac.Asset]): +class AssetDetailedMLMExtension( + _AssetMLMExtension, + _IncludedInAssetProps, + ExtensionManagementMixin[pystac.Item | pystac.Collection], +): """A class that can be used to extend the properties of an :class:`pystac.Asset` object with properties from the :stac-ext:`Machine Learning Model Extension `. @@ -1923,11 +1932,8 @@ def ext( def apply( self, - name: str, architecture: str, tasks: list[TaskType], - input: list[ModelInput], - output: list[ModelOutput], framework: str | None = None, framework_version: str | None = None, memory_size: int | None = None, @@ -1939,7 +1945,6 @@ def apply( accelerator_constrained: bool | None = None, accelerator_summary: str | None = None, accelerator_count: int | None = None, - hyperparameters: Hyperparameters | None = None, artifact_type: str | None = None, compile_method: str | None = None, entrypoint: str | None = None, @@ -1948,12 +1953,9 @@ def apply( Sets the properties of a new AssetDetailedMLMExtensions Args: - name: name for the model architecture: A generic and well established architecture name of the model tasks: Specifies the Machine Learning tasks for which the model can be used for - input: Describes the transformation between the EO data and the model input - output: Describes each model output and how to interpret it. framework: Framework used to train the model framework_version: The ``framework`` library version memory_size: The in-memory size of the model on the accelerator during @@ -1971,7 +1973,6 @@ def apply( accelerator_summary: A high level description of the ``accelerator`` accelerator_count: A minimum amount of ``accelerator`` instances required to run the model - hyperparameters: Additional hyperparameters relevant for the model artifact_type: Specifies the kind of model artifact, any string is allowed. Typically related to a particular ML framework. This property is required when ``mlm:model`` is listed as a role of this asset @@ -1980,26 +1981,21 @@ def apply( entrypoint: Specific entrypoint reference in the code to use for running model inference. """ - MLMExtension.apply( - self, - name=name, - architecture=architecture, - tasks=tasks, - input=input, - output=output, - framework=framework, - framework_version=framework_version, - memory_size=memory_size, - total_parameters=total_parameters, - pretrained=pretrained, - pretrained_source=pretrained_source, - batch_size_suggestion=batch_size_suggestion, - accelerator=accelerator, - accelerator_constrained=accelerator_constrained, - accelerator_summary=accelerator_summary, - accelerator_count=accelerator_count, - hyperparameters=hyperparameters, - ) + + self.architecture = architecture + self.tasks = tasks + self.framework = framework + self.framework_version = framework_version + self.memory_size = memory_size + self.total_parameters = total_parameters + self.pretrained = pretrained + self.pretrained_source = pretrained_source + self.batch_size_suggestion = batch_size_suggestion + self.accelerator = accelerator + self.accelerator_constrained = accelerator_constrained + self.accelerator_summary = accelerator_summary + self.accelerator_count = accelerator_count + self.artifact_type = artifact_type self.compile_method = compile_method self.entrypoint = entrypoint @@ -2026,11 +2022,325 @@ class MLMExtensionHooks(ExtensionHooks): } stac_object_types = {pystac.STACObjectType.ITEM, pystac.STACObjectType.COLLECTION} + @staticmethod + def _migrate_1_0_to_1_1(obj: dict[str, Any]) -> None: + def migrate(props_obj: dict[str, Any]) -> None: + if "mlm:framework" in props_obj: + framework = props_obj["mlm:framework"] + # remove invalid characters at beginning and end + forbidden_chars = [".", "_", "-", " ", "\t", "\n", "\r", "\f", "\v"] + if framework[0] in forbidden_chars or framework[-1] in forbidden_chars: + warnings.warn( + "Value for mlm:framework is invalid in mlm>=1.1, as it must" + "not start or end with one of the following characters: " + "._- and whitespace. These characters are therefore removed " + "while migrating the STAC object to v1.1.", + SyntaxWarning, + ) + while props_obj["mlm:framework"][0] in forbidden_chars: + new_str = props_obj["mlm:framework"][1:] + props_obj["mlm:framework"] = new_str + while props_obj["mlm:framework"][-1] in forbidden_chars: + new_str = props_obj["mlm:framework"][:-1] + props_obj["mlm:framework"] = new_str + + # rename frameworks + if props_obj["mlm:framework"] == "Scikit-learn": + props_obj["mlm:framework"] = "scikit-learn" + warnings.warn( + "mlm:framework value Scikit-learn is no longer valid in " + "mlm>=1.1. Renaming it to scikit-learn", + SyntaxWarning, + ) + if props_obj["mlm:framework"] == "Huggingface": + props_obj["mlm:framework"] = "Hugging Face" + warnings.warn( + "mlm:framework value Huggingface is no longer valid in " + "mlm>=1.1. Renaming it to Hugging Face", + SyntaxWarning, + ) + + # if no bands definition is given in mlm:input (bands=[]), + # raster definitions are not allowed to be in the assets object that is + # stac:mlm + if "mlm:input" in props_obj: + no_bands_present = all( + not inp["bands"] for inp in props_obj["mlm:input"] + ) + + if no_bands_present: + for inner_asset_name in obj["assets"]: + inner_asset = obj["assets"][inner_asset_name] + + if "mlm:model" not in inner_asset["roles"]: + continue + + if "raster:bands" in inner_asset: + bands_obj = inner_asset["raster:bands"] + + warnings.warn( + "stac:mlm does not allow 'raster:bands' in mlm:model " + "asset if mlm:input.bands is empty. Moving it to " + "properties if it contains values, or deleting it if " + "it does not contain any values.", + SyntaxWarning, + ) + + # move the bands_obj if it is not an empty list + if bands_obj: + if obj["type"] == "Feature": + obj["properties"]["raster:bands"] = bands_obj + if obj["type"] == "Collection": + obj["raster:bands"] = bands_obj + inner_asset.pop("raster:bands") + + if "eo:bands" in inner_asset: + bands_obj = inner_asset["eo:bands"] + + warnings.warn( + "stac:mlm does not allow 'raster:bands' in mlm:model " + "asset if mlm:input.bands is empty. Moving it to " + "properties if it contains values, or deleting it if " + "it does not contain any values.", + SyntaxWarning, + ) + + # move the bands_obj if it is not an empty list + if bands_obj: + if obj["type"] == "Feature": + obj["properties"]["eo:bands"] = bands_obj + if obj["type"] == "Collection": + obj["eo:bands"] = bands_obj + inner_asset.pop("eo:bands") + + if obj["type"] == "Feature": + migrate(obj["properties"]) + if obj["type"] == "Collection": + migrate(obj) + + if "assets" in obj: + for asset_name in obj["assets"]: + asset = obj["assets"][asset_name] + migrate(asset) + + if obj["type"] == "Collection" and "item_assets" in obj: + for asset_name in obj["item_assets"]: + asset = obj["item_assets"][asset_name] + migrate(asset) + + @staticmethod + def _migrate_1_1_to_1_2(obj: dict[str, Any]) -> None: + def migrate(obj_assets: dict[str, Any]) -> None: + model_in_assets = any( + ["mlm:model" in obj_assets[asset]["roles"] for asset in obj_assets] + ) + if not model_in_assets: + raise pystac.errors.STACError( + 'Error migrating stac:mlm version: An asset with role "mlm:model" ' + "is required in mlm>=1.2. Include at least one asset with role " + '"mlm:model" ' + ) + + if "assets" in obj: + migrate(obj["assets"]) + if "item_assets" in obj: + migrate(obj["item_assets"]) + + @staticmethod + def _migrate_1_2_to_1_3(obj: dict[str, Any]) -> None: + def migrate(props_obj: dict[str, Any]) -> None: + if "mlm:input" not in props_obj: + return + + # check if mlm:input.bands is present and contains items + bands_objs_present = [ + "bands" in inp and len(inp["bands"]) > 0 + for inp in props_obj["mlm:input"] + ] + + if not any(bands_objs_present): + return + + if "eo:bands" in props_obj or "bands" in props_obj: + return + + if ( + "raster:bands" in props_obj + and "eo:bands" not in props_obj + and "bands" not in props_obj + ): + raster_bands = props_obj["raster:bands"] + + bands_valid = all( + "name" in band and len(band["name"]) > 0 for band in raster_bands + ) + + if not bands_valid: + raise STACError( + "Error migrating stac:mlm version: In mlm>=1.3, each band in " + 'raster:bands is required to have a property "name" with ' + "length > 0" + ) + + # no need to perform the actions below if props_obj is not an asset + # this is checked by the presence of "roles" prop + if "roles" in props_obj: + return + + # move raster:bands to assets that contain "mlm:model" role + for inner_asset_name in obj["assets"]: + inner_asset = obj["assets"][inner_asset_name] + if "mlm:model" not in inner_asset["roles"]: + continue + inner_asset["raster:bands"] = raster_bands + props_obj.pop("raster:bands") + + # create new bands object from mlm:input.bands if none exist + if ( + "raster:bands" not in props_obj + and "eo:bands" not in props_obj + and "bands" not in props_obj + ): + i = bands_objs_present.index(True) + bands = [ + {"name": band if type(band) is str else band["name"]} + for band in props_obj["mlm:input"][i]["bands"] + ] + + # copy the raster:bands to assets + for inner_asset_name in obj["assets"]: + inner_asset = obj["assets"][inner_asset_name] + if "mlm:model" not in inner_asset["roles"]: + continue + inner_asset["raster:bands"] = bands + + if obj["type"] == "Feature" and "mlm:input" in obj["properties"]: + migrate(obj["properties"]) + if obj["type"] == "Collection": + migrate(obj) + if "assets" in obj: + for asset_name in obj["assets"]: + asset = obj["assets"][asset_name] + migrate(asset) + + @staticmethod + def _migrate_1_3_to_1_4(obj: dict[str, Any]) -> None: + def migrate(props_obj: dict[str, Any]) -> None: + if "mlm:input" not in props_obj: + return + + # Migrate to value_scaling + for input_obj in props_obj["mlm:input"]: + if "norm_type" in input_obj and input_obj["norm_type"] is not None: + norm_type = input_obj["norm_type"] + value_scaling_list = [] + if norm_type == "min-max": + for band_statistic in input_obj["statistics"]: + value_scaling_obj = { + "type": "min-max", + "minimum": band_statistic["minimum"], + "maximum": band_statistic["maximum"], + } + value_scaling_list.append(value_scaling_obj) + elif norm_type == "z-score": + for band_statistic in input_obj["statistics"]: + value_scaling_obj = { + "type": "z-score", + "mean": band_statistic["mean"], + "stddev": band_statistic["stddev"], + } + value_scaling_list.append(value_scaling_obj) + elif norm_type == "clip": + for clip_value in input_obj["norm_clip"]: + value_scaling_obj = { + "type": "processing", + "format": "gdal-calc", + "expression": f"numpy.clip(A / {clip_value}, 0, 1)", + } + value_scaling_list.append(value_scaling_obj) + else: + raise NotImplementedError( + f"Normalization type {norm_type} is not supported in " + f"stac:mlm >= 1.3. Therefore an automatic migration is not " + f"possible. Please migrate this normalization manually " + f'using type="processing".' + ) + input_obj["value_scaling"] = value_scaling_list + input_obj.pop("norm_by_channel", None) + input_obj.pop("norm_type", None) + input_obj.pop("norm_clip", None) + input_obj.pop("statistics", None) + + if obj["type"] == "Feature": + migrate(obj["properties"]) + if obj["type"] == "Collection": + migrate(obj) + + if "assets" in obj: + for asset in obj["assets"]: + migrate(obj["assets"][asset]) + + # move forbidden fields from asset to properties + if "mlm:name" in obj["assets"][asset]: + mlm_name = obj["assets"][asset]["mlm:name"] + if obj["type"] == "Feature": + obj["properties"]["mlm:name"] = mlm_name + if obj["type"] == "Collection": + obj["mlm:name"] = mlm_name + obj["assets"][asset].pop("mlm:name") + if "mlm:input" in obj["assets"][asset]: + inp = obj["assets"][asset]["mlm:input"] + if obj["type"] == "Feature": + obj["properties"]["mlm:input"] = inp + if obj["type"] == "Collection": + obj["mlm:input"] = inp + obj["assets"][asset].pop("mlm:input") + if "mlm:output" in obj["assets"][asset]: + outp = obj["assets"][asset]["mlm:output"] + if obj["type"] == "Feature": + obj["properties"]["mlm:output"] = outp + if obj["type"] == "Collection": + obj["mlm:output"] = outp + obj["assets"][asset].pop("mlm:output") + if "mlm:hyperparameters" in obj["assets"][asset]: + hyp = obj["assets"][asset]["mlm:hyperparameters"] + if obj["type"] == "Feature": + obj["properties"]["mlm:hyperparameters"] = hyp + if obj["type"] == "Collection": + obj["mlm:hyperparameters"] = hyp + obj["assets"][asset].pop("mlm:hyperparameters") + + # add new REQUIRED proretie mlm:artifact_type to asset + if "mlm:model" in obj["assets"][asset]["roles"]: + obj["assets"][asset]["mlm:artifact_type"] = ( + "Placeholder string to satisfy requirements when migrating " + "from mlm v1.3 to v1.4" + ) + def migrate( self, obj: dict[str, Any], version: STACVersionID, info: STACJSONDescription ) -> None: # mo adjustments to objects needed when migrating yet # schema back to v1.0 is fully backwards compatible + + if SCHEMA_URI_PATTERN.format(version="1.0.0") in info.extensions: + self._migrate_1_0_to_1_1(obj) + self._migrate_1_1_to_1_2(obj) + self._migrate_1_2_to_1_3(obj) + self._migrate_1_3_to_1_4(obj) + + if SCHEMA_URI_PATTERN.format(version="1.1.0") in info.extensions: + self._migrate_1_1_to_1_2(obj) + self._migrate_1_2_to_1_3(obj) + self._migrate_1_3_to_1_4(obj) + + if SCHEMA_URI_PATTERN.format(version="1.2.0") in info.extensions: + self._migrate_1_2_to_1_3(obj) + self._migrate_1_3_to_1_4(obj) + + if SCHEMA_URI_PATTERN.format(version="1.3.0") in info.extensions: + self._migrate_1_3_to_1_4(obj) + super().migrate(obj, version, info) diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.0.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.0.0].yaml new file mode 100644 index 000000000..6833292b2 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.0.0].yaml @@ -0,0 +1,759 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.0.0/examples/item_basic.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.0.0/schema.json\"\n + \ ],\n \"type\": \"Feature\",\n \"id\": \"example-model\",\n \"collection\": + \"ml-model-examples\",\n \"geometry\": {\n \"type\": \"Polygon\",\n \"coordinates\": + [\n [\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ]\n ]\n ]\n },\n \"bbox\": [\n -7.882190080512502,\n + \ 37.13739173208318,\n 27.911651652899923,\n 58.21798141355221\n ],\n + \ \"properties\": {\n \"description\": \"Basic STAC Item with only the + MLM extension and no other extension cross-references.\",\n \"datetime\": + null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n \"end_datetime\": + \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"example-model\",\n \"mlm:tasks\": + [\n \"classification\"\n ],\n \"mlm:architecture\": \"ResNet\",\n + \ \"mlm:input\": [\n {\n \"name\": \"Model with RGB input that + does not refer to any band.\",\n \"bands\": [],\n \"input\": + {\n \"shape\": [\n -1,\n 3,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n }\n }\n ],\n + \ \"mlm:output\": [\n {\n \"name\": \"classification\",\n \"tasks\": + [\n \"classification\"\n ],\n \"result\": {\n \"shape\": + [\n -1,\n 1\n ],\n \"dim_order\": + [\n \"batch\",\n \"class\"\n ],\n \"data_type\": + \"uint8\"\n },\n \"classification_classes\": [\n {\n + \ \"value\": 0,\n \"name\": \"BACKGROUND\",\n \"description\": + \"Background non-city.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 0\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"CITY\",\n \"description\": + \"A city is detected.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 255\n ]\n }\n ]\n + \ }\n ]\n },\n \"assets\": {\n \"model\": {\n \"href\": \"https://huggingface.co/example/model-card\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"Example + model.\",\n \"type\": \"text/html\",\n \"roles\": [\n \"mlm:model\"\n + \ ]\n }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n + \ \"href\": \"./collection.json\",\n \"type\": \"application/json\"\n + \ },\n {\n \"rel\": \"self\",\n \"href\": \"./item_basic.json\",\n + \ \"type\": \"application/geo+json\"\n }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '931' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:43 GMT + ETag: + - W/"06b55e576e4efab26350d8d7551913db9419014d18bff024af7e5818a2366f4b" + Expires: + - Wed, 30 Apr 2025 08:53:43 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - fe2615757ad9d5339688e39fb8c970b71f222932 + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 7E10:242658:8C51EB:96C1B3:6811E3EA + X-Served-By: + - cache-fra-etou8220138-FRA + X-Timer: + - S1746002923.164423,VS0,VE198 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '0' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:43 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Fastly-Request-ID: + - 585f28d624a7b4f5c9c871c09fd669aa472f58fd + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220055-FRA + X-Timer: + - S1746002924.509723,VS0,VE112 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '356' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:43 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - bb24e9c9ded013b390fc64ccd78acbbad3385dae + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220084-FRA + X-Timer: + - S1746002924.793418,VS0,VE3 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.1.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.1.0].yaml new file mode 100644 index 000000000..d0dd017c3 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.1.0].yaml @@ -0,0 +1,759 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.1.0/examples/item_basic.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.1.0/schema.json\"\n + \ ],\n \"type\": \"Feature\",\n \"id\": \"example-model\",\n \"collection\": + \"ml-model-examples\",\n \"geometry\": {\n \"type\": \"Polygon\",\n \"coordinates\": + [\n [\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ]\n ]\n ]\n },\n \"bbox\": [\n -7.882190080512502,\n + \ 37.13739173208318,\n 27.911651652899923,\n 58.21798141355221\n ],\n + \ \"properties\": {\n \"description\": \"Basic STAC Item with only the + MLM extension and no other extension cross-references.\",\n \"datetime\": + null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n \"end_datetime\": + \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"example-model\",\n \"mlm:tasks\": + [\n \"classification\"\n ],\n \"mlm:architecture\": \"ResNet\",\n + \ \"mlm:input\": [\n {\n \"name\": \"Model with RGB input that + does not refer to any band.\",\n \"bands\": [],\n \"input\": + {\n \"shape\": [\n -1,\n 3,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n }\n }\n ],\n + \ \"mlm:output\": [\n {\n \"name\": \"classification\",\n \"tasks\": + [\n \"classification\"\n ],\n \"result\": {\n \"shape\": + [\n -1,\n 1\n ],\n \"dim_order\": + [\n \"batch\",\n \"class\"\n ],\n \"data_type\": + \"uint8\"\n },\n \"classification_classes\": [\n {\n + \ \"value\": 0,\n \"name\": \"BACKGROUND\",\n \"description\": + \"Background non-city.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 0\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"CITY\",\n \"description\": + \"A city is detected.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 255\n ]\n }\n ]\n + \ }\n ]\n },\n \"assets\": {\n \"model\": {\n \"href\": \"https://huggingface.co/example/model-card\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"Example + model.\",\n \"type\": \"text/html\",\n \"roles\": [\n \"mlm:model\"\n + \ ]\n }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n + \ \"href\": \"./collection.json\",\n \"type\": \"application/json\"\n + \ },\n {\n \"rel\": \"self\",\n \"href\": \"./item_basic.json\",\n + \ \"type\": \"application/geo+json\"\n }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '933' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:44 GMT + ETag: + - W/"60cdf768894e2f4eaafeb01906736c2bb03903640b6615f1cea0dd4ace03a6d3" + Expires: + - Wed, 30 Apr 2025 08:53:44 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - bf6693b35b4566740830843d786c128a9675bbab + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 8CA2:119D:9A5F86:A5AD73:6811E3E9 + X-Served-By: + - cache-fra-etou8220112-FRA + X-Timer: + - S1746002924.883973,VS0,VE172 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '1' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:44 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 52f5131bf4481a9ca075ab040545a8acd55f1b35 + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220176-FRA + X-Timer: + - S1746002924.192519,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '356' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:44 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 85f9d20bac6ba5cae559ab4d282fbbccab0c0ff4 + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220116-FRA + X-Timer: + - S1746002924.334339,VS0,VE2 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.2.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.2.0].yaml new file mode 100644 index 000000000..ddefcd3ec --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.2.0].yaml @@ -0,0 +1,759 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.2.0/examples/item_basic.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.2.0/schema.json\"\n + \ ],\n \"type\": \"Feature\",\n \"id\": \"example-model\",\n \"collection\": + \"ml-model-examples\",\n \"geometry\": {\n \"type\": \"Polygon\",\n \"coordinates\": + [\n [\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ]\n ]\n ]\n },\n \"bbox\": [\n -7.882190080512502,\n + \ 37.13739173208318,\n 27.911651652899923,\n 58.21798141355221\n ],\n + \ \"properties\": {\n \"description\": \"Basic STAC Item with only the + MLM extension and no other extension cross-references.\",\n \"datetime\": + null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n \"end_datetime\": + \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"example-model\",\n \"mlm:tasks\": + [\n \"classification\"\n ],\n \"mlm:architecture\": \"ResNet\",\n + \ \"mlm:input\": [\n {\n \"name\": \"Model with RGB input that + does not refer to any band.\",\n \"bands\": [],\n \"input\": + {\n \"shape\": [\n -1,\n 3,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n }\n }\n ],\n + \ \"mlm:output\": [\n {\n \"name\": \"classification\",\n \"tasks\": + [\n \"classification\"\n ],\n \"result\": {\n \"shape\": + [\n -1,\n 1\n ],\n \"dim_order\": + [\n \"batch\",\n \"class\"\n ],\n \"data_type\": + \"uint8\"\n },\n \"classification_classes\": [\n {\n + \ \"value\": 0,\n \"name\": \"BACKGROUND\",\n \"description\": + \"Background non-city.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 0\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"CITY\",\n \"description\": + \"A city is detected.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 255\n ]\n }\n ]\n + \ }\n ]\n },\n \"assets\": {\n \"model\": {\n \"href\": \"https://huggingface.co/example/model-card\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"Example + model.\",\n \"type\": \"text/html\",\n \"roles\": [\n \"mlm:model\"\n + \ ]\n }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n + \ \"href\": \"./collection.json\",\n \"type\": \"application/json\"\n + \ },\n {\n \"rel\": \"self\",\n \"href\": \"./item_basic.json\",\n + \ \"type\": \"application/geo+json\"\n }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '934' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:44 GMT + ETag: + - W/"4214e4c8a7e047eaff361f43a1e2ce58d4e403d064c4a0a9fc870a0f02f3ffd4" + Expires: + - Wed, 30 Apr 2025 08:53:44 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - d88738ce45c7c7ca88a02eb8b695fa53f146e42e + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 8E2D:1D50CE:2AE04ED:2EA689B:6811E3EC + X-Served-By: + - cache-fra-etou8220034-FRA + X-Timer: + - S1746002924.433248,VS0,VE164 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '1' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:44 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - c781a0966d4eada9d4e33c7e9601a23b9c43f7f9 + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220157-FRA + X-Timer: + - S1746002925.743663,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '357' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:44 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 13aab05cd7ea17b8fc8c9084d6789922b1108b77 + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220106-FRA + X-Timer: + - S1746002925.852991,VS0,VE2 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.3.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.3.0].yaml new file mode 100644 index 000000000..2642bdfff --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_basic.json-1.3.0].yaml @@ -0,0 +1,759 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.3.0/examples/item_basic.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.3.0/schema.json\"\n + \ ],\n \"type\": \"Feature\",\n \"id\": \"example-model\",\n \"collection\": + \"ml-model-examples\",\n \"geometry\": {\n \"type\": \"Polygon\",\n \"coordinates\": + [\n [\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ]\n ]\n ]\n },\n \"bbox\": [\n -7.882190080512502,\n + \ 37.13739173208318,\n 27.911651652899923,\n 58.21798141355221\n ],\n + \ \"properties\": {\n \"description\": \"Basic STAC Item with only the + MLM extension and no other extension cross-references.\",\n \"datetime\": + null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n \"end_datetime\": + \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"example-model\",\n \"mlm:tasks\": + [\n \"classification\"\n ],\n \"mlm:architecture\": \"ResNet\",\n + \ \"mlm:input\": [\n {\n \"name\": \"Model with RGB input that + does not refer to any band.\",\n \"bands\": [],\n \"input\": + {\n \"shape\": [\n -1,\n 3,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n }\n }\n ],\n + \ \"mlm:output\": [\n {\n \"name\": \"classification\",\n \"tasks\": + [\n \"classification\"\n ],\n \"result\": {\n \"shape\": + [\n -1,\n 1\n ],\n \"dim_order\": + [\n \"batch\",\n \"class\"\n ],\n \"data_type\": + \"uint8\"\n },\n \"classification_classes\": [\n {\n + \ \"value\": 0,\n \"name\": \"BACKGROUND\",\n \"description\": + \"Background non-city.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 0\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"CITY\",\n \"description\": + \"A city is detected.\",\n \"color_hint\": [\n 0,\n + \ 0,\n 255\n ]\n }\n ]\n + \ }\n ]\n },\n \"assets\": {\n \"model\": {\n \"href\": \"https://huggingface.co/example/model-card\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"Example + model.\",\n \"type\": \"text/html\",\n \"roles\": [\n \"mlm:model\"\n + \ ]\n }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n + \ \"href\": \"./collection.json\",\n \"type\": \"application/json\"\n + \ },\n {\n \"rel\": \"self\",\n \"href\": \"./item_basic.json\",\n + \ \"type\": \"application/geo+json\"\n }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '934' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:45 GMT + ETag: + - W/"2cdd4c4b8a96681920b5e858cc552b3b19ca2a40e211d9ef29e3863f040782c2" + Expires: + - Wed, 30 Apr 2025 08:53:45 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - c47fe1bd7eb6e2683b454f2e4dab7077cef1508b + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 0F29:112C:2960BD2:2D10907:6811E3EC + X-Served-By: + - cache-fra-etou8220083-FRA + X-Timer: + - S1746002925.933909,VS0,VE204 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '2' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:45 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - c9f3ae052220e429bc406f0dec0d36a862b0f614 + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220069-FRA + X-Timer: + - S1746002925.331941,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '357' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:45 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 3177e6d1a3ce1848ca4ef432ae3e0f1d13ec176e + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220059-FRA + X-Timer: + - S1746002925.456796,VS0,VE1 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.0.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.0.0].yaml new file mode 100644 index 000000000..5deed6eab --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.0.0].yaml @@ -0,0 +1,1194 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.0.0/examples/item_multi_io.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"resnet-18_sentinel-2_all_moco_classification\",\n + \ \"collection\": \"ml-model-examples\",\n \"geometry\": {\n \"type\": + \"Polygon\",\n \"coordinates\": [\n [\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ]\n ]\n ]\n },\n \"bbox\": + [\n -7.882190080512502,\n 37.13739173208318,\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n \"properties\": {\n \"description\": \"Sourced + from torchgeo python library, identifier is ResNet18_Weights.SENTINEL2_ALL_MOCO\",\n + \ \"datetime\": null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n + \ \"end_datetime\": \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"Resnet-18 + Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n \"classification\"\n ],\n + \ \"mlm:architecture\": \"ResNet\",\n \"mlm:framework\": \"pytorch\",\n + \ \"mlm:framework_version\": \"2.1.2+cu121\",\n \"file:size\": 43000000,\n + \ \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": 11700000,\n \"mlm:pretrained_source\": + \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": \"cuda\",\n \"mlm:accelerator_constrained\": + false,\n \"mlm:accelerator_summary\": \"Unknown\",\n \"mlm:batch_size_suggestion\": + 256,\n \"mlm:input\": [\n {\n \"name\": \"RGB\",\n \"bands\": + [\n \"B04\",\n \"B03\",\n \"B02\"\n ],\n + \ \"input\": {\n \"shape\": [\n -1,\n 3,\n + \ 64,\n 64\n ],\n \"dim_order\": [\n + \ \"batch\",\n \"channel\",\n \"height\",\n + \ \"width\"\n ],\n \"data_type\": \"uint16\"\n + \ },\n \"norm_by_channel\": false,\n \"norm_type\": null,\n + \ \"resize_type\": null\n },\n {\n \"name\": \"NDVI\",\n + \ \"bands\": [\n \"B04\",\n \"B08\"\n ],\n + \ \"pre_processing_function\": {\n \"format\": \"gdal-calc\",\n + \ \"expression\": \"(A - B) / (A + B)\"\n },\n \"input\": + {\n \"shape\": [\n -1,\n 1,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"ndvi\",\n \"height\",\n \"width\"\n ],\n + \ \"data_type\": \"uint16\"\n }\n }\n ],\n \"mlm:output\": + [\n {\n \"name\": \"vegetation-segmentation\",\n \"tasks\": + [\n \"semantic-segmentation\"\n ],\n \"result\": {\n + \ \"shape\": [\n -1,\n 1\n ],\n \"dim_order\": + [\n \"batch\",\n \"class\"\n ],\n \"data_type\": + \"uint8\"\n },\n \"classification_classes\": [\n {\n + \ \"value\": 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": null\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 255,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": null\n },\n {\n + \ \"name\": \"inverse-mask\",\n \"tasks\": [\n \"semantic-segmentation\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 1\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"uint8\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": [\n 255,\n + \ 255,\n 255\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 0,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": {\n \"format\": + \"gdal-calc\",\n \"expression\": \"logical_not(A)\"\n }\n + \ }\n ],\n \"raster:bands\": [\n {\n \"name\": \"B02 + - blue\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B03 - + green\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B04 - + red\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B08 - + nir\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n }\n ]\n },\n \"assets\": {\n \"weights\": + {\n \"href\": \"https://huggingface.co/torchgeo/resnet50_sentinel2_rgb_moco/blob/main/resnet50_sentinel2_rgb_moco.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-50 classification model trained on Sentinel-2 RGB imagery with torchgeo.\",\n + \ \"type\": \"application/octet-stream; application=pytorch\",\n \"roles\": + [\n \"mlm:model\",\n \"mlm:weights\"\n ]\n }\n },\n + \ \"links\": [\n {\n \"rel\": \"collection\",\n \"href\": \"./collection.json\",\n + \ \"type\": \"application/json\"\n },\n {\n \"rel\": \"self\",\n + \ \"href\": \"./item_multi_io.json\",\n \"type\": \"application/geo+json\"\n + \ },\n {\n \"rel\": \"derived_from\",\n \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1572' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:45 GMT + ETag: + - W/"b8e68364828f14a588c33c8a9e49382d8e69c2bbe5052e997e7a039f612178aa" + Expires: + - Wed, 30 Apr 2025 08:53:45 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - 60aa8b326adae43581693904cc35d310511edb79 + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 4B88:184A0:8D6654:97D80C:6811E3ED + X-Served-By: + - cache-fra-etou8220024-FRA + X-Timer: + - S1746002926.544023,VS0,VE166 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '2' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:45 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - e1ab6a7104f41a450de16e24abf6f0a5cd19a07b + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220106-FRA + X-Timer: + - S1746002926.835542,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '358' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:45 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 8954eba3dc7f240928f66419c526b8d7e8b8746f + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220178-FRA + X-Timer: + - S1746002926.936132,VS0,VE1 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '353' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:46 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 8ee10dec29ee3c117655023143b03f82c4fbcfc1 + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220040-FRA + X-Timer: + - S1746002926.064746,VS0,VE2 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '0' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:46 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Fastly-Request-ID: + - 0ab859df17885b144bb25675b1710468e436264f + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220062-FRA + X-Timer: + - S1746002926.175468,VS0,VE109 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '337' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:46 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - ea574301be2f279231d07243f6c9787ea2afdedd + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220022-FRA + X-Timer: + - S1746002926.458421,VS0,VE2 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.1.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.1.0].yaml new file mode 100644 index 000000000..f67393032 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.1.0].yaml @@ -0,0 +1,1200 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.1.0/examples/item_multi_io.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.1.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"model-multi-input\",\n \"collection\": + \"ml-model-examples\",\n \"geometry\": {\n \"type\": \"Polygon\",\n \"coordinates\": + [\n [\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ]\n ]\n ]\n },\n \"bbox\": [\n -7.882190080512502,\n + \ 37.13739173208318,\n 27.911651652899923,\n 58.21798141355221\n ],\n + \ \"properties\": {\n \"description\": \"Generic model that employs multiple + input sources with different combination of bands.\",\n \"datetime\": null,\n + \ \"start_datetime\": \"1900-01-01T00:00:00Z\",\n \"end_datetime\": \"9999-12-31T23:59:59Z\",\n + \ \"mlm:name\": \"Resnet-18 Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n + \ \"classification\"\n ],\n \"mlm:architecture\": \"ResNet\",\n + \ \"mlm:framework\": \"pytorch\",\n \"mlm:framework_version\": \"2.1.2+cu121\",\n + \ \"file:size\": 43000000,\n \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": + 11700000,\n \"mlm:pretrained_source\": \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": + \"cuda\",\n \"mlm:accelerator_constrained\": false,\n \"mlm:accelerator_summary\": + \"Unknown\",\n \"mlm:batch_size_suggestion\": 256,\n \"mlm:input\": + [\n {\n \"name\": \"RGB\",\n \"bands\": [\n \"B04\",\n + \ \"B03\",\n \"B02\"\n ],\n \"input\": {\n + \ \"shape\": [\n -1,\n 3,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"uint16\"\n },\n \"norm_by_channel\": + false,\n \"norm_type\": null,\n \"resize_type\": null\n },\n + \ {\n \"name\": \"NDVI\",\n \"bands\": [\n \"B04\",\n + \ \"B08\"\n ],\n \"pre_processing_function\": {\n \"format\": + \"gdal-calc\",\n \"expression\": \"(A - B) / (A + B)\"\n },\n + \ \"input\": {\n \"shape\": [\n -1,\n 1,\n + \ 64,\n 64\n ],\n \"dim_order\": [\n + \ \"batch\",\n \"ndvi\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"uint16\"\n }\n },\n {\n + \ \"name\": \"DEM\",\n \"description\": \"Digital elevation model. + Comes from another source than the Sentinel bands. Therefore, no 'bands' associated + to it.\",\n \"bands\": [],\n \"input\": {\n \"shape\": + [\n -1,\n 1,\n 64,\n 64\n ],\n + \ \"dim_order\": [\n \"batch\",\n \"ndvi\",\n + \ \"height\",\n \"width\"\n ],\n \"data_type\": + \"float32\"\n }\n }\n ],\n \"mlm:output\": [\n {\n + \ \"name\": \"vegetation-segmentation\",\n \"tasks\": [\n \"semantic-segmentation\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 1\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"uint8\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": null\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 255,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": null\n },\n {\n + \ \"name\": \"inverse-mask\",\n \"tasks\": [\n \"semantic-segmentation\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 1\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"uint8\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": [\n 255,\n + \ 255,\n 255\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 0,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": {\n \"format\": + \"gdal-calc\",\n \"expression\": \"logical_not(A)\"\n }\n + \ }\n ],\n \"raster:bands\": [\n {\n \"name\": \"B02 + - blue\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B03 - + green\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B04 - + red\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B08 - + nir\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n }\n ]\n },\n \"assets\": {\n \"weights\": + {\n \"href\": \"https://huggingface.co/torchgeo/resnet50_sentinel2_rgb_moco/blob/main/resnet50_sentinel2_rgb_moco.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-50 classification model trained on Sentinel-2 RGB imagery with torchgeo.\",\n + \ \"type\": \"application/octet-stream; application=pytorch\",\n \"roles\": + [\n \"mlm:model\",\n \"mlm:weights\"\n ]\n }\n },\n + \ \"links\": [\n {\n \"rel\": \"collection\",\n \"href\": \"./collection.json\",\n + \ \"type\": \"application/json\"\n },\n {\n \"rel\": \"self\",\n + \ \"href\": \"./item_multi_io.json\",\n \"type\": \"application/geo+json\"\n + \ },\n {\n \"rel\": \"derived_from\",\n \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1657' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:46 GMT + ETag: + - W/"ec315329c9c65996484f1dab9aa184c19906db9ce90cb2300b05235d2c2faddb" + Expires: + - Wed, 30 Apr 2025 08:53:46 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - 60852f9e73c043dc33915063b3f3495986ca1952 + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - DB77:FDDB1:89859E:93F5CA:6811E3ED + X-Served-By: + - cache-fra-etou8220111-FRA + X-Timer: + - S1746002927.558899,VS0,VE189 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '3' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:46 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 612e2b2c6d6962315cf558c9dd8d132051fbbd8e + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220143-FRA + X-Timer: + - S1746002927.864726,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '359' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:46 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 0d1cc605497f003af298f9686c95a693894bb27e + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220045-FRA + X-Timer: + - S1746002927.979422,VS0,VE1 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '354' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 17b4fdbccdfb010cfbfebe30cc4b6eaf8bfad393 + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220046-FRA + X-Timer: + - S1746002927.091214,VS0,VE2 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '1' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - b4f4a197a7d5f9b79be3559f46485c0e3bb2a4f2 + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220075-FRA + X-Timer: + - S1746002927.202749,VS0,VE1 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '338' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 0756264fd0e2e5c2e043b281e9806e161b07d218 + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220173-FRA + X-Timer: + - S1746002927.292189,VS0,VE1 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.2.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.2.0].yaml new file mode 100644 index 000000000..c8012b511 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.2.0].yaml @@ -0,0 +1,1200 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.2.0/examples/item_multi_io.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.2.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"model-multi-input\",\n \"collection\": + \"ml-model-examples\",\n \"geometry\": {\n \"type\": \"Polygon\",\n \"coordinates\": + [\n [\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ]\n ]\n ]\n },\n \"bbox\": [\n -7.882190080512502,\n + \ 37.13739173208318,\n 27.911651652899923,\n 58.21798141355221\n ],\n + \ \"properties\": {\n \"description\": \"Generic model that employs multiple + input sources with different combination of bands.\",\n \"datetime\": null,\n + \ \"start_datetime\": \"1900-01-01T00:00:00Z\",\n \"end_datetime\": \"9999-12-31T23:59:59Z\",\n + \ \"mlm:name\": \"Resnet-18 Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n + \ \"classification\"\n ],\n \"mlm:architecture\": \"ResNet\",\n + \ \"mlm:framework\": \"pytorch\",\n \"mlm:framework_version\": \"2.1.2+cu121\",\n + \ \"file:size\": 43000000,\n \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": + 11700000,\n \"mlm:pretrained_source\": \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": + \"cuda\",\n \"mlm:accelerator_constrained\": false,\n \"mlm:accelerator_summary\": + \"Unknown\",\n \"mlm:batch_size_suggestion\": 256,\n \"mlm:input\": + [\n {\n \"name\": \"RGB\",\n \"bands\": [\n \"B04\",\n + \ \"B03\",\n \"B02\"\n ],\n \"input\": {\n + \ \"shape\": [\n -1,\n 3,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"uint16\"\n },\n \"norm_by_channel\": + false,\n \"norm_type\": null,\n \"resize_type\": null\n },\n + \ {\n \"name\": \"NDVI\",\n \"bands\": [\n \"B04\",\n + \ \"B08\"\n ],\n \"pre_processing_function\": {\n \"format\": + \"gdal-calc\",\n \"expression\": \"(A - B) / (A + B)\"\n },\n + \ \"input\": {\n \"shape\": [\n -1,\n 1,\n + \ 64,\n 64\n ],\n \"dim_order\": [\n + \ \"batch\",\n \"ndvi\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"uint16\"\n }\n },\n {\n + \ \"name\": \"DEM\",\n \"description\": \"Digital elevation model. + Comes from another source than the Sentinel bands. Therefore, no 'bands' associated + to it.\",\n \"bands\": [],\n \"input\": {\n \"shape\": + [\n -1,\n 1,\n 64,\n 64\n ],\n + \ \"dim_order\": [\n \"batch\",\n \"ndvi\",\n + \ \"height\",\n \"width\"\n ],\n \"data_type\": + \"float32\"\n }\n }\n ],\n \"mlm:output\": [\n {\n + \ \"name\": \"vegetation-segmentation\",\n \"tasks\": [\n \"semantic-segmentation\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 1\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"uint8\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": null\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 255,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": null\n },\n {\n + \ \"name\": \"inverse-mask\",\n \"tasks\": [\n \"semantic-segmentation\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 1\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"uint8\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": [\n 255,\n + \ 255,\n 255\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 0,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": {\n \"format\": + \"gdal-calc\",\n \"expression\": \"logical_not(A)\"\n }\n + \ }\n ],\n \"raster:bands\": [\n {\n \"name\": \"B02 + - blue\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B03 - + green\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B04 - + red\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B08 - + nir\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n }\n ]\n },\n \"assets\": {\n \"weights\": + {\n \"href\": \"https://huggingface.co/torchgeo/resnet50_sentinel2_rgb_moco/blob/main/resnet50_sentinel2_rgb_moco.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-50 classification model trained on Sentinel-2 RGB imagery with torchgeo.\",\n + \ \"type\": \"application/octet-stream; application=pytorch\",\n \"roles\": + [\n \"mlm:model\",\n \"mlm:weights\"\n ]\n }\n },\n + \ \"links\": [\n {\n \"rel\": \"collection\",\n \"href\": \"./collection.json\",\n + \ \"type\": \"application/json\"\n },\n {\n \"rel\": \"self\",\n + \ \"href\": \"./item_multi_io.json\",\n \"type\": \"application/geo+json\"\n + \ },\n {\n \"rel\": \"derived_from\",\n \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1659' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - W/"2615bf01905ff85470ba440bcbe17f54614988b43e703b01bcc24b09a5cba5df" + Expires: + - Wed, 30 Apr 2025 08:53:47 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - 96b38bddced809799ad7c28e40c74626a0516540 + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - A31C:1BD2FE:2AD2784:2E98B62:6811E3EE + X-Served-By: + - cache-fra-etou8220060-FRA + X-Timer: + - S1746002927.379240,VS0,VE167 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '4' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 793b5e819c50caeb7902e42d41e402d7bcf32330 + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220156-FRA + X-Timer: + - S1746002928.680619,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '360' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 68ef10efb4cb5bba88b5a9cf4cc437d8a2fe0616 + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220163-FRA + X-Timer: + - S1746002928.778665,VS0,VE2 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '355' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 1ec804b265fe231750b3793c321964ba4d80c60e + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220117-FRA + X-Timer: + - S1746002928.883978,VS0,VE2 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '2' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:47 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 665a01e30fd27bed3a134d2784f684a9bea7f423 + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220086-FRA + X-Timer: + - S1746002928.985252,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '339' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:48 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 028298b99f1f646e52f32118f290378188cd86a6 + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220064-FRA + X-Timer: + - S1746002928.078278,VS0,VE1 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.3.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.3.0].yaml new file mode 100644 index 000000000..88596d164 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_multi_io.json-1.3.0].yaml @@ -0,0 +1,1204 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.3.0/examples/item_multi_io.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.3.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"model-multi-input\",\n \"collection\": + \"ml-model-examples\",\n \"geometry\": {\n \"type\": \"Polygon\",\n \"coordinates\": + [\n [\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 58.21798141355221\n + \ ],\n [\n 27.911651652899923,\n 37.13739173208318\n + \ ],\n [\n -7.882190080512502,\n 37.13739173208318\n + \ ]\n ]\n ]\n },\n \"bbox\": [\n -7.882190080512502,\n + \ 37.13739173208318,\n 27.911651652899923,\n 58.21798141355221\n ],\n + \ \"properties\": {\n \"description\": \"Generic model that employs multiple + input sources with different combination of bands, and some inputs without + any band at all.\",\n \"datetime\": null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n + \ \"end_datetime\": \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"Resnet-18 + Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n \"classification\"\n ],\n + \ \"mlm:architecture\": \"ResNet\",\n \"mlm:framework\": \"pytorch\",\n + \ \"mlm:framework_version\": \"2.1.2+cu121\",\n \"file:size\": 43000000,\n + \ \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": 11700000,\n \"mlm:pretrained_source\": + \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": \"cuda\",\n \"mlm:accelerator_constrained\": + false,\n \"mlm:accelerator_summary\": \"Unknown\",\n \"mlm:batch_size_suggestion\": + 256,\n \"mlm:input\": [\n {\n \"name\": \"RGB\",\n \"bands\": + [\n \"B04\",\n \"B03\",\n \"B02\"\n ],\n + \ \"input\": {\n \"shape\": [\n -1,\n 3,\n + \ 64,\n 64\n ],\n \"dim_order\": [\n + \ \"batch\",\n \"channel\",\n \"height\",\n + \ \"width\"\n ],\n \"data_type\": \"uint16\"\n + \ },\n \"norm_by_channel\": false,\n \"norm_type\": null,\n + \ \"resize_type\": null\n },\n {\n \"name\": \"NDVI\",\n + \ \"bands\": [\n \"B04\",\n \"B08\"\n ],\n + \ \"pre_processing_function\": {\n \"format\": \"gdal-calc\",\n + \ \"expression\": \"(A - B) / (A + B)\"\n },\n \"input\": + {\n \"shape\": [\n -1,\n 1,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"ndvi\",\n \"height\",\n \"width\"\n ],\n + \ \"data_type\": \"uint16\"\n }\n },\n {\n \"name\": + \"DEM\",\n \"description\": \"Digital elevation model. Comes from another + source than the Sentinel bands. Therefore, no 'bands' associated to it.\",\n + \ \"bands\": [],\n \"input\": {\n \"shape\": [\n -1,\n + \ 1,\n 64,\n 64\n ],\n \"dim_order\": + [\n \"batch\",\n \"ndvi\",\n \"height\",\n + \ \"width\"\n ],\n \"data_type\": \"float32\"\n + \ }\n }\n ],\n \"mlm:output\": [\n {\n \"name\": + \"vegetation-segmentation\",\n \"tasks\": [\n \"semantic-segmentation\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 1\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"uint8\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": null\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 255,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": null\n },\n {\n + \ \"name\": \"inverse-mask\",\n \"tasks\": [\n \"semantic-segmentation\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 1\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"uint8\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"NON_VEGETATION\",\n \"description\": + \"background pixels\",\n \"color_hint\": [\n 255,\n + \ 255,\n 255\n ]\n },\n {\n + \ \"value\": 1,\n \"name\": \"VEGETATION\",\n \"description\": + \"pixels where vegetation was detected\",\n \"color_hint\": [\n + \ 0,\n 0,\n 0\n ]\n }\n + \ ],\n \"post_processing_function\": {\n \"format\": + \"gdal-calc\",\n \"expression\": \"logical_not(A)\"\n }\n + \ }\n ]\n },\n \"assets\": {\n \"weights\": {\n \"href\": + \"https://huggingface.co/torchgeo/resnet50_sentinel2_rgb_moco/blob/main/resnet50_sentinel2_rgb_moco.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-50 classification model trained on Sentinel-2 RGB imagery with torchgeo.\",\n + \ \"type\": \"application/octet-stream; application=pytorch\",\n \"roles\": + [\n \"mlm:model\",\n \"mlm:weights\"\n ],\n \"raster:bands\": + [\n {\n \"name\": \"B02 - blue\",\n \"nodata\": 0,\n + \ \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": + \"B03 - green\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n + \ \"bits_per_sample\": 15,\n \"spatial_resolution\": 10,\n + \ \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n },\n {\n \"name\": \"B04 - red\",\n \"nodata\": + 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": + \"B08 - nir\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n + \ \"bits_per_sample\": 15,\n \"spatial_resolution\": 10,\n + \ \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n }\n ]\n }\n },\n \"links\": [\n {\n \"rel\": + \"collection\",\n \"href\": \"./collection.json\",\n \"type\": \"application/json\"\n + \ },\n {\n \"rel\": \"self\",\n \"href\": \"./item_multi_io.json\",\n + \ \"type\": \"application/geo+json\"\n },\n {\n \"rel\": \"derived_from\",\n + \ \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1688' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:48 GMT + ETag: + - W/"8a7f7c7f98bd63496692bef25107288160f2763f8618048b0a4516885afcdd1d" + Expires: + - Wed, 30 Apr 2025 08:53:48 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - c7fb1566a7b001b7b7c9a719b61918039f2610bb + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - FFE5:11B6:128191D:140375C:6811E3F0 + X-Served-By: + - cache-fra-etou8220095-FRA + X-Timer: + - S1746002928.154086,VS0,VE202 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '5' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:48 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - f806de900570c5302cf282e37cfa39752bdc3ba0 + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220127-FRA + X-Timer: + - S1746002929.503033,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '361' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:48 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - e93d25a3dfb739c905b0c40843dd991f984459ae + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220054-FRA + X-Timer: + - S1746002929.609425,VS0,VE1 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '356' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:48 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 567ba9fbfb6ce06933aa025adaa32c70ac853d03 + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220152-FRA + X-Timer: + - S1746002929.708216,VS0,VE2 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '3' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:48 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 0feb186679670da798be6438865740d1fea5c6c9 + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220152-FRA + X-Timer: + - S1746002929.807178,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '339' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:48 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - d1098e090c1293ff0ba5541890bea8b1f0aff54b + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220042-FRA + X-Timer: + - S1746002929.898510,VS0,VE1 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.0.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.0.0].yaml new file mode 100644 index 000000000..ecbfcfa3b --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.0.0].yaml @@ -0,0 +1,1232 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.0.0/examples/item_raster_bands.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"resnet-18_sentinel-2_all_moco_classification\",\n + \ \"collection\": \"ml-model-examples\",\n \"geometry\": {\n \"type\": + \"Polygon\",\n \"coordinates\": [\n [\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ]\n ]\n ]\n },\n \"bbox\": + [\n -7.882190080512502,\n 37.13739173208318,\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n \"properties\": {\n \"description\": \"Sourced + from torchgeo python library, identifier is ResNet18_Weights.SENTINEL2_ALL_MOCO\",\n + \ \"datetime\": null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n + \ \"end_datetime\": \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"Resnet-18 + Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n \"classification\"\n ],\n + \ \"mlm:architecture\": \"ResNet\",\n \"mlm:framework\": \"pytorch\",\n + \ \"mlm:framework_version\": \"2.1.2+cu121\",\n \"file:size\": 43000000,\n + \ \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": 11700000,\n \"mlm:pretrained_source\": + \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": \"cuda\",\n \"mlm:accelerator_constrained\": + false,\n \"mlm:accelerator_summary\": \"Unknown\",\n \"mlm:batch_size_suggestion\": + 256,\n \"mlm:input\": [\n {\n \"name\": \"13 Band Sentinel-2 + Batch\",\n \"bands\": [\n \"B01\",\n \"B02\",\n \"B03\",\n + \ \"B04\",\n \"B05\",\n \"B06\",\n \"B07\",\n + \ \"B08\",\n \"B8A\",\n \"B09\",\n \"B10\",\n + \ \"B11\",\n \"B12\"\n ],\n \"input\": {\n + \ \"shape\": [\n -1,\n 13,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n },\n \"norm_type\": + null,\n \"resize_type\": null,\n \"pre_processing_function\": + {\n \"format\": \"python\",\n \"expression\": \"torchgeo.datamodules.eurosat.EuroSATDataModule.collate_fn\"\n + \ }\n }\n ],\n \"mlm:output\": [\n {\n \"name\": + \"classification\",\n \"tasks\": [\n \"classification\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 10\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"float32\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"Annual Crop\",\n \"description\": null,\n + \ \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 1,\n \"name\": + \"Forest\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 2,\n \"name\": \"Herbaceous + Vegetation\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 3,\n \"name\": + \"Highway\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 4,\n \"name\": \"Industrial + Buildings\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 5,\n \"name\": \"Pasture\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n },\n {\n \"value\": + 6,\n \"name\": \"Permanent Crop\",\n \"description\": + null,\n \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 7,\n \"name\": + \"Residential Buildings\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 8,\n \"name\": + \"River\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 9,\n \"name\": \"SeaLake\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n }\n ],\n \"post_processing_function\": + null\n }\n ],\n \"raster:bands\": [\n {\n \"name\": + \"B01\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B02\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B03\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B04\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B05\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B06\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B07\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B08\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B8A\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B09\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B10\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B11\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B12\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n }\n ]\n },\n \"assets\": {\n \"weights\": + {\n \"href\": \"https://huggingface.co/torchgeo/resnet18_sentinel2_all_moco/resolve/main/resnet18_sentinel2_all_moco-59bfdff9.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-18 classification model trained on normalized Sentinel-2 imagery with + Eurosat landcover labels with torchgeo\",\n \"type\": \"application/octet-stream; + application=pytorch\",\n \"roles\": [\n \"mlm:model\",\n \"mlm:weights\"\n + \ ]\n },\n \"source_code\": {\n \"href\": \"https://github.com/microsoft/torchgeo/blob/61efd2e2c4df7ebe3bd03002ebbaeaa3cfe9885a/torchgeo/models/resnet.py#L207\",\n + \ \"title\": \"Model implementation.\",\n \"description\": \"Source + code to run the model.\",\n \"type\": \"text/x-python\",\n \"roles\": + [\n \"mlm:model\",\n \"code\",\n \"metadata\"\n ]\n + \ }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n \"href\": + \"./collection.json\",\n \"type\": \"application/json\"\n },\n {\n + \ \"rel\": \"self\",\n \"href\": \"./item_raster_bands.json\",\n + \ \"type\": \"application/geo+json\"\n },\n {\n \"rel\": \"derived_from\",\n + \ \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1785' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:49 GMT + ETag: + - W/"27c40ee3df9fd2dbdd00cea8e1d17b857c904ad289a6c2c0a9fe0cf407d24bf0" + Expires: + - Wed, 30 Apr 2025 08:53:49 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - 42924440e215af557ead5eb020696d90b55955e4 + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 9532:116B:1004257:11531F8:6811E3F0 + X-Served-By: + - cache-fra-etou8220132-FRA + X-Timer: + - S1746002929.984751,VS0,VE162 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '6' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:49 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 708cb79a28fa037030bc1e5de3f35490d37104da + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220045-FRA + X-Timer: + - S1746002929.246087,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '362' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:49 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '2' + X-Fastly-Request-ID: + - 764a946d642365a7a59b2e3993b21439a1688631 + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220163-FRA + X-Timer: + - S1746002929.351571,VS0,VE0 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '356' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:49 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 4138c397ae89b08d84976e1a791abd866a9bbcd9 + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220149-FRA + X-Timer: + - S1746002929.450482,VS0,VE3 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '3' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:49 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - afaeb47490c7efd66feea509e5725cc12c46f39b + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220111-FRA + X-Timer: + - S1746002930.558707,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '340' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:49 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 1c079335dbdc15d572963f7af233e656c95abe7e + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220080-FRA + X-Timer: + - S1746002930.653546,VS0,VE1 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.1.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.1.0].yaml new file mode 100644 index 000000000..b7cdb4409 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.1.0].yaml @@ -0,0 +1,1232 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.1.0/examples/item_raster_bands.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.1.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"resnet-18_sentinel-2_all_moco_classification\",\n + \ \"collection\": \"ml-model-examples\",\n \"geometry\": {\n \"type\": + \"Polygon\",\n \"coordinates\": [\n [\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ]\n ]\n ]\n },\n \"bbox\": + [\n -7.882190080512502,\n 37.13739173208318,\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n \"properties\": {\n \"description\": \"Sourced + from torchgeo python library, identifier is ResNet18_Weights.SENTINEL2_ALL_MOCO\",\n + \ \"datetime\": null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n + \ \"end_datetime\": \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"Resnet-18 + Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n \"classification\"\n ],\n + \ \"mlm:architecture\": \"ResNet\",\n \"mlm:framework\": \"pytorch\",\n + \ \"mlm:framework_version\": \"2.1.2+cu121\",\n \"file:size\": 43000000,\n + \ \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": 11700000,\n \"mlm:pretrained_source\": + \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": \"cuda\",\n \"mlm:accelerator_constrained\": + false,\n \"mlm:accelerator_summary\": \"Unknown\",\n \"mlm:batch_size_suggestion\": + 256,\n \"mlm:input\": [\n {\n \"name\": \"13 Band Sentinel-2 + Batch\",\n \"bands\": [\n \"B01\",\n \"B02\",\n \"B03\",\n + \ \"B04\",\n \"B05\",\n \"B06\",\n \"B07\",\n + \ \"B08\",\n \"B8A\",\n \"B09\",\n \"B10\",\n + \ \"B11\",\n \"B12\"\n ],\n \"input\": {\n + \ \"shape\": [\n -1,\n 13,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n },\n \"norm_type\": + null,\n \"resize_type\": null,\n \"pre_processing_function\": + {\n \"format\": \"python\",\n \"expression\": \"torchgeo.datamodules.eurosat.EuroSATDataModule.collate_fn\"\n + \ }\n }\n ],\n \"mlm:output\": [\n {\n \"name\": + \"classification\",\n \"tasks\": [\n \"classification\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 10\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"float32\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"Annual Crop\",\n \"description\": null,\n + \ \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 1,\n \"name\": + \"Forest\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 2,\n \"name\": \"Herbaceous + Vegetation\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 3,\n \"name\": + \"Highway\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 4,\n \"name\": \"Industrial + Buildings\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 5,\n \"name\": \"Pasture\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n },\n {\n \"value\": + 6,\n \"name\": \"Permanent Crop\",\n \"description\": + null,\n \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 7,\n \"name\": + \"Residential Buildings\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 8,\n \"name\": + \"River\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 9,\n \"name\": \"SeaLake\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n }\n ],\n \"post_processing_function\": + null\n }\n ],\n \"raster:bands\": [\n {\n \"name\": + \"B01\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B02\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B03\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B04\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B05\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B06\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B07\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B08\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B8A\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B09\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B10\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B11\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B12\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n }\n ]\n },\n \"assets\": {\n \"weights\": + {\n \"href\": \"https://huggingface.co/torchgeo/resnet18_sentinel2_all_moco/resolve/main/resnet18_sentinel2_all_moco-59bfdff9.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-18 classification model trained on normalized Sentinel-2 imagery with + Eurosat landcover labels with torchgeo\",\n \"type\": \"application/octet-stream; + application=pytorch\",\n \"roles\": [\n \"mlm:model\",\n \"mlm:weights\"\n + \ ]\n },\n \"source_code\": {\n \"href\": \"https://github.com/microsoft/torchgeo/blob/61efd2e2c4df7ebe3bd03002ebbaeaa3cfe9885a/torchgeo/models/resnet.py#L207\",\n + \ \"title\": \"Model implementation.\",\n \"description\": \"Source + code to run the model.\",\n \"type\": \"text/x-python\",\n \"roles\": + [\n \"mlm:model\",\n \"code\",\n \"metadata\"\n ]\n + \ }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n \"href\": + \"./collection.json\",\n \"type\": \"application/json\"\n },\n {\n + \ \"rel\": \"self\",\n \"href\": \"./item_raster_bands.json\",\n + \ \"type\": \"application/geo+json\"\n },\n {\n \"rel\": \"derived_from\",\n + \ \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1786' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:49 GMT + ETag: + - W/"5c22d84a039a443127d9a87f0dbfdee885ebebdcfd2e1ee13a7ade60744f8d7f" + Expires: + - Wed, 30 Apr 2025 08:53:49 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - 7d02b19c5255e71303e5a9a17d3ca4cbf586f3d1 + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 8E28:119D:9A69F9:A5B877:6811E3EA + X-Served-By: + - cache-fra-etou8220093-FRA + X-Timer: + - S1746002930.731532,VS0,VE228 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '7' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:50 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 64619ac3a14801dae3ba320141c3292efbd07f0f + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220146-FRA + X-Timer: + - S1746002930.135895,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '362' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:50 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 56da344255d88d52ca78446397cbbfb293a7c6a1 + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220174-FRA + X-Timer: + - S1746002930.255407,VS0,VE3 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '357' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:50 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 90a0f8fd55b659570222b66862330ef3a01285da + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220131-FRA + X-Timer: + - S1746002930.354278,VS0,VE2 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '4' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:50 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - fba5b86249978d66056d486954749b1ea8239951 + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220024-FRA + X-Timer: + - S1746002930.455185,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '341' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:50 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - d5af0da6e63063b949d9f49e364f6f7fc6265f84 + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220076-FRA + X-Timer: + - S1746002931.549027,VS0,VE2 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.2.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.2.0].yaml new file mode 100644 index 000000000..f5ca376e6 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.2.0].yaml @@ -0,0 +1,1232 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.2.0/examples/item_raster_bands.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.2.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"resnet-18_sentinel-2_all_moco_classification\",\n + \ \"collection\": \"ml-model-examples\",\n \"geometry\": {\n \"type\": + \"Polygon\",\n \"coordinates\": [\n [\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ]\n ]\n ]\n },\n \"bbox\": + [\n -7.882190080512502,\n 37.13739173208318,\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n \"properties\": {\n \"description\": \"Sourced + from torchgeo python library, identifier is ResNet18_Weights.SENTINEL2_ALL_MOCO\",\n + \ \"datetime\": null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n + \ \"end_datetime\": \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"Resnet-18 + Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n \"classification\"\n ],\n + \ \"mlm:architecture\": \"ResNet\",\n \"mlm:framework\": \"pytorch\",\n + \ \"mlm:framework_version\": \"2.1.2+cu121\",\n \"file:size\": 43000000,\n + \ \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": 11700000,\n \"mlm:pretrained_source\": + \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": \"cuda\",\n \"mlm:accelerator_constrained\": + false,\n \"mlm:accelerator_summary\": \"Unknown\",\n \"mlm:batch_size_suggestion\": + 256,\n \"mlm:input\": [\n {\n \"name\": \"13 Band Sentinel-2 + Batch\",\n \"bands\": [\n \"B01\",\n \"B02\",\n \"B03\",\n + \ \"B04\",\n \"B05\",\n \"B06\",\n \"B07\",\n + \ \"B08\",\n \"B8A\",\n \"B09\",\n \"B10\",\n + \ \"B11\",\n \"B12\"\n ],\n \"input\": {\n + \ \"shape\": [\n -1,\n 13,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n },\n \"norm_type\": + null,\n \"resize_type\": null,\n \"pre_processing_function\": + {\n \"format\": \"python\",\n \"expression\": \"torchgeo.datamodules.eurosat.EuroSATDataModule.collate_fn\"\n + \ }\n }\n ],\n \"mlm:output\": [\n {\n \"name\": + \"classification\",\n \"tasks\": [\n \"classification\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 10\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"float32\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"Annual Crop\",\n \"description\": null,\n + \ \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 1,\n \"name\": + \"Forest\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 2,\n \"name\": \"Herbaceous + Vegetation\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 3,\n \"name\": + \"Highway\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 4,\n \"name\": \"Industrial + Buildings\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 5,\n \"name\": \"Pasture\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n },\n {\n \"value\": + 6,\n \"name\": \"Permanent Crop\",\n \"description\": + null,\n \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 7,\n \"name\": + \"Residential Buildings\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 8,\n \"name\": + \"River\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 9,\n \"name\": \"SeaLake\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n }\n ],\n \"post_processing_function\": + null\n }\n ],\n \"raster:bands\": [\n {\n \"name\": + \"B01\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B02\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B03\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B04\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B05\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B06\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B07\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B08\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B8A\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B09\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B10\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B11\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": \"B12\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n }\n ]\n },\n \"assets\": {\n \"weights\": + {\n \"href\": \"https://huggingface.co/torchgeo/resnet18_sentinel2_all_moco/resolve/main/resnet18_sentinel2_all_moco-59bfdff9.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-18 classification model trained on normalized Sentinel-2 imagery with + Eurosat landcover labels with torchgeo\",\n \"type\": \"application/octet-stream; + application=pytorch\",\n \"roles\": [\n \"mlm:model\",\n \"mlm:weights\"\n + \ ]\n },\n \"source_code\": {\n \"href\": \"https://github.com/microsoft/torchgeo/blob/61efd2e2c4df7ebe3bd03002ebbaeaa3cfe9885a/torchgeo/models/resnet.py#L207\",\n + \ \"title\": \"Model implementation.\",\n \"description\": \"Source + code to run the model.\",\n \"type\": \"text/x-python\",\n \"roles\": + [\n \"mlm:model\",\n \"code\",\n \"metadata\"\n ]\n + \ }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n \"href\": + \"./collection.json\",\n \"type\": \"application/json\"\n },\n {\n + \ \"rel\": \"self\",\n \"href\": \"./item_raster_bands.json\",\n + \ \"type\": \"application/geo+json\"\n },\n {\n \"rel\": \"derived_from\",\n + \ \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1788' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:50 GMT + ETag: + - W/"610fc710cdb0bf17cbf12e94e38d37a3c0111ca0df0c43ce55494f377c599a06" + Expires: + - Wed, 30 Apr 2025 08:53:50 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - faf2b1cf573dfb9718ebf90228830b598b126a4f + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 9218:112C:29614DE:2D11292:6811E3F2 + X-Served-By: + - cache-fra-etou8220143-FRA + X-Timer: + - S1746002931.636231,VS0,VE250 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '7' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 116508e56e051bcfe7643603eaacfa375680f997 + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220034-FRA + X-Timer: + - S1746002931.058296,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '363' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - d8ac3f8ec147e9347656651254db60b62600c79f + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220145-FRA + X-Timer: + - S1746002931.164839,VS0,VE2 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '358' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 6846c831ed987c00ff57b367aa6fb3b155feeba3 + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220107-FRA + X-Timer: + - S1746002931.270275,VS0,VE1 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '5' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 621c46e23b749c062dd42088f4b1753f39c89c75 + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220135-FRA + X-Timer: + - S1746002931.364711,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '342' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 8aa1e689200e323ce6042a89abe6c327347ed31e + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220037-FRA + X-Timer: + - S1746002931.458632,VS0,VE1 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.3.0].yaml b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.3.0].yaml new file mode 100644 index 000000000..a3c0321d0 --- /dev/null +++ b/tests/extensions/cassettes/test_mlm/test_migrate[https---raw.githubusercontent.com-stac-extensions-mlm-refs-tags-v{version}-examples-item_raster_bands.json-1.3.0].yaml @@ -0,0 +1,1239 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/v1.3.0/examples/item_raster_bands.json + response: + body: + string: "{\n \"stac_version\": \"1.0.0\",\n \"stac_extensions\": [\n \"https://crim-ca.github.io/mlm-extension/v1.3.0/schema.json\",\n + \ \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\",\n \"https://stac-extensions.github.io/file/v1.0.0/schema.json\",\n + \ \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n ],\n + \ \"type\": \"Feature\",\n \"id\": \"resnet-18_sentinel-2_all_moco_classification\",\n + \ \"collection\": \"ml-model-examples\",\n \"geometry\": {\n \"type\": + \"Polygon\",\n \"coordinates\": [\n [\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n [\n 27.911651652899923,\n + \ 37.13739173208318\n ],\n [\n -7.882190080512502,\n + \ 37.13739173208318\n ]\n ]\n ]\n },\n \"bbox\": + [\n -7.882190080512502,\n 37.13739173208318,\n 27.911651652899923,\n + \ 58.21798141355221\n ],\n \"properties\": {\n \"description\": \"Sourced + from torchgeo python library, identifier is ResNet18_Weights.SENTINEL2_ALL_MOCO\",\n + \ \"datetime\": null,\n \"start_datetime\": \"1900-01-01T00:00:00Z\",\n + \ \"end_datetime\": \"9999-12-31T23:59:59Z\",\n \"mlm:name\": \"Resnet-18 + Sentinel-2 ALL MOCO\",\n \"mlm:tasks\": [\n \"classification\"\n ],\n + \ \"mlm:architecture\": \"ResNet\",\n \"mlm:framework\": \"pytorch\",\n + \ \"mlm:framework_version\": \"2.1.2+cu121\",\n \"file:size\": 43000000,\n + \ \"mlm:memory_size\": 1,\n \"mlm:total_parameters\": 11700000,\n \"mlm:pretrained_source\": + \"EuroSat Sentinel-2\",\n \"mlm:accelerator\": \"cuda\",\n \"mlm:accelerator_constrained\": + false,\n \"mlm:accelerator_summary\": \"Unknown\",\n \"mlm:batch_size_suggestion\": + 256,\n \"mlm:input\": [\n {\n \"name\": \"13 Band Sentinel-2 + Batch\",\n \"bands\": [\n \"B01\",\n \"B02\",\n \"B03\",\n + \ \"B04\",\n \"B05\",\n \"B06\",\n \"B07\",\n + \ \"B08\",\n \"B8A\",\n \"B09\",\n \"B10\",\n + \ \"B11\",\n \"B12\"\n ],\n \"input\": {\n + \ \"shape\": [\n -1,\n 13,\n 64,\n + \ 64\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"channel\",\n \"height\",\n \"width\"\n + \ ],\n \"data_type\": \"float32\"\n },\n \"norm_type\": + null,\n \"resize_type\": null,\n \"pre_processing_function\": + {\n \"format\": \"python\",\n \"expression\": \"torchgeo.datamodules.eurosat.EuroSATDataModule.collate_fn\"\n + \ }\n }\n ],\n \"mlm:output\": [\n {\n \"name\": + \"classification\",\n \"tasks\": [\n \"classification\"\n + \ ],\n \"result\": {\n \"shape\": [\n -1,\n + \ 10\n ],\n \"dim_order\": [\n \"batch\",\n + \ \"class\"\n ],\n \"data_type\": \"float32\"\n + \ },\n \"classification_classes\": [\n {\n \"value\": + 0,\n \"name\": \"Annual Crop\",\n \"description\": null,\n + \ \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 1,\n \"name\": + \"Forest\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 2,\n \"name\": \"Herbaceous + Vegetation\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 3,\n \"name\": + \"Highway\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 4,\n \"name\": \"Industrial + Buildings\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 5,\n \"name\": \"Pasture\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n },\n {\n \"value\": + 6,\n \"name\": \"Permanent Crop\",\n \"description\": + null,\n \"title\": null,\n \"color_hint\": null,\n \"nodata\": + false\n },\n {\n \"value\": 7,\n \"name\": + \"Residential Buildings\",\n \"description\": null,\n \"title\": + null,\n \"color_hint\": null,\n \"nodata\": false\n + \ },\n {\n \"value\": 8,\n \"name\": + \"River\",\n \"description\": null,\n \"title\": null,\n + \ \"color_hint\": null,\n \"nodata\": false\n },\n + \ {\n \"value\": 9,\n \"name\": \"SeaLake\",\n + \ \"description\": null,\n \"title\": null,\n \"color_hint\": + null,\n \"nodata\": false\n }\n ],\n \"post_processing_function\": + null\n }\n ]\n },\n \"assets\": {\n \"weights\": {\n \"href\": + \"https://huggingface.co/torchgeo/resnet18_sentinel2_all_moco/resolve/main/resnet18_sentinel2_all_moco-59bfdff9.pth\",\n + \ \"title\": \"Pytorch weights checkpoint\",\n \"description\": \"A + Resnet-18 classification model trained on normalized Sentinel-2 imagery with + Eurosat landcover labels with torchgeo\",\n \"type\": \"application/octet-stream; + application=pytorch\",\n \"roles\": [\n \"mlm:model\",\n \"mlm:weights\"\n + \ ],\n \"raster:bands\": [\n {\n \"name\": \"B01\",\n + \ \"nodata\": 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": + 15,\n \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n + \ \"offset\": 0,\n \"unit\": \"m\"\n },\n {\n + \ \"name\": \"B02\",\n \"nodata\": 0,\n \"data_type\": + \"uint16\",\n \"bits_per_sample\": 15,\n \"spatial_resolution\": + 10,\n \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n },\n {\n \"name\": \"B03\",\n \"nodata\": + 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 10,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": + \"B04\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n + \ \"bits_per_sample\": 15,\n \"spatial_resolution\": 10,\n + \ \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n },\n {\n \"name\": \"B05\",\n \"nodata\": + 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": + \"B06\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n + \ \"bits_per_sample\": 15,\n \"spatial_resolution\": 20,\n + \ \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n },\n {\n \"name\": \"B07\",\n \"nodata\": + 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": + \"B08\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n + \ \"bits_per_sample\": 15,\n \"spatial_resolution\": 10,\n + \ \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n },\n {\n \"name\": \"B8A\",\n \"nodata\": + 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": + \"B09\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n + \ \"bits_per_sample\": 15,\n \"spatial_resolution\": 60,\n + \ \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n },\n {\n \"name\": \"B10\",\n \"nodata\": + 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 60,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n },\n {\n \"name\": + \"B11\",\n \"nodata\": 0,\n \"data_type\": \"uint16\",\n + \ \"bits_per_sample\": 15,\n \"spatial_resolution\": 20,\n + \ \"scale\": 0.0001,\n \"offset\": 0,\n \"unit\": + \"m\"\n },\n {\n \"name\": \"B12\",\n \"nodata\": + 0,\n \"data_type\": \"uint16\",\n \"bits_per_sample\": 15,\n + \ \"spatial_resolution\": 20,\n \"scale\": 0.0001,\n \"offset\": + 0,\n \"unit\": \"m\"\n }\n ]\n },\n \"source_code\": + {\n \"href\": \"https://github.com/microsoft/torchgeo/blob/61efd2e2c4df7ebe3bd03002ebbaeaa3cfe9885a/torchgeo/models/resnet.py#L207\",\n + \ \"title\": \"Model implementation.\",\n \"description\": \"Source + code to run the model.\",\n \"type\": \"text/x-python\",\n \"roles\": + [\n \"mlm:source_code\",\n \"code\",\n \"metadata\"\n + \ ]\n }\n },\n \"links\": [\n {\n \"rel\": \"collection\",\n + \ \"href\": \"./collection.json\",\n \"type\": \"application/json\"\n + \ },\n {\n \"rel\": \"self\",\n \"href\": \"./item_raster_bands.json\",\n + \ \"type\": \"application/geo+json\"\n },\n {\n \"rel\": \"derived_from\",\n + \ \"href\": \"https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a\",\n + \ \"type\": \"application/json\",\n \"ml-aoi:split\": \"train\"\n + \ }\n ]\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Cache-Control: + - max-age=300 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1803' + Content-Security-Policy: + - default-src 'none'; style-src 'unsafe-inline'; sandbox + Content-Type: + - text/plain; charset=utf-8 + Cross-Origin-Resource-Policy: + - cross-origin + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - W/"a27ee1f30298ca82fea5f599426403c50df7b1da816b19a0b602af5649b1531b" + Expires: + - Wed, 30 Apr 2025 08:53:51 GMT + Source-Age: + - '0' + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization,Accept-Encoding,Origin + Via: + - 1.1 varnish + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Content-Type-Options: + - nosniff + X-Fastly-Request-ID: + - 3990d560c254fad46e7869359cc67e9ac0180f01 + X-Frame-Options: + - deny + X-GitHub-Request-Id: + - 4FE1:242658:8C60AA:96D16F:6811E3F3 + X-Served-By: + - cache-fra-etou8220110-FRA + X-Timer: + - S1746002932.545537,VS0,VE179 + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/mlm/v1.4.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\",\n \"title\": + \"Machine Learning Model STAC Extension Schema\",\n \"description\": \"This + object represents the metadata for a Machine Learning Model (MLM) used in + STAC documents.\",\n \"$comment\": \"Use 'allOf+if/then' for each 'type' + to allow implementations to report more specific messages about the exact + case in error (if any). Using only a 'oneOf/allOf' with the 'type' caused + any incompatible 'type' to be reported first with a minimal and poorly described + error by 'pystac'.\",\n \"allOf\": [\n {\n \"description\": \"This + is the schema for STAC extension MLM in Items.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"description\": + \"Schema to validate the MLM fields permitted under Item properties or Assets + properties.\",\n \"type\": \"object\",\n \"required\": + [\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"properties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Item properties.\",\n + \ \"$ref\": \"#/$defs/mlmItemFields\"\n },\n \"assets\": + {\n \"additionalProperties\": {\n \"$comment\": + \"Schema to validate the MLM fields permitted under Asset properties.\",\n + \ \"$ref\": \"#/$defs/mlmAssetFields\"\n }\n + \ }\n }\n },\n {\n \"$ref\": + \"#/$defs/stac_extensions_mlm\"\n },\n {\n \"$comment\": + \"Schema to validate cross-references of bands between MLM inputs and any + 'bands'-compliant section describing them using another STAC definition.\",\n + \ \"$ref\": \"#/$defs/AnyBandsRef\"\n },\n {\n + \ \"$comment\": \"Schema to validate that at least one Asset defines + a model role.\",\n \"$ref\": \"#/$defs/AssetModelRoleMinimumOneDefinition\"\n + \ },\n {\n \"$comment\": \"Schema to validate + that the Asset model properties are mutually exclusive to the model role.\",\n + \ \"$ref\": \"#/$defs/AssetModelRequiredProperties\"\n }\n + \ ]\n }\n },\n {\n \"description\": \"This is the schema + for STAC extension MLM in Collections.\",\n \"if\": {\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n }\n }\n },\n + \ \"then\": {\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"properties\": {\n \"summaries\": {\n + \ \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/$defs/mlmCollectionFields\"\n }\n + \ },\n \"assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/$defs/mlmAssetFields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/$defs/mlmAssetFields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_mlm\"\n + \ }\n ]\n }\n }\n ],\n \"$defs\": {\n \"stac_extensions_mlm\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/mlm/v1.4.0/schema.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/eo/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_item\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition, + which describes the STAC-Item field named 'properties' containing 'eo:bands' + as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"properties\": {\n \"required\": + [\n \"eo:bands\"\n ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": + {\n \"type\": \"object\"\n }\n }\n + \ }\n }\n }\n },\n \"stac_extensions_eo_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Asset + containing 'eo:bands' as described in [https://github.com/stac-extensions/eo#item-properties-or-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"eo:bands\"\n + \ ],\n \"properties\": {\n \"eo:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\"\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_extensions_raster\": {\n \"type\": + \"object\",\n \"required\": [\n \"stac_extensions\"\n ],\n + \ \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"string\",\n + \ \"pattern\": \"https://stac-extensions\\\\.github\\\\.io/raster/v1(\\\\.[0-9]+){2}/schema\\\\.json\"\n + \ }\n }\n }\n },\n \"stac_extensions_raster_bands_asset\": + {\n \"required\": [\n \"assets\"\n ],\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + at least one Asset field containing 'raster:bands' as described in [https://github.com/stac-extensions/raster/tree/v1.1.0#item-asset-fields].\",\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"required\": [\n \"raster:bands\"\n + \ ],\n \"properties\": {\n \"raster:bands\": + {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"$comment\": \"Raster + extension does not explicitly indicate a 'name', but one is needed for MLM.\",\n + \ \"type\": \"object\",\n \"required\": + [\n \"name\"\n ],\n \"properties\": + {\n \"name\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n }\n }\n + \ }\n }\n }\n }\n }\n + \ }\n }\n },\n \"stac_version_1.1\": {\n \"$comment\": + \"Requirement for STAC 1.1 or above.\",\n \"type\": \"object\",\n \"required\": + [\n \"stac_version\"\n ],\n \"properties\": {\n \"stac_version\": + {\n \"pattern\": \"1\\\\.[1-9][0-9]*\\\\.[0-9]+(-.*)?\"\n }\n + \ }\n },\n \"fields\": {\n \"description\": \"All possible + MLM fields regardless of the level they apply (Collection, Item, Asset, Link).\",\n + \ \"type\": \"object\",\n \"properties\": {\n \"mlm:name\": + {\n \"$ref\": \"#/$defs/mlm:name\"\n },\n \"mlm:architecture\": + {\n \"$ref\": \"#/$defs/mlm:architecture\"\n },\n \"mlm:tasks\": + {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n \"mlm:framework\": + {\n \"$ref\": \"#/$defs/mlm:framework\"\n },\n \"mlm:framework_version\": + {\n \"$ref\": \"#/$defs/mlm:framework_version\"\n },\n \"mlm:memory_size\": + {\n \"$ref\": \"#/$defs/mlm:memory_size\"\n },\n \"mlm:total_parameters\": + {\n \"$ref\": \"#/$defs/mlm:total_parameters\"\n },\n \"mlm:pretrained\": + {\n \"$ref\": \"#/$defs/mlm:pretrained\"\n },\n \"mlm:pretrained_source\": + {\n \"$ref\": \"#/$defs/mlm:pretrained_source\"\n },\n \"mlm:batch_size_suggestion\": + {\n \"$ref\": \"#/$defs/mlm:batch_size_suggestion\"\n },\n + \ \"mlm:accelerator\": {\n \"$ref\": \"#/$defs/mlm:accelerator\"\n + \ },\n \"mlm:accelerator_constrained\": {\n \"$ref\": + \"#/$defs/mlm:accelerator_constrained\"\n },\n \"mlm:accelerator_summary\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_summary\"\n },\n \"mlm:accelerator_count\": + {\n \"$ref\": \"#/$defs/mlm:accelerator_count\"\n },\n \"mlm:input\": + {\n \"$ref\": \"#/$defs/mlm:input\"\n },\n \"mlm:output\": + {\n \"$ref\": \"#/$defs/mlm:output\"\n },\n \"mlm:hyperparameters\": + {\n \"$ref\": \"#/$defs/mlm:hyperparameters\"\n },\n \"mlm:artifact_type\": + {\n \"$ref\": \"#/$defs/mlm:artifact_type\"\n },\n \"mlm:compile_method\": + {\n \"$ref\": \"#/$defs/mlm:compile_method\"\n }\n },\n + \ \"$comment\": \"Allow properties not defined by MLM prefix to work with + other extensions and attributes, but disallow undefined MLM fields.\",\n \"patternProperties\": + {\n \"^(?!mlm:)\": {}\n },\n \"additionalProperties\": false\n + \ },\n \"mlmCollectionFields\": {\n \"description\": \"Schema to + validate the MLM fields permitted under Collection summaries.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Collection summaries.\",\n \"type\": \"object\",\n \"required\": + []\n },\n {\n \"description\": \"Fields that are disallowed + under the Collection summaries.\",\n \"not\": {\n \"required\": + [\n \"mlm:input\",\n \"mlm:output\",\n \"mlm:artifact_type\",\n + \ \"mlm:compile_method\"\n ]\n }\n },\n + \ {\n \"description\": \"Field with known definitions that + must be validated.\",\n \"$ref\": \"#/$defs/fields\"\n }\n + \ ]\n },\n \"mlmItemFields\": {\n \"description\": \"Schema + to validate the MLM fields permitted under Item properties.\",\n \"allOf\": + [\n {\n \"description\": \"Fields that are mandatory under + the Item properties.\",\n \"required\": [\n \"mlm:name\",\n + \ \"mlm:architecture\",\n \"mlm:tasks\",\n \"mlm:input\",\n + \ \"mlm:output\"\n ]\n },\n {\n \"description\": + \"Fields that are disallowed under the Item properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\"required\": + [\"mlm:artifact_type\"]},\n {\"required\": [\"mlm:compile_method\"]}\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlmAssetFields\": {\n + \ \"description\": \"Schema to validate the MLM fields permitted under + Assets properties.\",\n \"allOf\": [\n {\n \"description\": + \"Fields that are disallowed under the Asset properties.\",\n \"$comment\": + \"Particularity of the 'not/required' approach: they must be tested one by + one. Otherwise, it validates that they are all (simultaneously) not present.\",\n + \ \"not\": {\n \"anyOf\": [\n {\n \"required\": + [\n \"mlm:name\"\n ]\n },\n {\n + \ \"required\": [\n \"mlm:input\"\n ]\n + \ },\n {\n \"required\": [\n \"mlm:output\"\n + \ ]\n },\n {\n \"required\": + [\n \"mlm:hyperparameters\"\n ]\n }\n + \ ]\n }\n },\n {\n \"description\": + \"Field with known definitions that must be validated.\",\n \"$ref\": + \"#/$defs/fields\"\n }\n ]\n },\n \"mlm:name\": {\n \"type\": + \"string\",\n \"pattern\": \"^[a-zA-Z][a-zA-Z0-9_.\\\\-\\\\s]+[a-zA-Z0-9]$\"\n + \ },\n \"mlm:architecture\": {\n \"type\": \"string\",\n \"title\": + \"Model Architecture\",\n \"description\": \"A descriptive name of the + model architecture, typically a common name from the literature.\",\n \"examples\": + [\n \"ResNet\",\n \"VGG\",\n \"GAN\",\n \"Vision + Transformer\"\n ]\n },\n \"mlm:framework\": {\n \"title\": + \"Name of the machine learning framework used.\",\n \"anyOf\": [\n {\n + \ \"$comment\": \"Add more entries here as needed, and repeat them + in the README.\",\n \"description\": \"Notable predefined framework + names.\",\n \"type\": \"string\",\n \"enum\": [\n \"PyTorch\",\n + \ \"TensorFlow\",\n \"scikit-learn\",\n \"Hugging + Face\",\n \"Keras\",\n \"ONNX\",\n \"rgee\",\n + \ \"spatialRF\",\n \"JAX\",\n \"MXNet\",\n + \ \"Caffe\",\n \"PyMC\",\n \"Weka\"\n ]\n + \ },\n {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"pattern\": \"^(?=[^\\\\s._\\\\-]).*[^\\\\s._\\\\-]$\",\n \"description\": + \"Any other framework name to allow extension. Enum names should be preferred + when possible to allow better portability.\"\n }\n ]\n },\n + \ \"mlm:framework_version\": {\n \"title\": \"Framework version\",\n + \ \"type\": \"string\",\n \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\"\n + \ },\n \"mlm:artifact_type\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"torch.save\",\n \"torch.jit.save\",\n + \ \"torch.export.save\",\n \"tf.keras.Model.save\",\n \"tf.keras.Model.save_weights\",\n + \ \"tf.saved_model.export(format='tf_saved_model')\"\n ]\n },\n + \ \"mlm:compile_method\": {\n \"type\": \"string\",\n \"minLength\": + 1,\n \"examples\": [\n \"aot\",\n \"jit\"\n ]\n },\n + \ \"mlm:tasks\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n + \ \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"regression\",\n + \ \"classification\",\n \"scene-classification\",\n \"detection\",\n + \ \"object-detection\",\n \"segmentation\",\n \"semantic-segmentation\",\n + \ \"instance-segmentation\",\n \"panoptic-segmentation\",\n + \ \"similarity-search\",\n \"generative\",\n \"image-captioning\",\n + \ \"super-resolution\"\n ]\n }\n },\n \"mlm:memory_size\": + {\n \"description\": \"Memory size (in bytes) required to load the model + with the specified accelerator.\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:total_parameters\": {\n \"description\": \"Total + number of model parameters (weights).\",\n \"type\": \"integer\",\n \"minimum\": + 0\n },\n \"mlm:pretrained\": {\n \"type\": \"boolean\",\n \"$comment\": + \"If trained from scratch, the source should be explicitly 'null'. However, + omitting the source if pretrained is allowed.\",\n \"if\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"properties\": {\n + \ \"mlm:pretrained\": {\n \"const\": false\n }\n + \ }\n }\n }\n },\n \"then\": {\n \"$comment\": + \"This is the JSON-object 'properties' definition, which describes the STAC-Item + field named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"$comment\": \"This is the JSON-object 'properties' definition + for the STAC MLM pretraining reference.\",\n \"required\": [\n + \ \"mlm:pretrained_source\"\n ],\n \"properties\": + {\n \"mlm:pretrained_source\": {\n \"const\": + null\n }\n }\n }\n }\n }\n },\n + \ \"mlm:pretrained_source\": {\n \"description\": \"Pre-training dataset + reference or training from scratch definition.\",\n \"oneOf\": [\n {\n + \ \"type\": \"string\",\n \"description\": \"The name or + URI of the dataset used for pretraining the model.\",\n \"examples\": + [\n \"ImageNet\",\n \"EuroSAT\"\n ]\n },\n + \ {\n \"type\": \"null\",\n \"description\": \"Explicit + mention that the model is trained from scratch.\"\n }\n ]\n },\n + \ \"mlm:batch_size_suggestion\": {\n \"description\": \"Recommended + batch size to employ the model with the accelerator.\",\n \"type\": \"integer\",\n + \ \"minimum\": 0\n },\n \"mlm:accelerator\": {\n \"oneOf\": + [\n {\n \"type\": \"string\",\n \"enum\": [\n \"amd64\",\n + \ \"cuda\",\n \"xla\",\n \"amd-rocm\",\n \"intel-ipex-cpu\",\n + \ \"intel-ipex-gpu\",\n \"macos-arm\"\n ]\n + \ },\n {\n \"type\": \"null\"\n }\n ],\n + \ \"default\": null\n },\n \"mlm:accelerator_constrained\": {\n + \ \"type\": \"boolean\",\n \"default\": false\n },\n \"mlm:accelerator_summary\": + {\n \"type\": \"string\"\n },\n \"mlm:accelerator_count\": {\n + \ \"type\": \"integer\",\n \"minimum\": 1\n },\n \"mlm:input\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/ModelInput\"\n + \ }\n },\n \"ModelInput\": {\n \"title\": \"Model Input Object\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\",\n \"bands\",\n + \ \"input\"\n ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"bands\": {\n \"$ref\": \"#/$defs/ModelBands\"\n },\n + \ \"input\": {\n \"$ref\": \"#/$defs/InputStructure\"\n },\n + \ \"description\": {\n \"type\": \"string\",\n \"minLength\": + 1\n },\n \"value_scaling\": {\n \"$ref\": \"#/$defs/ValueScaling\"\n + \ },\n \"resize_type\": {\n \"$ref\": \"#/$defs/ResizeType\"\n + \ },\n \"pre_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n },\n \"mlm:output\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"title\": \"Model Output Object\",\n \"type\": + \"object\",\n \"required\": [\n \"name\",\n \"tasks\",\n + \ \"result\"\n ],\n \"properties\": {\n \"name\": + {\n \"type\": \"string\",\n \"minLength\": 1\n },\n + \ \"tasks\": {\n \"$ref\": \"#/$defs/mlm:tasks\"\n },\n + \ \"result\": {\n \"$ref\": \"#/$defs/ResultStructure\"\n + \ },\n \"description\": {\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n \"classification:classes\": + {\n \"$ref\": \"#/$defs/ClassificationClasses\"\n },\n + \ \"post_processing_function\": {\n \"$ref\": \"#/$defs/ProcessingExpression\"\n + \ }\n }\n }\n },\n \"mlm:hyperparameters\": {\n + \ \"type\": \"object\",\n \"minProperties\": 1,\n \"patternProperties\": + {\n \"^[0-9a-zA-Z_.-]+$\": true\n },\n \"additionalProperties\": + false\n },\n \"InputStructure\": {\n \"title\": \"Input Structure + Object\",\n \"type\": \"object\",\n \"required\": [\n \"shape\",\n + \ \"dim_order\",\n \"data_type\"\n ],\n \"properties\": + {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"ResultStructure\": {\n \"title\": \"Result + Structure Object\",\n \"type\": \"object\",\n \"required\": [\n + \ \"shape\",\n \"dim_order\",\n \"data_type\"\n ],\n + \ \"properties\": {\n \"shape\": {\n \"$ref\": \"#/$defs/DimensionShape\"\n + \ },\n \"dim_order\": {\n \"$ref\": \"#/$defs/DimensionOrder\"\n + \ },\n \"data_type\": {\n \"$ref\": \"#/$defs/DataType\"\n + \ }\n }\n },\n \"DimensionShape\": {\n \"type\": \"array\",\n + \ \"minItems\": 1,\n \"items\": {\n \"type\": \"integer\",\n + \ \"minimum\": -1\n }\n },\n \"DimensionOrder\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": + {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": + \"^[a-z-_]+$\",\n \"examples\": [\n \"batch\",\n \"channel\",\n + \ \"time\",\n \"height\",\n \"width\",\n \"depth\",\n + \ \"token\",\n \"class\",\n \"score\",\n \"confidence\"\n + \ ]\n }\n },\n \"ValueScaling\": {\n \"oneOf\": [\n + \ {\n \"type\": \"null\"\n },\n {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": + \"#/$defs/ValueScalingObject\"\n }\n }\n ]\n },\n + \ \"ValueScalingObject\": {\n \"oneOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\",\n + \ \"maximum\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"min-max\"\n },\n \"minimum\": + {\n \"type\": \"number\"\n },\n \"maximum\": + {\n \"type\": \"number\"\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"required\": [\n \"type\",\n + \ \"mean\",\n \"stddev\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"z-score\"\n },\n + \ \"mean\": {\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"type\": \"number\"\n }\n + \ }\n },\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"minimum\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"minimum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-min\"\n },\n \"minimum\": {\n \"type\": + \"number\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"maximum\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"clip-max\"\n },\n \"maximum\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"offset\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"value\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"scale\"\n },\n \"value\": {\n \"type\": + \"number\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ValueScalingProcessingExpression\"\n }\n ]\n },\n + \ \"ValueScalingProcessingExpression\": {\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"processing\"\n }\n }\n },\n {\n \"$ref\": + \"#/$defs/ProcessingExpression\"\n }\n ]\n },\n \"ResizeType\": + {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"enum\": + [\n \"crop\",\n \"pad\",\n \"interpolation-nearest\",\n + \ \"interpolation-linear\",\n \"interpolation-cubic\",\n + \ \"interpolation-area\",\n \"interpolation-lanczos4\",\n + \ \"interpolation-max\",\n \"wrap-fill-outliers\",\n + \ \"wrap-inverse-map\"\n ]\n },\n {\n \"type\": + \"null\"\n }\n ]\n },\n \"ClassificationClasses\": {\n \"$comment\": + \"Must allow empty array for outputs that provide other predictions than classes.\",\n + \ \"oneOf\": [\n {\n \"$ref\": \"https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes\"\n + \ },\n {\n \"type\": \"array\",\n \"maxItems\": + 0\n }\n ]\n },\n \"ProcessingExpression\": {\n \"oneOf\": + [\n {\n \"$ref\": \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression\"\n + \ },\n {\n \"type\": \"null\"\n }\n ]\n + \ },\n \"DataType\": {\n \"$ref\": \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type\"\n + \ },\n \"HasArtifactType\": {\n \"$comment\": \"Used to check the + artifact type property that is required by a Model Asset annotated by 'mlm:model' + role.\",\n \"type\": \"object\",\n \"required\": [\n \"mlm:artifact_type\"\n + \ ],\n \"properties\": {\n \"mlm:artifact_type\": {\n \"$ref\": + \"#/$defs/mlm:artifact_type\"\n }\n }\n },\n \"AssetModelRole\": + {\n \"$comment\": \"Used to check the presence of 'mlm:model' role required + by a Model Asset.\",\n \"type\": \"object\",\n \"required\": [\n + \ \"roles\"\n ],\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"contains\": {\n \"const\": + \"mlm:model\"\n },\n \"minItems\": 1\n }\n }\n + \ },\n \"AssetModelRequiredProperties\": {\n \"$comment\": \"Asset + containing the model definition must indicate both the 'mlm:model' role and + an artifact type.\",\n \"required\": [\n \"assets\"\n ],\n + \ \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"if\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ },\n \"then\": {\n \"$ref\": \"#/$defs/HasArtifactType\"\n + \ },\n \"else\": {\n \"not\": {\n \"$ref\": + \"#/$defs/HasArtifactType\"\n }\n }\n }\n + \ }\n }\n },\n \"AssetModelRoleMinimumOneDefinition\": {\n + \ \"$comment\": \"At least one Asset must provide the model definition + indicated by the 'mlm:model' role.\",\n \"required\": [\n \"assets\"\n + \ ],\n \"anyOf\": [\n {\n \"properties\": {\n \"assets\": + {\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/AssetModelRole\"\n + \ }\n }\n }\n },\n {\n \"not\": + {\n \"properties\": {\n \"assets\": {\n \"additionalProperties\": + {\n \"properties\": {\n \"roles\": {\n + \ \"type\": \"array\",\n \"items\": + {\n \"type\": \"string\",\n \"not\": + {\n \"const\": \"mlm:model\"\n }\n + \ }\n }\n }\n }\n + \ }\n }\n }\n }\n ]\n },\n + \ \"ModelBands\": {\n \"description\": \"List of bands (if any) that + compose the input. Band order represents the index position of the bands.\",\n + \ \"$comment\": \"No 'minItems' here to support model inputs not using + any band (other data source).\",\n \"type\": \"array\",\n \"items\": + {\n \"oneOf\": [\n {\n \"description\": \"Implied + named-band with the name directly provided.\",\n \"type\": \"string\",\n + \ \"minLength\": 1\n },\n {\n \"description\": + \"Explicit named-band with optional derived expression to obtain it.\",\n + \ \"type\": \"object\",\n \"required\": [\n \"name\"\n + \ ],\n \"properties\": {\n \"name\": {\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"format\": {\n \"description\": + \"Format to interpret the specified expression used to obtain the band.\",\n + \ \"type\": \"string\",\n \"minLength\": 1\n + \ },\n \"expression\": {\n \"description\": + \"Any representation relevant for the specified 'format'.\"\n }\n + \ },\n \"dependencies\": {\n \"format\": + [\n \"expression\"\n ],\n \"expression\": + [\n \"format\"\n ]\n },\n \"additionalProperties\": + false\n }\n ]\n }\n },\n \"AnyBandsRef\": {\n \"$comment\": + \"This definition ensures that, if at least 1 named MLM input 'bands' is provided, + at least 1 of the supported references from EO, Raster or STAC Core 1.1 are + provided as well. Otherwise, 'bands' must be explicitly empty.\",\n \"if\": + {\n \"type\": \"object\",\n \"$comment\": \"This is the JSON-object + 'properties' definition, which describes the STAC-Item field named 'properties'.\",\n + \ \"properties\": {\n \"properties\": {\n \"type\": + \"object\",\n \"required\": [\n \"mlm:input\"\n ],\n + \ \"$comment\": \"This is the JSON-object 'properties' definition + for the MLM input with bands listing referring to at least one band name.\",\n + \ \"properties\": {\n \"mlm:input\": {\n \"type\": + \"array\",\n \"$comment\": \"Below 'minItems' ensures that + band check does not fail for explicitly empty 'mlm:inputs'.\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n + \ \"required\": [\n \"bands\"\n ],\n + \ \"$comment\": \"This is the 'Model Input Object' properties.\",\n + \ \"properties\": {\n \"bands\": {\n \"type\": + \"array\",\n \"minItems\": 1\n }\n + \ }\n }\n }\n }\n }\n + \ }\n },\n \"then\": {\n \"$comment\": \"Need at least + one 'bands' definition, but multiple are allowed.\",\n \"anyOf\": [\n + \ {\n \"$comment\": \"Bands described by raster extension.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_extensions_raster\"\n + \ },\n {\n \"$ref\": \"#/$defs/stac_extensions_raster_bands_asset\"\n + \ }\n ]\n },\n {\n \"$comment\": + \"Bands described by eo extension.\",\n \"allOf\": [\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo\"\n },\n + \ {\n \"anyOf\": [\n {\n \"$ref\": + \"#/$defs/stac_extensions_eo_bands_item\"\n },\n {\n + \ \"$ref\": \"#/$defs/stac_extensions_eo_bands_asset\"\n + \ }\n ]\n }\n ]\n },\n + \ {\n \"$comment\": \"Bands described by STAC Core 1.1.\",\n + \ \"allOf\": [\n {\n \"$ref\": \"#/$defs/stac_version_1.1\"\n + \ },\n {\n \"$comment\": \"This is + the JSON-object 'properties' definition, which describes the STAC-Item field + named 'properties'.\",\n \"properties\": {\n \"properties\": + {\n \"required\": [\n \"bands\"\n + \ ],\n \"$comment\": \"This is the JSON-object + 'properties' definition for the STAC Core 'bands' field defined by [https://github.com/radiantearth/stac-spec/blob/bands/item-spec/common-metadata.md#bands].\",\n + \ \"properties\": {\n \"bands\": {\n + \ \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": + \"object\"\n }\n }\n }\n + \ }\n }\n }\n ]\n }\n + \ ]\n },\n \"else\": {\n \"$comment\": \"Case where + no 'bands' (empty list) are referenced in the MLM input. Because models can + use a mixture of inputs with/without bands, we cannot enforce eo/raster/stac + bands references to be omitted. If bands are provided in the 'mlm:model', + it will simply be an odd case if none are used in any 'mlm:input' bands'.\"\n + \ }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '8' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '33494' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - '"67a12887-82d6"' + Last-Modified: + - Mon, 03 Feb 2025 20:35:19 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - ea3acb22572b1c15d3e138abfdd6eadd70d2934e + X-GitHub-Request-Id: + - A3CF:119E:933E42:94ABEA:6811E3EB + X-Served-By: + - cache-fra-etou8220096-FRA + X-Timer: + - S1746002932.850023,VS0,VE2 + expires: + - Wed, 30 Apr 2025 08:58:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/raster/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json#\",\n \"title\": + \"raster Extension\",\n \"description\": \"STAC Raster Extension for STAC + Items.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema + for STAC extension raster in Items.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\",\n \"assets\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Feature\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n }\n }\n + \ },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Collections.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/assetfields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/assetfields\"\n }\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/raster/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"assetfields\": {\n \"type\": \"object\",\n + \ \"properties\": {\n \"raster:bands\": {\n \"$ref\": + \"#/definitions/bands\"\n }\n },\n \"patternProperties\": + {\n \"^(?!raster:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n },\n \"bands\": {\n \"title\": \"Bands\",\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n \"title\": + \"Band\",\n \"type\": \"object\",\n \"minProperties\": 1,\n + \ \"additionalProperties\": true,\n \"properties\": {\n \"data_type\": + {\n \"title\": \"Data type of the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"int8\",\n \"int16\",\n + \ \"int32\",\n \"int64\",\n \"uint8\",\n + \ \"uint16\",\n \"uint32\",\n \"uint64\",\n + \ \"float16\",\n \"float32\",\n \"float64\",\n + \ \"cint16\",\n \"cint32\",\n \"cfloat32\",\n + \ \"cfloat64\",\n \"other\"\n ]\n },\n + \ \"unit\": {\n \"title\": \"Unit denomination of the pixel + value\",\n \"type\": \"string\"\n },\n \"bits_per_sample\": + {\n \"title\": \"The actual number of bits used for this band\",\n + \ \"type\": \"integer\"\n },\n \"sampling\": {\n + \ \"title\": \"Pixel sampling in the band\",\n \"type\": + \"string\",\n \"enum\": [\n \"area\",\n \"point\"\n + \ ]\n },\n \"nodata\": {\n \"title\": + \"No data pixel value\",\n \"oneOf\": [\n {\n \"type\": + \"number\"\n },\n {\n \"type\": \"string\",\n + \ \"enum\": [\n \"nan\",\n \"inf\",\n + \ \"-inf\"\n ]\n }\n ]\n + \ },\n \"scale\": {\n \"title\": \"multiplicator + factor of the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"offset\": {\n \"title\": + \"number to be added to the pixel value to transform into the value\",\n \"type\": + \"number\"\n },\n \"spatial_resolution\": {\n \"title\": + \"Average spatial resolution (in meters) of the pixels in the band\",\n \"type\": + \"number\"\n },\n \"statistics\": {\n \"title\": + \"Statistics\",\n \"type\": \"object\",\n \"minProperties\": + 1,\n \"additionalProperties\": false,\n \"properties\": + {\n \"mean\": {\n \"title\": \"Mean value of all + the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"minimum\": {\n \"title\": \"Minimum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"maximum\": {\n \"title\": \"Maximum value of + all the pixels in the band\",\n \"type\": \"number\"\n },\n + \ \"stddev\": {\n \"title\": \"Standard deviation + value of all the pixels in the band\",\n \"type\": \"number\"\n + \ },\n \"valid_percent\": {\n \"title\": + \"Percentage of valid (not nodata) pixel\",\n \"type\": \"number\"\n + \ }\n }\n },\n \"histogram\": {\n + \ \"title\": \"Histogram\",\n \"type\": \"object\",\n + \ \"additionalItems\": false,\n \"required\": [\n \"count\",\n + \ \"min\",\n \"max\",\n \"buckets\"\n + \ ],\n \"additionalProperties\": false,\n \"properties\": + {\n \"count\": {\n \"title\": \"number of buckets\",\n + \ \"type\": \"number\"\n },\n \"min\": + {\n \"title\": \"Minimum value of the buckets\",\n \"type\": + \"number\"\n },\n \"max\": {\n \"title\": + \"Maximum value of the buckets\",\n \"type\": \"number\"\n + \ },\n \"buckets\": {\n \"title\": + \"distribution buckets\",\n \"type\": \"array\",\n \"minItems\": + 3,\n \"items\": {\n \"title\": \"number of + pixels in the bucket\",\n \"type\": \"integer\"\n }\n + \ }\n }\n }\n }\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '364' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '6318' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:51 GMT + ETag: + - '"66df5c80-18ae"' + Last-Modified: + - Mon, 09 Sep 2024 20:37:20 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 2b02ba0c8898ac2e1e4ff998eb889de5117ca36d + X-GitHub-Request-Id: + - 64B5:6EDF6:28F2EAC:295801B:681184F8 + X-Served-By: + - cache-fra-etou8220160-FRA + X-Timer: + - S1746002932.950606,VS0,VE2 + expires: + - Wed, 30 Apr 2025 02:13:36 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/processing/v1.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json#\",\n \"title\": + \"Processing Extension\",\n \"description\": \"STAC Processing Extension + for STAC Items and STAC Collections.\",\n \"anyOf\": [\n {\n \"$comment\": + \"This is the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\": + [\n \"type\",\n \"properties\",\n \"assets\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": \"Feature\"\n + \ },\n \"properties\": {\n \"allOf\": [\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n },\n + \ {\n \"$ref\": \"#/definitions/fields\"\n }\n + \ ]\n },\n \"assets\": {\n \"$comment\": \"This + validates the fields in Item Assets, but does not require them.\",\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n }\n },\n \"allOf\": + [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n + \ ]\n },\n {\n \"$comment\": \"This is the schema for STAC + Collections.\",\n \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"providers\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"item_assets\": {\n \"type\": \"object\",\n + \ \"additionalProperties\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n },\n \"summaries\": {\n \"$comment\": + \"The values of summaries are not validated yet!\"\n },\n \"assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": {\n + \ \"$ref\": \"#/definitions/fields\"\n }\n }\n },\n + \ \"allOf\": [\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ],\n \"anyOf\": [\n {\n \"$comment\": + \"Requires at least one provider to contain processing fields.\",\n \"type\": + \"object\",\n \"required\": [\n \"providers\"\n ],\n + \ \"properties\": {\n \"providers\": {\n \"type\": + \"array\",\n \"contains\": {\n \"type\": \"object\",\n + \ \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n + \ ],\n \"properties\": {\n \"roles\": + {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n + \ \"processor\"\n ]\n }\n + \ }\n }\n },\n {\n + \ \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ ]\n }\n }\n }\n },\n + \ {\n \"$comment\": \"Requires at least one asset to contain + processing fields.\",\n \"type\": \"object\",\n \"required\": + [\n \"assets\"\n ],\n \"properties\": {\n \"assets\": + {\n \"type\": \"object\",\n \"not\": {\n \"additionalProperties\": + {\n \"not\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n }\n }\n + \ },\n {\n \"$comment\": \"Requires at least one item + asset definition to contain processing fields.\",\n \"type\": \"object\",\n + \ \"required\": [\n \"item_assets\"\n ],\n \"properties\": + {\n \"item_assets\": {\n \"type\": \"object\",\n \"not\": + {\n \"additionalProperties\": {\n \"not\": + {\n \"$ref\": \"#/definitions/require_any_field\"\n }\n + \ }\n }\n }\n }\n },\n + \ {\n \"type\": \"object\",\n \"$comment\": \"Requires + at least one summary to be a processing field.\",\n \"required\": + [\n \"summaries\"\n ],\n \"properties\": {\n + \ \"summaries\": {\n \"$ref\": \"#/definitions/require_any_field\"\n + \ }\n }\n }\n ]\n }\n ],\n \"definitions\": + {\n \"stac_extensions\": {\n \"type\": \"object\",\n \"required\": + [\n \"stac_extensions\"\n ],\n \"properties\": {\n \"stac_extensions\": + {\n \"type\": \"array\",\n \"contains\": {\n \"const\": + \"https://stac-extensions.github.io/processing/v1.1.0/schema.json\"\n }\n + \ }\n }\n },\n \"require_provider_role\": {\n \"type\": + \"object\",\n \"required\": [\n \"roles\"\n ],\n \"properties\": + {\n \"roles\": {\n \"type\": \"array\",\n \"contains\": + {\n \"enum\": [\n \"producer\",\n \"processor\"\n + \ ]\n }\n }\n }\n },\n \"require_any_field\": + {\n \"anyOf\": [\n {\"type\": \"object\", \"required\": [\"processing:expression\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:lineage\"]},\n + \ {\"type\": \"object\", \"required\": [\"processing:level\"]},\n {\"type\": + \"object\", \"required\": [\"processing:facility\"]},\n {\"type\": + \"object\", \"required\": [\"processing:software\"]}\n ]\n },\n \"fields\": + {\n \"type\": \"object\",\n \"properties\": {\n \"processing:expression\": + {\n \"title\": \"Processing Expression\",\n \"type\": \"object\",\n + \ \"required\": [\n \"format\",\n \"expression\"\n + \ ],\n \"properties\": {\n \"format\": {\n \"type\": + \"string\"\n },\n \"expression\": {\n \"description\": + \"Any data type, depending on the format chosen.\"\n }\n }\n + \ },\n \"processing:lineage\": {\n \"title\": \"Processing + Lineage Information\",\n \"type\": \"string\",\n \"examples\": + [\n \"Post Processing GRD\"\n ]\n },\n \"processing:level\": + {\n \"title\": \"Processing Level\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"RAW\",\n \"L1\",\n \"L1A\",\n + \ \"L1B\",\n \"L1C\",\n \"L2\",\n \"L2A\",\n + \ \"L3\",\n \"L4\"\n ]\n },\n \"processing:facility\": + {\n \"title\": \"Processing Facility\",\n \"type\": \"string\",\n + \ \"examples\": [\n \"Copernicus S1 Core Ground Segment + - DPA\"\n ]\n },\n \"processing:software\": {\n \"title\": + \"Processing Software Name / version\",\n \"type\": \"object\",\n + \ \"patternProperties\": {\n \".{1,}\": {\n \"type\": + \"string\"\n }\n },\n \"examples\": [\n {\n + \ \"Sentinel-1 IPF\": \"002.71\"\n }\n ]\n + \ }\n },\n \"patternProperties\": {\n \"^(?!processing:)\": + {}\n },\n \"additionalProperties\": false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '359' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '7146' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:52 GMT + ETag: + - '"663cfd3e-1bea"' + Last-Modified: + - Thu, 09 May 2024 16:43:42 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - e95607f0f6ec3b7e2cc08a772e10d0b1b55a5c09 + X-GitHub-Request-Id: + - CCB6:11BF:2646467:26A98A1:6811AA24 + X-Served-By: + - cache-fra-etou8220168-FRA + X-Timer: + - S1746002932.035253,VS0,VE2 + expires: + - Wed, 30 Apr 2025 04:52:12 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/file/v2.1.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/file/v2.1.0/schema.json#\",\n \"title\": + \"File Info Extension\",\n \"description\": \"STAC File Info Extension for + STAC Items, STAC Catalogs, and STAC Collections.\",\n \"oneOf\": [\n {\n + \ \"$comment\": \"This is the schema for STAC Items.\",\n \"allOf\": + [\n {\n \"type\": \"object\",\n \"required\": [\n + \ \"type\",\n \"assets\"\n ],\n \"properties\": + {\n \"type\": {\n \"const\": \"Feature\"\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"links\": {\n \"type\": \"array\",\n \"items\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Catalogs.\",\n \"allOf\": [\n {\n \"type\": + \"object\",\n \"required\": [\n \"type\"\n ],\n + \ \"properties\": {\n \"type\": {\n \"const\": + \"Catalog\"\n },\n \"links\": {\n \"type\": + \"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n + \ }\n }\n }\n },\n {\n \"$ref\": + \"#/definitions/stac_extensions\"\n }\n ]\n },\n {\n \"$comment\": + \"This is the schema for STAC Collections.\",\n \"allOf\": [\n {\n + \ \"type\": \"object\",\n \"required\": [\n \"type\"\n + \ ],\n \"properties\": {\n \"type\": {\n \"const\": + \"Collection\"\n },\n \"assets\": {\n \"type\": + \"object\",\n \"additionalProperties\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"links\": + {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": + \"#/definitions/fields\"\n }\n },\n \"item_assets\": + {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/file/v2.1.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"$comment\": + \"Add your new fields here. Don't require them here, do that above in the + item schema.\",\n \"type\": \"object\",\n \"properties\": {\n \"file:byte_order\": + {\n \"type\": \"string\",\n \"enum\": [\n \"big-endian\",\n + \ \"little-endian\"\n ],\n \"title\": \"File Byte + Order\"\n },\n \"file:checksum\": {\n \"type\": \"string\",\n + \ \"pattern\": \"^[a-f0-9]+$\",\n \"title\": \"File Checksum + (Multihash)\"\n },\n \"file:header_size\": {\n \"type\": + \"integer\",\n \"minimum\": 0,\n \"title\": \"File Header + Size\"\n },\n \"file:size\": {\n \"type\": \"integer\",\n + \ \"minimum\": 0,\n \"title\": \"File Size\"\n },\n + \ \"file:values\": {\n \"type\": \"array\",\n \"minItems\": + 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": + [\n \"values\",\n \"summary\"\n ],\n + \ \"properties\": {\n \"values\": {\n \"type\": + \"array\",\n \"minItems\": 1,\n \"items\": {\n + \ \"description\": \"Any data type is allowed\"\n }\n + \ },\n \"summary\": {\n \"type\": + \"string\",\n \"minLength\": 1\n }\n }\n + \ }\n },\n \"file:local_path\": {\n \"type\": + \"string\",\n \"pattern\": \"^[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+(/[^\\\\r\\\\n\\\\t\\\\\\\\:'\\\"/]+)*/?$\",\n + \ \"title\": \"Relative File Path\"\n }\n },\n \"patternProperties\": + {\n \"^(?!file:)\": {\n \"$comment\": \"Above, change `template` + to the prefix of this extension\"\n }\n },\n \"additionalProperties\": + false\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '6' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '4536' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:52 GMT + ETag: + - '"61b4cf00-11b8"' + Last-Modified: + - Sat, 11 Dec 2021 16:17:04 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - 2fd6aeb2d6ee2a363a2f7c0678ba774b9ebdcfff + X-GitHub-Request-Id: + - 868B:11B5:DD2BB0:DF64F4:6811E3EE + X-Served-By: + - cache-fra-etou8220145-FRA + X-Timer: + - S1746002932.180129,VS0,VE1 + expires: + - Wed, 30 Apr 2025 08:58:46 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - stac-extensions.github.io + User-Agent: + - Python-urllib/3.10 + method: GET + uri: https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json + response: + body: + string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": + \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json#\",\n \"title\": + \"ML AOI Extension\",\n \"description\": \"ML AOI Extension for STAC definitions.\",\n + \ \"oneOf\": [\n {\n \"$comment\": \"This is the schema for STAC Collections.\",\n + \ \"allOf\": [\n {\n \"type\": \"object\",\n \"required\": + [\n \"type\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Collection\"\n },\n \"summaries\": + {\n \"type\": \"object\",\n \"properties\": {\n + \ \"ml-aoi:split\": {\n \"type\": \"array\",\n + \ \"items\": {\n \"$ref\": \"#/definitions/fields/properties/ml-aoi:split\"\n + \ }\n }\n }\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n },\n + \ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n },\n {\n \"$comment\": \"This is the schema + for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n + \ \"required\": [\n \"type\",\n \"properties\",\n + \ \"assets\"\n ],\n \"properties\": {\n \"type\": + {\n \"const\": \"Feature\"\n },\n \"properties\": + {\n \"allOf\": [\n {\n \"$ref\": + \"#/definitions/fields\"\n }\n ]\n },\n + \ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\": + {\n \"$ref\": \"#/definitions/fields\"\n }\n }\n + \ }\n },\n {\n \"$ref\": \"#/definitions/stac_extensions\"\n + \ }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\": + {\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n + \ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\": + \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/ml-aoi/v0.2.0/schema.json\"\n + \ }\n }\n }\n },\n \"fields\": {\n \"type\": + \"object\",\n \"properties\": {\n \"ml-aoi:split\": {\n \"type\": + \"string\",\n \"enum\": [\"train\", \"test\", \"validate\"]\n },\n + \ \"ml-aoi:role\": {\n \"type\": \"string\",\n \"enum\": + [\"label\", \"feature\"]\n },\n \"ml-aoi:reference-grid\": {\n + \ \"type\": \"boolean\"\n },\n \"ml-aoi:resampling-method\": + {\n \"$comment\": \"Supported GDAL resampling method (https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r)\",\n + \ \"type\": \"string\",\n \"enum\": [\n \"near\",\n + \ \"bilinear\",\n \"cubic\",\n \"cubcspline\",\n + \ \"lanczos\",\n \"average\",\n \"rms\",\n + \ \"mode\",\n \"max\",\n \"min\",\n + \ \"med\",\n \"q1\",\n \"q3\",\n \"sum\"\n + \ ]\n }\n },\n \"patternProperties\": {\n \"^(?!ml-aoi:)\": + {}\n }\n }\n }\n}\n" + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Origin: + - '*' + Age: + - '343' + Cache-Control: + - max-age=600 + Connection: + - close + Content-Length: + - '3400' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 30 Apr 2025 08:48:52 GMT + ETag: + - '"6605925b-d48"' + Last-Modified: + - Thu, 28 Mar 2024 15:52:59 GMT + Server: + - GitHub.com + Strict-Transport-Security: + - max-age=31556952 + Vary: + - Accept-Encoding + Via: + - 1.1 varnish + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Fastly-Request-ID: + - accce148756425d70a4443818f038623af3e340c + X-GitHub-Request-Id: + - E06D:14F99C:2DEDC77:2E61FB6:6811CF0F + X-Served-By: + - cache-fra-etou8220047-FRA + X-Timer: + - S1746002932.279262,VS0,VE1 + expires: + - Wed, 30 Apr 2025 07:29:43 GMT + permissions-policy: + - interest-cohort=() + x-proxy-cache: + - MISS + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extensions/test_mlm.py b/tests/extensions/test_mlm.py index cb7090fe7..c091b13ac 100644 --- a/tests/extensions/test_mlm.py +++ b/tests/extensions/test_mlm.py @@ -1,9 +1,12 @@ +import itertools import json import logging +import re from copy import deepcopy from typing import Any, cast import pytest +import requests import pystac.errors from pystac import Asset, Collection, Item, ItemAssetDefinition @@ -11,7 +14,6 @@ from pystac.extensions.classification import Classification from pystac.extensions.mlm import ( ARCHITECTURE_PROP, - NAME_PROP, TASKS_PROP, AcceleratorType, AssetDetailedMLMExtension, @@ -20,6 +22,7 @@ InputStructure, ItemMLMExtension, MLMExtension, + MLMExtensionHooks, ModelBand, ModelInput, ModelOutput, @@ -232,19 +235,19 @@ def test_model_input_structure_props() -> None: input_testdata = [ ( ["B02", "B03", "B04"], - ValueScaling.create(ValueScalingType.SCALE, value=3), + [ValueScaling.create(ValueScalingType.SCALE, value=3)], ResizeType.CROP, ProcessingExpression.create("python", "asdf"), ), ( ["B02", "B03", "B04"], - ValueScaling.create(ValueScalingType.SCALE, value=3), + [ValueScaling.create(ValueScalingType.SCALE, value=3)], None, ProcessingExpression.create("python", "asdf"), ), ( [ModelBand.create("B02"), ModelBand.create("B03"), ModelBand.create("B04")], - ValueScaling.create(ValueScalingType.SCALE, value=3), + [ValueScaling.create(ValueScalingType.SCALE, value=3)], ResizeType.CROP, ProcessingExpression.create("python", "asdf"), ), @@ -256,7 +259,7 @@ def test_model_input_structure_props() -> None: ), ( ["B02", "B03", "B04"], - ValueScaling.create(ValueScalingType.SCALE, value=3), + [ValueScaling.create(ValueScalingType.SCALE, value=3)], ResizeType.CROP, None, ), @@ -268,7 +271,7 @@ def test_model_input_structure_props() -> None: ) def test_model_input( bands: list[str] | list[ModelBand], - value_scaling: ValueScaling | None, + value_scaling: list[ValueScaling] | None, resize_type: ResizeType | None, pre_processing_function: ProcessingExpression | None, ) -> None: @@ -323,7 +326,7 @@ def test_model_input_props() -> None: assert c.input == inp assert c.value_scaling is None - val_obj = ValueScaling.create(ValueScalingType.SCALE, value=3) + val_obj = [ValueScaling.create(ValueScalingType.SCALE, value=3)] c.value_scaling = val_obj assert c.value_scaling == val_obj @@ -768,20 +771,16 @@ def test_add_to_asset(plain_item: Item) -> None: MLMExtension.ext(plain_item, add_if_missing=True) asset = plain_item.assets["analytic"] - assert NAME_PROP not in asset.extra_fields.keys() assert ARCHITECTURE_PROP not in asset.extra_fields.keys() assert TASKS_PROP not in asset.extra_fields.keys() asset_ext = AssetDetailedMLMExtension.ext(asset) - asset_ext.mlm_name = "asdf" asset_ext.architecture = "ResNet" asset_ext.tasks = [TaskType.CLASSIFICATION] - assert NAME_PROP in asset.extra_fields.keys() assert ARCHITECTURE_PROP in asset.extra_fields.keys() assert TASKS_PROP in asset.extra_fields.keys() - assert asset.extra_fields[NAME_PROP] == "asdf" assert asset.extra_fields[ARCHITECTURE_PROP] == "ResNet" assert asset.extra_fields[TASKS_PROP] == [TaskType.CLASSIFICATION] @@ -864,21 +863,6 @@ def test_to_dict_asset_generic() -> None: def test_add_to_detailled_asset() -> None: - model_input = ModelInput.create( - name="model", - bands=["B02"], - input=InputStructure.create( - shape=[1], dim_order=["batch"], data_type=DataType.FLOAT64 - ), - ) - model_output = ModelOutput.create( - name="output", - tasks=[TaskType.CLASSIFICATION], - result=ResultStructure.create( - shape=[1], dim_order=["batch"], data_type=DataType.FLOAT64 - ), - ) - asset = pystac.Asset( href="http://example.com/test.tiff", title="image", @@ -886,11 +870,8 @@ def test_add_to_detailled_asset() -> None: media_type="application/tiff", roles=["mlm:model"], extra_fields={ - "mlm:name": "asdf", "mlm:architecture": "ResNet", "mlm:tasks": [TaskType.CLASSIFICATION], - "mlm:input": [model_input.to_dict()], - "mlm:output": [model_output.to_dict()], "mlm:artifact_type": "foo", "mlm:compile_method": "bar", "mlm:entrypoint": "baz", @@ -899,11 +880,8 @@ def test_add_to_detailled_asset() -> None: asset_ext = AssetDetailedMLMExtension.ext(asset, add_if_missing=False) - assert asset_ext.mlm_name == "asdf" assert asset_ext.architecture == "ResNet" assert asset_ext.tasks == [TaskType.CLASSIFICATION] - assert asset_ext.input == [model_input] - assert asset_ext.output == [model_output] assert asset_ext.artifact_type == "foo" assert asset_ext.compile_method == "bar" assert asset_ext.entrypoint == "baz" @@ -928,7 +906,7 @@ def test_correct_asset_extension_is_used() -> None: asset = Asset("https://example.com") assert isinstance(asset.ext.mlm, AssetGeneralMLMExtension) - asset.extra_fields["mlm:name"] = "asdf" + asset.extra_fields["mlm:architecture"] = "ResNet" assert isinstance(asset.ext.mlm, AssetDetailedMLMExtension) @@ -949,37 +927,16 @@ def test_apply_detailled_asset() -> None: ) asset_ext = AssetDetailedMLMExtension.ext(asset, add_if_missing=False) - model_input = ModelInput.create( - name="model", - bands=["B02"], - input=InputStructure.create( - shape=[1], dim_order=["batch"], data_type=DataType.FLOAT64 - ), - ) - model_output = ModelOutput.create( - name="output", - tasks=[TaskType.CLASSIFICATION], - result=ResultStructure.create( - shape=[1], dim_order=["batch"], data_type=DataType.FLOAT64 - ), - ) - asset_ext.apply( - "asdf", "ResNet", [TaskType.CLASSIFICATION], - [model_input], - [model_output], artifact_type="foo", compile_method="bar", entrypoint="baz", ) - assert asset_ext.mlm_name == "asdf" assert asset_ext.architecture == "ResNet" assert asset_ext.tasks == [TaskType.CLASSIFICATION] - assert asset_ext.input == [model_input] - assert asset_ext.output == [model_output] assert asset_ext.artifact_type == "foo" assert asset_ext.compile_method == "bar" assert asset_ext.entrypoint == "baz" @@ -995,38 +952,17 @@ def test_to_dict_detailed_asset() -> None: ) asset_ext = AssetDetailedMLMExtension.ext(asset, add_if_missing=False) - model_input = ModelInput.create( - name="model", - bands=["B02"], - input=InputStructure.create( - shape=[1], dim_order=["batch"], data_type=DataType.FLOAT64 - ), - ) - model_output = ModelOutput.create( - name="output", - tasks=[TaskType.CLASSIFICATION], - result=ResultStructure.create( - shape=[1], dim_order=["batch"], data_type=DataType.FLOAT64 - ), - ) - asset_ext.apply( - "asdf", "ResNet", [TaskType.CLASSIFICATION], - [model_input], - [model_output], artifact_type="foo", compile_method="bar", entrypoint="baz", ) d = { - "mlm:name": "asdf", "mlm:architecture": "ResNet", "mlm:tasks": [TaskType.CLASSIFICATION], - "mlm:input": [model_input.to_dict()], - "mlm:output": [model_output.to_dict()], "mlm:artifact_type": "foo", "mlm:compile_method": "bar", "mlm:entrypoint": "baz", @@ -1071,3 +1007,849 @@ def test_raise_exception_on_mlm_extension_and_asset() -> None: ) with pytest.raises(TypeError): MLMExtension.ext(asset, add_if_missing=False) + + +@pytest.mark.parametrize( + "framework_old, framework_new, valid", + ( + ("Scikit-learn", "scikit-learn", False), + ("Huggingface", "Hugging Face", False), + ("-_ .asdf", "asdf", False), + ("asdf-_ .", "asdf", False), + ("-._ asdf-.", "asdf", False), + ("test_framework", "test_framework", True), + ), +) +def test_migration_1_0_to_1_1_item( + framework_old: None | str, framework_new: None | str, valid: bool +) -> None: + data: dict[str, Any] = {"type": "Feature", "properties": {}} + + MLMExtensionHooks._migrate_1_0_to_1_1(data) + assert "mlm:framework" not in data["properties"] + + pattern = r"^(?=[^\s._\-]).*[^\s._\-]$" + data["properties"]["mlm:framework"] = framework_old + + if valid: + MLMExtensionHooks._migrate_1_0_to_1_1(data) + else: + with pytest.warns(SyntaxWarning): + MLMExtensionHooks._migrate_1_0_to_1_1(data) + + assert data["properties"]["mlm:framework"] == framework_new + assert bool(re.match(pattern, data["properties"]["mlm:framework"])) + + +@pytest.mark.parametrize( + "framework_old, framework_new, valid", + ( + ("Scikit-learn", "scikit-learn", False), + ("Huggingface", "Hugging Face", False), + ("-_ .asdf", "asdf", False), + ("asdf-_ .", "asdf", False), + ("-._ asdf-.", "asdf", False), + ("test_framework", "test_framework", True), + ), +) +def test_migration_1_0_to_1_1_collection( + framework_old: None | str, framework_new: None | str, valid: bool +) -> None: + data: dict[str, Any] = {"type": "Collection"} + + MLMExtensionHooks._migrate_1_0_to_1_1(data) + assert "mlm:framework" not in data + + pattern = r"^(?=[^\s._\-]).*[^\s._\-]$" + data["mlm:framework"] = framework_old + + if valid: + MLMExtensionHooks._migrate_1_0_to_1_1(data) + else: + with pytest.warns(SyntaxWarning): + MLMExtensionHooks._migrate_1_0_to_1_1(data) + + assert data["mlm:framework"] == framework_new + assert bool(re.match(pattern, data["mlm:framework"])) + + +@pytest.mark.parametrize( + "framework_old, framework_new, valid", + ( + ("Scikit-learn", "scikit-learn", False), + ("Huggingface", "Hugging Face", False), + ("-_ .asdf", "asdf", False), + ("asdf-_ .", "asdf", False), + ("-._ asdf-.", "asdf", False), + ("test_framework", "test_framework", True), + ), +) +def test_migration_1_0_to_1_1_asset( + framework_old: None | str, framework_new: None | str, valid: bool +) -> None: + data: dict[str, Any] = { + "type": "Item", + "assets": {"asset1": Asset("https://asdf.com").to_dict()}, + } + + MLMExtensionHooks._migrate_1_0_to_1_1(data) + assert "mlm:framework" not in data["assets"]["asset1"] + + pattern = r"^(?=[^\s._\-]).*[^\s._\-]$" + data["assets"]["asset1"]["mlm:framework"] = framework_old + + if valid: + MLMExtensionHooks._migrate_1_0_to_1_1(data) + else: + with pytest.warns(SyntaxWarning): + MLMExtensionHooks._migrate_1_0_to_1_1(data) + + assert data["assets"]["asset1"]["mlm:framework"] == framework_new + assert bool(re.match(pattern, data["assets"]["asset1"]["mlm:framework"])) + + +@pytest.mark.parametrize( + "framework_old, framework_new, valid", + ( + ("Scikit-learn", "scikit-learn", False), + ("Huggingface", "Hugging Face", False), + ("-_ .asdf", "asdf", False), + ("asdf-_ .", "asdf", False), + ("-._ asdf-.", "asdf", False), + ("test_framework", "test_framework", True), + ), +) +def test_migration_1_0_to_1_1_item_assets( + framework_old: None | str, framework_new: None | str, valid: bool +) -> None: + data: dict[str, Any] = {"type": "Collection", "item_assets": {"asset1": {}}} + + MLMExtensionHooks._migrate_1_0_to_1_1(data) + assert "mlm:framework" not in data + + pattern = r"^(?=[^\s._\-]).*[^\s._\-]$" + data["item_assets"]["asset1"]["mlm:framework"] = framework_old + + if valid: + MLMExtensionHooks._migrate_1_0_to_1_1(data) + else: + with pytest.warns(SyntaxWarning): + MLMExtensionHooks._migrate_1_0_to_1_1(data) + + assert data["item_assets"]["asset1"]["mlm:framework"] == framework_new + assert bool(re.match(pattern, data["item_assets"]["asset1"]["mlm:framework"])) + + +@pytest.mark.parametrize( + "bands_obj_name, bands_obj", + ( + ("raster:bands", {"raster:bands": []}), + ("raster:bands", {"raster:bands": [{"name": "B01"}, {"name": "B02"}]}), + ("eo:bands", {"eo:bands": []}), + ("eo:bands", {"eo:bands": [{"name": "B01"}, {"name": "B02"}]}), + ), +) +def test_migration_1_0_to_1_1_asset_bands_item( + bands_obj_name: str, bands_obj: dict[str, Any] +) -> None: + data: dict[str, Any] = { + "type": "Feature", + "properties": {"mlm:input": [{"bands": []}]}, + "assets": { + "asset1": {"href": "https://example.com", "roles": ["analytic"]}, + "asset2": { + "href": "https://example.com", + "roles": ["analytic"], + **bands_obj, + }, + "asset3": { + "href": "https://example.com", + "roles": ["mlm:model"], + **bands_obj, + }, + }, + } + + with pytest.warns(SyntaxWarning): + MLMExtensionHooks._migrate_1_0_to_1_1(data) + + if bands_obj[bands_obj_name]: + assert bands_obj_name in data["assets"]["asset2"] + assert bands_obj_name not in data["assets"]["asset3"] + assert bands_obj_name in data["properties"] + else: + assert bands_obj_name in data["assets"]["asset2"] + assert bands_obj_name not in data["assets"]["asset3"] + assert bands_obj_name not in data["properties"] + + +@pytest.mark.parametrize( + "bands_obj_name, bands_obj", + ( + ("raster:bands", {"raster:bands": []}), + ("raster:bands", {"raster:bands": [{"name": "B01"}, {"name": "B02"}]}), + ("eo:bands", {"eo:bands": []}), + ("eo:bands", {"eo:bands": [{"name": "B01"}, {"name": "B02"}]}), + ), +) +def test_migration_1_0_to_1_1_asset_bands_collection( + bands_obj_name: str, bands_obj: dict[str, Any] +) -> None: + data: dict[str, Any] = { + "type": "Collection", + "mlm:input": [{"bands": []}], + "assets": { + "asset1": {"href": "https://example.com", "roles": ["analytic"]}, + "asset2": { + "href": "https://example.com", + "roles": ["analytic"], + **bands_obj, + }, + "asset3": { + "href": "https://example.com", + "roles": ["mlm:model"], + **bands_obj, + }, + }, + } + + with pytest.warns(SyntaxWarning): + MLMExtensionHooks._migrate_1_0_to_1_1(data) + + if bands_obj[bands_obj_name]: + assert bands_obj_name in data["assets"]["asset2"] + assert bands_obj_name not in data["assets"]["asset3"] + assert bands_obj_name in data + else: + assert bands_obj_name in data["assets"]["asset2"] + assert bands_obj_name not in data["assets"]["asset3"] + assert bands_obj_name not in data + + +@pytest.mark.parametrize("asset_type", ("assets", "item_assets")) +def test_migration_1_1_to_1_2(asset_type: str) -> None: + data: dict[str, Any] = {} + MLMExtensionHooks._migrate_1_1_to_1_2(data) + + data[asset_type] = {"asset1": {"roles": ["data"]}, "asset2": {"roles": ["labels"]}} + + with pytest.raises(pystac.errors.STACError): + MLMExtensionHooks._migrate_1_1_to_1_2(data) + + data[asset_type]["asset3"] = {"roles": ["mlm:model"]} + + MLMExtensionHooks._migrate_1_1_to_1_2(data) + + +@pytest.mark.parametrize( + "inp_bands, raster_bands, valid", + ( + ([], None, True), + ( + ["B02", "B03"], + [ + {"name": "B02", "data_type": "float64"}, + {"name": "B03", "data_type": "float64"}, + ], + True, + ), + (["B02", "B03"], None, True), + ( + ["B02", "B03"], + [ + {"name": "", "data_type": "float64"}, + {"name": "", "data_type": "float64"}, + ], + False, + ), + ( + ["B02", "B03"], + [ + {"name": "B02", "data_type": "float64"}, + {"name": "", "data_type": "float64"}, + ], + False, + ), + ( + ["B02", "B03"], + [{"name": "B02", "data_type": "float64"}, {"data_type": "float64"}], + False, + ), + ( + ["B02", "B03"], + [{"name": "", "data_type": "float64"}, {"data_type": "float64"}], + False, + ), + (["B02", "B03"], [{"data_type": "float64"}, {"data_type": "float64"}], False), + ), +) +def test_migration_1_2_to_1_3_item( + inp_bands: list[str], raster_bands: list[dict[str, Any]], valid: bool +) -> None: + data: dict[str, Any] = { + "type": "Feature", + "properties": {"mlm:input": [{}]}, + "assets": {"asset1": {"roles": ["data"]}, "asset2": {"roles": ["mlm:model"]}}, + } + + data["properties"]["mlm:input"][0]["bands"] = inp_bands + if raster_bands: + data["properties"]["raster:bands"] = raster_bands + + if valid: + MLMExtensionHooks._migrate_1_2_to_1_3(data) + if raster_bands: + assert "raster:bands" not in data["assets"]["asset1"] + assert "raster:bands" in data["assets"]["asset2"] + else: + with pytest.raises(STACError): + MLMExtensionHooks._migrate_1_2_to_1_3(data) + + +@pytest.mark.parametrize( + "inp_bands, raster_bands, valid", + ( + ([], None, True), + ( + ["B02", "B03"], + [ + {"name": "B02", "data_type": "float64"}, + {"name": "B03", "data_type": "float64"}, + ], + True, + ), + (["B02", "B03"], None, True), + ( + ["B02", "B03"], + [ + {"name": "", "data_type": "float64"}, + {"name": "", "data_type": "float64"}, + ], + False, + ), + ( + ["B02", "B03"], + [ + {"name": "B02", "data_type": "float64"}, + {"name": "", "data_type": "float64"}, + ], + False, + ), + ( + ["B02", "B03"], + [{"name": "B02", "data_type": "float64"}, {"data_type": "float64"}], + False, + ), + ( + ["B02", "B03"], + [{"name": "", "data_type": "float64"}, {"data_type": "float64"}], + False, + ), + (["B02", "B03"], [{"data_type": "float64"}, {"data_type": "float64"}], False), + ), +) +def test_migration_1_2_to_1_3_collection( + inp_bands: list[str], raster_bands: list[dict[str, Any]], valid: bool +) -> None: + data: dict[str, Any] = { + "type": "Collection", + "mlm:input": [{}], + "assets": {"asset1": {"roles": ["data"]}, "asset2": {"roles": ["mlm:model"]}}, + } + + data["mlm:input"][0]["bands"] = inp_bands + if raster_bands: + data["raster:bands"] = raster_bands + + if valid: + MLMExtensionHooks._migrate_1_2_to_1_3(data) + if raster_bands: + assert "raster:bands" not in data["assets"]["asset1"] + assert "raster:bands" in data["assets"]["asset2"] + else: + with pytest.raises(STACError): + MLMExtensionHooks._migrate_1_2_to_1_3(data) + + +@pytest.mark.parametrize( + "inp_bands, raster_bands, valid", + ( + ([], None, True), + ( + ["B02", "B03"], + [ + {"name": "B02", "data_type": "float64"}, + {"name": "B03", "data_type": "float64"}, + ], + True, + ), + (["B02", "B03"], None, True), + ( + ["B02", "B03"], + [ + {"name": "", "data_type": "float64"}, + {"name": "", "data_type": "float64"}, + ], + False, + ), + ( + ["B02", "B03"], + [ + {"name": "B02", "data_type": "float64"}, + {"name": "", "data_type": "float64"}, + ], + False, + ), + ( + ["B02", "B03"], + [{"name": "B02", "data_type": "float64"}, {"data_type": "float64"}], + False, + ), + ( + ["B02", "B03"], + [{"name": "", "data_type": "float64"}, {"data_type": "float64"}], + False, + ), + (["B02", "B03"], [{"data_type": "float64"}, {"data_type": "float64"}], False), + ), +) +def test_migration_1_2_to_1_3_asset( + inp_bands: list[str], raster_bands: list[dict[str, Any]], valid: bool +) -> None: + data: dict[str, Any] = { + "type": "Feature", + "properties": [], + "assets": { + "asset1": {"roles": ["data"]}, + "asset2": {"roles": ["mlm:model"], "mlm:input": [{}]}, + }, + } + + data["assets"]["asset2"]["mlm:input"][0]["bands"] = inp_bands + if raster_bands: + data["assets"]["asset2"]["raster:bands"] = raster_bands + + if valid: + MLMExtensionHooks._migrate_1_2_to_1_3(data) + if raster_bands: + assert "raster:bands" not in data["assets"]["asset1"] + assert "raster:bands" in data["assets"]["asset2"] + else: + with pytest.raises(STACError): + MLMExtensionHooks._migrate_1_2_to_1_3(data) + + +@pytest.mark.parametrize( + ("norm_by_channel", "norm_type", "norm_clip", "statistics", "value_scaling"), + ( + (None, None, None, None, None), + (False, None, None, None, None), + ( + False, + "z-score", + None, + [{"mean": 5, "stddev": 2}], + [ValueScaling.create(ValueScalingType.Z_SCORE, mean=5, stddev=2)], + ), + ( + False, + "min-max", + None, + [{"minimum": 10, "maximum": 20}], + [ValueScaling.create(ValueScalingType.MIN_MAX, minimum=10, maximum=20)], + ), + ( + True, + "z-score", + None, + [ + {"mean": 5, "stddev": 2}, + {"mean": 6, "stddev": 3}, + {"mean": 10, "stddev": 1}, + ], + [ + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=5, stddev=2), + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=6, stddev=3), + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=10, stddev=1), + ], + ), + ( + True, + "clip", + [3, 4, 5], + None, + [ + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 3, 0, 1)", + ), + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 4, 0, 1)", + ), + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 5, 0, 1)", + ), + ], + ), + ), +) +def test_migration_1_3_to_1_4_value_scaling_item( + norm_by_channel: bool | None, + norm_type: str | None, + norm_clip: list[int] | None, + statistics: list[dict[str, Any]] | None, + value_scaling: list[ValueScaling] | None, +) -> None: + data: dict[str, Any] = {"type": "Feature", "properties": {"mlm:input": []}} + MLMExtensionHooks._migrate_1_3_to_1_4(data) # nothing is supposed to happen here + + input_obj: dict[str, Any] = {} + if norm_by_channel is not None: + input_obj["norm_by_channel"] = norm_by_channel + if norm_type is not None: + input_obj["norm_type"] = norm_type + if norm_clip is not None: + input_obj["norm_clip"] = norm_clip + if statistics is not None: + input_obj["statistics"] = statistics + data["properties"]["mlm:input"].append(input_obj) + + MLMExtensionHooks._migrate_1_3_to_1_4(data) + if norm_type is not None and value_scaling is not None: + assert len(data["properties"]["mlm:input"][0]["value_scaling"]) == len( + value_scaling + ) + assert data["properties"]["mlm:input"][0]["value_scaling"] == [ + obj.to_dict() for obj in value_scaling + ] + + new_input_obj = data["properties"]["mlm:input"][0] + assert "norm_by_channel" not in new_input_obj + assert "norm_type" not in new_input_obj + assert "norm_clip" not in new_input_obj + assert "statistics" not in new_input_obj + + +@pytest.mark.parametrize( + ("norm_by_channel", "norm_type", "norm_clip", "statistics", "value_scaling"), + ( + (None, None, None, None, None), + (False, None, None, None, None), + ( + False, + "z-score", + None, + [{"mean": 5, "stddev": 2}], + [ValueScaling.create(ValueScalingType.Z_SCORE, mean=5, stddev=2)], + ), + ( + False, + "min-max", + None, + [{"minimum": 10, "maximum": 20}], + [ValueScaling.create(ValueScalingType.MIN_MAX, minimum=10, maximum=20)], + ), + ( + True, + "z-score", + None, + [ + {"mean": 5, "stddev": 2}, + {"mean": 6, "stddev": 3}, + {"mean": 10, "stddev": 1}, + ], + [ + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=5, stddev=2), + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=6, stddev=3), + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=10, stddev=1), + ], + ), + ( + True, + "clip", + [3, 4, 5], + None, + [ + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 3, 0, 1)", + ), + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 4, 0, 1)", + ), + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 5, 0, 1)", + ), + ], + ), + ), +) +def test_migration_1_3_to_1_4_value_scaling_collection( + norm_by_channel: bool | None, + norm_type: str | None, + norm_clip: list[int] | None, + statistics: list[dict[str, Any]] | None, + value_scaling: list[ValueScaling] | None, +) -> None: + data: dict[str, Any] = {"type": "Collection", "mlm:input": []} + MLMExtensionHooks._migrate_1_3_to_1_4(data) # nothing is supposed to happen here + + input_obj: dict[str, Any] = {} + if norm_by_channel is not None: + input_obj["norm_by_channel"] = norm_by_channel + if norm_type is not None: + input_obj["norm_type"] = norm_type + if norm_clip is not None: + input_obj["norm_clip"] = norm_clip + if statistics is not None: + input_obj["statistics"] = statistics + data["mlm:input"].append(input_obj) + + MLMExtensionHooks._migrate_1_3_to_1_4(data) + if norm_type is not None and value_scaling is not None: + assert len(data["mlm:input"][0]["value_scaling"]) == len(value_scaling) + assert data["mlm:input"][0]["value_scaling"] == [ + obj.to_dict() for obj in value_scaling + ] + + new_input_obj = data["mlm:input"][0] + assert "norm_by_channel" not in new_input_obj + assert "norm_type" not in new_input_obj + assert "norm_clip" not in new_input_obj + assert "statistics" not in new_input_obj + + +@pytest.mark.parametrize( + ("norm_by_channel", "norm_type", "norm_clip", "statistics", "value_scaling"), + ( + (None, None, None, None, None), + (False, None, None, None, None), + ( + False, + "z-score", + None, + [{"mean": 5, "stddev": 2}], + [ValueScaling.create(ValueScalingType.Z_SCORE, mean=5, stddev=2)], + ), + ( + False, + "min-max", + None, + [{"minimum": 10, "maximum": 20}], + [ValueScaling.create(ValueScalingType.MIN_MAX, minimum=10, maximum=20)], + ), + ( + True, + "z-score", + None, + [ + {"mean": 5, "stddev": 2}, + {"mean": 6, "stddev": 3}, + {"mean": 10, "stddev": 1}, + ], + [ + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=5, stddev=2), + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=6, stddev=3), + ValueScaling.create(type=ValueScalingType.Z_SCORE, mean=10, stddev=1), + ], + ), + ( + True, + "clip", + [3, 4, 5], + None, + [ + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 3, 0, 1)", + ), + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 4, 0, 1)", + ), + ValueScaling.create( + type=ValueScalingType.PROCESSING, + format="gdal-calc", + expression="numpy.clip(A / 5, 0, 1)", + ), + ], + ), + ), +) +def test_migration_1_3_to_1_4_value_scaling_asset( + norm_by_channel: bool | None, + norm_type: str | None, + norm_clip: list[int] | None, + statistics: list[dict[str, Any]] | None, + value_scaling: list[ValueScaling] | None, +) -> None: + data: dict[str, Any] = { + "type": "Feature", + "properties": {}, + "assets": {"asset1": {"href": "https://example.com", "roles": ["mlm:model"]}}, + } + MLMExtensionHooks._migrate_1_3_to_1_4(data) # nothing is supposed to happen here + + input_obj: dict[str, Any] = {} + if norm_by_channel is not None: + input_obj["norm_by_channel"] = norm_by_channel + if norm_type is not None: + input_obj["norm_type"] = norm_type + if norm_clip is not None: + input_obj["norm_clip"] = norm_clip + if statistics is not None: + input_obj["statistics"] = statistics + + data["assets"]["asset1"]["mlm:input"] = [] + data["assets"]["asset1"]["mlm:input"].append(input_obj) + + MLMExtensionHooks._migrate_1_3_to_1_4(data) + + assert "mlm:input" not in data["assets"]["asset1"] + + if norm_type is not None and value_scaling is not None: + assert len(data["properties"]["mlm:input"][0]["value_scaling"]) == len( + value_scaling + ) + assert data["properties"]["mlm:input"][0]["value_scaling"] == [ + obj.to_dict() for obj in value_scaling + ] + + new_input_obj = data["properties"]["mlm:input"][0] + assert "norm_by_channel" not in new_input_obj + assert "norm_type" not in new_input_obj + assert "norm_clip" not in new_input_obj + assert "statistics" not in new_input_obj + + +@pytest.mark.parametrize( + "norm_type", + ("l1", "l2", "l2sqr", "hamming", "hamming2", "type-mask", "relative", "inf"), +) +def test_migration_1_3_to_1_4_failure(norm_type: str) -> None: + # test that previously supported but now unsupported types raise an error + data: dict[str, Any] = { + "type": "Feature", + "properties": {"mlm:input": [{"norm_type": norm_type}]}, + } + + with pytest.raises(NotImplementedError): + MLMExtensionHooks._migrate_1_3_to_1_4(data) + + +def test_migration_1_3_to_1_4_assets_item() -> None: + data: dict[str, Any] = { + "type": "Feature", + "properties": {}, + "assets": { + "asset1": { + "mlm:name": "asdf", + "mlm:input": {}, + "mlm:output": {}, + "mlm:hyperparameters": {}, + "roles": ["mlm:model"], + } + }, + } + + MLMExtensionHooks._migrate_1_3_to_1_4(data) + + assert "mlm:name" not in data["assets"]["asset1"] + assert "mlm:name" in data["properties"] + + assert "mlm:input" not in data["assets"]["asset1"] + assert "mlm:input" in data["properties"] + + assert "mlm:output" not in data["assets"]["asset1"] + assert "mlm:output" in data["properties"] + + assert "mlm:hyperparameters" not in data["assets"]["asset1"] + assert "mlm:hyperparameters" in data["properties"] + + assert "mlm:artifact_type" in data["assets"]["asset1"] + + +def test_migration_1_3_to_1_4_collection() -> None: + data: dict[str, Any] = { + "type": "Collection", + "assets": { + "asset1": { + "mlm:name": "asdf", + "mlm:input": {}, + "mlm:output": {}, + "mlm:hyperparameters": {}, + "roles": ["mlm:model"], + } + }, + } + + MLMExtensionHooks._migrate_1_3_to_1_4(data) + + assert "mlm:name" not in data["assets"]["asset1"] + assert "mlm:name" in data + + assert "mlm:input" not in data["assets"]["asset1"] + assert "mlm:input" in data + + assert "mlm:output" not in data["assets"]["asset1"] + assert "mlm:output" in data + + assert "mlm:hyperparameters" not in data["assets"]["asset1"] + assert "mlm:hyperparameters" in data + + assert "mlm:artifact_type" in data["assets"]["asset1"] + + +@pytest.mark.vcr +@pytest.mark.parametrize( + "url_template, version", + tuple( + itertools.product( + ( + "https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/" + "v{version}/examples/item_basic.json", + "https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/" + "v{version}/examples/item_multi_io.json", + "https://raw.githubusercontent.com/stac-extensions/mlm/refs/tags/" + "v{version}/examples/item_raster_bands.json", + ), + ("1.0.0", "1.1.0", "1.2.0", "1.3.0"), + ) + ), +) +def test_migrate(url_template: str, version: str) -> None: + url = url_template.format(version=version) + r = requests.get(url) + data = r.json() + + old_uri = f"https://crim-ca.github.io/mlm-extension/v{version}/schema.json" + new_uri = f"https://stac-extensions.github.io/mlm/v{version}/schema.json" + + try: + i = data["stac_extensions"].index(old_uri) + data["stac_extensions"][i] = new_uri + except ValueError: + if new_uri not in data["stac_extensions"]: + raise Exception( + f"Stac object does not list stac:mlm v{version} as extension" + ) + + item = pystac.Item.from_dict(data) + + assert MLMExtension.get_schema_uri() in item.stac_extensions + assert old_uri not in item.stac_extensions + assert new_uri not in item.stac_extensions + + item.validate() diff --git a/uv.lock b/uv.lock index a7d4cb4a8..cc4a64401 100644 --- a/uv.lock +++ b/uv.lock @@ -1989,6 +1989,7 @@ dev = [ { name = "types-jsonschema" }, { name = "types-orjson" }, { name = "types-python-dateutil" }, + { name = "types-requests" }, { name = "types-urllib3" }, { name = "virtualenv" }, ] @@ -2041,6 +2042,7 @@ dev = [ { name = "types-jsonschema", specifier = ">=4.23.0.20240813" }, { name = "types-orjson", specifier = ">=3.6.2" }, { name = "types-python-dateutil", specifier = ">=2.9.0.20241003" }, + { name = "types-requests", specifier = ">=2.32.0.20250328" }, { name = "types-urllib3", specifier = ">=1.26.25.14" }, { name = "virtualenv", specifier = ">=20.26.6" }, ] @@ -2923,6 +2925,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53", size = 14384 }, ] +[[package]] +name = "types-requests" +version = "2.32.0.20250328" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/7d/eb174f74e3f5634eaacb38031bbe467dfe2e545bc255e5c90096ec46bc46/types_requests-2.32.0.20250328.tar.gz", hash = "sha256:c9e67228ea103bd811c96984fac36ed2ae8da87a36a633964a21f199d60baf32", size = 22995 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/15/3700282a9d4ea3b37044264d3e4d1b1f0095a4ebf860a99914fd544e3be3/types_requests-2.32.0.20250328-py3-none-any.whl", hash = "sha256:72ff80f84b15eb3aa7a8e2625fffb6a93f2ad5a0c20215fc1dcfa61117bcb2a2", size = 20663 }, +] + [[package]] name = "types-urllib3" version = "1.26.25.14"