RO-Crate export¶
What ATRIUM can publish as an RO-Crate, and how the blocks page-classification and the translator write are carried into it.
Scope
The exporter handles every block. The mapping below is for the blocks these two tools
write, taken from the exporter's own output.
docs/rocrate_export.md
is the full guide, including an RO-Crate tutorial from zero.
RO-Crate in one paragraph¶
An RO-Crate is a folder with one extra file, ro-crate-metadata.json: a JSON-LD description of
what is in the folder, who made it, with which software, and under which licence — written in
schema.org terms so that repositories and catalogues can read it without knowing anything about
ATRIUM. ATRIUM's exporter, atrium_rocrate.py (RO-Crate 1.1), turns a
document record into such a description, and a set of records
from one run into a crate of crates.
A crate is what a repository, a catalogue or a reviewer receives: the data files plus a description they can read with generic RO-Crate tooling — who produced what, with which program, when, under which licence — without running any ATRIUM code.
What happens to these two tools' blocks¶
Exporting the worked-example record —
page-classification's page_categories and pages, then the translator's translations and
derived_from — gives 18 entities:
| In the record | In the crate | What the crate carries |
|---|---|---|
page_categories: {"1": "TEXT_P"} |
a DefinedTerm https://w3id.org/atrium/page-category/TEXT_P, in the DefinedTermSet …/scheme/page-category, listed in the root's about |
the label: a crate says the document is about TEXT_P; the per-page assignment stays in the record |
pages[].category, pages[].category_confidence |
the same DefinedTerm, de-duplicated |
the label, once; the confidence stays in the record |
translations |
a #block-translations CreativeWork, created by #tool-translator |
the block, with its creator and date; the language pair, backend and output mode stay in the record |
derived_from.translated_xml |
a File CTX000000003-1_en.alto.xml, encodingFormat: application/alto+xml, in the root's hasPart |
the translated file, by the name the translator records |
derived_from.classification (when present) |
a File in hasPart |
page-classification's result table for the run |
each assembled.blocks stamp |
a #block-<name> CreativeWork with recordBlock, dateModified and creator |
who wrote each block last |
each provenance.contributors[] entry |
a #run-<program>-<run_id> CreateAction: instrument the tool, result the blocks it wrote |
who ran, when, and what they produced |
| each program | a #tool-<program> SoftwareApplication with the repository url |
the program and its repository; version, image and runtime when a paradata map is passed in from Python |
provenance.license |
the root's license |
the record's computed licence — see how the record's licence is computed |
The root also names the project's authors as ORCID Person entities.
For page-classification's half of that record, the heart of the output reads:
{ "@id": "./", "@type": "Dataset",
"name": "ATRIUM document record CTX000000003", "identifier": "CTX000000003",
"about": [ { "@id": "https://w3id.org/atrium/page-category/TEXT_P" } ],
"license": { "@id": "https://opensource.org/license/mit/" },
"datePublished": "2026-09-22",
"mentions": [ { "@id": "#run-page-classification-260922-220516" } ],
"author": [ "…" ] },
{ "@id": "#block-page_categories", "@type": "CreativeWork", "recordBlock": "page_categories",
"creator": { "@id": "#tool-page-classification" },
"dateModified": "2026-09-22T22:05:16.866272+00:00" },
{ "@id": "https://w3id.org/atrium/page-category/TEXT_P", "@type": "DefinedTerm",
"name": "TEXT_P", "termCode": "TEXT_P",
"inDefinedTermSet": { "@id": "https://w3id.org/atrium/scheme/page-category" } }
Properties of a crate¶
- It is deterministic. Entities are merged by
@id, the descriptor and the root come first, everything else is sorted by@id, and the JSON is written with sorted keys. The same record always produces byte-identical output, so a crate can be diffed and committed. datePublishedis derived, not stamped. It is the newest of the record's block stamps and contributor times, cut to a date — never the export clock.- Granularity survives. Each block keeps its own entity with its own creator, so "who produced the page categories" and "who produced the translation" have separate answers.
- Controlled values become resolvable terms, under the SKOS URIs.
Running the exporter¶
The exporter is vendored into every tool as atrium_rocrate.py and runs as a separate step,
over records that already exist — a tool run writes records, and a crate is made from them
when they are to be published:
python atrium_rocrate.py --document CTX000000003.document.json --out-dir crate/
python atrium_rocrate.py --run 1.document.json 2.document.json --paradata run.json --out-dir crate/
python atrium_rocrate.py --selftest
--document writes one document's crate; --run writes a run crate whose hasPart holds one
sub-crate per document, and additionally conforms to the Process Run Crate profile. The write is
atomic.
A crate describes; it does not replace the record. Per-page detail — which page carries
which category, with what confidence, and the language pair of a translation — stays in the
record, which can itself be shipped inside the crate as one of its files.
rocrate_export.md §7 lists what the export leaves for later work.
Where RO-Crate sits among the standards¶
RO-Crate is one of the standards the project's data management plan names, alongside CIDOC-CRM,
SKOS, PeriodO, Getty AAT, TEI, DataCite and IIIF. The ecosystem deliberately does not apply
heavyweight ontologies — W3C PROV-O, CIDOC-CRM — during raw extraction over a corpus of more than a
million pages: the record stays a plain JSON document, and the crate is the view that a
catalogue reads. rocrate_export.md §3 is the reasoning in full.
Sources¶
This table records provenance: what this page was written from, not a build instruction.
| Source | What was taken from it |
|---|---|
atrium-project/docs/templates/shared/atrium_rocrate.py — run on the worked-example record |
the mapping table and the JSON excerpt |
atrium-project/docs/rocrate_export.md §§3, 4.1, 6, 7 |
the design and the reasoning |