Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
92 changes: 92 additions & 0 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3755,6 +3755,20 @@
"title": "OptimadeError",
"description": "detail MUST be present"
},
"OptimizationType": {
"type": "string",
"enum": [
"experimental",
"hybrid",
"global",
"local",
"none",
"indeterminate",
"other"
],
"title": "OptimizationType",
"description": "Enumeration of optimization_type values"
},
"Periodicity": {
"type": "integer",
"enum": [
Expand Down Expand Up @@ -4878,6 +4892,21 @@
"title": "ResponseMetaQuery",
"description": "Information on the query that was requested."
},
"SiteCoordinateSpan": {
"type": "string",
"enum": [
"fundamental_domain",
"asymmetric_unit",
"molecular_fundamental_domain",
"molecular_asymmetric_unit",
"unit_cell",
"molecular_unit_cell",
"molecular_entities",
"other"
],
"title": "SiteCoordinateSpan",
"description": "Enumeration of site_coordinate_span values"
},
"Species": {
"properties": {
"name": {
Expand Down Expand Up @@ -5416,6 +5445,55 @@
"x-optimade-support": "should",
"x-optimade-unit": "\u00c5"
},
"fractional_site_positions": {
"anyOf": [
{
"items": {
"items": {
"type": "number"
},
"type": "array",
"maxItems": 3,
"minItems": 3
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Fractional Site Positions",
"description": "Fractional coordinates (positions) of each site in the structure.\n A site is usually used to describe positions of atoms; what atoms can be encountered at a given site is conveyed by the `species_at_sites` property, and the species themselves are described in the `species` property.\n Site coordinates MAY be given as `cartesian_site_positions`_, `fractional_site_positions`_, or both.\n When symmetry operations given in `space_group_symmetry_operations_xyz`_ are applied, they MUST be applied to coordinates given in the `fractional_site_positions`_ array.\n\n- **Type**: list of list of floats\n\n- **Requirements/Conventions**:\n - **Support**: SHOULD be supported by all implementations, i.e., SHOULD NOT be `null`.\n - **Query**: Support for queries on this property is OPTIONAL.\n If supported, filters MAY support only a subset of comparison operators.\n - It MUST be a list of length equal to the number of sites in the structure, where every element is a list of the three fractional coordinates of a site expressed as float values in the fractions of the unit cell vectors given by the `lattice_vectors`_ property.\n - An entry MAY have multiple sites at the same site position (for a relevant use of this, see e.g., the property `assemblies`_).\n - **Note**: Since both `cartesian_site_positions`_ and the `fractional_site_positions`_ always describe the same sites, they MUST always have the same number of elements, equal to the number of elements in the `species_at_sites`_ array.\n\n- **Examples**:\n\n - `[[0,0,0],[0,0,0.2]]` indicates a structure with two sites, one sitting at the origin and one along the third unit cell axis (*c*-axis), 1/5-th (0.2) of the vector *c* in the direction of the vector *c* from the origin.",
"x-optimade-queryable": "optional",
"x-optimade-support": "should"
},
"site_coordinate_span": {
"anyOf": [
{
"$ref": "#/components/schemas/SiteCoordinateSpan"
},
{
"type": "null"
}
],
"description": "Indicates the extent of the material (crystal) described in the response.\n In particular, properties `cartesian_site_positions` and `fractional_site_positions` MUST contain all sites *belonging* to the described extent.\n- **Type**: string\n- **Requirements/conventions**:\n\n - **Support**: MUST be supported by all implementations if coordinates in `fractional_site_positions` are returned.\n It SHOULD be supported if coordinates in `cartesian_site_positions` are returned.\n - **Query**: Support for queries on this property is OPTIONAL.\n\n - The value of this property MUST be one of the following:\n\n - `\"fundamental_domain\"`: means that sites described in the response span a fundamental domain (Vinberg, 1994; European Mathematical Society, 2020) of a periodic system.\n When a server indicates this span in the response, it MUST provide those sites that enable reconstruction of the whole periodic system by applying symmetry operations from `space_group_symmetry_operations_xyz` property and then applying translations given by `lattice_vectors`.\n The fundamental domain does not need to be a connected space region.\n - `\"asymmetric_unit\"`: all sites are in a simply connected space region that is a fundamental domain, as per IUCr Online Dictionary of Crystallography definition (IUCr, 2017).\n - `\"molecular_fundamental_domain\"`: a fundamental domain where all atoms connected by covalent or donor-acceptor coordination bonds are adjacent to each other, placed at a bond distance.\n - `\"molecular_asymmetric_unit\"`: an asymmetric unit (a simply connected fundamental domain) where all atoms bound by covalent or donor-acceptor coordination bonds are adjacent to each other, placed at a bond distance.\n - `\"unit_cell\"`: a full unit cell of a periodic system (crystal), i.e., any repeating unit chosen by the server defined by the property `lattice_vectors`.\n For this span, the server MUST provide a set of sites in the response that can be used to reconstruct the whole periodic system (crystal) by simply applying translations from the `lattice_vectors` property to those sites.\n - `\"molecular_unit_cell\"`: same as `\"unit_cell\"`, but in addition places atoms that are bound by covalent or coordination bonds at a bond distance from each other.\n - `\"molecular_entities\"`: sets of atoms that are bound by covalent or coordination bonds, as per IUPAC definition of a 'molecular entity'.\n This set of sites MAY be larger than a fundamental domain.\n - `\"other\"`: any other collection of sites that does not fit the enumerated values above.\n - `null`: if omitted or `null`, the default value of `site_coordinate_span` is `unit_cell`.\n This is the assumed behavior of all main implementations before the `site_coordinate_span` definition was introduced.\n\n- **Note**: In all cases it is RECOMMENDED that only the minimal set of the sites that is needed to reconstruct the whole material is provided.\n For example, for the 'unit_cell' span the server SHOULD NOT return sites that can be obtained from other returned sites through the translations given in `lattice_vectors`; only a non-redundant set of sites SHOULD be provided.\n\n- **Bibliographic References**:\n\n E.B. Vinberg (originator). (1994) Encyclopedia of Mathematics. ISBN [1402006098](https://isbnsearch.org/isbn/1402006098), URL: https://encyclopediaofmath.org/index.php?title=Fundamental_domain&oldid=13590 [accessed 2025-04-30T08:55+03:00].\n\n European Mathematical Society (2020). Fundamental domain. Encyclopedia of Mathematics. URL: http://encyclopediaofmath.org/index.php?title=Fundamental_domain&oldid=47023 [accessed 2025-04-30T08:53+03:00].\n\n IUCr (2017). Asymmetric unit. Online Dictionary of Crystallography, URL: https://dictionary.iucr.org/Asymmetric_unit [accessed 2025-04-30T09:01+03:00].",
"x-optimade-queryable": "optional",
"x-optimade-support": "should"
},
"site_coordinate_span_description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Site Coordinate Span Description",
"description": "Human-readable semi-formal characterization of the coordinate span when the `site_coordinate_span` property has value `\"other\"`.\n- **Type**: string\n- **Example**: `\"Two fullerene molecules with a VdW contact.\"`",
"x-optimade-queryable": "optional",
"x-optimade-support": "should"
},
"nsites": {
"anyOf": [
{
Expand Down Expand Up @@ -5490,6 +5568,20 @@
"description": "A list of strings that flag which special features are used by the structure.\n\n- **Type**: list of strings\n\n- **Requirements/Conventions**:\n - **Support**: MUST be supported by all implementations, MUST NOT be `null`.\n - **Query**: MUST be a queryable property.\n Filters on the list MUST support all mandatory HAS-type queries.\n Filter operators for comparisons on the string components MUST support equality, support for other comparison operators are OPTIONAL.\n - MUST be an empty list if no special features are used.\n - MUST be sorted alphabetically.\n - If a special feature listed below is used, the list MUST contain the corresponding string.\n - If a special feature listed below is not used, the list MUST NOT contain the corresponding string.\n - **List of strings used to indicate special structure features**:\n - `disorder`: this flag MUST be present if any one entry in the `species` list has a `chemical_symbols` list that is longer than 1 element.\n - `implicit_atoms`: this flag MUST be present if the structure contains atoms that are not assigned to sites via the property `species_at_sites` (e.g., because their positions are unknown).\n When this flag is present, the properties related to the chemical formula will likely not match the type and count of atoms represented by the `species_at_sites`, `species` and `assemblies` properties.\n - `site_attachments`: this flag MUST be present if any one entry in the `species` list includes `attached` and `nattached`.\n - `assemblies`: this flag MUST be present if the property `assemblies` is present.\n\n- **Examples**: A structure having implicit atoms and using assemblies: `[\"assemblies\", \"implicit_atoms\"]`",
"x-optimade-queryable": "must",
"x-optimade-support": "must"
},
"optimization_type": {
"anyOf": [
{
"$ref": "#/components/schemas/OptimizationType"
},
{
"type": "null"
}
],
"title": "Optimization Type",
"description": "A string that classifies the type of optimization that has resulted in the structural data.\n\nIf the property is `null` or omitted, no information is provided about the type of optimization used to obtain the structural data.\n\nIf present and not `null`, the property SHOULD take one of the following values:\n\n * `experimental`: the structure results from an optimization or refinement process part of an experimental technique, e.g., minimization of the discrepancy between observed and predicted scattered amplitudes from diffraction data.\n\n * `hybrid`: the structure is the result of the combination of an experiment and further optimization based on a reasonable theoretical energy model so that it remains a fair representation of the original experimental structure.\n For example, experimental structures relaxed using *ab initio* calculations are in this category.\n Structures where the experimental coordinates are kept, but one or more elements are substituted for other elements, are not included in this category.\n\n * `global`: the structure has been optimized using a theoretical technique based on a reasonable energy model in a way that takes into account the global energy surface.\n The structure has been optimized into the global energy minimum or into a local minimum within an energy range of the global minimum commonly considered for potential metastability (typically on the scale of 100 meV/atom).\n A common technique for this type of optimization is to construct the convex hull of thermodynamical stability from the known minima and dismiss structures outside the relevant energy range.\n\n * `local`: the structure has been optimized using a theoretical technique based on a reasonable energy model into a local minimum of the energy surface.\n For example, structures relaxed using *ab initio* calculations without consideration of the energy of other minima in configuration space qualify for this category.\n\n * `none`: the structure has not undergone an optimization process and is thus, in some sense, arbitrary.\n Structures of this kind can come from, e.g., randomly generated coordinates or non-equilibrium snapshots.\n\n * `indeterminate`: the database declares that the type of optimization used for this specific entry cannot be determined, e.g., because that information is missing.\n This value represents a stronger statement (that the database knows that the type of optimization is not known) than an omitted classification (i.e., the field is missing or has the value `null`) which communicates that the property is unknown only in the sense discussed in the section `Properties with an unknown value`.)\n\n * `other`: the structure is the result of some optimization process, but none of the other categories correctly represents the type of optimization used.\n\nOther strings prefixed by a database-specific prefix, e.g., `_exmpl_optimized_on_fixed_grid`, SHOULD NOT be used.\nOther non-standard strings MUST NOT be used.\nClients encountering unrecognized strings SHOULD treat them to mean the same as the field having the value `\"other\"`.\n\nStructures produced by AI models and other techniques that have been reasonably tested to reliably generate results equivalent to structural optimization using energy models SHOULD be classified the same as if that type of energy model had been used.\n\n**Explained examples**:\n\n- For a structure entry directly encoding structural information obtained from a neutron diffraction experiment: `\"experimental\"`.\n\n- For a structure entry that encodes the structural information from a theoretical relaxation of an `\"experimental\"` entry using computational software that implements density functional theory: `\"hybrid\"`.",
"x-optimade-queryable": "optional",
"x-optimade-support": "optional"
}
},
"additionalProperties": true,
Expand Down
1 change: 1 addition & 0 deletions optimade/adapters/structures/ase.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ def from_ase_atoms(atoms: Atoms) -> StructureResourceAttributes:

attributes = {}
attributes["cartesian_site_positions"] = atoms.positions.tolist()
attributes["fractional_site_positions"] = atoms.get_scaled_positions().tolist()
attributes["lattice_vectors"] = atoms.cell.tolist()
attributes["species_at_sites"] = atoms.get_chemical_symbols()
attributes["elements_ratios"] = elements_ratios_from_species_at_sites(
Expand Down
8 changes: 3 additions & 5 deletions optimade/adapters/structures/cif.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,14 @@ def get_cif(

# Since some structure viewers are having issues with cartesian coordinates,
# we calculate the fractional coordinates if this is a 3D structure and we have all the necessary information.
if not hasattr(attributes, "fractional_site_positions"):
if not getattr(attributes, "fractional_site_positions", None):
attributes.fractional_site_positions = fractional_coordinates(
cell=attributes.lattice_vectors, # type:ignore[arg-type]
cartesian_positions=attributes.cartesian_site_positions, # type:ignore[arg-type]
)

# NOTE: This is otherwise a bit ahead of its time, since this OPTIMADE property is part of an open PR.
# See https://github.com/Materials-Consortia/OPTIMADE/pull/206
coord_type = (
"fract" if hasattr(attributes, "fractional_site_positions") else "Cartn"
"fract" if getattr(attributes, "fractional_site_positions", None) else "Cartn"
)

cif += (
Expand Down Expand Up @@ -130,7 +128,7 @@ def get_cif(
symbol_occurences: dict[str, int] = {}
for site_number in range(attributes.nsites): # type: ignore[arg-type]
species_name = attributes.species_at_sites[site_number] # type: ignore[index]
site = sites[site_number]
site = sites[site_number] # type: ignore[index]

current_species = species[species_name]

Expand Down
6 changes: 3 additions & 3 deletions optimade/adapters/structures/proteindatabank.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def get_pdbx_mmcif(

# Since some structure viewers are having issues with cartesian coordinates,
# we calculate the fractional coordinates if this is a 3D structure and we have all the necessary information.
if not hasattr(attributes, "fractional_site_positions"):
if not getattr(attributes, "fractional_site_positions", None):
attributes.fractional_site_positions = fractional_coordinates(
cell=attributes.lattice_vectors, # type: ignore[arg-type]
cartesian_positions=attributes.cartesian_site_positions, # type: ignore[arg-type]
Expand Down Expand Up @@ -136,7 +136,7 @@ def get_pdbx_mmcif(
# NOTE: This is otherwise a bit ahead of its time, since this OPTIMADE property is part of an open PR.
# See https://github.com/Materials-Consortia/OPTIMADE/pull/206
coord_type = (
"fract" if hasattr(attributes, "fractional_site_positions") else "Cartn"
"fract" if getattr(attributes, "fractional_site_positions", None) else "Cartn"
)

cif += (
Expand Down Expand Up @@ -170,7 +170,7 @@ def get_pdbx_mmcif(

for site_number in range(attributes.nsites): # type: ignore[arg-type]
species_name = attributes.species_at_sites[site_number] # type: ignore[index]
site = sites[site_number]
site = sites[site_number] # type: ignore[index]

current_species = species[species_name]

Expand Down
Loading
Loading