The tables below are generated from the schema itself at build time.
Subject-scoped identity. Per-occasion identifiers (study_uid, series_uids, dates, age) belong to the timepoint entry, not here.
Open: accepts keys beyond those listed below.
Open: accepts keys beyond those listed below.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/XwK-P/medh5/schemas/medh5-sample-1.0.schema.json",
"title": "MEDH5 1.0 sample document",
"description": "JSON document stored in the scalar string dataset `meta` at a MEDH5 sample root. See docs/spec/medh5-1.0.md §2.4.",
"type": "object",
"required": ["identity", "timepoints"],
"additionalProperties": false,
"properties": {
"identity": { "$ref": "#/$defs/identity" },
"timepoints": {
"type": "array",
"description": "Ordered declaration of the sample's observation occasions. See docs/spec/medh5-1.0.md §3.7.",
"minItems": 1,
"items": { "$ref": "#/$defs/timepoint" }
},
"cohort": { "$ref": "#/$defs/cohort" },
"label_set": { "$ref": "#/$defs/labelSet" },
"provenance": { "$ref": "#/$defs/provenance" },
"quality": {
"type": "object",
"description": "Quality records keyed by the value of an annotation's `quality` attribute.",
"additionalProperties": { "$ref": "#/$defs/qualityRecord" }
},
"splits": { "type": "array", "items": { "$ref": "#/$defs/splitClaim" } },
"acquisition": {
"type": "object",
"description": "Acquisition parameters keyed by image id. Keys SHOULD follow DICOM keyword names.",
"additionalProperties": { "type": "object" }
},
"deidentification": { "$ref": "#/$defs/deidentification" },
"extra": {
"type": "object",
"description": "Free-form writer data. Third-party extensions SHOULD use a reverse-DNS namespace key."
}
},
"$defs": {
"id": { "type": "string", "pattern": "^[A-Za-z0-9_.-]{1,128}$" },
"timestamp": { "type": "string", "format": "date-time" },
"classId": { "type": "integer", "minimum": 1, "maximum": 65534 },
"identity": {
"type": "object",
"required": ["sample_id", "subject_id"],
"additionalProperties": true,
"description": "Subject-scoped identity. Per-occasion identifiers (study_uid, series_uids, dates, age) belong to the timepoint entry, not here.",
"properties": {
"sample_id": { "type": "string", "minLength": 1 },
"subject_id": { "type": "string", "minLength": 1,
"description": "Pseudonymised subject key. A sample never spans subjects, so assigning whole files to splits is subject-safe." },
"sex": { "type": ["string", "null"], "enum": ["F", "M", "O", "unknown", null] },
"laterality": { "type": ["string", "null"], "enum": ["left", "right", "bilateral", null] },
"bodypart": { "type": "string" }
}
},
"timepoint": {
"type": "object",
"required": ["id", "index"],
"additionalProperties": false,
"properties": {
"id": { "$ref": "#/$defs/id",
"description": "Referenced by grid `timepoint` attributes and annotation `timepoints` attributes." },
"index": { "type": "integer", "minimum": 0,
"description": "0-based acquisition order; dense and strictly increasing with time." },
"label": { "type": "string", "examples": ["baseline", "follow_up_3mo", "post_treatment"] },
"date": { "type": "string", "description": "Shifted per deidentification.date_shift_days." },
"days_from_baseline": { "type": "number",
"description": "Interval from index 0. Survives date shifting; prefer this over `date` in models." },
"study_uid": { "type": "string" },
"series_uids": { "type": "object", "additionalProperties": { "type": "string" },
"description": "Image id -> pseudonymised source series identifier." },
"subject_age_years": { "type": "number", "minimum": 0 },
"description": { "type": "string" }
}
},
"cohort": {
"type": "object",
"additionalProperties": true,
"properties": {
"dataset_id": { "type": "string" },
"site_id": { "type": "string" },
"scanner_id": { "type": "string" },
"group_id": { "type": "string", "description": "Split grouping key; defaults to identity.subject_id." },
"acquisition_protocol": { "type": "string" }
}
},
"labelSet": {
"type": "object",
"required": ["id", "version", "form"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "minLength": 1 },
"version": { "type": "string", "minLength": 1 },
"sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
"uri": { "type": "string" },
"form": { "enum": ["inline", "ref"] },
"classes": { "type": "array", "items": { "$ref": "#/$defs/labelClass" } },
"relations": { "type": "array", "items": { "$ref": "#/$defs/relation" } },
"skeletons": { "type": "array", "items": { "$ref": "#/$defs/skeleton" } }
},
"allOf": [
{ "if": { "properties": { "form": { "const": "inline" } } },
"then": { "required": ["classes"] } },
{ "if": { "properties": { "form": { "const": "ref" } } },
"then": { "required": ["uri", "sha256"] } }
]
},
"labelClass": {
"type": "object",
"required": ["id", "key", "name"],
"additionalProperties": false,
"properties": {
"id": { "$ref": "#/$defs/classId" },
"key": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_]*$" },
"name": { "type": "string", "minLength": 1 },
"parents": { "type": "array", "items": { "$ref": "#/$defs/classId" },
"description": "is_a parents. Zero or more: the hierarchy is a DAG." },
"category": { "type": "string" },
"laterality": { "type": ["string", "null"], "enum": ["left", "right", "bilateral", null] },
"color": { "type": "array", "items": { "type": "integer", "minimum": 0, "maximum": 255 },
"minItems": 4, "maxItems": 4 },
"codes": { "type": "array", "items": { "$ref": "#/$defs/ontologyCode" } },
"properties": { "type": "object" }
}
},
"ontologyCode": {
"type": "object",
"required": ["system", "code"],
"additionalProperties": false,
"properties": {
"system": { "type": "string", "examples": ["SNOMED-CT", "RadLex", "FMA", "UBERON", "ICD-10", "LOINC"] },
"code": { "type": "string" },
"name": { "type": "string" }
}
},
"relation": {
"type": "object",
"required": ["subject", "predicate", "object"],
"additionalProperties": false,
"properties": {
"subject": { "$ref": "#/$defs/classId" },
"predicate": { "type": "string", "examples": ["part_of", "adjacent_to", "supplies", "drains"] },
"object": { "$ref": "#/$defs/classId" }
}
},
"skeleton": {
"type": "object",
"required": ["id", "keypoints", "edges"],
"additionalProperties": false,
"properties": {
"id": { "$ref": "#/$defs/id" },
"keypoints": { "type": "array", "items": { "$ref": "#/$defs/classId" } },
"edges": { "type": "array",
"items": { "type": "array", "items": { "$ref": "#/$defs/classId" }, "minItems": 2, "maxItems": 2 } }
}
},
"provenance": {
"type": "object",
"required": ["agents", "activities"],
"additionalProperties": false,
"properties": {
"agents": { "type": "array", "items": { "$ref": "#/$defs/agent" } },
"activities": { "type": "array", "items": { "$ref": "#/$defs/activity" } }
}
},
"agent": {
"type": "object",
"required": ["id", "type", "name"],
"additionalProperties": false,
"properties": {
"id": { "$ref": "#/$defs/id" },
"type": { "enum": ["person", "software", "organization"] },
"name": { "type": "string", "minLength": 1,
"description": "MUST NOT be a direct identifier of a natural person; use a pseudonym." },
"version": { "type": "string" },
"role": { "enum": ["annotator", "reviewer", "arbiter", "converter", "predictor", "curator", "other"] },
"qualification": { "type": "string" },
"organization": { "$ref": "#/$defs/id" }
}
},
"activity": {
"type": "object",
"required": ["id", "type", "agent"],
"additionalProperties": false,
"properties": {
"id": { "$ref": "#/$defs/id" },
"type": { "enum": ["import", "annotate", "review", "predict", "resample", "register",
"derive", "deidentify", "transcode", "other"] },
"agent": { "$ref": "#/$defs/id" },
"started": { "$ref": "#/$defs/timestamp" },
"ended": { "$ref": "#/$defs/timestamp" },
"tool": { "type": "string" },
"inputs": { "type": "array", "items": { "type": "string" },
"description": "HDF5 object paths, or external URIs for out-of-file sources." },
"outputs": { "type": "array", "items": { "type": "string" } },
"params": { "type": "object" }
}
},
"qualityRecord": {
"type": "object",
"required": ["status"],
"additionalProperties": false,
"properties": {
"status": { "enum": ["draft", "submitted", "reviewed", "approved", "rejected", "deprecated"] },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"reviewed_by": { "type": "array", "items": { "$ref": "#/$defs/id" } },
"agreement": { "type": "array", "items": { "$ref": "#/$defs/agreement" } },
"issues": { "type": "array", "items": { "$ref": "#/$defs/issue" } },
"edit_effort_s": { "type": "number", "minimum": 0 }
}
},
"agreement": {
"type": "object",
"required": ["metric", "value", "against"],
"additionalProperties": false,
"properties": {
"metric": { "type": "string", "examples": ["dice", "iou", "hausdorff95", "surface_dice", "kappa", "tre"] },
"value": { "type": "number" },
"against": { "type": "string", "description": "HDF5 path of the annotation compared against." },
"per_class": { "type": "object",
"patternProperties": { "^[0-9]{1,5}$": { "type": "number" } },
"additionalProperties": false }
}
},
"issue": {
"type": "object",
"required": ["code", "severity"],
"additionalProperties": false,
"properties": {
"code": { "type": "string" },
"severity": { "enum": ["info", "warning", "error"] },
"class_ids": { "type": "array", "items": { "$ref": "#/$defs/classId" } },
"note": { "type": "string" }
}
},
"splitClaim": {
"type": "object",
"required": ["set_id", "partition"],
"additionalProperties": false,
"properties": {
"set_id": { "type": "string", "minLength": 1 },
"partition": { "type": "string", "examples": ["train", "val", "test", "holdout"] },
"fold": { "type": "integer", "minimum": 0 },
"assigned_by": { "type": "string" },
"assigned_at": { "$ref": "#/$defs/timestamp" },
"manifest_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$",
"description": "Digest of the authoritative dataset manifest; lets readers detect stale claims." }
}
},
"deidentification": {
"type": "object",
"required": ["method"],
"additionalProperties": false,
"properties": {
"method": { "type": "string" },
"profile": { "type": "string", "examples": ["DICOM PS3.15 E.1 basic", "custom"] },
"date_shift_days": { "type": "integer" },
"id_mapping": { "enum": ["external", "irreversible", "none"] },
"performed_by": { "$ref": "#/$defs/id" },
"date": { "$ref": "#/$defs/timestamp" },
"burned_in_annotation_checked": { "type": "boolean" }
}
}
}
}