Altermagnets Database

High-throughput computational screening for altermagnetic materials

Programmatic access via the OPTIMADE API

The OPTIMADE API is a REST API for materials databases, developed by the OPTIMADE consortium of materials-science data providers so that the same query language and response format work across dozens of independent databases. The Altermagnets Database (amdb) serves data through the OPTIMADE API v1.3.0 at:

Overview

While the standard OPTIMADE API endpoints are available, e.g., structures, the primary entry type in amdb is _anyterial_altermagnet_screening_results. These entries represent the outcome of a screened candidate material, with the same quantities as shown on the detailed information pages on this website.

Fetching a single entry by id uses the JSON:API "included" feature to include all linked _httk_records data records, with information about, e.g., extracted quantities from the originating DFT calculation.

Results represented as _httk_records provide provenance information via _httk_runs relationships.

Example queries

The amdb OPTIMADE endpoint can be queried with command line tools such as curl. For example, a filter query restricted to a couple of fields and a few rows:

Shell

curl -G \
  "https://altermagnets.anyterial.se/optimade/amdb/v1/"\
"_anyterial_altermagnet_screening_results" \
  --data-urlencode \
    "filter=_anyterial_max_spin_splitting > 0.5" \
  --data-urlencode \
    "response_fields=_anyterial_formula,"\
"_anyterial_max_spin_splitting" \
  --data-urlencode "page_limit=3"

Output

{
  "data": [
    { "id": "anyt.am-1-1", "type": "_anyterial_altermagnet_screening_results",
      "attributes": { "_anyterial_formula": "CrSb", "_anyterial_max_spin_splitting": 1.8724 } },
    { "id": "anyt.am-1-2", "type": "_anyterial_altermagnet_screening_results",
      "attributes": { "_anyterial_formula": "MnTe", "_anyterial_max_spin_splitting": 0.9227 } },
    { "id": "anyt.am-1-3", "type": "_anyterial_altermagnet_screening_results",
      "attributes": { "_anyterial_formula": "RuO2", "_anyterial_max_spin_splitting": 0.8654 } }
  ],
  "meta": { "data_returned": 7, "data_available": 180, "more_data_available": true }
}

(the response copied below is trimmed: relationships and the rest of meta is omitted.) We find that 7 of 180 screened materials have a maximum spin splitting above 0.5 eV.

A single-entry fetch, showing the default-included records:

Shell

curl "https://altermagnets.anyterial.se/optimade/amdb/v1/_anyterial_altermagnet_screening_results/anyt.am-1-1"

Output

{
  "data": {
    "id": "anyt.am-1-1",
    "type": "_anyterial_altermagnet_screening_results",
    "attributes": {
      "_anyterial_formula": "CrSb",
      "_anyterial_classification": "collinear",
      "_anyterial_max_spin_splitting": 1.8724,
      "_anyterial_avg_spin_splitting": 0.763170313,
      "..." : "..."
    },
    "relationships": {
      "_httk_records": { "data": [{"id": "anyt.am.records-1-1", "type": "_httk_records"}, {"id": "anyt.am.records-1-135", "type": "_httk_records"}] },
      "_httk_runs": { "data": [{"id": "anyt.am.runs-1-1", "type": "_httk_runs"}] },
      "references": { "data": [{"id": "anyt.am.references-1-1", "type": "references"}] },
      "structures": { "data": [{"id": "anyt.am.structures-1-1", "type": "structures"}] }
    }
  },
  "included": [
    { "id": "anyt.am.records-1-1", "type": "_httk_records",
      "attributes": { "_httk_total_energy": -22.40776312 } },
    { "id": "anyt.am.records-1-135", "type": "_httk_records",
      "attributes": { "_anyterial_max_spin_splitting": 1.8724, "_anyterial_avg_spin_splitting": 0.763170313, "..." : "..." } },
    { "id": "anyt.am.references-1-1", "type": "references",
      "attributes": { "doi": "10.1039/d0dt03277h" } }
  ]
}

Query amdb with OPTIMADE in Python using httk

The high-throughput toolkit (httk) is a Python toolkit supporting high-throughput computations. Its provides an OPTIMADE client that lets you query amdb with Python. The following instructions are fairly generic, and should be adaptable to any database that supports OPTIMADE API.

To follow the examples below, make sure to have httk2 installed (preferably in a virtual environment):

Shell

pip install httk2

Connect and discover what entry types the database provides:

Python

from httk.store.optimade import OptimadeStore

store = OptimadeStore("https://altermagnets.anyterial.se/optimade/amdb")
print("api_version:", store.api_version)
for entry_type in store.entry_types:
    if not entry_type.name.endswith(("~revs", "~alts")): # (skip technical endpoints)
        print(entry_type.name, "->", entry_type.backend.__name__)

Output

api_version: 1.3.0
_anyterial_altermagnet_screening_results -> OptimadeResource
structures -> OptimadeStructure
references -> OptimadeReference
_httk_runs -> OptimadeResource
_httk_records -> OptimadeResource
files -> OptimadeFile

The OPTIMADE API filtering language can be used to extract entries you are looking for. A Pandas dataframe-type slicing syntax is supported. Conditions combine with & (and) and | (or):

Python

from httk.store.optimade import OptimadeStore

store = OptimadeStore("https://altermagnets.anyterial.se/optimade/amdb/")
results = store.slicer("_anyterial_altermagnet_screening_results")
selected = materials[(results["_anyterial_max_spin_splitting"] > 0.5) & (results["_anyterial_classification"] == "collinear")]
for entry, i in selected:
    print(i, entry.id, entry._anyterial_formula, entry._anyterial_max_spin_splitting)

Output

0 anyt.am-1-1 CrSb 1.8724
1 anyt.am-1-2 MnTe 0.9227
2 anyt.am-1-3 RuO2 0.8654
3 anyt.am-1-5 UCr2Si2C 0.7192

A more sophisticated searcher interface is also available, offering sorting and ways to formulate queries across relationships between entry types (for more details, see the httk-store documentation).

For example, fetching one material with its _httk_records and its crystal structure as links outputs, so they ride along in the same response:

Python

from httk.store.optimade import OptimadeStore
from pprint import pprint

store = OptimadeStore("https://altermagnets.anyterial.se/optimade/amdb")
results = store.entry_type("_anyterial_altermagnet_screening_results")
search = store.searcher()
selected = search.variable(results)
search.add(selected.id == "anyt.am-1-1")

row = search.results(
    item=selected,
    formula=selected._anyterial_formula,
    max_ss=selected._anyterial_max_spin_splitting,
    # link outputs ride along in the same response: the client adds
    # include= for these two automatically, at no extra request.
    records=selected.links._httk_records,
    structures=selected.links.structures,
).one()

print("Entry:",row.item.id, row.formula, "with max_spin_splitting =", row.max_ss)
print("Is linked to",len(row.records),"records and",len(row.structures),"structures\n")

for record in row.records:
    print("== record:", record.id)
    pprint(dict(record["attributes"]))
    print()

for structure in row.structures:
    print("== structure:", structure.id, structure.chemical_formula_reduced, structure.elements)

Output

Entry: anyt.am-1-1 CrSb with max_spin_splitting = 1.8724
Is linked to 2 records and 1 structures

== record: anyt.am.records-1-181
{'_httk_total_energy': Decimal('-22.40776312'),
 'immutable_id': 'anyt.am.records-1-181~1',
 'last_modified': None}

== record: anyt.am.records-1-1
{'_anyterial_avg_spin_splitting': Decimal('0.763170313'),
 '_anyterial_electronic_type': 'metallic',
 '_anyterial_max_spin_splitting': Decimal('1.8724'),
 '_anyterial_spin_splitting_fraction': Decimal('0.34375'),
 '_httk_dft_band_gap': Decimal('0.0'),
 'immutable_id': 'anyt.am.records-1-1~1',
 'last_modified': None}

== structure: anyt.am.structures-1-1 CrSb ('Cr', 'Sb')

Following provenance one step further, to the workflow run and its declared input structure and outputs, by walking .links on the returned record:

Python

from httk.store.optimade import OptimadeStore

store = OptimadeStore("https://altermagnets.anyterial.se/optimade/amdb")
results = store.entry_type("_anyterial_altermagnet_screening_results")
search = store.searcher()
selected = search.variable(results)
search.add(selected.id == "anyt.am-1-1")
row = search.results(item=selected).one()

(run,) = row.item.links._httk_runs
print(run.id, run["attributes"]["_httk_workflow_declaration_uri"])
for edge in run.links._httk_has_input:
    print(" input:", edge.type, edge.id)
for edge in run.links._httk_has_output:
    print(" output:", edge.type, edge.id)

Output

anyt.am.runs-1-1 https://schemas.anyterial.se/defs/v0.1/workflows/altermagnets-scf-httk-v1
 input: structures anyt.am.structures-1-1
 output: _httk_records anyt.am.records-1-1
 output: files anyt.am.files-1-1
 output: files anyt.am.files-1-2
 output: files anyt.am.files-1-3

(the _httk_label meta on each edge, e.g. input_structure, total_energy, vasprun, is dropped here: .links.<name> resolves the edge targets, not their labels, and run["relationships"]["_httk_has_input"]["data"][i]["meta"] would be needed to recover them -- the example stays clear without it.)

A depth-1 relationship filter reaches through structures directly, without following any relationship at runtime:

Python

from httk.store.optimade import OptimadeStore

store = OptimadeStore("https://altermagnets.anyterial.se/optimade/amdb")
results = store.entry_type("_anyterial_altermagnet_screening_results")
search = store.searcher()
selected = search.variable(results)
search.add(selected.links.structures.nelements > 3)
print("matches:", search.count())

Output

matches: 63