{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://stac-extensions.github.io/mlm/v1.5.1/schema.json", "title": "Machine Learning Model STAC Extension Schema", "description": "This object represents the metadata for a Machine Learning Model (MLM) used in STAC documents.", "$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'.", "allOf": [ { "description": "This is the schema for STAC extension MLM in Items.", "if": { "required": [ "type" ], "properties": { "type": { "const": "Feature" } } }, "then": { "allOf": [ { "description": "Schema to validate the MLM fields permitted under Item properties or Assets properties.", "type": "object", "required": [ "properties", "assets" ], "properties": { "properties": { "$comment": "Schema to validate the MLM fields permitted under Item properties.", "$ref": "#/$defs/mlmItemFields" }, "assets": { "additionalProperties": { "$comment": "Schema to validate the MLM fields permitted under Asset properties.", "$ref": "#/$defs/mlmAssetFields" } } } }, { "$ref": "#/$defs/stac_extensions_mlm" }, { "$comment": "Schema to validate cross-references of bands between MLM inputs and any compliant section describing them using another STAC definition.", "$ref": "#/$defs/AnyBandsRef" }, { "$comment": "Schema to validate cross-references of variables between MLM inputs and any compliant section describing them using another STAC definition.", "$ref": "#/$defs/AnyVariablesRef" }, { "$comment": "Schema to validate that at least one Asset defines a model role.", "$ref": "#/$defs/AssetModelRoleMinimumOneDefinition" }, { "$comment": "Schema to validate any Asset containing an entrypoint is associated with code role.", "$ref": "#/$defs/AssetCodeRoleWithEntrypoint" }, { "$comment": "Schema to validate that the Asset model properties are mutually exclusive to the model role.", "$ref": "#/$defs/AssetModelRequiredProperties" } ] } }, { "description": "This is the schema for STAC extension MLM in Collections.", "if": { "required": [ "type" ], "properties": { "type": { "const": "Collection" } } }, "then": { "allOf": [ { "type": "object", "properties": { "summaries": { "type": "object", "additionalProperties": { "$ref": "#/$defs/mlmCollectionFields" } }, "assets": { "type": "object", "additionalProperties": { "$ref": "#/$defs/mlmAssetFields" } }, "item_assets": { "type": "object", "additionalProperties": { "$ref": "#/$defs/mlmAssetFields" } } } }, { "$ref": "#/$defs/stac_extensions_mlm" } ] } } ], "$defs": { "stac_extensions_mlm": { "type": "object", "required": [ "stac_extensions" ], "properties": { "stac_extensions": { "type": "array", "contains": { "const": "https://stac-extensions.github.io/mlm/v1.5.1/schema.json" } } } }, "stac_extensions_datacube_variables": { "$comment": "STAC extension reference to [https://github.com/stac-extensions/datacube]. V2 and above is required to reference 'cube:variables'.", "type": "object", "required": [ "stac_extensions" ], "properties": { "stac_extensions": { "type": "array", "contains": { "type": "string", "pattern": "https://stac-extensions\\.github\\.io/datacube/v2(\\.[0-9]+){2}/schema\\.json" } } } }, "stac_extensions_datacube_variables_field": { "type": "object", "required": [ "cube:variables" ], "properties": { "cube:variables": { "type": "object", "minProperties": 1, "additionalProperties": true } } }, "stac_extensions_datacube_variables_item": { "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties' containing 'cube:variables' as described in [https://github.com/stac-extensions/datacube#fields].", "properties": { "properties": { "$ref": "#/$defs/stac_extensions_datacube_variables_field" } } }, "stac_extensions_datacube_variables_asset": { "required": [ "assets" ], "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Asset containing 'cube:variables' as described in [https://github.com/stac-extensions/datacube#fields].", "properties": { "assets": { "additionalProperties": { "if": { "$ref": "#/$defs/AssetModelRole" }, "then": { "$ref": "#/$defs/stac_extensions_datacube_variables_field" } } } } }, "stac_extensions_eo": { "type": "object", "required": [ "stac_extensions" ], "properties": { "stac_extensions": { "type": "array", "contains": { "type": "string", "pattern": "https://stac-extensions\\.github\\.io/eo/v1(\\.[0-9]+){2}/schema\\.json" } } } }, "stac_extensions_eo_bands_item": { "$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].", "properties": { "properties": { "required": [ "eo:bands" ], "properties": { "eo:bands": { "type": "array", "minItems": 1, "items": { "type": "object" } } } } } }, "stac_extensions_eo_bands_asset": { "required": [ "assets" ], "$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].", "properties": { "assets": { "additionalProperties": { "if": { "$ref": "#/$defs/AssetModelRole" }, "then": { "required": [ "eo:bands" ], "properties": { "eo:bands": { "type": "array", "minItems": 1, "items": { "type": "object" } } } } } } } }, "stac_extensions_raster": { "type": "object", "required": [ "stac_extensions" ], "properties": { "stac_extensions": { "type": "array", "contains": { "type": "string", "pattern": "https://stac-extensions\\.github\\.io/raster/v1(\\.[0-9]+){2}/schema\\.json" } } } }, "stac_extensions_raster_bands_asset": { "required": [ "assets" ], "$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].", "properties": { "assets": { "additionalProperties": { "if": { "$ref": "#/$defs/AssetModelRole" }, "then": { "required": [ "raster:bands" ], "properties": { "raster:bands": { "type": "array", "minItems": 1, "items": { "$comment": "Raster extension does not explicitly indicate a 'name', but one is needed for MLM.", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1 } } } } } } } } } }, "stac_version_1.1": { "$comment": "Requirement for STAC 1.1 or above.", "type": "object", "required": [ "stac_version" ], "properties": { "stac_version": { "pattern": "1\\.[1-9][0-9]*\\.[0-9]+(-.*)?" } } }, "fields": { "description": "All possible MLM fields regardless of the level they apply (Collection, Item, Asset, Link).", "type": "object", "properties": { "mlm:name": { "$ref": "#/$defs/mlm:name" }, "mlm:architecture": { "$ref": "#/$defs/mlm:architecture" }, "mlm:tasks": { "$ref": "#/$defs/mlm:tasks" }, "mlm:framework": { "$ref": "#/$defs/mlm:framework" }, "mlm:framework_version": { "$ref": "#/$defs/mlm:framework_version" }, "mlm:memory_size": { "$ref": "#/$defs/mlm:memory_size" }, "mlm:total_parameters": { "$ref": "#/$defs/mlm:total_parameters" }, "mlm:pretrained": { "$ref": "#/$defs/mlm:pretrained" }, "mlm:pretrained_source": { "$ref": "#/$defs/mlm:pretrained_source" }, "mlm:batch_size_suggestion": { "$ref": "#/$defs/mlm:batch_size_suggestion" }, "mlm:accelerator": { "$ref": "#/$defs/mlm:accelerator" }, "mlm:accelerator_constrained": { "$ref": "#/$defs/mlm:accelerator_constrained" }, "mlm:accelerator_summary": { "$ref": "#/$defs/mlm:accelerator_summary" }, "mlm:accelerator_count": { "$ref": "#/$defs/mlm:accelerator_count" }, "mlm:input": { "$ref": "#/$defs/mlm:input" }, "mlm:output": { "$ref": "#/$defs/mlm:output" }, "mlm:hyperparameters": { "$ref": "#/$defs/mlm:hyperparameters" }, "mlm:artifact_type": { "$ref": "#/$defs/mlm:artifact_type" }, "mlm:compile_method": { "$ref": "#/$defs/mlm:compile_method" }, "mlm:entrypoint": { "$ref": "#/$defs/mlm:entrypoint" } }, "$comment": "Allow properties not defined by MLM prefix to work with other extensions and attributes, but disallow undefined MLM fields.", "patternProperties": { "^(?!mlm:)": {} }, "additionalProperties": false }, "mlmCollectionFields": { "description": "Schema to validate the MLM fields permitted under Collection summaries.", "allOf": [ { "description": "Fields that are mandatory under the Collection summaries.", "type": "object", "required": [] }, { "description": "Fields that are disallowed under the Collection summaries.", "not": { "required": [ "mlm:input", "mlm:output", "mlm:artifact_type", "mlm:compile_method" ] } }, { "description": "Field with known definitions that must be validated.", "$ref": "#/$defs/fields" } ] }, "mlmItemFields": { "description": "Schema to validate the MLM fields permitted under Item properties.", "allOf": [ { "description": "Fields that are mandatory under the Item properties.", "required": [ "mlm:name", "mlm:architecture", "mlm:tasks", "mlm:input", "mlm:output" ] }, { "description": "Fields that are disallowed under the Item properties.", "$comment": "Particularity of the 'not/required' approach: they must be tested one by one. Otherwise, it validates that they are all (simultaneously) not present.", "not": { "anyOf": [ {"required": ["mlm:artifact_type"]}, {"required": ["mlm:compile_method"]}, {"required": ["mlm:entrypoint"]} ] } }, { "description": "Field with known definitions that must be validated.", "$ref": "#/$defs/fields" } ] }, "mlmAssetFields": { "description": "Schema to validate the MLM fields permitted under Assets properties.", "allOf": [ { "description": "Fields that are disallowed under the Asset properties.", "$comment": "Particularity of the 'not/required' approach: they must be tested one by one. Otherwise, it validates that they are all (simultaneously) not present.", "not": { "anyOf": [ { "required": [ "mlm:name" ] }, { "required": [ "mlm:input" ] }, { "required": [ "mlm:output" ] }, { "required": [ "mlm:hyperparameters" ] } ] } }, { "description": "Field with known definitions that must be validated.", "$ref": "#/$defs/fields" } ] }, "mlm:name": { "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9_.\\-\\s]+[a-zA-Z0-9]$" }, "mlm:architecture": { "type": "string", "title": "Model Architecture", "description": "A descriptive name of the model architecture, typically a common name from the literature.", "examples": [ "ResNet", "VGG", "GAN", "Vision Transformer" ] }, "mlm:framework": { "title": "Name of the machine learning framework used.", "anyOf": [ { "$comment": "Add more entries here as needed, and repeat them in the README.", "description": "Notable predefined framework names.", "type": "string", "enum": [ "PyTorch", "TensorFlow", "scikit-learn", "Hugging Face", "Keras", "ONNX", "rgee", "spatialRF", "JAX", "Flax", "MXNet", "Caffe", "PyMC", "Weka", "Paddle" ] }, { "type": "string", "minLength": 1, "pattern": "^(?=[^\\s._\\-]).*[^\\s._\\-]$", "description": "Any other framework name to allow extension. Enum names should be preferred when possible to allow better portability." } ] }, "mlm:framework_version": { "title": "Framework version", "type": "string", "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-]+)*))?$" }, "mlm:artifact_type": { "type": "string", "minLength": 1, "examples": [ "torch.save", "torch.jit.save", "torch.export.save", "tf.keras.Model.save", "tf.keras.Model.save_weights", "tf.keras.Model.export", "safetensors.torch.save_file", "safetensors.tensorflow.save_file", "safetensors.flax.save_file", "safetensors.paddle.save_file" ] }, "mlm:compile_method": { "type": "string", "minLength": 1, "examples": [ "aot", "jit" ] }, "mlm:entrypoint": { "type": "string", "minLength": 1, "description": "Entrypoint script or function where the model can be invoked for inference on input data.", "examples": [ "my_package.my_module:inference_function", "inference.py" ] }, "mlm:tasks": { "type": "array", "uniqueItems": true, "items": { "type": "string", "enum": [ "regression", "classification", "scene-classification", "detection", "object-detection", "segmentation", "semantic-segmentation", "instance-segmentation", "panoptic-segmentation", "similarity-search", "generative", "image-captioning", "super-resolution", "downscaling" ] } }, "mlm:memory_size": { "description": "Memory size (in bytes) required to load the model with the specified accelerator.", "type": "integer", "minimum": 0 }, "mlm:total_parameters": { "description": "Total number of model parameters (weights).", "type": "integer", "minimum": 0 }, "mlm:pretrained": { "type": "boolean", "$comment": "If trained from scratch, the source should be explicitly 'null'. However, omitting the source if pretrained is allowed.", "if": { "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties'.", "properties": { "properties": { "$comment": "This is the JSON-object 'properties' definition for the STAC MLM pretraining reference.", "properties": { "mlm:pretrained": { "const": false } } } } }, "then": { "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties'.", "properties": { "properties": { "$comment": "This is the JSON-object 'properties' definition for the STAC MLM pretraining reference.", "required": [ "mlm:pretrained_source" ], "properties": { "mlm:pretrained_source": { "const": null } } } } } }, "mlm:pretrained_source": { "description": "Pre-training dataset reference or training from scratch definition.", "oneOf": [ { "type": "string", "description": "The name or URI of the dataset used for pretraining the model.", "examples": [ "ImageNet", "EuroSAT" ] }, { "type": "null", "description": "Explicit mention that the model is trained from scratch." } ] }, "mlm:batch_size_suggestion": { "description": "Recommended batch size to employ the model with the accelerator.", "type": "integer", "minimum": 0 }, "mlm:accelerator": { "oneOf": [ { "type": "string", "enum": [ "amd64", "cuda", "xla", "amd-rocm", "intel-ipex-cpu", "intel-ipex-gpu", "macos-arm" ] }, { "type": "null" } ], "default": null }, "mlm:accelerator_constrained": { "type": "boolean", "default": false }, "mlm:accelerator_summary": { "type": "string" }, "mlm:accelerator_count": { "type": "integer", "minimum": 1 }, "mlm:input": { "type": "array", "items": { "allOf": [ {"$ref": "#/$defs/ModelInput"}, {"$ref": "#/$defs/ModelInputBandsDimensionRef"}, {"$ref": "#/$defs/ModelInputVariablesDimensionRef"} ] } }, "ModelInput": { "title": "Model Input Object", "type": "object", "required": [ "name", "input" ], "properties": { "name": { "type": "string", "minLength": 1 }, "bands": { "$ref": "#/$defs/ModelBandsVariables" }, "variables": { "$ref": "#/$defs/ModelBandsVariables" }, "input": { "$ref": "#/$defs/InputStructure" }, "description": { "type": "string", "minLength": 1 }, "value_scaling": { "$ref": "#/$defs/ValueScaling" }, "resize_type": { "$ref": "#/$defs/ResizeType" }, "pre_processing_function": { "oneOf": [ {"$ref": "#/$defs/ProcessingExpression"}, { "type": "array", "items": { "$ref": "#/$defs/ProcessingExpression" }, "minItems": 1 } ] } } }, "mlm:output": { "type": "array", "items": { "allOf": [ {"$ref": "#/$defs/ModelOutput"}, {"$ref": "#/$defs/ModelOutputBandsDimensionRef"}, {"$ref": "#/$defs/ModelOutputVariablesDimensionRef"} ] } }, "ModelOutput": { "title": "Model Output Object", "type": "object", "required": [ "name", "tasks", "result" ], "properties": { "name": { "type": "string", "minLength": 1 }, "description": { "type": "string", "minLength": 1 }, "tasks": { "$ref": "#/$defs/mlm:tasks" }, "result": { "$ref": "#/$defs/ResultStructure" }, "bands": { "$ref": "#/$defs/ModelBandsVariables" }, "variables": { "$ref": "#/$defs/ModelBandsVariables" }, "classification:classes": { "$ref": "#/$defs/ClassificationClasses" }, "post_processing_function": { "oneOf": [ {"$ref": "#/$defs/ProcessingExpression"}, { "type": "array", "items": { "$ref": "#/$defs/ProcessingExpression" }, "minItems": 1 } ] } } }, "mlm:hyperparameters": { "type": "object", "minProperties": 1, "patternProperties": { "^[0-9a-zA-Z_.-]+$": true }, "additionalProperties": false }, "InputStructure": { "title": "Input Structure Object", "type": "object", "required": [ "shape", "dim_order", "data_type" ], "properties": { "shape": { "$ref": "#/$defs/DimensionShape" }, "dim_order": { "$ref": "#/$defs/DimensionOrder" }, "data_type": { "$ref": "#/$defs/DataType" } } }, "ResultStructure": { "title": "Result Structure Object", "type": "object", "required": [ "shape", "dim_order", "data_type" ], "properties": { "shape": { "$ref": "#/$defs/DimensionShape" }, "dim_order": { "$ref": "#/$defs/DimensionOrder" }, "data_type": { "$ref": "#/$defs/DataType" } } }, "DimensionShape": { "type": "array", "minItems": 1, "items": { "type": "integer", "minimum": -1 } }, "DimensionOrder": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "pattern": "^[a-z-_]+$", "examples": [ "batch", "channel", "bands", "variables", "temperature", "pressure", "time", "height", "width", "depth", "token", "class", "score", "confidence", "embedding" ] } }, "ValueScaling": { "oneOf": [ { "type": "null" }, { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/ValueScalingObject" } } ] }, "ValueScalingObject": { "oneOf": [ { "type": "object", "required": [ "type", "minimum", "maximum" ], "properties": { "type": { "const": "min-max" }, "minimum": { "type": "number" }, "maximum": { "type": "number" } } }, { "type": "object", "required": [ "type", "mean", "stddev" ], "properties": { "type": { "const": "z-score" }, "mean": { "type": "number" }, "stddev": { "type": "number" } } }, { "type": "object", "required": [ "type", "minimum", "maximum" ], "properties": { "type": { "const": "clip" }, "minimum": { "type": "number" }, "maximum": { "type": "number" } } }, { "type": "object", "required": [ "type", "minimum" ], "properties": { "type": { "const": "clip-min" }, "minimum": { "type": "number" }, "maximum": { "type": "number" } } }, { "type": "object", "required": [ "type", "maximum" ], "properties": { "type": { "const": "clip-max" }, "maximum": { "type": "number" } } }, { "type": "object", "required": [ "type", "value" ], "properties": { "type": { "const": "offset" }, "value": { "type": "number" } } }, { "type": "object", "required": [ "type", "value" ], "properties": { "type": { "const": "scale" }, "value": { "type": "number" } } }, { "$ref": "#/$defs/ValueScalingProcessingExpression" } ] }, "ValueScalingProcessingExpression": { "allOf": [ { "type": "object", "required": [ "type" ], "properties": { "type": { "const": "processing" } } }, { "$ref": "#/$defs/ProcessingExpression" } ] }, "ResizeType": { "oneOf": [ { "type": "string", "enum": [ "crop", "pad", "interpolation-nearest", "interpolation-linear", "interpolation-cubic", "interpolation-area", "interpolation-lanczos4", "interpolation-max", "wrap-fill-outliers", "wrap-inverse-map" ] }, { "type": "null" } ] }, "ClassificationClasses": { "$comment": "Must allow empty array for outputs that provide other predictions than classes.", "oneOf": [ { "$ref": "https://stac-extensions.github.io/classification/v1.1.0/schema.json#/definitions/fields/properties/classification:classes" }, { "type": "array", "maxItems": 0 } ] }, "ProcessingExpression": { "oneOf": [ { "allOf": [ { "$ref": "https://stac-extensions.github.io/processing/v1.1.0/schema.json#/definitions/fields/properties/processing:expression" }, { "properties": { "description": { "type": "string", "description": "Optional information about the processing function." } } } ] }, { "type": "null" } ] }, "DataType": { "$ref": "https://stac-extensions.github.io/raster/v1.1.0/schema.json#/definitions/bands/items/properties/data_type" }, "HasArtifactType": { "$comment": "Used to check the artifact type property that is required by a Model Asset annotated by 'mlm:model' role.", "type": "object", "required": [ "mlm:artifact_type" ], "properties": { "mlm:artifact_type": { "$ref": "#/$defs/mlm:artifact_type" } } }, "AssetModelRole": { "$comment": "Used to check the presence of 'mlm:model' role required by a Model Asset.", "type": "object", "required": [ "roles" ], "properties": { "roles": { "type": "array", "contains": { "const": "mlm:model" }, "minItems": 1 } } }, "AssetModelRequiredProperties": { "$comment": "Asset containing the model definition must indicate both the 'mlm:model' role and an artifact type.", "required": [ "assets" ], "properties": { "assets": { "additionalProperties": { "if": { "$ref": "#/$defs/AssetModelRole" }, "then": { "$ref": "#/$defs/HasArtifactType" }, "else": { "not": { "$ref": "#/$defs/HasArtifactType" } } } } } }, "AssetModelRoleMinimumOneDefinition": { "$comment": "At least one Asset must provide the model definition indicated by the 'mlm:model' role.", "required": [ "assets" ], "anyOf": [ { "properties": { "assets": { "additionalProperties": { "$ref": "#/$defs/AssetModelRole" } } } }, { "not": { "properties": { "assets": { "additionalProperties": { "properties": { "roles": { "type": "array", "items": { "type": "string", "not": { "const": "mlm:model" } } } } } } } } } ] }, "AssetCodeRoleWithEntrypoint": { "$comment": "Used to check the presence of 'code' role if an entrypoint is provided in an Asset.", "properties": { "assets": { "additionalProperties": { "oneOf": [ { "required": [ "mlm:entrypoint", "roles" ], "properties": { "mlm:entrypoint": { "$ref": "#/$defs/mlm:entrypoint" }, "roles": { "type": "array", "contains": { "const": "code" }, "minItems": 1 } } }, { "not": { "required": [ "mlm:entrypoint" ] } } ] } } } }, "ModelBandsVariables": { "description": "List of bands or variables (if any) that compose the input. Band and/or variable order represents the index position within the input. If both bands and variables are provided, their order should be distinguished using corresponding names in 'dim_order'.", "$comment": "No 'minItems' here to support model inputs not using any band (other data source).", "type": "array", "items": { "oneOf": [ { "description": "Implied name of the band or variable with the name directly provided with no further properties.", "type": "string", "minLength": 1 }, { "description": "Explicitly named band or variable with optional derived expression to obtain it.", "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1 }, "format": { "description": "Format to interpret the specified expression used to obtain the band.", "type": "string", "minLength": 1 }, "expression": { "description": "Any representation relevant for the specified 'format'." } }, "dependencies": { "format": [ "expression" ], "expression": [ "format" ] }, "additionalProperties": false } ] } }, "ModelInputBandsDimensionRef": { "$comment": "This definition ensures that, if an MLM input 'bands' is provided with at least one entry, the corresponding 'bands' dimension is defined in 'dim_order'. Otherwise, 'bands' must be omitted or empty.", "if": { "required": [ "bands" ], "properties": { "bands": { "type": "array", "minItems": 1 } } }, "then": { "$comment": "The 'bands' dimension is required if bands were indicated.", "properties": { "input": { "properties": { "dim_order": { "type": "array", "contains": { "const": "bands" } } } } } }, "else": { "$comment": "The 'bands' dimension is forbidden since none are indicated.", "properties": { "input": { "properties": { "dim_order": { "not": { "contains": { "const": "bands" } } } } } } } }, "ModelOutputBandsDimensionRef": { "$comment": "This definition ensures that, if an MLM output 'bands' is provided with at least one entry, the corresponding 'bands' dimension is defined in 'dim_order'. Otherwise, 'bands' must be omitted or empty.", "if": { "required": [ "bands" ], "properties": { "bands": { "type": "array", "minItems": 1 } } }, "then": { "$comment": "The 'bands' dimension is required if bands were indicated.", "properties": { "result": { "properties": { "dim_order": { "type": "array", "contains": { "const": "bands" } } } } } }, "else": { "$comment": "The 'bands' dimension is forbidden since none are indicated.", "properties": { "result": { "properties": { "dim_order": { "not": { "contains": { "const": "bands" } } } } } } } }, "ModelInputVariablesDimensionRef": { "$comment": "This definition ensures that, if an MLM input 'variables' is provided with at least one entry, the corresponding 'variables' dimension is defined in 'dim_order'. Otherwise, 'variables' must be omitted or empty.", "if": { "required": [ "variables" ], "properties": { "variables": { "type": "array", "minItems": 1 } } }, "then": { "$comment": "The 'variables' dimension is required if bands were indicated.", "properties": { "input": { "properties": { "dim_order": { "type": "array", "contains": { "const": "variables" } } } } } }, "else": { "$comment": "The 'variables' dimension is forbidden since none are indicated.", "properties": { "input": { "properties": { "dim_order": { "not": { "contains": { "const": "variables" } } } } } } } }, "ModelOutputVariablesDimensionRef": { "$comment": "This definition ensures that, if an MLM output 'variables' is provided with at least one entry, the corresponding 'variables' dimension is defined in 'dim_order'. Otherwise, 'variables' must be omitted or empty.", "if": { "required": [ "variables" ], "properties": { "variables": { "type": "array", "minItems": 1 } } }, "then": { "$comment": "The 'variables' dimension is required if bands were indicated.", "properties": { "result": { "properties": { "dim_order": { "type": "array", "contains": { "const": "variables" } } } } } }, "else": { "$comment": "The 'variables' dimension is forbidden since none are indicated.", "properties": { "result": { "properties": { "dim_order": { "not": { "contains": { "const": "variables" } } } } } } } }, "AnyBandInputRef": { "type": "object", "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties'.", "properties": { "properties": { "type": "object", "required": [ "mlm:input" ], "$comment": "This is the JSON-object 'properties' definition for the MLM input with bands listing referring to at least one band name.", "properties": { "mlm:input": { "type": "array", "$comment": "Below 'minItems' ensures that band check does not fail for explicitly empty 'mlm:input'.", "minItems": 1, "items": { "type": "object", "required": [ "bands" ], "$comment": "This is the 'Model Input Object' properties.", "properties": { "bands": { "type": "array", "minItems": 1 } } } } } } } }, "AnyBandOutputRef": { "type": "object", "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties'.", "properties": { "properties": { "type": "object", "required": [ "mlm:output" ], "$comment": "This is the JSON-object 'properties' definition for the MLM output with bands listing referring to at least one band name.", "properties": { "mlm:output": { "type": "array", "$comment": "Below 'minItems' ensures that band check does not fail for explicitly empty 'mlm:output'.", "minItems": 1, "items": { "type": "object", "required": [ "bands" ], "$comment": "This is the 'Model Output Object' properties.", "properties": { "bands": { "type": "array", "minItems": 1 } } } } } } } }, "AnyBandsRef": { "$comment": "This definition ensures that, if at least 1 named MLM input or output '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.", "if": { "anyOf": [ {"$ref": "#/$defs/AnyBandInputRef"}, {"$ref": "#/$defs/AnyBandOutputRef"} ] }, "then": { "$comment": "Need at least one 'bands' definition, but multiple are allowed.", "anyOf": [ { "$comment": "Bands described by raster extension.", "allOf": [ { "$ref": "#/$defs/stac_extensions_raster" }, { "$ref": "#/$defs/stac_extensions_raster_bands_asset" } ] }, { "$comment": "Bands described by eo extension.", "allOf": [ { "$ref": "#/$defs/stac_extensions_eo" }, { "anyOf": [ { "$ref": "#/$defs/stac_extensions_eo_bands_item" }, { "$ref": "#/$defs/stac_extensions_eo_bands_asset" } ] } ] }, { "$comment": "Bands described by STAC Core 1.1.", "allOf": [ { "$ref": "#/$defs/stac_version_1.1" }, { "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties'.", "properties": { "properties": { "required": [ "bands" ], "$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].", "properties": { "bands": { "type": "array", "minItems": 1, "items": { "type": "object" } } } } } } ] } ] }, "else": { "$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." } }, "AnyVariablesInputRef": { "type": "object", "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties'.", "properties": { "properties": { "type": "object", "required": [ "mlm:input" ], "$comment": "This is the JSON-object 'properties' definition for the MLM input with variables listing referring to at least one variable name.", "properties": { "mlm:input": { "type": "array", "$comment": "Below 'minItems' ensures that band check does not fail for explicitly empty 'mlm:input'.", "minItems": 1, "items": { "type": "object", "required": [ "variables" ], "$comment": "This is the 'Model Input Object' properties.", "properties": { "variables": { "type": "array", "minItems": 1 } } } } } } } }, "AnyVariablesOutputRef": { "type": "object", "$comment": "This is the JSON-object 'properties' definition, which describes the STAC-Item field named 'properties'.", "properties": { "properties": { "type": "object", "required": [ "mlm:output" ], "$comment": "This is the JSON-object 'properties' definition for the MLM output with variables listing referring to at least one variable name.", "properties": { "mlm:output": { "type": "array", "$comment": "Below 'minItems' ensures that band check does not fail for explicitly empty 'mlm:output'.", "minItems": 1, "items": { "type": "object", "required": [ "variables" ], "$comment": "This is the 'Model Output Object' properties.", "properties": { "variables": { "type": "array", "minItems": 1 } } } } } } } }, "AnyVariablesRef": { "$comment": "This definition ensures that, if at least 1 named MLM input or output 'variables' is provided, at least 1 of the supported references from STAC datacube is provided as well. Otherwise, 'variables' must be explicitly empty.", "if": { "anyOf": [ {"$ref": "#/$defs/AnyVariablesInputRef"}, {"$ref": "#/$defs/AnyVariablesOutputRef"} ] }, "then": { "$comment": "Need at least one 'variables' definition, but multiple are allowed (although for now, only 'datacube' is defined).", "anyOf": [ { "$comment": "Variables described by datacube extension.", "allOf": [ { "$ref": "#/$defs/stac_extensions_datacube_variables" }, { "anyOf": [ { "$ref": "#/$defs/stac_extensions_datacube_variables_item" }, { "$ref": "#/$defs/stac_extensions_datacube_variables_asset" } ] } ] } ] }, "else": { "$comment": "Case where no 'variables' (empty list) are referenced in the MLM input. Because models can use a mixture of inputs with/without variables, we cannot enforce their references to be omitted. If variables are provided in the 'mlm:model', it will simply be an odd case if none are used in any 'mlm:input' variables." } } } }