Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the property_ranges query parameter and associated metadata #481

Open
wants to merge 39 commits into
base: develop
Choose a base branch
from
Open
Changes from 34 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3b9cbc5
Intermediate progress writing property ranges parameter.
JPBergsma Jun 26, 2023
eae1679
Added metadata fields to be able to use property ranges query parameter.
JPBergsma Jun 27, 2023
f00b52d
Small corrections.
JPBergsma Jun 28, 2023
2a0bef8
moved property ranges to single_entryendpoint query param + further r…
JPBergsma Jun 29, 2023
4a00af4
Some small changes after proof reading.
JPBergsma Jun 29, 2023
6905d7f
added that fields should be placed in the range dictionary.
JPBergsma Jun 29, 2023
d579c6e
Some more sentences that had to be moved to a new line.
JPBergsma Jun 30, 2023
6792962
Update optimade.rst
JPBergsma Jun 30, 2023
93ecd0b
removed unintentional changes in appendix.
JPBergsma Jun 30, 2023
a84c72e
Seperated property_ranges query parameter from the partial data.
JPBergsma Jul 4, 2023
dc11574
Merge branch 'develop' into JPBergsma/property_ranges
ml-evs Dec 19, 2023
17beeef
Apply formatting suggestions from code review
ml-evs Jan 18, 2024
cc89029
Merge branch 'develop' into JPBergsma/property_ranges
ml-evs Jan 18, 2024
6d8e24f
Apply suggestions from review
rartino Mar 22, 2024
680317b
Merge branch 'develop' into JPBergsma/property_ranges
rartino Mar 22, 2024
f2a2799
Merge branch 'develop' into JPBergsma/property_ranges
rartino Mar 22, 2024
63e3821
Minor corrections from review
rartino Mar 22, 2024
0efb5e7
Merge branch 'develop' into JPBergsma/property_ranges
rartino Jun 13, 2024
bf7e5b4
Edit property slice definition [WIP]
rartino Jun 13, 2024
d029756
Edit property slice definition [WIP]
rartino Jun 13, 2024
63f122f
Edit property slice definition [WIP]
rartino Jun 13, 2024
f863308
Edit property slice definition [WIP]
rartino Jun 13, 2024
a73029a
Edit property slice definition [WIP]
rartino Jun 13, 2024
c098e47
Improve handing of Python dependencies
rartino Jun 14, 2024
4f704c1
Improve handing of Python dependencies
rartino Jun 14, 2024
266545b
Improve handing of Python dependencies
rartino Jun 14, 2024
e562f49
Revert "Improve handing of Python dependencies"
rartino Jun 14, 2024
315546a
Edit property slice definition [WIP]
rartino Jun 14, 2024
ce9661b
Small sentence fix
giovannipizzi Jun 14, 2024
358157f
Clarifying the part on dimension names.
giovannipizzi Jun 14, 2024
7e29652
Apply suggestions from review
rartino Jun 15, 2024
085030d
Define the term array for OPTMADE data types
rartino Jun 15, 2024
b3a96a0
Fix examples for slicing assuming a trajectory cartesian_site_coordin…
rartino Jun 15, 2024
6231d2a
Adjust confusing phrasing about slicing based on review comment
rartino Jun 15, 2024
9f639d1
Apply suggestions from code review
giovannipizzi Jul 4, 2024
46eafb5
Apply suggestions from code review
giovannipizzi Jul 4, 2024
657a696
Change the format of property_slices to the syntax dim_xxx[start:stop…
rartino Jun 18, 2024
919b83d
Fix in formulation for property_slices format dim_xxx[start:stop:step]
rartino Oct 18, 2024
a623390
Apply suggestions from review
rartino Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 200 additions & 6 deletions optimade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ representation in all contexts. They are as follows:
- Basic types: **string**, **integer**, **float**, **boolean**, **timestamp**.
- **list**: an ordered collection of items, where all items are of the same type, unless they are unknown.
A list can be empty, i.e., contain no items.
- **dictionary**: an associative array of **keys** and **values**, where **keys** are pre-determined strings, i.e., for the same entry property, the **keys** remain the same among different entries whereas the **values** change.
Multidimensional collections of items are represented as nested lists.
The specification uses **array** as a more general term for structures of nested lists representing single or multidimensional data, and the term **array axes** for the levels of nesting.
sauliusg marked this conversation as resolved.
Show resolved Hide resolved
Note that arrays are represented using lists and not as a separate data type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In JSON? If we move to e.g. HDF5 then there the arrays will be a real distinct data type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part discusses the data model internal to OPTIMADE itself, where we (for now) only formally need list in lists (but we say here ~"lets use the term 'arrays' for lists in lists"). How this data model is mapped onto JSON types is first described in section 4.2, where indeed lists -> JSON lists. A future section discussing HDF5, or for that matter XML, parquet, etc., would define how these types are mapped into native data types. It would be valid for HDF5 to say that lists in lists (in lists...) should be mapped to the HDF5 array format.

If you ask "why don't we just adopt arrays as a fundamental data type and say that in JSON arrays map to lists in lists", I think that would be a valid change (but not in this PR).

- **dictionary**: an associative set of **keys** and **values**, where **keys** are pre-determined strings, i.e., for the same entry property, the **keys** remain the same among different entries whereas the **values** change.
giovannipizzi marked this conversation as resolved.
Show resolved Hide resolved
The **values** of a dictionary can be any basic type, list, dictionary, or unknown.

An entry property value that is not present in the database is **unknown**.
Expand Down Expand Up @@ -491,7 +494,8 @@ The default partial data format is named "jsonlines" and is described in the App
An implementation SHOULD always include this format as one of the partial data formats provided for a property that has been omitted from the response to the initial query.
Implementations MAY provide links to their own non-standard formats, but non-standard format names MUST be prefixed by a database-provider-specific prefix.

Below follows an example of the :field:`data` and :field:`meta` parts of a response using the JSON response format that communicates that the property value has been omitted from the response, with three different links for different partial data formats provided.
Below follows an example of the :field:`data` and :field:`meta` parts of a response using the JSON response format.
It communicates that the property value has been omitted from the response and includes three different links for different partial data formats provided.

.. code:: jsonc

Expand Down Expand Up @@ -537,8 +541,10 @@ Database providers are allowed to define their own metadata properties in :field
For example, the metadata property definition of the field :field:`_exmpl_example_field` MUST NOT define a metadata field named, e.g., :field:`accuracy`; the field rather needs to be named, e.g., :field:`_exmpl_accuracy`.
The reason for this limitation is to avoid name collisions with metadata fields defined by the OPTIMADE standard in the future that apply also to database-specific data fields.

Implementation of the :field:`meta` field is OPTIONAL.
However, when an implementation supports the :field:`property_metadata` field, it SHOULD include metadata fields for all properties which have metadata and are present in the data part of the response.
Implementation of the :field:`meta` field is OPTIONAL, unless the server implements slicing, in which case it is MANDATORY (see `Slices of array properties`_).
When an implementation supports the :field:`property_metadata` field, it SHOULD include metadata fields for all properties which have metadata and are present in the data part of the response.
If the client includes the string ``property_metadata`` in the query parameter :query-param:`response_fields`, the server MUST include metadata fields for all properties which have metadata.
Furthermore, if the server returns metadata for a property, it must be included in its entirety, i.e., including all non-null fields.

Example of a response in the JSON response format with two structure entries that each include a metadata property for the attribute field :field:`elements_ratios` and the database-specific per entry metadata field :field:`_exmpl_originates_from_project`:

Expand Down Expand Up @@ -602,6 +608,163 @@ Example of the corresponding metadata property definition contained in the field
}
// ...

Slices of array properties
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest using "list" instead of "array" everywhere, as in the specification "list" is defined as data type, whereas "array" is used much less often and mostly as a synonym of "list".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, good catch. Array should almost everywhere be replaced by list. Array should only be kept when we explicitly refer to JSON:API output arrays.

Copy link
Contributor

@rartino rartino Jun 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking about this, I don't find a good way to handle this without defining the term 'array' to be a general word for a list or a structure of nested lists. (IMO "Multidimensional lists" is far worse as a term.) So, I've pushed a commit that does this.

(Note: 'resolve' this conversation if you are happy with the fix, otherwise comment below).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave it up to somebody more experienced in the protocol to resolve this.

--------------------------

The OPTIMADE standard defines a way for a client to request only a subset of the items of an array, referred to as a slice.
rartino marked this conversation as resolved.
Show resolved Hide resolved
The protocol for this functionality allows the server to allow slicing independently per entry, per array, and per array axis.
rartino marked this conversation as resolved.
Show resolved Hide resolved
This functionality is separate from the protocol described in `Transmission of large property values`_.
rartino marked this conversation as resolved.
Show resolved Hide resolved
Slices are used for a client to ask the server to only provide a subset of items of an array, which can result in a small or large set of items.
In contrast, the protocol for large property values is used by the server implementation to transmit a set of items that it deems too large to provide inside the normal OPTIMADE response.
Comment on lines +617 to +618

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gather that "small" and "large" have a techncial meaning here (wrt to the transmission).
Do you have any kind of annotation trick to makes this clearer?

Copy link
Contributor

@rartino rartino Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Slices are used for a client to ask the server to only provide a subset of items of an array, which can result in a small or large set of items.
In contrast, the protocol for large property values is used by the server implementation to transmit a set of items that it deems too large to provide inside the normal OPTIMADE response.
The protocol for large property values is used by the server implementation to transmit a set of items that it deems too large to provide inside the normal OPTIMADE response.
Slices, on the other hand, are used for a client to request a subset of any size of the items of an array, which can possibly (but not necessarily) result in such a large amount of values that the protocol for large property values is required to transmit them.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this better, yes. Given that only large has a meaning, it's better to remove small, as you did.
2 minor suggestions:

  1. The protocol for large property values: can this refer to the relevant section?
  2. If we decide on using some kind of highlighting (as brought up above), I'd mark server and client. I think it's a good short-hand for navigating the protocol.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The protocol for large property values: can this refer to the relevant section?

I realize that the way these comments chop up the text can make it a bit difficult to see the context, but the link you ask for is already right on the row before this line (numbered 616 right now).


The main mechanism is provided through the query parameter :query-param:`property_slices` defined in section `Single Entry URL Query Parameters`_.
Information relating to the ability of the server to handle this query parameter and the relevant ranges of indexes is provided using metadata property field :field:`array_axes` (see `Metadata properties`_).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the relevant ranges of indexes

Above you used the term "array axis". I'd use the same term here, as with "index" idk whether you mean the dimension or a slice along a dimension.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean here, can you use the GitHub suggest edit feature to show a suggestion? (Also, the discussion of terminology with regards to indices and axes may have been clarified by a discussion we had last web meet?)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Also, the discussion of terminology with regards to indices and axes may have been clarified by a discussion we had last web meet?)

I'd need a refresher there, sorry.

Copy link

@ndaelman-hu ndaelman-hu Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Information relating to the ability of the server to handle this query parameter and the relevant ranges of indexes is provided using metadata property field :field:`array_axes` (see `Metadata properties`_).
Information relating to the ability of the server to handle this query parameter. This SHOULD include the property field :field:`array_axes` (see `Metadata properties`_), listing the numerical indices of axes that may be sliced.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, this doesn't read cleanly to me in the context it appears. The first sentence in the suggestion isn't even a complete sentence?

The context here is that we are in the general text at the top of the section trying to outline what this feature is and how it is used. The sentence right now is just trying to communicate that the metadata property array_axis is one of the essential mechanisms of the protocol.

When the client request includes the query parameter :query-param:`property_slices`, the server MUST provide metadata for all properties for which including the subfield :field:`requested_slice` of the :field:`array_axes` is MANDATORY (see below).
The field :field:`array_axes` is defined as follows:

- :field:`array_axes`: List of Dictionary.
A list of dictionaries which provide information related to the axes of an array property, which is relevant for slicing.
rartino marked this conversation as resolved.
Show resolved Hide resolved
Each item, in order, represents the array axis as declared in the corresponding property definition.

Each item MUST be a dictionary with the following REQUIRED field:

- :field:`dimension_name`: String.
The dimension name of the corresponding array axis.

If the request specifies the :query-param:`property_slices` query parameter for any of the array axes of this array property the following key MUST be present, otherwise the key MUST be omitted or equal to :val:`null`:
rartino marked this conversation as resolved.
Show resolved Hide resolved

- :field:`requested_slice`: Dictionary.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, these are very different modes of querying. Typically, a client will have to query them in separate stages.

  1. I'd think it would be good to explicitely state this, either between this and specification above, or at the very beginning of the enumeration.
  2. Fun edge case: which response should a server provide when both fields are used in a query? Kind of silly, but I could see clients make this mistake.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean here: these fields are included as information from the server to the client to provide information related to slicing; so I'm not sure what the two different "modes" you refer to, or how you from what is written here or what stages you mean. Maybe you can clarify a bit?

Copy link

@ndaelman-hu ndaelman-hu Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 2 query modes, I meant:

  1. requesting metadata about the schema (explicitly demanding metadata on sliceable properties). This section explains the responses format.
  2. actually querying for data, sliced to the desired format.

Perhaps mode 1 could be split into 1.1 (sliceable metadata implicit requested) and 1.2 (sliceable metadata explicitly requested).

Anyhow, I was just asking for a clearer distinction between which query mode is covered where. Subtitles could work? Maybe I highlighted the wrong lines, but that would underscore my point.

Lastly, my 2nd question was about the responses when a query asks for both schema metadata and regular data.

A field that describes the requested slice that was provided via the query parameter :query-param:`property_slices`.
The subfields MUST reflect the values provided via the :query-param:`property_slices`.
The implementation MUST preserve the values as given in the query parameter, including the distinction between specific values and default values even when they are equivalent.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one was kinda though to get on the first read. Maybe refer to the example below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The implementation MUST preserve the values as given in the query parameter, including the distinction between specific values and default values even when they are equivalent.
The implementation MUST preserve the values as given in the query parameter, including the distinction between specific values and default values even when they are equivalent (see example below).

It MAY contain the following subfields that are defined according to the specification of a `slice object`_.

- :field:`start`: Integer or :val:`null`.

- :field:`stop`: Integer or :val:`null`.

- :field:`step`: Integer or :val:`null`.
giovannipizzi marked this conversation as resolved.
Show resolved Hide resolved

A :val:`null` value for any of these fields means it has the default value defined for a `slice object`_.
A missing value is equivalent to a :val:`null` value.
(Consequently, the dictionary MAY be empty if all fields take the default values.)

Examples:

- For :query-string:`property_slices=dim_frames:::` some of the equivalent valid representations are:

- ``{}``
- ``{"start": null, "stop": null, "step": null}``
- ``{"start": null}``
- ``{"stop": null, "step": null}``

Whereas, e.g., the following representation is not valid:

- ``{"start": 0}`` (despite that :val:`0` is the default value of the :field:`start` field.)
But it is instead a valid representation if the query parameter was :query-string:`property_slices=dim_frames:0::`.
Comment on lines +663 to +664

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be clearer when presented as 2 bulletpoints in the format query: response.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a suggested edit here to understand the format you are after.


- :query-string:`property_slices=dim_frames:3:5:2` the representation MUST be:

- ``{"start": 3, "stop": 5, "step": 2}``

The dictionary MAY contain the following fields:

- :field:`length`: Integer.
The length of this array axis which MUST be the same as the length of the declared dimension for this axis in the corresponding property definition.
Note that the length of a dimension can be different for different entries if the length is not explicitly declared by the property definition.
For example, the number of frames, i.e., the length of the dimension named ``dim_frames``, is generally different for different trajectories.

- :field:`sliceable`: Boolean.
If :val:`true`, the server MUST handle slices for that dimension.
If :val:`false`, the server MAY handle slices for that dimension, or MAY return the error :http-error:`501 Not Implemented` when a client requests a slice involving this dimension.
If the field is omitted or :val:`null`, it means the same thing as :val:`false`.

- :field:`available_slice`: Dictionary or :val:`null`.
This field describes a `slice object`_ where there MAY be non-null values in the data.
By including this field, the server certifies that there are only :val:`null` values outside this slice.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the server certifies that [...]

Can I interpret this as a MUST? If so, I would put the stronger specifier before the weaker MAY.

rartino marked this conversation as resolved.
Show resolved Hide resolved
If not provided, or equal to :val:`null` or an empty dictionary, the client cannot make any assumptions about what part of the array contains :val:`null` values.

Examples:

- ``{"start": 3, "stop": 7, "step": 2}`` means the server certifies that values at indexes 0, 1, 2, 4, 6 and any index from 8 to the end of the array are :val:`null`.

Below follows an example of the :field:`data` and :field:`meta` parts of a response using the JSON response format for a request to the trajectory endpoint with the query parameter :query-param:`property_slices=dim_frames:3:37:5` and :query-param:`response_fields=frame_cartesian_site_positions,_exmpl_temperature` where the trajectory consists of 432934 frames (with indexes 0 to 432933) and where the :field:`frame_cartesian_site_positions` contains 7 sites.
Furthermore, the metadata subfield :field:`available_slice` in :field:`array_axes` in :field:`_exmpl_temperature` certifies that all values of the data field :field:`_exmpl_temperature` are :val:`null` except at indexes 1000, 1030, 1060, ..., 4000, where values can be either numeric or :val:`null`).

.. code:: jsonc

{
// ...
"data": {
"type": "trajectories",
"id": "2345678",
"attributes": {
"frame_cartesian_site_positions": null,
"_exmpl_temperature": null
},
"meta": {
"property_metadata": {
"frame_cartesian_site_positions": {
"array_axes": [
{
"dimension_name": "dim_frames",
"requested_slice": {
"start": 3,
"stop": 37,
"step": 5
},
"available_slice": {
"start": 0,
"stop": 432933,
"step": 1
},
"sliceable": true,
"length": 432934
},
{
"dimension_name": "dim_sites",
"available_slice": {
"start": 0,
"stop": 6,
"step": 1
},
"sliceable": false,
"length": 7
},
{
"dimension_name": "dim_spatial",
"length": 3
}
]
},
"_exmpl_temperature": {
"array_axes": [
{
"dimension_name": "dim_frames",
"requested_slice": {
"start": 3,
"stop": 37,
"step": 5
},
"available_slice": {
"start": 1000,
"stop": 4000,
"step": 30
},
"sliceable": true,
"length": 432934
}
]
}
},
"partial_data_links": {
//...
}
}
}
// ...
}

Responses
=========

Expand Down Expand Up @@ -1118,6 +1281,7 @@ Standard OPTIONAL URL query parameters not in the JSON:API specification:
Additional OPTIONAL URL query parameters not described above are not considered to be part of this standard, and are instead considered to be "custom URL query parameters".
These custom URL query parameters MUST be of the format "<database-provider-specific prefix><url\_query\_parameter\_name>".
These names adhere to the requirements on implementation-specific query parameters of `JSON:API v1.1 <http://jsonapi.org/format/1.1>`__ since the database-provider-specific prefixes contain at least two underscores (a LOW LINE character '\_').
If the server receives an unrecognized query parameter that does not adhere to this format it MUST return the error :http-error:`400 Bad Request`.

Example uses of custom URL query parameters include providing an access token for the request, to tell the database to increase verbosity in error output, or providing a database-specific extended searching format.

Expand Down Expand Up @@ -1211,6 +1375,31 @@ While the following URL query parameters are OPTIONAL for clients, API implement
The URL query parameter :query-param:`include` is OPTIONAL for both clients and API implementations.
The meaning of these URL query parameters are as defined above in section `Entry Listing URL Query Parameters`_.

One additional query parameter :query-param:`property_slices` MUST be handled by the API implementation either as defined below or by returning the error :http-error:`501 Not Implemented`:
rartino marked this conversation as resolved.
Show resolved Hide resolved

- **property\_slices**: A number of slice specifications to request only parts of array properties for the functionality described in `Slices of array properties`_.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May the client request multiple (different) slices from the same array axis in the same query?
E.g. property_slices=[dim_frames:3:37:5,dim_frames:49:105:2]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clarified in "REQUIRED keys". A link suffices then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the present version (which may have changed since you commented) I think this information is quite clear in the text right below.


The query parameter contains a comma-separated (",", ASCII 44(0x2C)) list of slice specifications.
giovannipizzi marked this conversation as resolved.
Show resolved Hide resolved
Each slice specification consists of an ordered sequence of four elements separated by the colon character (":", ASCII 58(0x3A)).
giovannipizzi marked this conversation as resolved.
Show resolved Hide resolved
The elements in the sequence are the dimension name and the three components of the slice, i.e., the start, stop, and step values defined in the same way as for a `slice object`_.
Omitting the value for any of the components of the slice specifies a default value (however, all the colon separators MUST be included).
The start value specifies the first index in that dimension for which values should be returned (which is 0-based and inclusive).
The default is :val:`0`.
The stop value specifies the last index for which values should be returned (inclusive).
The default is the last index of the array along the specified dimension.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The default is the last index of the array along the specified dimension.
The default is :val:`null`, which represents the last index of the array along the specified dimension.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually already explaiend that :val:null refers to the default value, and that it should be returned unless a specified value was used.
From how I understood it, the same applies to the start and step keys too.

rartino marked this conversation as resolved.
Show resolved Hide resolved
The step value specifies the step size in that dimension.
The default is :val:`1`.

An empty value of the :query-param:`property_slices` query parameter MUST be interpreted as equivalent to the query parameter not being included in the request.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this then equivalent to property_ranges=[<first_dim>:::, ...]?
I.e. should this return the full property or leave it out?

This might be defined somewhere else. If so, pls refer to that section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query parameter not being included means the client isn't trying to use this protocol; so I think the natural interpretation is that "everything works as usual without the slices protocol". I guess that could be clarified somewhere, but I'm not sure exactly where.


Requirements and conventions for the response when this query parameter is used are described in `Slices of array properties`_.

Example:

- :query-url:`http://optimade.example.com/v1/trajectories/id_12345?response_fields=frame_cartesian_site_positions&property_ranges=dim_frames::999:10,dim_sites:30:70:`

This query URL requests items from the array :field:`frame_cartesian_site_positions` only for the 31st to 71st sites (i.e., with indexes 30 through 70 inclusive) for 1 out of every 10 frames of the first 1000 frames (i.e., taking steps of 10 over indexes 0 through 999 inclusive, which requests the frames with indexes 0, 10, 20, 30, ..., 990) of a trajectory with ID :val:`id_12345`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor style changes to make the phrase clearer:

  1. Split the phrase up by both attributes.
  2. Align the order of the example with the explanation, i.e. concerning dim_frames and dim_sites.
  3. Just reiterate the 0-indexing convention after "the 31st to 71st sites". Apart from that, it's a great refresher.
  4. the frames with indexes 0, 10, 20, 30, ..., 990 explains it enough. The paranteses else become too verbose.

Comment on lines +1401 to +1403
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this addresses @ndaelman-hu suggestions, except for removing the explanation in the last parenthesis, which from our discussions on the workshop I do think still is necessary to be completely clear.

Suggested change
- :query-url:`http://optimade.example.com/v1/trajectories/id_12345?response_fields=frame_cartesian_site_positions&property_ranges=dim_frames::999:10,dim_sites:30:70:`
This query URL requests items from the array :field:`frame_cartesian_site_positions` only for the 31st to 71st sites (i.e., with indexes 30 through 70 inclusive) for 1 out of every 10 frames of the first 1000 frames (i.e., taking steps of 10 over indexes 0 through 999 inclusive, which requests the frames with indexes 0, 10, 20, 30, ..., 990) of a trajectory with ID :val:`id_12345`.
- :query-url:`http://optimade.example.com/v1/trajectories/id_12345?response_fields=frame_cartesian_site_positions&property_ranges=dim_sites:30:70:,dim_frames::999:10`
This query URL requests items from the trajectory with ID :val:`id_12345`.
It requests items from the array :field:`frame_cartesian_site_positions` for this trajectory.
The items that are requested are for only the 31st to 71st sites (i.e., with indexes 30 through 70 inclusive) for 1 out of every 10 frames of the first 1000 frames (i.e., taking steps of 10 over indexes 0 through 999 inclusive, which requests the frames with indexes 0, 10, 20, 30, ..., 990).


Single Entry JSON Response Schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -2182,8 +2371,13 @@ A Property Definition MUST be composed according to the combination of the requi
**REQUIRED keys:**

- :field:`names`: List of Strings.
A list of names of the dimensions of the underlying one or multi-dimensionsional data represented as mutiple levels of lists.
The order is that the the first name applies to the outermost list, the next name to the lists embedded in that list, etc.
A list of names of the dimensions of the underlying one or multi-dimensionsional data represented as multiple levels of lists.
The order is such that the first name applies to the outermost list, the next name to the lists embedded in that list, etc.
Dimension names defined by the OPTIMADE standard are prefixed by ``dim_``.
Dimension names defined by database or definition providers MUST be prefixed by the corresponding database or namespace prefix, and SHOULD also be prefixed by ``dim_``, e.g., ``_exmpl_dim_particles``.
rartino marked this conversation as resolved.
Show resolved Hide resolved
If, within one entry, two or more array axes in one or more properties share the same dimension :field:`name`, those represent the same dimension.
For example, let us consider the property :property:`frame_cartesian_site_positions` of the trajectory entry, where the first dimension name is :val:`dim_frames`.
If there is another one-dimensional (i.e., with a single axis) array property :property:`_exmpl_energy` of the same trajectory entry that specifies in its property definition the same dimension name :val:`dim_frames` for its axis, then the values of :property:`_exmpl_energy` and of :property:`frame_cartesian_site_positions` at index *i* pertain to the same frame.
Comment on lines +2381 to +2382

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Her, you lost me

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ndaelman-hu is this more clear?:

Suggested change
If there is another one-dimensional (i.e., with a single axis) array property :property:`_exmpl_energy` of the same trajectory entry that specifies in its property definition the same dimension name :val:`dim_frames` for its axis, then the values of :property:`_exmpl_energy` and of :property:`frame_cartesian_site_positions` at index *i* pertain to the same frame.
Let the trajectory entry in this example have another, one-dimensional, array property :property:`_exmpl_energy`, which in its property definition specifies *the same name*, :val:`dim_frames`, as the name of the axis corresponding to its single dimension.
The joint dimension name means the values of :property:`_exmpl_energy` and of :property:`frame_cartesian_site_positions` at index *i* pertain to the same frame.
If slicing is used to request only parts of the data along the :val:`dim_frames` dimension, that is a request to slice both the properties according to the specified slice.


- :field:`sizes`: List of Integers or :val:`null`.
A list of fixed length requirements on the underlying one or multi-dimensionsional data represented as mutiple levels of lists.
Expand Down
Loading