The same way we did it last year - as `display_note` (`SKOS:note`). The DFG does not ask for that specific input, but with all the structured we are spoiled for choice - and whenever someone selects a subject area, broader categories follow unambiguously via `part_of`.
91 lines
3.3 KiB
Python
91 lines
3.3 KiB
Python
from pathlib import Path
|
|
import tomllib
|
|
|
|
from rdflib import Graph, URIRef, Literal, Namespace, BNode
|
|
from rdflib.namespace import DCTERMS, RDF, SKOS
|
|
|
|
|
|
def get_label_and_desc(record: dict):
|
|
"""Get label and description from a record
|
|
|
|
We stored prefLabel.de (always) and prefLabel.en (usually). The
|
|
schema does not support internationalization, so we prefer using
|
|
english label as the prefLabel and put the German one into
|
|
description.
|
|
|
|
"""
|
|
prefLabel = record["prefLabel"]
|
|
try:
|
|
label = prefLabel["en"]
|
|
except KeyError:
|
|
label = prefLabel["de"]
|
|
description = prefLabel["de"]
|
|
return label, description
|
|
|
|
|
|
def add_discipline(g: Graph, uriref: URIRef, label: str, desc: str, identifier: str, note: str | None = None):
|
|
g.add((uriref, RDF.type, trr379cps.Discipline))
|
|
g.add((uriref, SKOS.prefLabel, Literal(label)))
|
|
g.add((uriref, trr379cps.name, Literal(label))) # redundant?
|
|
g.add((uriref, DCTERMS.description, Literal(desc)))
|
|
g.add((uriref, DCTERMS.identifier, create_identifier(g, identifier))) # or dlthings.identifiers?
|
|
if note is not None:
|
|
g.add((uriref, SKOS.note, Literal(f"{note} Please try to select a more specific subject area.")))
|
|
|
|
|
|
def create_identifier(g: Graph, notation: str):
|
|
id = BNode()
|
|
g.add((id, RDF.type, dlthings.Identifier))
|
|
g.add((id, SKOS.notation, Literal(notation)))
|
|
g.add((id, DCTERMS.creator, ror["01kratx56"])) # last year, Literal("https://destatis.de/", datatype=XSD.anyURI)))
|
|
return id
|
|
|
|
|
|
with Path("derived/personal-stellenstatistik.toml").open("rb") as fp:
|
|
data = tomllib.load(fp)
|
|
|
|
|
|
dlthings = Namespace("https://concepts.datalad.org/s/things/v2/")
|
|
trr379cps = Namespace("https://concepts.trr379.de/s/dfg-cp-survey/unreleased/")
|
|
trr379dfgsurvey = Namespace("https://trr379.de/ns/dfg-cp-survey/") # or sns for survey namespace?
|
|
ror = Namespace("https://ror.org/")
|
|
|
|
g = Graph()
|
|
g.bind("dlthings", dlthings)
|
|
g.bind("trr379cps", trr379cps)
|
|
g.bind("trr379dfgsurvey", trr379dfgsurvey)
|
|
g.bind("ror", ror)
|
|
|
|
for group_id, group in data.items():
|
|
|
|
group_label, group_desc = get_label_and_desc(group)
|
|
|
|
group_uri = trr379dfgsurvey[f"discipline/{group_id}"]
|
|
add_discipline(g, group_uri, group_label, group_desc, group_id, note="This is an area of study (subject group).")
|
|
|
|
for field_id, field in group.items():
|
|
if field_id == "prefLabel":
|
|
# this is not a field, this is a label
|
|
# same effect as if not isinstance(area, dict)
|
|
continue
|
|
|
|
field_label, field_desc = get_label_and_desc(field)
|
|
|
|
field_uri = trr379dfgsurvey[f"discipline/{field_id}"]
|
|
add_discipline(g, field_uri, field_label, field_desc, field_id, note="This is a teaching and research field.")
|
|
|
|
g.add((group_uri, trr379cps.parts, field_uri))
|
|
g.add((field_uri, trr379cps.part_of, group_uri))
|
|
|
|
for area_id, area in field.items():
|
|
if area_id == "prefLabel":
|
|
continue
|
|
|
|
area_label, area_desc = get_label_and_desc(area)
|
|
area_uri = trr379dfgsurvey[f"discipline/{area_id}"]
|
|
add_discipline(g, area_uri, area_label, area_desc, area_id)
|
|
|
|
g.add((field_uri, trr379cps.parts, area_uri))
|
|
g.add((area_uri, trr379cps.part_of, field_uri))
|
|
|
|
g.serialize(Path("derived/all_records.ttl"))
|