Abstract

This document presents the abstract design of the data model for the Planetary Data System Search Platform (PDSSP) within the STACPlanet framework.

The objective is to define an interoperable data model enabling the discovery, access, and reuse of planetary science data through modern open standards adopted by the scientific community.

The design is based on several complementary reference frameworks:

  • NASA’s Orbital Data Explorer (ODE) data model, widely used for planetary data indexing and search services.

  • The principles of Open Science, promoting accessibility, interoperability, and reusability of scientific data.

  • The Observation and Measurements (O&M) model defined by the Open Geospatial Consortium (OGC), providing a conceptual framework for representing scientific observations.

  • The SpatioTemporal Asset Catalog (STAC) standard, widely adopted for geospatial data discovery and metadata description.

  • The Europlanet Table Access Protocol (EPN-TAP) from the IVOA, which provides a standardized interface and data model for accessing planetary science data services.

The document first introduces the core concepts of the O&M model and its relevance for planetary science data representation. It then analyzes the NASA ODE data model in order to identify key entities and relationships required for planetary observation systems.

A conceptual mapping between O&M, EPN-TAP, and STAC is then proposed. This mapping translates observation concepts, procedures, observed phenomena, results, and target entities into STAC core constructs such as Catalogs, Collections, Items, and Assets, while aligning them with EPN-TAP parameterization principles and service-oriented access models.

Finally, the document defines the resulting STAC data model for PDSSP, which emerges from the convergence of NASA practices, OGC standards, IVOA EPN-TAP recommendations, and the STAC ecosystem.

This model forms the foundation of the STACPlanet architecture and aims to enable federated access to planetary datasets while ensuring semantic interoperability across modern scientific infrastructures.

Keywords

STAC, STACPlanet, PDSSP, ODE, IVOA, EPN-TAP, OGC, O&M

List of Figures

1. Acronyms

This section lists, in alphabetical order, the acronyms used throughout this document. Each occurrence of an acronym in the text links back to its definition here.

Acronym Definition

DALI

Data Access Layer Interface

DEM

Digital Elevation Model

DOI

Digital Object Identifier

EPN-TAP

Europlanet Table Access Protocol

FAIR

Findable, Accessible, Interoperable, Reusable

IHID

Instrument Host Id

IID

Instrument Id

IVOA

International Virtual Observatory Alliance

JD

Julian Days

O&M

Observations and Measurements

ODE

Orbital Data Explorer

OGC

Open Geospatial Consortium

OMS

Observations, Measurements, and Samples

PDS

Planetary Data System

PDSSP

Planetary Surfaces Data and Services Pole

PROV

W3C Provenance (data model and family of specifications)

PT

Product Type

STAC

SpatioTemporal Asset Catalog

TAP

Table Access Protocol

UWS

Universal Worker Service

2. General Context

In the current landscape of planetary research, the interoperability of data sets is an unavoidable requirement. Spatial programs and the massive publication of data volumes via the ODE service are on the rise. On the other hand, European researchers and archive services use the EPN-TAP model to describe and disseminate their data sets, while the DOI (Digital Object Identifier) ensures the permanence and citability of numerical resources.

Finally, the Open Science movement requires that these data be FAIR (Findable, Accessible, Interoperable, Reusable) (Wilkinson et al., 2016) in order to maximize their scientific and societal value.

2.1. FAIR Principles

The FAIR principles, originally defined by Wilkinson et al. (2016), are organized into four groups, each broken down into sub-criteria (source):

Sub-criterion Description

Findable

F1

(Meta)data are assigned a globally unique and persistent identifier.

F2

Data are described with rich metadata.

F3

Metadata clearly and explicitly include the identifier of the data they describe.

F4

(Meta)data are registered or indexed in a searchable resource.

Accessible

A1

(Meta)data are retrievable by their identifier using a standardised communications protocol.

A1.1

The protocol is open, free, and universally implementable.

A1.2

The protocol allows for an authentication and authorisation procedure, where necessary.

A2

Metadata are accessible, even when the data are no longer available.

Interoperable

I1

(Meta)data use a formal, accessible, shared, and broadly applicable language for knowledge representation.

I2

(Meta)data use vocabularies that follow FAIR principles.

I3

(Meta)data include qualified references to other (meta)data.

Reusable

R1

(Meta)data are richly described with a plurality of accurate and relevant attributes.

R1.1

(Meta)data are released with a clear and accessible data usage license.

R1.2

(Meta)data are associated with detailed provenance (W3C PROV-Overview, 2013).

R1.3

(Meta)data meet domain-relevant community standards.

FAIR and Open are complementary but distinct requirements, and PDSSP must satisfy both. Being FAIR does not automatically mean being Open: principle A1.2 above explicitly allows access to be gated behind authentication or authorization "where necessary," so a dataset can be fully FAIR while remaining access-restricted. For PDSSP data to genuinely support Open Science, it must therefore be:

  • FAIR — findable, accessible (in the FAIR sense above), interoperable, and reusable; and

  • Open — freely accessible without unjustified technical, legal, or financial barriers, and released under an open license, following the "as open as possible, as closed as necessary" principle.

2.2. STAC Planet data model constraints

The Planetary Surfaces Data and Services Pole (PDSSP) must therefore be able to ingest the free products provided by NASA/ODE, transform them into a format compliant with EPN-TAP, assign them a DOI, and make them fully reusable within the Open Science ecosystem. This dual constraint—accepting a very specific input format and producing a set of heterogeneous outputs—requires a central data model that serves as a pivot between the different standards.

PDSSP Pivot Architecture
Figure 1. PDSSP Pivot Architecture

3. Objectives of the Document

The objectives of this document are as follows:

  • Define the data model of the Pole, structured as follows:

    • Directly import data compliant with NASA/ODE;

    • Export sets of metadata compatible with EPN-TAP, DataCite/DOI, and Open Science principles.

  • Illustrate each reference model (NASA/ODE, EPN-TAP, DOI, Open Science) and show how its concepts are projected onto the Pole’s model.

  • Compare the Pole’s model with the O&M standard (Observations & Measurements — ISO 19156), in order to:

    • Provide an internationally recognized reference framework;

    • Facilitate future extensions and exchanges with other communities that already use O&M.

4. Methodology

To ensure a rigorous comparison, each reference model will be summarized into three to five key elements (entities, attributes, relationships) and then mapped to the components of the Pole’s model using correspondence tables.

The O&M standard will be presented first in the document, as it constitutes the semantic anchor point: the Pole’s model is built as a specialization of O&M, enriched with fields required by NASA/ODE, EPN-TAP, DOI, and Open Science.

This "top-down" approach (from the generic O&M standard to the specifics of the Pole) ensures:

  • Conceptual coherence across all stages of the data value chain;

  • The possibility of extending the model further (e.g., adoption of other observation standards or new FAIR requirements).

5. Brief Overview of the O&M Standard

5.1. Observation & Measurement 2011

Observation & Measurements (O&M), jointly published by the Open Geospatial Consortium (OGC) and ISO under the ISO 19156:2011 reference, is a conceptual standard that defines a common schema for describing scientific observations and their results.

It is designed to be used in a wide variety of domains—meteorology, hydrology, oceanography, environmental sciences—and to facilitate the exchange of data between scientific and technical communities.

The standard provides a natural language definition that serves as a guide for the entire model:

An observation is the process by which an observer applies a specific procedure to estimate a property of a feature of interest and produces a result.

<<acr-om
Figure 2. OM UML Data Model

Each term in bold corresponds to a formal interface in the model.

<<acr-om
Figure 3. OM 2011 Conceptual Model
Interface Role PDSSP example

Observation

The act of observing, located in time

A THEMIS acquisition on July 5, 2002

FeatureOfInterest

The real-world object whose property is observed

The surface of Mars

ObservableProperty

The physical property being measured

Brightness temperature in infrared

Observer

The instrument or sensor that measures

THEMIS instrument

Host

The platform carrying the instrument

Mars Odyssey spacecraft

ObservingProcedure

The method or processing chain applied

Radiometric calibration (BTR)

Deployment

TODO

TODO

The Observation interface includes attributes that contextualize the act of observing in time and qualify its result:

Attribute Description

phenomenonTime

The moment when the observed phenomenon actually occurred

resultTime

The moment when the result was produced or recorded

validTime

The period during which the result is considered valid

result

The value produced by the observation (of type Any: number, text, image, etc.)

resultQuality

The quality or reliability of the result

observationType

The category of observation performed

parameter

Contextual parameters such as field of view angle, pressure, altitude

The relationships to the five interfaces (featureOfInterest, observer, host, observingProcedure, observedProperty) are modeled as associations, not as attributes. This means that each entity has its own independent existence and can be shared among multiple observations.

5.2. Observation & Measurement 2023

The revised ISO 19156:2023, jointly prepared with the Open Geospatial Consortium, introduces missing concepts from the previous version and provides clarifications on existing concepts and their relationships, while keeping the fundamental data model largely intact.

The 2011 version was primarily designed in the context of the OGC's Sensor Web Enablement, meaning it was intended for relatively homogeneous environmental sensor networks. Twelve years of use across much broader domains—planetary sciences, medicine, industrial IoT—revealed gaps and ambiguities that the 2023 revision addresses.

The name of the standard itself subtly reflects this evolution: it shifts from Observations and Measurements to Observations, Measurements, and Samples (OMS), signaling that physical samples are now a first-class concept in the model, rather than an appendix.

The 2011 conceptual schema is fully preserved. Any profile or implementation compliant with the 2011 version remains conceptually compatible with the 2023 version.

The Five Addressed Gaps:

  • Formal Collection Absence : In 2011, there was no formal way to indicate that a set of observations constituted a coherent whole with its own metadata—such as a measurement campaign, a time series, or a mission dataset. This gap forced each implementation to invent its own grouping concept, which was incompatible with others. The 2023 version introduces AbstractObservationCollection, a class that groups observations and shares common characteristics with them via AbstractObservationCharacteristics.

  • Rigid Result Typing : In 2011, each result type required a dedicated subclass: OM_Measurement for a number, OM_CategoryObservation for text, and OM_ComplexObservation for a structure. This rigid hierarchy made extending the model complex and produced schemas that were difficult to maintain. The 2023 version adopts "soft-typing": the observation type is carried by an observationType attribute rather than the class hierarchy, providing much more flexibility without losing expressiveness.

  • Ambiguity of Feature of Interest : In scientific practice, an intermediate sample is often observed to learn something about a real object of interest. For example, a rover collects a fragment of Martian rock to analyze its mineralogical composition—the fragment is what is directly measured, while Mars is what is ultimately being characterized. In 2011, a single featureOfInterest association did not allow distinguishing between these two levels. The 2023 version explicitly introduces proximateFeatureOfInterest for the directly measured object and ultimateFeatureOfInterest for the final object of interest.

  • Absence of Deployment : How to model that an instrument is installed on a platform at a given date, in a specific configuration, and then replaced or reconfigured? In 2011, the relationship between Observer and Host was a simple association without temporality or parameterization. The 2023 version introduces Deployment to formalize this link over time, which is essential for space missions or long-lived ground-based telescopes where instruments evolve.

  • Redesign of Sample Types : In 2011, SF_SamplingFeature types were classified according to their topological dimension—point, curve, surface, or volume. This classification was suitable for terrestrial geospatial data but poorly adapted to experimental sciences in general. The 2023 version reclassifies samples according to their physical nature: SpatialSample for objects located in space, MaterialSample for physical ex-situ samples, and StatisticalSample for statistical populations. This classification is immediately understandable for a chemist, biologist, or planetary scientist.

<<acr-om
Figure 4. OM 2023 Conceptual Model

6. Presentation of Reference Data Models

6.1. EPN Core

The EPN-TAP data model, a standard of the International Virtual Observatory Alliance (IVOA), is a comprehensive framework designed to facilitate the discovery and access of data related to the solar system. This model is integral to the EPN-TAP protocol, which extends the IVOA's Table Access Protocol (TAP) to provide standardized access to planetary science data.

The EPN-TAP data model includes the EPN-TAP metadata dictionary, which defines essential parameters for describing data products. These parameters cover various aspects such as temporal, spectral, spatial, and photometric characteristics, as well as the origin, content, and access methods of the data.

An EPN-TAP service consists of a single table that describes a list of granules using the metadata dictionary. Each granule corresponds to a row in the table, while each parameter corresponds to a column. Only one data product can be described and linked per row of the table, supporting observations, simulations, or experimental data.

The global philosophy of EPN-TAP is to describe all tables with a common set of mandatory parameters. This standardization allows for the seamless querying of multiple EPN-TAP services together, enhancing interoperability and data accessibility across different platforms and disciplines. Several independent services can reside on a single server, further promoting efficient data management and collaboration within the scientific community.

EPN Data model
Figure 5. EPN Core UML Data Model
Parameter Description

granule_uid

Identifier for this row. This parameter is a primary key in epn_core tables, i.e., no two different rows may share the same granule_uid. There can be only one data file associated to a granule (plus possibly a thumbnail for quick-look purpose in a search interface). Basic ASCII characters are allowed, including internal spaces, except for the # character.

obs_id

Associates granules derived from the same data (e.g., various representations or processing levels). May be the ID of the original observation.

granule_gid

Associates granules of the same type (e.g., same map projection, or geometry data products). Think of it as a simple and convenient way to group or differentiate types of data. When several files relate to the same data, this parameter helps distinguishing them.

dataproduct_type

Describes the high-level scientific organization of the data product linked by the access_url parameter, or directly included in the table (in which case the value is ci for catalogue_item). EPN-TAP defines several types. Data providers must select the type most adapted to their data. In complex situations, several types can be used in a hash-separated list.

measurement_type

Defines the physical quantities contained in the data, using UCDs (Cecconi and Louys et al., 2021). It relates to the reported quantity, not to the type of experiment. Only UCDs related to physical quantities can be used (e.g., phys.absorption;em.opt.I is eligible, while pos.lunar.occult is not). Used to provide indications to visualization/processing tools.

processing_level

Provides a quick evaluation of data readiness level. EPN-TAP uses a simplified scheme. Several classifications are in use in different contexts. EPN-TAP uses the CODMAC/PDS3 levels but removes intermediate calibration levels. "Partially calibrated" data collections are generally considered as not calibrated. "Ancillary" data include extra information documenting the measurements.

processing_level_desc

Optional parameter to provide a specific encoding of processing levels related to a data collection, or more details about partial calibrations.

target_name

Identifies a target by name or ID. The target may be any Solar System body, exoplanet, planetary sample, or meteorite, plus in some cases astronomical objects or spacecraft. Alternative names of the same target must not be listed here but may be provided through the optional alt_target_name parameter. This parameter is case-sensitive.

target_class

Identifies the type of the target. Solar System bodies are defined without ambiguity by the couple target_class and target_name. In other cases, targets may have no proper name, but the target_class parameter must contain a value in all cases.

time_min, time_max

Provide the date and time of acquisition in the observer frame. Always provided in UTC and formatted in Julian Days (double precision). EPN-TAP uses standard JD to avoid ambiguity with time origin. Double precision floats ensure an accuracy on the order of 1 ms.

time_sampling_step (min/max)

Provide the sampling step in seconds for measurements of dynamical phenomena and computations. This is the time between 2 successive measurements or data, mostly relevant when the measurements are regularly spaced.

time_exp (min/max)

Correspond to the integration time (or exposure time) of measurements in seconds. Provide an estimate of the time resolution for dynamical phenomena, as well as an indication of relative S/N ratio inside a given data collection.

spectral_range (min/max)

Define the upper and lower bounds of the spectral domain of the data. Expressed on a frequency scale in Hertz. The spectral range and associated parameters only apply to electromagnetic waves. Recommended to fill even for images obtained through a filter.

spectral_sampling_step (min/max)

Provide the spectral separation between the centers of two adjacent filters or channels. Expressed on a frequency scale in Hz. Most relevant for radio observations with regular sampling.

spectral_resolution (min/max)

Provide the (dimensionless) resolving power λ/∆λ = ν/∆ν. Mostly intended to provide an order of magnitude, e.g., to distinguish between Fourier spectrometers, grating spectrometers, or filter cameras.

c1 (min/max)

Provide up to three spatial coordinates of the measured target. Coordinates depend on the spatial_frame_type parameter. All services must handle three spatial coordinates, even if the third one is always set to NULL. Some coordinates are measured along a circle and must handle 0-meridian crossing.

c2 (min/max)

-

c3 (min/max)

-

c1_resol (min/max)

Provide a simple estimate of the resolution in the same frame/units as c1/c2/c3. For instance, if spatial_frame_type = celestial, it can accommodate the FWHM of the PSF on the sky (in degrees).

c2_resol (min/max)

-

c3_resol (min/max)

-

spatial_frame_type

2D angles in body-fixed frame: longitude c1 and latitude c2, plus possibly altitude as c3. A planetocentric system with eastward longitudes in the range (0, 360)° is required for service interoperability. IAU 2009 planetocentric convention applies. Parameter c3 is measured above the reference ellipsoid and can be <0 for interiors.

incidence (min/max)

Define the upper and lower bounds of the incidence angle range in the data (Solar Zenith Angle). Always indicated in decimal degrees, usually ranging from 0 to 90° (with 0° indicating the normal to the surface).

emergence (min/max)

Define the upper and lower bounds of the emergence, emission, or viewing angle range in the data. Always indicated in decimal degrees, usually ranging from 0 to 90° (with 0° indicating the normal to the surface).

phase (min/max)

Define the upper and lower bounds of the phase angle range in the data (scattering angle − 180°, or light source−target-observer angle). Always indicated in decimal degrees, may range from -180 to 180° (with 0° corresponding to opposition).

s_region

Introduces a footprint as a contour. Should be given for geolocalized data products in 2D, most notably on the sky (using RA, Dec) or on planetary surfaces (using E longitude, latitude). Coordinates are provided in the same reference system as c1/c2 parameters.

coverage

Introduces another type of footprint, with potential extension to time coverage. When both s_region and coverage are present, care must be taken that they are consistent.

instrument_host_name

Provides the name of the observatory, spacecraft, or facility that performed the measurements. A hash-separated-list of host names must be provided for integrated data sets. In the EPN-TAP table, the acronym is preferred to the full name.

instrument_name

Identifies the instrument(s) that acquired the data. A hash-separated-list of instruments must be provided for integrated data products. Service providers are invited to include multiple values for instrument name, e.g., complete name and usual acronym.

service_title

The schema name of the service: provides a unique acronym for the service/table, constant throughout the service. Intended to identify the source of the data in later stages, e.g., when handling multiservice results. Special/unusual characters must be avoided (including #, ?, etc.).

creation_date

Provides the date when the granule was introduced in the service.

modification_date

Provides the date when the granule was last updated. Intended to speed up mirroring between sites and to flag recalibrations. When unknown or not relevant, the creation date is replicated here.

release_date

Provides the date when the granule becomes public. Intended to support a proprietary period. When unknown or not relevant, the creation date is replicated here.

6.2. Nasa ODE

The ODE (Orbital Data Explorer) data model from NASA provides a comprehensive framework for describing planetary data products, their metadata, and associated files. This model supports querying and discovery of planetary science data through standardized interfaces.

6.2.1. ProductFile Class

The ProductFile class represents a single downloadable file associated with a PDS product.

ProductFile Class Diagram
Figure 6. ProductFile Class Diagram
Attribute Description

FileName

Name of the file (without path).

Type

ODE classification: "Browse", "Product", "Label", etc.

KBytes

File size in kilobytes.

URL

Download URL for the file.

Description

Human-readable description of the file content.

Creation_date

ISO 8601 date string when the file was created.

The ProductFile class provides metadata for individual files associated with PDS products, including classification, size, access information, and descriptive content.

6.2.2. PdsRecordModel Class

The PdsRecordModel class represents a full metadata record for a single planetary data product. It contains comprehensive information about the product, including identifiers, temporal data, geometry, observation details, and file access.

PdsRecordModel Class Diagram
Figure 7. PdsRecordModel Class Diagram
PdsRecordModel Core Attributes
Attribute Description

ode_id

An internal ODE product identifier. NOTE: This id is assigned by ODE when the product is added to the ODE metadata database. It is generally stable but can be changed when the ODE metadatabase is rebuilt. In general, this id should only be used shortly after acquisition.

pdsid

PDS Product Id

ihid

Instrument host id. See ODE for valid instrument host ids

iid

Instrument id. See ODE for valid instrument ids

pt

ODE Product type. This is ODE's product type. In general, it is obtained from the label but can be changed depending on whether a label has a product type, whether there are other products in the same instrument with the same product type in the label, etc. If this is not the same product type as in the label, the return will include a Label_Product_Type value as well.

LabelFileName

The file name of the product label

Target_name

Product target (example: Mars)

Data_Set_Id

PDS Data Set Id

PdsRecordModel Temporal Attributes
Attribute Description

Product_creation_time

Product creation time (UTC)

Product_release_date

Product release date

Observation_time

Observation time (mid-point between the start and end of the observation)

UTC_start_time

Observation start time in UTC

UTC_stop_time

Observation end time in UTC

PdsRecordModel Descriptive Attributes
Attribute Description

Product_title

Product title

Product_version_id

Product version

Label_product_type

Label product type (if it exists in the label and is different from the ODE_Product_Type)

Description

Label description

Comment

Any associated comment

ODE_notes

A note about how data has been entered into ODE

PdsRecordModel Geometry Attributes
Attribute Description

Easternmost_longitude

Longitude 0-360 Easternmost longitude of the footprint

Maximum_latitude

Planetocentric maximum latitude of the footprint

Minimum_latitude

Planetocentric minimum latitude of the footprint

Westernmost_longitude

Longitude 0-360 Westernmost longitude of the footprint

Footprint_geometry

Cylindrical projected planetocentric, longitude 0-360 product footprint in WKT format. Only if there is a valid footprint. Note - this is a cylindrical projected footprint. The footprint has been split into multiple polygons when crossing the 0/360 longitude line and any footprints that cross the poles have been adjusted to add points to and around the pole. It is meant for use in cylindrical projects and is not appropriate for spherical displays.

Footprint_C0_geometry

Planetocentric, longitude -180-180 product footprint in WKT format. Only if there is a valid footprint. Note - this is a cylindrical projected footprint. The footprint has been split into multiple polygons when crossing the -180/180 longitude line and any footprints that cross the poles have been adjusted to add points to and around the pole. It is meant for use in cylindrical projects and is not appropriate for spherical displays.

Footprint_GL_geometry

Planetocentric, longitude 0-360 product footprint in WKT format. Only if there is a valid footprint. This is not a projected footprint.

Footprint_NP_geometry

Stereographic north polar projected footprint in WKT format. Only if there is a valid footprint. This footprint has been projected into meters in stereographic north polar projection.

Footprint_SP_geometry

Stereographic south polar projected footprint in WKT format. Only if there is a valid footprint. This footprint has been projected into meters in stereographic south polar projection.

Footprints_cross_meridian

T if the footprint crosses the 0/360 longitude line

Pole_state

String of "none", "north", or "south"

PdsRecordModel Center Coordinates Attributes
Attribute Description

Center_georeferenced

T if the product has a footprint center

Center_latitude

Planetocentric footprint center latitude

Center_longitude

Longitude 0-360 center longitude

Center_latitude_text

Text found in the center latitude label keyword if the center latitude is not a valid number

Center_longitude_text

Text found in the center longitude label keyword if the center longitude is not a valid number

PdsRecordModel Bounding Box Attributes
Attribute Description

BB_georeferenced

T if the product has a footprint bounding box

Easternmost_longitude_text

Text found in the easternmost longitude label keyword if the easternmost longitude is not a valid number

Maximum_latitude_text

Text found in the maximum latitude label keyword if the maximum latitude is not a valid number

Minimum_latitude_text

Text found in the minimum latitude label keyword if the minimum latitude is not a valid number

Westernmost_longitude_text

Text found in the westernmost longitude label keyword if the westernmost longitude is not a valid number

Footprint_souce

A brief description of where the footprint came from

PdsRecordModel Observation Attributes
Attribute Description

Observation_id

Identifies a scientific observation within a dataset.

Observation_number

Monotonically increasing ordinal counter of the EDRs generated for a particular OBSERVATION_ID.

Observation_type

Identifies the general type of an observation

Activity_id

Label Activity id

Start_orbit_number

Start orbit number

Stop_orbit_number

End orbit number

SpaceCraft_clock_start_count

Spacecraft clock start

SpaceCraft_clock_stop_count

Spacecraft clock end

PdsRecordModel Geometry-Derived Angles
Attribute Description

Emission_angle

Emission angle

Emission_angle_text

Emission angle text from the product label

Phase_angle

Phase angle

Phase_angle_text

Phase angle text from the product label

Incidence_angle

Incidence angle

Incidence_angle_text

Incidence angle text from the product label

PdsRecordModel Map Projection Attributes
Attribute Description

Map_resolution

Map resolution

Map_resolution_text

Map resolution text from the product label

Map_scale

Map scale

Map_scale_text

Map scale text from the product label

PdsRecordModel Solar/Atmospheric Attributes
Attribute Description

Solar_distance

Solar distance

Solar_distance_text

Solar distance text from the product label

Solar_longitude

Solar longitude

Predicted_dust_opacity

Predicted dust opacity

Predicted_dust_opacity_text

Predicted dust opacity text

PdsRecordModel Archive/Volume Attributes
Attribute Description

PDSVolume_Id

Volume Id

RelativePathtoVol

The relative path from the volume root to the product label file

Producer_id

Producer id

Product_name

Product name

label

Complete product label for PDS3 product labels

USGS_Sites

A USGS site that this product’s footprint partially or completely covers

PdsRecordModel URL Attributes
Attribute Description

PDS4LabelURL

Pointer to PDS4 XML label for PDS4 products

LabelURL

URL to the product label

FilesURL

URL to the product files

ProductURL

URL to the product

External_url

URL to an external reference to the product (e.g. the HiRISE site)

External_url2

URL to a second external reference to the product (e.g. the HiRISE site)

External_url3

URL to a third external reference to the product (e.g. the HiRISE site)

PdsRecordModel File Attributes
Attribute Description

Product_files

Dictionary of file lists (ProductFile objects) associated with the product

browse

If there is an ODE browse image - returns a base64 string of the PNG image

thumbnail

If there is an ODE thumbnail image - returns a base64 string of the PNG image

The PdsRecordModel class inherits from the O&M Observation model and extends it with comprehensive NASA-specific metadata for planetary data products, including temporal, geometric, observational, and archival information.

6.2.3. IIPTSetModel Class

The IIPTSetModel class represents a single instrument/product-type combination from an ODE query=iipt response. It provides metadata about the instrument, product type, and valid search parameters for that combination.

IIPTSetModel Class Diagram
Figure 8. IIPTSetModel Class Diagram
IIPTSetModel Attributes
Attribute Description

ODEMetaDB

ODE Meta DB – can be used as a Target input

IHID

Instrument Host Id

IHName

Instrument Host Name

IID

Instrument Id

IName

Instrument Name

PT

Product Type

PTName

Product Type Name

DataSetId

Data Set Id

IIPTSetModel Filter Validity Attributes
Attribute Description

ValidEmissionAngles

True if valid Emission Angles exist for searches

ValidPhaseAngles

True if valid Phase Angles exist for searches

ValidIncidenceAngles

True if valid Incidence Angles exist for searches

ValidSolLongs

True if valid Solar Longitudes exist for searches

ValidFootprints

True if valid Footprints exist for searches

ValidObservationTimes

True if valid Observation Times exist for searches

ValidTargets

Set of valid target values for the Target query parameter for a given instrument host, instrument, product type

IIPTSetModel Statistical Attributes
Attribute Description

NumberProducts

Number of products with this instrument host/instrument/product type

MinOrbit

Minimum orbit value for all products with this instrument host/instrument/product type

MaxOrbit

Maximum orbit value for all products with this instrument host/instrument/product type

MinObservationTime

Minimum observation time value for all products with this instrument host/instrument/product type

MaxObservationTime

Maximum observation time value for all products with this instrument host/instrument/product type

MinProductId

Minimum product id value for all products with this instrument host/instrument/product type

MaxProductId

Maximum product id value for all products with this instrument host/instrument/product type

NumberObservations

Number of observation values found in the products (valid only for selected instrument host/instrument/product types)

IIPTSetModel Special Values Attributes
Attribute Description

SpecialValue1

Name or description of special value 1 unique to this product set

MinSpecialValue1

Minimum special value 1

MaxSpecialValue1

Maximum special value 1

SpecialValue2

Name or description of special value 2 unique to this product set

MinSpecialValue2

Minimum special value 2

MaxSpecialValue2

Maximum special value 2

The IIPTSetModel class provides metadata about instrument and product type combinations, including information about which search parameters are valid and statistical information about the products in each combination.

6.3. DOI

The Digital Object Identifier (DOI) is, strictly speaking, a persistent identifier system built on the Handle System: it guarantees that a digital resource remains uniquely and durably referenceable and citable. On its own, a DOI is only a string; what turns it into a reference data model is the metadata schema attached to it at registration time.

For research data, this schema is the DataCite Metadata Schema. It is the model the Pole relies on to expose its datasets in a citable, machine-readable form when minting DOIs. The current version is Schema 4.7 (released March 2026); it defines a small set of mandatory properties, completed by recommended and optional ones.

The DataCite schema defines six mandatory properties that must be supplied for every DOI:

Property Description

Identifier

The DOI itself, with identifierType set to DOI. Unique and persistent identifier of the resource.

Creator

The main entities responsible for producing the resource (person, organization, or instrument team). Used to build the citation.

Title

The name by which the resource is known.

Publisher

The entity that holds, archives, publishes, or otherwise makes the resource available. For the Pole, this is the publishing organization (CNES/PDSSP).

PublicationYear

The year the resource was made publicly available.

ResourceType

The nature of the resource, with the mandatory controlled attribute resourceTypeGeneral (e.g., Dataset, Collection).

Several recommended and optional properties are particularly relevant to planetary data: Date (with a dateType such as Collected, Created, or Issued), RelatedIdentifier (qualified links to related products or observations), GeoLocation (place name, point, box, or polygon footprint), FundingReference (funder, award, programme), Rights (licence), Version, Size, and Format.

Because the Pole already captures most of this information through EPN-TAP, STAC, and the O&M-derived models, DOI registration does not require a separate model: it is essentially a projection of existing fields onto the DataCite properties. The table below summarizes this projection.

DataCite property Source in the Pole’s model

Identifier (DOI)

DOI minted for the dataset or collection

Creator

Data producers (Producer_id, instrument host / team)

Title

Product_title / STAC title

Publisher

Publishing organization (CNES/PDSSP)

PublicationYear

Year derived from release_date

ResourceType (Dataset)

dataproduct_type

Date (Collected / Issued / Created)

time_min/time_max / release_date / creation_date

GeoLocation (polygon/box)

s_region / footprint_geometry

RelatedIdentifier

obs_id, related products, access_url

FundingReference

ContributiveWorksExtension (funding_source, programme_id)

Rights

STAC license

Version

Product_version_id

Size / Format

access_estsize / access_format

In this way, the DOI/DataCite layer provides the citability and long-term referenceability required by Open Science, while reusing the metadata already produced by the other reference models.

6.4. Open Science

Unlike the other sections of this chapter, Open Science is not a data model. It is a framework of principles: it does not define entities, attributes, or relationships, but rather states a set of requirements that any data model must satisfy in order to maximize the scientific and societal value of the data. These requirements are commonly summarized by the FAIR principles — Findable, Accessible, Interoperable, Reusable — formalized by Wilkinson et al. (2016).

For this reason, Open Science is not implemented in the Pole through a dedicated model. Instead, the FAIR principles are jointly realized by the reference models presented elsewhere in this document. The following table makes this correspondence explicit.

FAIR principle Realization in the Pole’s model

Findable

Persistent, unique identifiers (DOI/DataCite, granule_uid, STAC Item id); rich and indexed metadata; standardized search interfaces (EPN-TAP, STAC API).

Accessible

Retrieval by identifier through open, standard protocols (HTTP, TAP); direct access to products (access_url, STAC asset href); metadata that remain accessible even when the data themselves are still under embargo (release_date).

Interoperable

Shared vocabularies and formats: the O&M semantic anchor, UCDs for physical quantities, IAU nomenclature for targets, WKT geometries, MIME types (access_format).

Reusable

Explicit licensing (STAC license field); detailed provenance (ContributiveWorksExtension: programme, funding source, collaboration; processing_level); life-cycle timestamps (creation_date, modification_date).

Open Science therefore acts as the cross-cutting criterion that justifies the modeling choices of the Pole: the joint adoption of EPN-TAP, STAC, and DataCite/DOI is precisely intended to guarantee FAIR compliance across the entire data value chain.

6.5. STAC

The SpatioTemporal Asset Catalog (STAC) data model is an open specification designed to enhance the discovery, accessibility, and interoperability of geospatial data. STAC provides a standardized way to describe and catalog geospatial assets, making it easier for users to search and utilize data from various providers. The model consists of four key components: Item, Collection, Catalog, and API. These components work together to organize and manage geospatial data, ensuring seamless integration into different systems and applications.

STAC supports a wide range of geospatial data types, including satellite imagery, SAR, LiDAR, hyperspectral imagery, point clouds, videos, and derived products like NDVI and Digital Elevation Models (DEMs). By adopting STAC, organizations can enhance the visibility and usability of their geospatial data, fostering better collaboration and innovation within the geospatial community. The STAC specification is widely adopted by major organizations such as NASA, USGS, Microsoft, ESRI, and Google, demonstrating its effectiveness and reliability in managing large-scale geospatial datasets.

The SpatioTemporal Asset Catalog (STAC) is a specification designed to improve the discoverability and accessibility of geospatial data. It provides a standardized way to describe geospatial assets, such as satellite imagery, drone data, and other observation data, using a simple and flexible JSON format. The STAC data model is built around three core components:

  • STAC Item: Represents a single asset, such as an image or a data file, along with its metadata. Each STAC item should include essential properties like the asset’s spatial and temporal extents.

  • STAC Collections: A grouping of STAC items that share common characteristics, such as data from the same sensor or mission. Collections provide additional metadata that describe the group as a whole, facilitating the discovery of related datasets.

  • STAC Catalog: Acts as a container for STAC items and collections. Catalogs can be nested, allowing for hierarchical organization of data. They provide structural elements to manage and navigate through large datasets.

STAC extensions enhance the core data model by adding domain-specific metadata fields. These extensions allow STAC to accommodate a wide range of geospatial data types and use cases.

Moreover, STAC can support more than just geolocated information. According to RFC 7946, section 3.2, the geometry can be null, enabling STAC to be used for any digital information by creating specific dictionaries. Here are some reasons for a null geometry:

  • Non-georeferenced Data: The item represents a resource without a spatial footprint, such as a metadata table or a document.

  • Unknown or Undetermined Geometry: During data ingestion, the geometry may not have been determined or extracted yet.

  • Confidentiality: Some data providers may intentionally hide the geometry for confidentiality reasons.

<<acr-stac
Figure 9. STAC UML Data Model

7. Comparison Reference Data Model with O&M

This chapter compares the reference data models with the O&M standard. Only EPN Core and NASA ODE are covered here: as discussed in Chapter 5, DOI/DataCite and Open Science are not data models in the same sense — DOI/DataCite is a citation metadata schema and Open Science is a framework of principles (FAIR) — and therefore do not map onto the O&M interfaces. The correspondences below present each EPN Core and ODE class as an extension of an O&M interface.

Data model compatibility
Figure 10. Compatibility of Reference Data Models with OM

PDSSP-StacPlanet serves as a pivot data model that enables interoperability between heterogeneous planetary science data models and standard access protocols. Input models such as PDS3, PDSSP-Labo, and future ESA/ESO data models can be transformed into a common PDSSP-StacPlanet representation, which can then be exported to EPN-TAP. The model also supports Open Science principles through DOI-based data citation and compliance with FAIR (Findable, Accessible, Interoperable, Reusable) guidelines.

The diagram below gives a consolidated view of how the three reference models — EPN-TAP, NASA ODE, and STAC — each realize the seven O&M interfaces. Reading it by row shows which standard covers a given O&M concept; reading it by column shows the full O&M coverage of each standard.

Alignment of EPN-TAP, NASA ODE, and STAC with the OM Interfaces
Figure 11. Alignment of EPN-TAP, NASA ODE, and STAC with the OM Interfaces

7.1. EPN Core

7.1.1. EPNHost Class

The EPNHost class implments the O&M Host interface to include the EPN-specific attributes for describing the platform carrying the instrument.

EPNHost Class Diagram
Figure 12. EPNHost Class Diagram

7.1.2. EPNObserver Class

The EPNObserver class implements the O&M Observer interface to include the EPN-specific attributes for describing the observer.

EPNObserver Class Diagram
Figure 13. EPNObserver Class Diagram

7.1.3. EPNObservingProcedure Class

The EPNObservingProcedure class implments the O&M ObservingProcedure interface to include the EPN-specific attributes for describing the observing procedure of the experiment.

EPNObservingProcedure Class Diagram
Figure 14. EPNObservingProcedure Class Diagram

7.1.4. EPNObservableProperty class

The EPNObservableProperty class implements the O&M ObservableProperty interface to include EPN-specific attributes for describing the measurable physical quantities and properties contained in the data.

EPNObservableProperty Class Diagram
Figure 15. EPNObservableProperty Class Diagram

7.1.5. EPNFeatureOfInterest class

The EPNFeatureOfInterest class implements the O&M FeatureOfInterest interface to include EPN-specific attributes, distinguishing between the ultimate target and the proximate (specific) region being observed, in accordance with the O&M standard which defines both UltimateFeatureOfInterest and ProximateFeatureOfInterest concepts.

EPNFeatureOfInterest Class Diagram
Figure 16. EPNFeatureOfInterest Class Diagram
EPNUltimateFeatureOfInterest and EPNProximateFeatureOfInterest Classes

In the O&M standard, FeatureOfInterest has two important specializations: UltimateFeatureOfInterest and ProximateFeatureOfInterest. The EPN-TAP implementation follows this distinction:

  • UltimateFeatureOfInterest: Represents the primary/ultimate target of the observation (e.g., a planet, moon, or other celestial body).

  • ProximateFeatureOfInterest: Represents the specific region or point on/around the ultimate target that is being observed (e.g., a particular area on a planetary surface, atmospheric layer, or coordinate).

7.1.6. EPNResult class

The EPNResult class implements the O&M Result interface to include EPN-specific attributes for describing the data products and their access information in the context of the EPN-TAP protocol.

EPNResult Class Diagram
Figure 17. EPNResult Class Diagram

7.1.7. EPNObservationType

The EPNObservationType class implements AbstractObservationType to include EPN-specific attributes for describing observations within the EPN-TAP framework.

EPNObservationType Class Diagram
Figure 18. EPNObservationType Class Diagram

7.1.8. EPNObservation

The EPNObservation class implements the O&M AbstractObservation to include EPN-specific temporal attributes for describing observations within the EPN-TAP framework.

EPNObservation Class Diagram2
Figure 19. EPNObservation Class Diagram2

7.1.9. EPnObservationCollection

The EPNObservationCollection class implements the O&M AbstractObservationCollection to include EPN-specific temporal attributes for describing collections within the EPN-TAP framework.

EPNObservationCollection Class Diagram
Figure 20. EPNObservationCollection Class Diagram

7.2. NASA ODE

This section details the mapping between the O&M (Observations & Measurements) standard interfaces and the NASA ODE (Orbital Data Explorer) model classes. Each ODE class is presented as an extension of the O&M interfaces, with ODE-specific attributes and associations tailored to NASA’s planetary data context.

7.2.1. ODEHost

The ODEHost class implements the O&M Host interface to include ODE-specific attributes for describing the platform (e.g., spacecraft, observatory) carrying the instrument.

ODEHost Class Diagram
Figure 21. ODEHost Class Diagram

7.2.2. ODEObserver

The ODEObserver class implements the O&M Observer interface to describe the instrument or sensor used for observations, with ODE-specific attributes.

ODEObserver Class Diagram
Figure 22. ODEObserver Class Diagram

7.2.3. ODEObservingProcedure

The ODEObservingProcedure implements the O&M ObservingProcedure interface to include ODE-specific details about observation procedures, such as calibration parameters or product types.

ODEObservingProcedure Class Diagram
Figure 23. ODEObservingProcedure Class Diagram

7.2.4. ODEObservableProperty

The ODEObservableProperty class extends the O&M ObservableProperty interface to describe the physical properties being measured, with ODE-specific attributes.

ODEObservableProperty Class Diagram
Figure 24. ODEObservableProperty Class Diagram

7.2.5. ODEFeatureOfInterest

The ODEFeatureOfInterest class extends the O&M FeatureOfInterest interface to distinguish between the ultimate target (e.g., Mars) and the proximate region being observed (e.g., a specific crater).

ODEFeatureOfInterest Class Diagram
Figure 25. ODEFeatureOfInterest Class Diagram

7.2.6. ODEResult

The ODEResult class extends the O&M Result interface to describe data products and their access metadata in ODE.

ODEResult Class Diagram
Figure 26. ODEResult Class Diagram

7.2.7. ODEObservation

The ODEObservation class extends AbstractObservation to include ODE-specific temporal and observational attributes.

ODEObservation Class Diagram
Figure 27. ODEObservation Class Diagram

7.2.8. ODEObservationType

The ODEObservationType class implements AbstractObservationType to include ODE-specific attributes for describing observations within the ODE framework.

ODEObservationType Class Diagram
Figure 28. ODEObservationType Class Diagram

7.2.9. ODEObservationCollection

The ODEObservationCollection class implements the O&M ODEObservationCollection to include EPN-specific temporal attributes for describing collections within the ODE framework.

ODEObservationCollection Class Diagram
Figure 29. ODEObservationCollection Class Diagram

7.3. STAC

This section details the mapping between the O&M (Observations & Measurements) standard interfaces and the STAC (SpatioTemporal Asset Catalog) model classes. Each STAC class is presented as an extension of the O&M interfaces, with STAC-specific attributes and associations tailored to STAC.

7.3.1. STACHost

The STACHost class implements the O&M Host interface to include STAC-specific attributes for describing the platform (e.g., spacecraft, observatory) carrying the instrument.

STACHost Class Diagram
Figure 30. STACHost Class Diagram

7.3.2. STACObserver

The STACObserver class implements the O&M Observer interface to describe the instrument or sensor used for observations, with STAC-specific attributes.

STACObserver Class Diagram
Figure 31. STACObserver Class Diagram

7.3.3. STACObservingProcedure

The STACObservingProcedure implements the O&M ObservingProcedure interface to include STAC-specific details about observation procedures, such as calibration parameters or product types.

STACObservingProcedure Class Diagram
Figure 32. STACObservingProcedure Class Diagram

7.3.4. STACObservableProperty

The STACObservableProperty class extends the O&M ObservableProperty interface to describe the physical properties being measured, with STAC-specific attributes.

STACObservableProperty Class Diagram
Figure 33. STACObservableProperty Class Diagram

7.3.5. STACFeatureOfInterest

The STACFeatureOfInterest class extends the O&M FeatureOfInterest interface to distinguish between the ultimate target (e.g., Mars) and the proximate region being observed (e.g., a specific crater).

STACFeatureOfInterest Class Diagram
Figure 34. STACFeatureOfInterest Class Diagram

7.3.6. STACResult

The STACResult class extends the O&M Result interface to describe data products and their access metadata in STAC.

STACResult Class Diagram
Figure 35. STACResult Class Diagram

7.3.7. STACObservation

The STACObservation class extends AbstractObservation to include STAC-specific temporal and observational attributes.

STACObservation Class Diagram
Figure 36. STACObservation Class Diagram

7.3.8. STACObservationType

The STACObservationType class implements AbstractObservationType to include STAC-specific attributes for describing observations within the STAC framework.

STACObservationType Class Diagram
Figure 37. STACObservationType Class Diagram

7.3.9. STACObservationCollection

The STACObservationCollection class implements the O&M STACObservationCollection to include STAC-specific temporal attributes for describing collections within the STAC framework.

STACObservationCollection Class Diagram
Figure 38. STACObservationCollection Class Diagram

8. Mapping NASA ODE to STAC

This section is generated from the actual mapping code in ode-stac-proxy (ode_plugin/response/{item_mapper,properties_builder,asset_builder,link_builder, collection_mapper,stac_extensions,projection_resolver,taxonomy,utils}.py). Any ODE field consumed nowhere in the mapper is still preserved: it is copied verbatim onto item.properties as pdsode:<Field_name> (see PdsProxy.unused_fields() in pds_proxy.py), so no science metadata is silently dropped even when a row below says "Not mapped" or is absent from this table.

8.1. Host

ODE PDSSP STAC Notes

ihid

item.properties.platform

Resolved through PLATFORM_TAXONOMY[ihid] (populated at collection load time from IHID/IHName) as "<IHName> (<IHID>)". Logs a warning and returns "UNKNOWN" when ihid is not in the taxonomy.

Data_Set_Id (of the parent collection)

item.properties.mission

Not an item-level ODE field: resolved via mission_name(dataset_id) against the parent collection’s pdsode:dataset_id. Fallback order: mission_name(dataset_id)mission_name(extract_before_separator(dataset_id)) (text before the first /, _data or -data) → "UNKNOWN". The MISSION taxonomy entry can itself be overridden per collection by the DOI/investigation lookup — see sci:publications in ObservationCollection.

8.2. Observer

ODE PDSSP STAC Notes

iid

items.properties.instruments

Single-element list. Resolved through INSTRUMENT_TAXONOMY[iid] (populated at collection load time from IID/IName) as "<IName> (<IID>)". Logs a warning and returns "UNKNOWN" when iid is not in the taxonomy.

ode_id

item.id

Start_orbit_number

item.properties.sat:absolute_orbit

Stop_orbit_number

N/A

Marked as consumed (without emitting a value) when it equals Start_orbit_number, so it does not appear as a redundant pdsode:Stop_orbit_number residual. When it differs from Start_orbit_number it is not consumed and does surface as pdsode:Stop_orbit_number.

SpaceCraft_clock_start_count

item.properties.pdsode:SpaceCraft_clock_start_count

Not read by the mapper; passes through as an unconsumed-field residual.

SpaceCraft_clock_stop_count

item.properties.pdsode:SpaceCraft_clock_stop_count

Not read by the mapper; passes through as an unconsumed-field residual.

8.3. ObservingProcedure

ODE PDSSP STAC Notes

Activity_id

item.properties.pdsode:Activity_id

Not read by the mapper; passes through as an unconsumed-field residual.

Producer_id

item.properties.providers[0].name

item.properties.providers is [] when Producer_id is null, otherwise a single Provider(name=Producer_id).

8.4. ObservableProperty

N/A

8.5. FeatureOfInterest

ODE PDSSP STAC Notes

Target_name

item.properties.ssys:targets[0]

"Phobos" when pt.upper() == "PHOBOS", otherwise Target_name.capitalize().

Target_name / pt

item.properties.ssys:target_class

"satellite" when Target_name.upper() == "MOON" or pt.upper() == "PHOBOS", else "planet".

Description

item.properties.description

Also used as a last-resort source for item.properties.datetime — see Observation.

Emission_angle / Emission_angle_text

item.properties.view:off_nadir

Fallback order: Emission_angle → float(Emission_angle_text) → None.

Incidence_angle / Incidence_angle_text

item.properties.view:incidence_angle

Fallback order: Incidence_angle → float(Incidence_angle_text) → None.

Phase_angle / Phase_angle_text

item.properties.view:phase_angle

Fallback order: Phase_angle → float(Phase_angle_text) → None.

Solar_distance

item.properties.pdssp:solar_distance

Solar_distance_text is not mapped (no fallback logic in code) — passes through independently as pdsode:Solar_distance_text when present.

Solar_longitude

item.properties.pdssp:solar_longitude

Solar_longitude_text is not mapped (no fallback logic in code) — passes through independently as pdsode:Solar_longitude_text when present.

Predicted_dust_opacity / Predicted_dust_opacity_text

item.properties.pdsode:Predicted_dust_opacity / pdsode:Predicted_dust_opacity_text

Neither field is read by the mapper. Unlike the angle fields above, there is no fallback logic between the numeric and _text variants in code — both pass through independently as separate pdsode:* residuals.

Easternmost_longitude / Easternmost_longitude_text / Westernmost_longitude / Westernmost_longitude_text / Maximimum_latitude / Maximimum_latitude_text / Minimum_latitude / Minimum_latitude_text

item.bbox

Footprint_C0_geometry / Footprint_GL_geometry

item.geometry

Fallback order: Footprint_C0_geometry → Footprint_GL_geometry → None - Pole_state, Footprint_cross_meridian, Footprint_souce, Footprint_SP_geometry, Footprint_NP_geometry, Footprint_geometry, bbox

Center_georeferenced

Not mapped

Center_latitude / Center_latitude_text

item.properties.proj:centroid.lat

Center_longitude / Center_longitude_text

item.properties.proj:centroid.lon

Center_longitude (range 0-360) is converted to the -180/180 convention (center_longitude_180 computed field) before being written to proj:centroid.lon. Center_longitude_text is not mapped.

Target_name / iid / Data_Set_Id

item.properties.proj:code

Only added when both Center_latitude and Center_longitude are non-null. Resolved by resolve_crs(): instrument/dataset overrides checked first (Target_name == "Mars" and iid == "HRSC" → IAU:2015:49900; Data_Set_Id == "MGS-M-MOLA-3-PEDR-L1A-V1.0" → IAU:2015:49900), then the default CRS per Target_name (Mercury, Venus, Mars, Moon). The property is omitted entirely when the target body has no default CRS.

BB_georeferenced

Not mapped

8.6. Result

ODE PDSSP STAC Notes

LabelFileName

Not mapped to a STAC field directly. Used, together with LabelURL and RelativePathtoVol, to reconstruct External_url / External_url2 / External_url3 when the raw ODE value is not already an absolute http(s) URL — see below.

Product_Title

item.properties.title

Falls back to item.id (pdsid) when Product_title is null.

Product_version_id

item.properties.version

TBC with vesion

Label_product_type

item.properties.pdsode:Label_product_type

Not read by the mapper; passes through as an unconsumed-field residual. item.properties.product:type is not derived from this field — it is inherited from the parent collection’s classification, see ObservationType.

PDSVolume_Id

item.properties.pdsode:PDSVolume_Id

RelativePathtoVol

item.properties.pdsode:RelativePathtoVol

Also consumed (without an explicit STAC field of its own) when reconstructing a relative External_url* — see LabelFileName above.

Product_name

item.properties.pdsode:product_name

label

item.properties.pdsode:label

USGS_Sites

item.properties.pdsode:USGS_Sites

Product_lid / Bundle_lid / Collection_lid

item.properties.pdsode:Product_lid / pdsode:Bundle_lid / pdsode:Collection_lid

PDS4-only identifiers, not read by the mapper; pass through as unconsumed-field residuals when present.

PDS4LabelURL

item.assets['pds4_label']

AssetRoles.metadata is used. type=MimeTypes.text, title "PDS4 label".

LabelURL

item.assets['label']

AssetRoles.metadata is used. type=MimeTypes.pds, title "PDS3 label".

FilesURL

items.links[rel="about"].href

title is "All files for this product" and type is html

ProductURL

items.links[rel="about"].href

title is "Product landing page" and type is html

External_url

items.links[rel="about"].href

title is "External reference" and type is html. When the raw value is not already an absolute http(s) URL, it is rebuilt as {dirname(LabelURL)}/{RelativePathtoVol}/{LabelFileName} (or without RelativePathtoVol when absent) by a model validator; stays None when LabelURL or LabelFileName is missing.

External_url2

items.links[rel="about"].href

title is "External reference" and type is html. Same relative-URL reconstruction rule as External_url.

External_url3

items.links[rel="about"].href

title is "External reference" and type is html. Same relative-URL reconstruction rule as External_url.

Product_files

item.assets[FileName]

Implemented in AssetBuilder._file_assets(): one item.assets[FileName] entry per Product_files.Product_file[] entry (see FileName/Type/KBytes/URL/Description/Creation_date rows below). An entry without a URL is skipped entirely.

browse

Not USED - image in base64

thumbnail

Not USED - image in base64

Map_resolution

item.properties.pdssp:map_resolution

Map_resolution_text

item.properties.pdsode:Map_resolution_text

Not read by the mapper; passes through as an unconsumed-field residual (no fallback to Map_resolution).

Map_scale

item.properties.pdssp:map_scale

Map_scale_text

item.properties.pdsode:Map_scale_text

Not read by the mapper; passes through as an unconsumed-field residual (no fallback to Map_scale).

Comment

item.properties.pdsode:Comment

ODE_notes

item.properties.pdsode:ODE_notes

FileName

item.assets[Filename].title

Also used as the asset dictionary key. Falls back to the literal "file" when absent.

Type

item.assets[Filename].type_image

Raw ODE type string, forwarded to AssetDetector.detect() to derive type (MIME) and roles. Priority order: .IMG/.LBL extension → data; ODE type browse (+ PNG/JPEG ⇒ thumbnail if ≤2000KB else overview; + TIFF/TIF ⇒ overview,visual); ODE type productdata; ODE type derivedderived; ODE type document/label or .xml/.kmlmetadata; ODE type archive or .zip/.tar.gzmetadata; ODE type calibration/ancillarydata; otherwise a per-extension fallback table (.png, .jpg/.jpeg, .tif/.tiff, .cub, .img, .pds, .fit, .kml, .csv, .txt, .xml, .pdf, .zip, .tar.gz, .jp2).

KBytes

items.assets[Filename].file:size

Value * 1024 to covnert in Bytes

URL

items.assets[Filename].href

Description

items.assets[Filename].description

Creation_date

items.asset[Filename].creation_date

The earliest Creation_date across all Product_file entries is also used as a fallback source for item.properties.datetime — see Observation.

8.7. Observation

ODE PDSSP STAC Notes

Observation_id

item.properties.pdsode:Observation_id

Observation_number

item.properties.pdsode:Observation_number

Observation_type

item.properties.pdsode:Observation_type

Not read by the mapper; passes through as an unconsumed-field residual. item.properties.product:type is not derived from this field — see ObservationType.

UTC_start_time

item.properties.datetime and item.properties.start_datetime

start_datetime is always utc(UTC_start_time) directly. Fallback order for datetime: Observation_time → UTC_start_time → Product_creation_time → Product_release_date → earliest(Creation_date) across Product_files → date parsed from Description (pattern DD-Mon-YYYY HH:MM:SS.ff) → None.

UTC_stop_time

item.properties.end_datetime

Direct mapping only, no fallback chain.

Observation_time

item.properties.datetime

Fallback order: Observation_time → UTC_start_time → Product_creation_time → Product_release_date → earliest(Creation_date) across Product_files → date parsed from Description → None.

Product_creation_time

item.properties.datetime and item.properties.created

created is always utc(Product_creation_time) directly (it does not feed start_datetime). Fallback order for datetime: Observation_time → UTC_start_time → Product_creation_time → Product_release_date → earliest(Creation_date) across Product_files → date parsed from Description → None.

Product_release_date

item.properties.datetime and item.properties.published

published is always utc(Product_release_date) directly. Fallback order for datetime : Observation_time → UTC_start_time → Product_creation_time → Product_release_date → earliest(Creation_date) across Product_files → date parsed from Description → None.

Description

item.properties.datetime

Last-resort fallback (lowest priority) when none of the date fields above nor any Product_files[].Creation_date yield a value. Parsed via a DD-Mon-YYYY HH:MM:SS.ff regex (extract_date_from_description()); yields None when the pattern is not found.

Product_files[].Creation_date

item.properties.datetime

Second-to-last fallback: the earliest ISO-8601-parseable Creation_date across all Product_files.Product_file[] entries (PropertiesBuilder._earliest_file_date()). Entries with a missing or unparseable date are silently skipped.

N/A

item.properties.datetime / created / published

Any resolved datetime with year > 3000 is treated as invalid and coerced to None (utc() helper), rather than propagated as-is.

8.8. ObservationType

ODE PDSSP STAC Notes

pt

item.properties.ssys:targets[0] / item.properties.ssys:target_class

pt is used at item level only for the Phobos special-case in ssys:targets / ssys:target_class — see FeatureOfInterest. It is not used to derive product:type or processing:level.

N/A (inherited from the parent collection)

item.properties.product:type

Looked up as PRODUCT_TYPE[collection.id] — a value computed once when the collection is built from DataSetId, PTName, and the instrument type / observing-system components fetched from the PDS4 dataset profile (see product:type row in ObservationCollection). Item-level pt, Label_product_type and Observation_type play no role in this computation in the current implementation.

N/A (inherited from the parent collection)

item.properties.processing:level

Looked up as PROCESSING_LEVEL[collection.id][0] — a value computed once when the collection is built from the dataset profile’s processing level, PTName, and DataSetId (see processing:level row in ObservationCollection). Item-level pt, Label_product_type and Observation_type play no role in this computation in the current implementation.

8.9. ObservationCollection

Collection building also consults two external, secondary lookups keyed off DataSetId — not raw fields of the ODE IIPTSet response — via explorer/pds_dsview_lookup.fetch() (PDS4 dataset-view: DOI, citation, investigation/mission name) and explorer/pds_profile.get_profile() (PDS4 dataset profile: processing level, observing-system components, instrument type). Rows below flag which values come from these enrichments rather than directly from ODE.
ODE PDSSP STAC Notes

ODEMetaDB

collection.keywords

value = target:<ODEMetaDB>

IHID

collection.keywords and collection.summaries.platform.append()

value = platform:<IHID>

IHName

used in collection.title and collection.description

IID

collection.keywords and collection.summaries.instruments.append()

value = instru:<IID> . Also used in collection.title and collection.description

IName

used in part of collection.title and used in part of collection.description

PT

collection.summaries.product_name.append() and collection.keywords

value = type:<PT> in keywords; collection.summaries['product_name'] = [PT].

PTName

collection.pdsode:product_name

used in part of collection.title and used in part of collection.description

DataSetId

collection.pdsode:dataset_id and collection.keywords

value = dataset:<DataSetId> in keywords (lowercased). Also the lookup key passed to the PDS4 dataset-view (fetch()) and dataset-profile (get_profile()) enrichments described above, which in turn feed product:type, processing:level, mission and sci:publications (see rows below).

ValidEmissionAngles

collection.keywords and collection.summaries['has_emission_angles'] = [True

False]

with_emission is displayed in keywords if ValidEmissionAngles is True else without_emission

ValidPhaseAngles

collection.keywords and collection.summaries['has_phase_angles'] = [True

False]

with_phase is displayed in keywords if ValidPhaseAngles is True else without_phase

ValidIncidenceAngles

collection.keywords and collection.summaries['has_incidence_angles'] = [True

False]

with_incidence is displayed in keywords if ValidIncidenceAngles is True else without_incidence

ValidSolLongs

collection.keywords and collection.summaries['has_solar_longitudes'] = [True

False]

with_ls is displayed in keywords if ValidSolLongs is True else without_ls

ValidFootprints

collection.keywords and collection.summaries['has_footprints'] = [True

False]

with_footprint is displayed in keywords if ValidFootprints is True else without_footprint

ValidObservationTimes

collection.keywords and collection.summaries['has_observation_times'] = [True

False]

with_obstime is displayed in keywords if ValidObservationTimes is True else without_obstime

ValidTargets

collection.target

Read from the nested ValidTargets.ValidTarget field of the ODE response.

NumberProducts

collection.pdsode:number_of_products

MinOrbit

collection.summaries["orbits"]["minimum"]

collection.summaries["orbits"] is only set when both MinOrbit and MaxOrbit are truthy (e.g. omitted entirely when MinOrbit is 0).

MaxOrbit

collection.summaries["orbits"]["maximum"]

Same condition as MinOrbit above.

MinObservationTime

collection.summaries["observationTime"]["minimum"]

Also used, together with MaxObservationTime, to build collection.extent.temporal.interval. Only set in summaries when both bounds are truthy.

MaxObservationTime

collection.summaries["observationTime"]["maximum"]

Same condition as MinObservationTime above.

MinProductId

collection.summaries["productId"]["minimum"]

Only set when both bounds are truthy.

MaxProductId

collection.summaries["productId"]["maximum"]

Only set when both bounds are truthy.

NumberObservations

collection.pdsode:number_of_observations

SpecialValue1

collection.pdsode:specialValue1

MinSpecialValue1

collection.summaries["specialValue1"]["minimum"]

Only set when both MinSpecialValue1 and MaxSpecialValue1 are truthy.

MaxSpecialValue1

collection.summaries["specialValue1"]["maximum"]

Same condition as MinSpecialValue1 above.

SpecialValue2

collection.pdsode:specialValue2

MinSpecialValue2

collection.summaries["specialValue2"]["minimum"]

Only set when both MinSpecialValue2 and MaxSpecialValue2 are truthy.

MaxSpecialValue2

collection.summaries["specialValue2"]["maximum"]

Same condition as MinSpecialValue2 above.

N/A (external: PDS4 dataset-view lookup keyed by DataSetId)

collection.summaries['sci:publications']

Set to [{"doi": doi_name, "citation": citation}] only when the dataset-view lookup returns a non-empty doi_name. When the lookup’s investigation.name is known (≠ "UNKNOWN"), it also overrides collection.summaries['mission'] (and the MISSION taxonomy entry used for item.properties.mission, see Host) in place of IHName.

N/A (inherited by items)

product:type

collection.summaries['product:type'] — computed once via extract_data_product_type(instrument_type, observing_system, dataset_id, title) (keyword rules tried in order: product-type name → observing-system text → instrument type → dataset id), defaulting to "UNKNOWN". instrument_type and observing_system come from the PDS4 dataset-profile enrichment (get_profile()); on lookup failure both default to empty. Cached as PRODUCT_TYPE[collection.id] and reused for every item’s item.properties.product:type (see ObservationType).

N/A (inherited by items)

processing:level

collection.summaries['processing:level'] — computed once via extract_processing_level(processing_level, dataset_id, pt_name): direct value from the PDS4 dataset-profile enrichment when available, else keyword rules on PTName then DataSetId (simple, multi-level, then exact-match rule tables), defaulting to ["UNKOWN"] (sic) when nothing matches. Cached as PROCESSING_LEVEL[collection.id] and reused for every item’s item.properties.processing:level (see ObservationType).

8.10. STAC extensions

item.stac_extensions is derived purely from which properties/assets ended up populated (response/stac_extensions.py), not from a dedicated ODE field:

  • Always declared: ssys and the PDSSP schema (pdssp_schema).

  • Declared when at least one property (on the item or on any asset) has a key starting with the given prefix: productproduct extension, satsat extension, viewview extension, filefile extension, projprojection extension, processingprocessing extension.

  • Declared when the exact key is present on the item properties: versionversion extension, publishedtimestamps extension.

collection.stac_extensions is a fixed list set at collection-build time (ssys, scientific, processing, product), independent of which fields are actually populated for a given collection.

9. Mapping STAC to EPN-TAP

9.1. Host

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

instrument_host_name

item.properties.platform

char

*

meta.id;instr.obsty

9.2. Observer

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

instrument_name

item.properties.instruments

char

*

meta.id;instr

properties.instruments is a list; see First element of a list-valued property.

instrument_type

detector_name

opt_elem

observer_id

observer_code

observer_institute

observer_country

observer_location

observer_lon

observer_lat

subobserver_longitude

subobserver_latitude

producer_name

collection.providers[role=producer].name

char

*

meta.note

see Value derived from the collection, not the item.

producer_institute

collection.providers[role=producer].name

char

*

meta.note

See Value derived from the collection, not the item.

9.3. ObservingProcedure

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

sample_id

data_calibration_desc

setup_desc

measurement_atmosphere

temperature

pressure

sample_desc

proposal_id

proposal_pi

proposal_title

proposal_target_name

proposal_target_description

campain

target_secondary_hemisphere

orientation

original_publisher

9.4. ObservableProperty

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

species

messenger

filter

item.properties.bands[0].name

char

*

meta.id;instr.filter

See Name of the first spectral band.

measurement_type

item.properties.pdssp:measurement_type

char

*

meta.code

particle_spectral_type

particle_spectral_range

particle_spectral_sampling_step

particle_spectral_resolution

spectrum_type

sample_classification

species_inchikey

grain_size

geometry_type

C1_resol

item.properties.gsd

double

pos.resolution

C2_resol

item.properties.gsd

double

pos.resolution

C3_resol

9.5. FeatureOfInterest

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

target_name

item.properties.ssys:targets[0]

char

*

meta.id;src

ssys:targets is a list; see First element of a list-valued property.

target_class

item.properties.ssys:target_class

char

*

meta.code.class;src.class

c1min

min longitude of item.geometry.coordinates

double

pos.bodyrc.lon;stat.min

See Bounding box of a GeoJSON geometry for the extraction algorithm.

c1max

max longitude of item.geometry.coordinates

double

pos.bodyrc.lon;stat.max

See Bounding box of a GeoJSON geometry.

c2min

min latitude of item.geometry.coordinates

double

pos.bodyrc.lat;stat.min

See Bounding box of a GeoJSON geometry.

c2max

max latitude of item.geometry.coordinates

double

pos.bodyrc.lat;stat.max

See Bounding box of a GeoJSON geometry.

c3min

Not implemented: no third coordinate axis in the STAC geometries seen so far.

c3max

Not implemented: no third coordinate axis in the STAC geometries seen so far.

spatial_frame_type

char

*

pos.frame

spatial_frame_type = body (a fixed value, not read from STAC — see Fixed (constant) columns)

incidence

item.properties.view:incidence_angle

double

pos.incidenceAng

emergence

no STAC equivalent

phase

item.properties.view:phase_angle

double

pos.phaseAng

s_region

char

*

pos.outline;obs.field

convert item.geometry.coordinates

solar_longitude

target_distance

earth_distance

sun_distance

item.properties.pdssp:solar_distance

double

pos.distance;pos.heliocentric

subsolar_longitude

subsolar_latitude

alt_target_name

feature_name

Inverted name resolver on coordinates

target_region

item.properties.ssys:targets[0], lower-cased

char

*

meta.id;src;obs.field

Vocabulary: IVOA UAT. See First element of a list-valued property, lower-cased.

coverage

item.assets[key contains "moc"/"healpix"].href

char

*

pos.outline;obs.field

See MOC/HEALPix coverage asset.

radial_distance

computes from pos(planetocentric) to (planeotgraphic)

altitude_fromshape

computes from the DTM

mean_radius

equatorial_radius

polar_radius

diameter

mass

sideral_rotation_period

semi_major_axis

inclination

eccentricity

long_asc

arg_perihel

mean_anomaly

epoch

magnitude

flux

albedo

dynamic_class

dynamic_type

taxonomy_code

azimuth

north_pole_position

target_primary_hemisphere

target_secondary_hemisphere

target_apparent_radius

orientation

spatial_origin

spatial_origin = Geocenter, item.properties.ssys:targets[0]

Spatial_coordinate_description

item.properties.proj:code

char

*

meta.code.class;pos.frame

IAU CRS name (see CRS Registry). Filled in 2026-08-30: this row’s STAC mapping was previously blank even though it is implemented.

9.6. Result

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

access_url

item.assets[name][role=data].href

char

*

meta.ref.url

See Picking the primary data asset.

access_format

item.assets[name][role=data].type

char

*

meta.code.mime

See Picking the primary data asset.

access_estsize

item.assets[name][role=data].file:size

long

phys.size;meta.file

See Picking the primary data asset. Filled in 2026-08-30: this row’s STAC mapping was previously blank even though it is implemented.

thumbnail_url

item.assets[name][role=thumbnail].href

char

*

meta.ref.url;meta.preview

See Picking an asset by role.

file_name

item.assets[name][role=data].title

char

*

meta.id;meta.file

See Picking the primary data asset.

access_md5

item.assets[name].file:checksum

char

*

meta.checksum;meta.file

See Picking the primary data asset.

datalink_url

map_projection

map_height

map_width

pixelscale

pdssp:map_resolution

double

instr.scale

map_scale

pdssp:map_scale

double

pos.wcs.scale

bib_reference

item.properties.sci:doi

char

*

meta.bib.doi

publisher

collection.providers[role=host].name

char

*

meta.curation

See Value derived from the collection, not the item.

internal_reference

external_link

item.assets[role=metadata].href

char

*

meta.ref.url

See Picking an asset by role.

service_title

char

*

meta.title

Not derived from a STAC field: fixed per proxy deployment. EPN-TAP2 mandatory. See Fixed (constant) columns.

creation_date

created

char

*

time.creation

modification_date

updated

char

*

time.update

release_date

published

char

*

time.release

timestamps extension

9.7. Observation

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

time_min

item.properties.start_datetime

double

time.start

The time parameters in EPN-TAP are always provided in UTC and formatted in Julian Days (expressed in double precision). EPNCore uses standard JD to avoid ambiguity with time origin. start_datetime in STAC uses UTC time. If datetime is not null, time_min must be set to datetime. Conversion: Julian Date ↔ ISO 8601 datetime.

time_max

item.properties.end_datetime

double

time.end

The time parameters in EPN-TAP are always provided in UTC and formatted in Julian Days (expressed in double precision). EPNCore uses standard JD to avoid ambiguity with time origin. start_datetime in STAC uses UTC time. Conversion: Julian Date ↔ ISO 8601 datetime.

time_exp_min

compute end_datetime-start_datetime, expressed as seconds

time_exp_max

time_refposition

item.properties.ssys:targets

char

*

meta.id

See First element of a list-valued property.

time_scale

Set time_scale = UTC

local_time_min

item.properties.ssys:local_time

double

time.phase;time.period.rotation;stat.min

Must be converted

local_time_max

target_time_min

item.properties.start_datetime

char

*

time.start;src

UTC time expressed as TIMESTAMP

target_time_max

item.properties.end_datetime

char

*

time.end;src

UTC time expressed as TIMESTAMP

obs_id

item.id

char

*

meta.id

granule_uid

char

*

meta.id

Convert granule_uid = id#md5(asset.href)

9.8. ObservationType

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

dataproduct_type

item.properties.product:type

char

*

meta.code.class

processing_level

item.properties.processing:level

char

*

meta.code

mapping with enums (EPN-TAP uses an acronym where PDSSP uses the name)

9.9. ObservationCollection

EPN-TAP PDSSP STAC Datatype Arraysize UCD Notes

granule_gid

collection.id

char

*

meta.id;meta.dataset

10. The PDSSP Data Model

This chapter defines the data model of the Pole itself — the convergence point of the reference models studied so far. It is deliberately built on STAC so that it stays generic and standard-compatible, while adding a thin, declarative layer that makes it extensible and strictly controllable: the requiredness of fields, the set of allowed values, the supported objects, and the accepted files can all be configured per use case without ever modifying the STAC core.

10.1. Why STAC as the Pivot

Among the models studied in this document, none of the others is fit to serve as the single upstream source of truth:

  • O&M is a conceptual standard — a set of abstract interfaces (Observation, FeatureOfInterest, Observer…) with no single interchange serialization of its own. It is the right semantic anchor (Chapter 4) but not an implementable pivot format.

  • EPN-TAP is a single flat table of granules (Section 6.1): sufficient for a queryable export, too thin to preserve everything captured from an ODE record without loss.

  • DOI/DataCite metadata is, by design, a projection of fields already held elsewhere (Section 6.3) — it consumes the pivot, it cannot be the pivot.

  • ODE's own model is NASA-specific (Section 6.2) and not an open, community-governed catalog format.

STAC is the only candidate that combines four properties simultaneously:

  1. Neutral, generic backbone. Catalog / Collection / Item / Asset / Link carries no domain bias toward any single input standard, so ingesting ODE today and ESA/ESO data tomorrow doesn’t require re-modeling the core.

  2. A first-class extension mechanism. stac_extensions + versioned JSON Schema is designed to let a community add vocabulary (ssys, proj, pdssp:…) without forking the spec — exactly the layered schema/profile separation described below in Design Principles. None of the other candidates has an equivalent, client-enforceable mechanism.

  3. An existing ecosystem. STAC is adopted by NASA, USGS, Microsoft, ESRI, and Google (Section 6.5); any standard STAC client (STAC Browser, pystac, stac-fastapi) can read the Pole’s catalog for free, rather than the Pole building bespoke tooling.

  4. Same standards lineage as O&M, with fewer constraints. STAC is an OGC community standard built on GeoJSON (RFC 7946), which permits geometry: null — so non-georeferenced products (documents, tables, not-yet-located products) remain first-class citizens, unlike purely geospatial formats.

Consequently, EPN-TAP and DOI/DataCite are treated as export targets (downstream projections), while STAC — enriched by the pdssp:/pdsode: extensions and the PDSSP Profile — is the pivot that holds the complete record.

10.2. Design Principles

The model is organized in four superimposed layers, from the most generic and stable to the most specific and configurable:

  1. STAC core (generic backbone). The Catalog / Collection / Item / Asset / Link structure is used unchanged. It is never specialized, which guarantees that any standard STAC client can read the Pole’s data. Following RFC 7946, the Item geometry may be null, so non-georeferenced resources (documents, tables, not-yet-located products) remain first-class.

  2. Standard extensions (shared vocabulary). A curated set of community STAC extensions provides the domain vocabulary, as established in Chapters 7 and 8 (ssys, view, proj, processing, product, sat, file, sci, datacube, eo, timestamps…). Reusing published extensions is what keeps the model interoperable rather than proprietary.

  3. The pdssp extension (custom keywords). Planetary concepts that no published extension covers (e.g. pdssp:phase_angle, pdssp:solar_longitude, pdssp:measurement_type) live in a single namespaced extension owned by the Pole, with its own JSON Schema. This is the controlled place to add custom keywords without polluting the core.

  4. The PDSSP Profile (configurable validation layer). A profile, published as a custom STAC extension JSON Schema and declared in each Item’s stac_extensions, expresses the rules: which fields are required, which values are allowed, which objects are supported, and which files are accepted. Because it is a declared extension, it is enforced wherever the Item is validated — including client-side in STAC Browser. It carries no data — only constraints — so it can be tightened or relaxed per system without touching the data model.

The separation between layers 1–3 (the schema: what can be described) and layer 4 (the profile: what must be true here) is the key design decision. It is what allows the global schema to stay generic while each deployment remains strictly controllable.
The Four Layers of the PDSSP Data Model
Figure 39. The Four Layers of the PDSSP Data Model

10.3. Architecture

The following UML diagram shows the STAC backbone, the extension bindings, and the configurable constraint layer that validates Items and Assets.

PDSSP Architecture: STAC Core, Extensions, and Profile Constraints
Figure 40. PDSSP Architecture: STAC Core, Extensions, and Profile Constraints

10.4. PDSSP Data Model (Class Diagram)

The following UML diagram shows the concrete PDSSP data model: how the PDSSP Profile adds planetary metadata to STAC Items and Collections through 5 mandatory extensions, with enumerated values.

PDSSP Data Model Class Diagram
Figure 41. PDSSP Data Model Class Diagram

10.5. Extensibility and Strict Control

All controllability is expressed through the PDSSP Profile, so the four capabilities requested by the Pole map onto four rule types.

10.5.1. File validation by media type and extension

FileValidationRule constrains Assets by roles: it lists the allowedMediaTypes (the Asset type) and allowedFileExtensions (the file-name suffix of href), and can require a checksum (file:checksum). When the rule is expressed in the declared PDSSP schema, any Asset whose media type is not in the allowed list is flagged by STAC Browser at validation time.

10.5.2. Configurable requiredness (turning required into a rule)

Instead of a static required array baked into a schema, requiredness is expressed by RequirednessRule. Each rule targets a field, sets it required or optional, and may carry a condition. This makes required data-driven: for example, cube:dimensions becomes required only when product:type = sp. The profile compiler translates these rules into JSON Schema required arrays and if/then blocks.

10.5.3. Restricting allowed values

ValueConstraint restricts a field to an allowedValues enumeration, a pattern, or a numeric range (minimum/maximum). This compiles to JSON Schema enum, pattern, or range keywords. For descriptive (non-enforced) advertising of the same information at group level, the Collection summaries are populated in parallel.

10.5.4. Restricting supported objects for a given system

ObjectRestriction is a specialization aimed at the "restrict the objects supported in a given system" requirement: it limits a target field — typically ssys:targets — to an explicit allowedObjects list. A Mars-only deployment, for instance, restricts ssys:targets to ["Mars", "Phobos", "Deimos"]; any other body is flagged by STAC Browser as invalid.

10.5.5. Custom keywords

New custom keywords are declared and constrained directly in the pdssp extension schema (layer 3). Listing that schema in an Item’s stac_extensions is what makes the keywords validated by STAC Browser. This keeps the core untouched and the custom vocabulary versioned and discoverable.

In addition to pdssp:, the model uses a second namespace, pdsode:, dedicated to ODE-specific fields that have no equivalent in the STAC core or in any published community extension, but that retain scientific or operational value and are worth surfacing in STAC Items — for example for display in STAC Browser or downstream processing pipelines. These fields (pdsode:Observation_id, pdsode:PDSVolume_Id, pdsode:ODE_notes, etc.) are not semantically mapped to any STAC construct: they are preserved verbatim from the source ODE record. Like pdssp:, the pdsode: namespace is governed by its own JSON Schema, declared alongside the PDSSP profile schema in each Item’s stac_extensions.

10.6. The PDSSP Profile as a Declared STAC Extension

Because the Pole relies on STAC Browser to perform validation, the profile is not kept as a separate document but published as a custom STAC extension JSON Schema and declared in the stac_extensions array of every Item. STAC Browser (via stac-node-validator) fetches each schema URI listed in stac_extensions — custom extensions included — and validates the Item against it, so all the rules below are enforced client-side. Two practical conditions apply: the schema URL must be resolvable (no 404), and its host must allow cross-origin (CORS) requests, since the fetch happens in the browser.

The single schema below realizes all four capabilities for a Mars-imagery deployment: it defines and constrains the pdssp: custom keywords, requires the companion extensions, turns selected fields into required (including a conditional rule), restricts allowed values and supported objects, and limits accepted asset media types — without modifying the generic STAC core.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://pdssp.github.io/stacplanet/v1.0.0/schema.json",
  "title": "PDSSP Planetary Data Schema for STAC Items and Collections",
  "description": "Schema defining PDSSP-specific keywords, constraints, and extensions for planetary imagery and data products. Applies to both STAC Items and Collections, with mandatory fields for solar system targets, product types, and processing levels. For items, ssys:targets, ssys:target_class, version, product:type, and processing:level are required. For collections, ssys:targets, ssys:target_class, product:type, and processing:level are required.",
  "type": "object",
  "allOf": [
    {
      "if": {
        "required": ["type"],
        "properties": {
          "type": {
            "const": "Feature"
          }
        }
      },
      "then": {
        "$ref": "#/definitions/item"
      }
    },
    {
      "if": {
        "required": ["type"],
        "properties": {
          "type": {
            "const": "Collection"
          }
        }
      },
      "then": {
        "$ref": "#/definitions/collection"
      }
    }
  ],
  "definitions": {
    "item": {
      "type": "object",
      "required": [
        "geometry",
        "properties",
        "stac_extensions"
      ],
      "properties": {
        "geometry": {
          "type": ["object", "null"]
        },
        "stac_extensions": {
          "type": "array",
          "if": {
            "properties": {
              "geometry": {
                "type": "null"
              }
            },
            "required": ["geometry"]
          },
          "then": {
            "allOf": [
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/ssys/"
                }
              },
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/product/"
                }
              },
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/processing/"
                }
              }
            ]
          },
          "else": {
            "allOf": [
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/ssys/"
                }
              },
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/projection/"
                }
              },
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/version/"
                }
              },
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/product/"
                }
              },
              {
                "contains": {
                  "type": "string",
                  "pattern": "stac-extensions\\.github\\.io/processing/"
                }
              }
            ]
          }
        },
        "properties": {
          "$ref": "#/definitions/fields"
        }
      }
    },
    "collection": {
      "type": "object",
      "required": [
        "stac_extensions",
        "ssys:targets",
        "ssys:target_class",
        "product:type",
        "processing:level"
      ],
      "properties": {
        "stac_extensions": {
          "type": "array",
          "allOf": [
            {
              "contains": {
                "type": "string",
                "pattern": "stac-extensions\\.github\\.io/ssys/"
              }
            },
            {
              "contains": {
                "type": "string",
                "pattern": "stac-extensions\\.github\\.io/processing/"
              }
            },
            {
              "contains": {
                "type": "string",
                "pattern": "stac-extensions\\.github\\.io/product/"
              }
            }
          ]
        },
        "ssys:targets": {
          "type": "array",
          "minItems": 1,
          "items": {
            "enum": ["Mercury", "Venus", "Mars", "Moon", "Titan"]
          },
          "description": "List of solar system targets covered by the collection. At least one target is required."
        },
        "ssys:target_class": {
          "type": "string",
          "enum": ["planet", "satellite"],
          "description": "Classification of the primary target (e.g., planet, satellite)."
        },
        "product:type": {
          "type": "string",
          "enum": [
            "Cube",
            "Spectrum",
            "Spectral Cube",
            "Image",
            "Map",
            "Volume",
            "Time Series",
            "Dynamic Spectrum",
            "Catalog",
            "Spatial Vector"
          ],
          "description": "Type of the data product. This field is mandatory."
        },
        "processing:level": {
          "type": "string",
          "enum": ["Ancillary", "Raw", "Calibrated", "Derived"],
          "description": "Processing level of the data product. This field is mandatory."
        }
      }
    },
    "fields": {
      "type": "object",
      "required": [
        "ssys:targets",
        "ssys:target_class",
        "version",
        "product:type",
        "processing:level"
      ],
      "properties": {
        "ssys:targets": {
          "type": "array",
          "minItems": 1,
          "items": {
            "enum": ["Mercury", "Venus", "Mars", "Moon", "Titan"]
          },
          "description": "List of solar system targets covered by the data. At least one target is required."
        },
        "ssys:target_class": {
          "type": "string",
          "enum": ["planet", "satellite"],
          "description": "Classification of the primary target (e.g., planet, satellite)."
        },
        "version": {
          "type": "string",
          "minLength": 1,
          "description": "Version identifier for the data product. This field is mandatory for items."
        },
        "product:type": {
          "type": "string",
          "enum": [
            "Cube",
            "Spectrum",
            "Spectral Cube",
            "Image",
            "Map",
            "Volume",
            "Time Series",
            "Dynamic Spectrum",
            "Catalog",
            "Spatial Vector"
          ],
          "description": "Type of the data product. This field is mandatory."
        },
        "processing:level": {
          "type": "string",
          "enum": ["Ancillary", "Raw", "Calibrated", "Derived"],
          "description": "Processing level of the data product. This field is mandatory."
        },
        "pdssp:solar_longitude": {
          "type": "number",
          "description": "Solar longitude of the target at the time of observation (optional)."
        },
        "pdssp:solar_distance": {
          "type": "number",
          "description": "Distance from the Sun to the target at the time of observation, in astronomical units (optional)."
        },
        "pdssp:map_resolution": {
          "type": "number",
          "description": "Spatial resolution of the map, in meters per pixel (optional)."
        },
        "pdssp:map_scale": {
          "type": "number",
          "description": "Scale of the map (optional)."
        }
      }
    }
  }
}

When an Item declares https://pdssp.cnes.fr/stac/pdssp/v1.0.0/schema.json in its stac_extensions, STAC Browser validates it against this schema and reports any breach directly in its validation panel: a missing required field, a target outside the supported planets in PDSSP, a processing:level outside the allowed set, a null geometry. The same generic STAC Item, published with a different PDSSP extension schema, can serve an entirely different mission under different rules — which is precisely the flexibility, extensibility, and strict, browser-side control sought for the Pole.

The PDSSP extension schemas (pdssp: and pdsode:) are maintained and versioned in the STACPlanet GitHub repository. Each released version is published to GitHub Pages at a stable, CORS-enabled URL, which is the URL that must appear in stac_extensions for STAC Browser to fetch and validate against it. The version embedded in the URL (v1.0.0, v1.1.0, …) is the contract: Items already in production are never broken by a new release because they reference an immutable versioned URL.

11. Reference Documents

This section lists the normative documents, standards, and frameworks referenced throughout this document.

11.1. OGC and ISO Standards

Reference Title Version/Date URL

ISO 19156:2011

Geographic information – Observations and Measurements

2011

https://www.iso.org/standard/32574.html

OGC 07-022r1

Observations and Measurements (O&M) - XML Implementation

2.0

https://docs.ogc.org/is/10-025r1/10-025r1.pdf

OGC STAC

SpatioTemporal Asset Catalog

1.0

https://www.ogc.org/standards/stac/

11.2. NASA Models and Services

Reference Title Version/Date URL

NASA ODE

Orbital Data Explorer Data Model

N/A

https://ode.rsl.wustl.edu/

PDS4

Planetary Data System Version 4 Standards

1.x

https://pds.nasa.gov/datastandards/

11.3. IVOA Standards

Reference Title Version/Date URL

EPN-TAP

Europlanet Table Access Protocol

1.1

https://www.ivoa.net/documents/EPNTAP/20220822/

IVOA TAP

Table Access Protocol

1.1

http://www.ivoa.net/documents/TAP/

IVOA DALI

Data Access Layer Interface

1.1

http://www.ivoa.net/documents/DALI/

IVOA UWS

Universal Worker Service

1.0

http://www.ivoa.net/documents/UWS/

11.4. Open Science and Identifiers

Reference Title Version/Date URL

Wilkinson et al.

The FAIR Guiding Principles for scientific data management and stewardship. Sci. Data 3:160018, doi: 10.1038/sdata.2016.18

2016

https://doi.org/10.1038/sdata.2016.18

FAIR Principles

Findable, Accessible, Interoperable, Reusable

2016

https://www.go-fair.org/fair-principles/

FAIR Principles (Ouvrir la Science)

French national Open Science portal — FAIR sub-criteria

N/A

https://www.ouvrirlascience.fr/fair-principles/

W3C PROV-Overview

An Overview of the PROV Family of Documents

2013

https://www.w3.org/TR/prov-overview/

DataCite Schema

DataCite Metadata Schema

4.7

https://schema.datacite.org/

DOI System

Digital Object Identifier System

N/A

https://www.doi.org/

Handle System

Handle System Specification

N/A

https://www.handle.net/

11.5. Other References

Reference Title Version/Date URL

RFC 7946

The GeoJSON Format

2016

https://datatracker.ietf.org/doc/html/rfc7946

IAU 2009

IAU/IAG Working Group on Cartographic Coordinates and Rotational Elements

2009

https://www.iau.org/publications/themes/planetary-sciences/

Index

Appendix A: EPN-TAP ↔ STAC Conversion Algorithms

The mapping tables in Mapping STAC to EPN-TAP reference several non-trivial conversions between an EPN-TAP parameter and its STAC source. This appendix describes each one as a plain algorithm, independent of any particular implementation, so the mapping stays meaningful to a reader without access to the proxy’s source code. A reference implementation of every algorithm below exists as a Python function in the epntap2cql2 proxy’s converters.py module.

Julian Date ↔ ISO 8601 datetime

EPN-TAP’s time_min/time_max are Julian Dates (UTC, double precision); STAC’s start_datetime/end_datetime are RFC 3339 / ISO 8601 strings.

EPN-TAP → STAC (Julian Date to ISO 8601):

  1. Let JD_UNIX_EPOCH = 2440587.5 (the Julian Date of 1970-01-01T00:00:00Z).

  2. unix_seconds = (jd - JD_UNIX_EPOCH) × 86400

  3. Convert unix_seconds (a Unix timestamp) to a UTC calendar date-time.

  4. Format it as an ISO 8601 string with a trailing Z (e.g. 2007-06-05T22:50:23.754900Z).

STAC → EPN-TAP (ISO 8601 to Julian Date): the inverse — 

  1. Parse the ISO 8601 string into a UTC date-time (a bare Z suffix is read as +00:00; a string with no timezone at all is assumed UTC).

  2. unix_seconds = seconds since 1970-01-01T00:00:00Z.

  3. jd = unix_seconds / 86400 + JD_UNIX_EPOCH

First element of a list-valued property

Several STAC properties are lists where EPN-TAP expects a single value (e.g. ssys:targets, instruments). Algorithm: if the value is a list, return its first element (or nothing, if the list is empty); otherwise return the value unchanged.

First element of a list-valued property, lower-cased

Same as First element of a list-valued property, then lower-case the result if it is a string. Used for target_region from ssys:targets, since the target region controlled vocabulary (see the IVOA UAT) uses lower case terms.

Comma-join a list-valued property

Alternative to First element of a list-valued property when every element should be kept rather than only the first: join every element of the list into one string with ", " as the separator.

Name of the first spectral band

For EPN-TAP’s filter from a STAC bands (or eo:bands) property: each entry of that list is an object with (at least) a name field. Return the name of the first entry, or nothing if the list is empty or absent.

Picking the primary data asset

Unlike EPN-TAP’s single access_url/access_format/access_estsize/ access_md5/file_name columns, a STAC item’s assets object is keyed by an arbitrary, per-item file name — there is no fixed key such as assets.data. The algorithm below picks one asset to represent "the" data product for that item, used by every one of those EPN-TAP columns:

  1. Consider every asset whose roles list contains "data".

  2. If at least one such asset exists, keep only those; otherwise, fall back to considering every asset regardless of role.

  3. Among the candidates, pick the one with the largest file:size (missing/absent size counts as 0).

  4. Read the requested attribute off that one asset: href (→ access_url), type (→ access_format), file:size (→ access_estsize), file:checksum (→ access_md5), or title (→ file_name).

If this heuristic picks the wrong file for a given collection (e.g. a browse/label file that happens to also be tagged "data"), it should be tuned per collection rather than universally.

Picking an asset by role

For thumbnail_url and external_link: return the href of the first asset (in the item’s own key order) whose roles list contains "thumbnail" (resp. "metadata"). Unlike Picking the primary data asset, no size-based tie-breaking is applied, since there is normally at most one asset of these roles per item.

MOC/HEALPix coverage asset

For coverage: return the href of the first asset (in the item’s own key order) whose key contains "moc" or "healpix" (case-insensitive) — a PDSSP-specific naming convention for a MOC/HEALPix footprint file, rather than a STAC roles entry.

Bounding box of a GeoJSON geometry

For c1min/c1max/c2min/c2max (and, were a third axis ever needed, c3min/c3max) from an item’s geometry (GeoJSON Point, Polygon, MultiPolygon, …​):

  1. Recursively walk the geometry’s coordinates array. At each level: if the current array is a flat list of 2 (or 3) numbers, it is one coordinate pair/triple [lon, lat(, alt)] — record it and stop recursing into it; otherwise recurse into each of its elements. This works uniformly for every GeoJSON geometry type without assuming a fixed nesting depth.

  2. c1min/c1max = the minimum/maximum of the first component (longitude) across every recorded coordinate.

  3. c2min/c2max = the minimum/maximum of the second component (latitude).

  4. If no coordinate could be extracted (missing/empty geometry), the result is absent, not zero.

Per EPN-TAP2’s own table of spatial UCDs (conditioned on spatial_frame_type), with spatial_frame_type = body (this proxy’s fixed value, see Fixed (constant) columns) the correct UCDs are pos.bodyrc.lon;stat.min/stat.max for c1min/c1max and pos.bodyrc.lat;stat.min/stat.max for c2min/c2max.

Fixed (constant) columns

Some EPN-TAP columns have no variable STAC source at all — either because the value is the same for every granule this proxy serves (e.g. spatial_frame_type, always "body") or because it identifies the service rather than any one granule (service_title, EPN-TAP2 mandatory, set to the service’s own title). Algorithm: none — the configured fixed value is returned for every row, unconditionally.

Value derived from the collection, not the item

publisher, producer_name and producer_institute are the same for every item of one STAC collection, but differ between collections — so, unlike a per-item conversion, this one is resolved once per collection rather than once per row:

  1. Read the STAC Collection object’s providers list (present directly in the /collections listing response; no extra request is needed).

  2. Return the name of the first provider entry whose roles list contains the requested role — "host" for publisher, "producer" for producer_name/producer_institute (STAC has no separate "institute" field, so both read the same provider’s name).

  3. If no provider has that role, the column has no value for that collection.