From 5aba9f7d4464abff85a2b78d52b11ef62eb4def2 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 21:15:37 +0000 Subject: [PATCH 01/16] V_epsilon: convert observation tier to Brainstorm E (named by property) Replaces the Option-A dimension-named scalar observation classes with Brainstorm E identity-named (property-named) classes; the typed composites become the shared shape library each property class pins as its value type. A is removed outright (not deprecated) per "no one is using A" in early dev. Scalar observations (isa scalar_observation; value pins a typed composite): body_weight_observation (mass), organ_volume_observation (volume), body_length_observation (length), age_observation (duration), core_temperature_observation (temperature), heart_rate_observation / respiration_rate_observation (frequency), blood_pressure_observation (pressure), litter_size_observation / cell_count_observation (count), body_condition_observation / behavioral_score_observation (score), concentration_observation (concentration), membrane_potential_observation (voltage), generic_scalar_observation (escape hatch, kept). Removed: mass_/length_/duration_/temperature_/pressure_/count_/score_/ frequency_/volume_observation. Categorical observations: categorical_observation is now an abstract genus; concrete classes are named by property (full E): developmental_stage_observation (pinned root UBERON:0000105), health_status_observation, behavioral_phenotype_observation, pigmentation_observation, estrous_stage_observation, generic_categorical_observation (escape hatch, free ontology_term). Series/expression families unchanged (already E-compatible, file-backed); no opaque_/standalone_/daq_ leaves, per Standalone_Removal_Decision. Updates index.json registrations, topics.json observation group, and the V_epsilon_SPEC.md observation section. All 96 schema tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- ..._observation.json => age_observation.json} | 4 +- .../behavioral_phenotype_observation.json | 43 + .../draft/behavioral_score_observation.json | 47 + ...n.json => blood_pressure_observation.json} | 4 +- ...n.json => body_condition_observation.json} | 4 +- ...tion.json => body_length_observation.json} | 4 +- .../draft/body_weight_observation.json | 37 + .../draft/categorical_observation.json | 33 +- .../draft/cell_count_observation.json | 43 + .../draft/concentration_observation.json | 2 +- ...json => core_temperature_observation.json} | 4 +- .../developmental_stage_observation.json | 43 + .../draft/estrous_stage_observation.json | 43 + .../generic_categorical_observation.json | 35 + .../draft/health_status_observation.json | 43 + ...ation.json => heart_rate_observation.json} | 6 +- ...tion.json => litter_size_observation.json} | 4 +- .../draft/membrane_potential_observation.json | 37 + ...ion.json => organ_volume_observation.json} | 4 +- .../draft/pigmentation_observation.json | 43 + ...json => respiration_rate_observation.json} | 4 +- schemas/V_epsilon/index.json | 4328 +++++++++-------- schemas/V_epsilon/topics.json | 669 +-- schemas/V_epsilon_SPEC.md | 29 +- 24 files changed, 3015 insertions(+), 2498 deletions(-) rename schemas/V_epsilon/draft/{duration_observation.json => age_observation.json} (84%) create mode 100644 schemas/V_epsilon/draft/behavioral_phenotype_observation.json create mode 100644 schemas/V_epsilon/draft/behavioral_score_observation.json rename schemas/V_epsilon/draft/{pressure_observation.json => blood_pressure_observation.json} (73%) rename schemas/V_epsilon/draft/{score_observation.json => body_condition_observation.json} (86%) rename schemas/V_epsilon/draft/{length_observation.json => body_length_observation.json} (76%) create mode 100644 schemas/V_epsilon/draft/body_weight_observation.json create mode 100644 schemas/V_epsilon/draft/cell_count_observation.json rename schemas/V_epsilon/draft/{temperature_observation.json => core_temperature_observation.json} (77%) create mode 100644 schemas/V_epsilon/draft/developmental_stage_observation.json create mode 100644 schemas/V_epsilon/draft/estrous_stage_observation.json create mode 100644 schemas/V_epsilon/draft/generic_categorical_observation.json create mode 100644 schemas/V_epsilon/draft/health_status_observation.json rename schemas/V_epsilon/draft/{mass_observation.json => heart_rate_observation.json} (79%) rename schemas/V_epsilon/draft/{count_observation.json => litter_size_observation.json} (86%) create mode 100644 schemas/V_epsilon/draft/membrane_potential_observation.json rename schemas/V_epsilon/draft/{volume_observation.json => organ_volume_observation.json} (80%) create mode 100644 schemas/V_epsilon/draft/pigmentation_observation.json rename schemas/V_epsilon/draft/{frequency_observation.json => respiration_rate_observation.json} (85%) diff --git a/schemas/V_epsilon/draft/duration_observation.json b/schemas/V_epsilon/draft/age_observation.json similarity index 84% rename from schemas/V_epsilon/draft/duration_observation.json rename to schemas/V_epsilon/draft/age_observation.json index a391afb..c75c248 100644 --- a/schemas/V_epsilon/draft/duration_observation.json +++ b/schemas/V_epsilon/draft/age_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "duration_observation", + "class_name": "age_observation", "class_version": "1.0.0", "superclasses": [ { @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed duration composite.", + "documentation": "Age of the subject at the moment of measurement; value is a typed duration composite.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/behavioral_phenotype_observation.json b/schemas/V_epsilon/draft/behavioral_phenotype_observation.json new file mode 100644 index 0000000..8496b81 --- /dev/null +++ b/schemas/V_epsilon/draft/behavioral_phenotype_observation.json @@ -0,0 +1,43 @@ +{ + "document_class": { + "class_name": "behavioral_phenotype_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "categorical_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "An observed (labeled) behavioral phenotype or state; value is a bound concept (e.g. NBO) governed by the binding registry keyed on measured_property. Scored behavior goes to behavioral_score_observation; behavioral traces go to a series observation.", + "constraints": { + "binding": { + "keyed_by": "measured_property", + "expansion": "descendants", + "node_kind": "class", + "strength": "preferred", + "source": "ontology" + } + } + } + ] +} diff --git a/schemas/V_epsilon/draft/behavioral_score_observation.json b/schemas/V_epsilon/draft/behavioral_score_observation.json new file mode 100644 index 0000000..df86e5a --- /dev/null +++ b/schemas/V_epsilon/draft/behavioral_score_observation.json @@ -0,0 +1,47 @@ +{ + "document_class": { + "class_name": "behavioral_score_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "scalar_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "score", + "blank_value": { + "value": 0.0, + "scale": { + "node": "", + "name": "" + }, + "scale_min": 0.0, + "scale_max": 0.0, + "approximate": false + }, + "default_value": { + "value": 0.0, + "scale": { + "node": "", + "name": "" + }, + "scale_min": 0.0, + "scale_max": 0.0, + "approximate": false + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A scored behavioral assessment (open-field anxiety, Likert, ...); value is a typed score composite.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/pressure_observation.json b/schemas/V_epsilon/draft/blood_pressure_observation.json similarity index 73% rename from schemas/V_epsilon/draft/pressure_observation.json rename to schemas/V_epsilon/draft/blood_pressure_observation.json index 9545bbd..4082792 100644 --- a/schemas/V_epsilon/draft/pressure_observation.json +++ b/schemas/V_epsilon/draft/blood_pressure_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "pressure_observation", + "class_name": "blood_pressure_observation", "class_version": "1.0.0", "superclasses": [ { @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed pressure composite.", + "documentation": "A blood-pressure or related pressure reading (systolic/diastolic, intraocular, partial pressure); value is a typed pressure composite (canonical mmhg). Which pressure rides measured_property; site rides target_structure.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/score_observation.json b/schemas/V_epsilon/draft/body_condition_observation.json similarity index 86% rename from schemas/V_epsilon/draft/score_observation.json rename to schemas/V_epsilon/draft/body_condition_observation.json index 7756bbb..6fbb015 100644 --- a/schemas/V_epsilon/draft/score_observation.json +++ b/schemas/V_epsilon/draft/body_condition_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "score_observation", + "class_name": "body_condition_observation", "class_version": "1.0.0", "superclasses": [ { @@ -40,7 +40,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed score composite.", + "documentation": "Body condition score; value is a typed score composite (rubric named in value.scale).", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/length_observation.json b/schemas/V_epsilon/draft/body_length_observation.json similarity index 76% rename from schemas/V_epsilon/draft/length_observation.json rename to schemas/V_epsilon/draft/body_length_observation.json index ce3c13f..5c3b446 100644 --- a/schemas/V_epsilon/draft/length_observation.json +++ b/schemas/V_epsilon/draft/body_length_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "length_observation", + "class_name": "body_length_observation", "class_version": "1.0.0", "superclasses": [ { @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed length composite.", + "documentation": "A length reading of the subject (body, tail, tibia, ...); value is a typed length composite. The specific length property rides measured_property; structure rides target_structure.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/body_weight_observation.json b/schemas/V_epsilon/draft/body_weight_observation.json new file mode 100644 index 0000000..94d0e2f --- /dev/null +++ b/schemas/V_epsilon/draft/body_weight_observation.json @@ -0,0 +1,37 @@ +{ + "document_class": { + "class_name": "body_weight_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "scalar_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "mass", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Body weight or other body-mass reading; value is a typed mass composite. The specific mass property (body weight, wet brain mass, tumor mass) rides measured_property; anatomical localization rides target_structure.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/categorical_observation.json b/schemas/V_epsilon/draft/categorical_observation.json index d4bcee7..bef521e 100644 --- a/schemas/V_epsilon/draft/categorical_observation.json +++ b/schemas/V_epsilon/draft/categorical_observation.json @@ -7,37 +7,10 @@ "class_name": "observation" } ], - "maturity_level": "draft" + "maturity_level": "draft", + "abstract": true }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "ontology_term", - "blank_value": { - "node": "", - "name": "" - }, - "default_value": { - "node": "", - "name": "" - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "The observed category/class as an ontology term. Admissible terms governed by the binding registry keyed on measured_property.", - "constraints": { - "binding": { - "keyed_by": "measured_property", - "expansion": "descendants", - "node_kind": "class", - "strength": "preferred", - "source": "ontology" - } - } - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/cell_count_observation.json b/schemas/V_epsilon/draft/cell_count_observation.json new file mode 100644 index 0000000..ccc1a53 --- /dev/null +++ b/schemas/V_epsilon/draft/cell_count_observation.json @@ -0,0 +1,43 @@ +{ + "document_class": { + "class_name": "cell_count_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "scalar_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "count", + "blank_value": { + "value": 0, + "unit": { + "node": "", + "name": "" + }, + "approximate": false + }, + "default_value": { + "value": 0, + "unit": { + "node": "", + "name": "" + }, + "approximate": false + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A cell or particle count in a region; value is a typed count composite. Region rides target_structure.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/concentration_observation.json b/schemas/V_epsilon/draft/concentration_observation.json index 5503fe4..465ab65 100644 --- a/schemas/V_epsilon/draft/concentration_observation.json +++ b/schemas/V_epsilon/draft/concentration_observation.json @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed concentration composite.", + "documentation": "Concentration of an analyte in a sample (blood glucose, serum cortisol, CSF protein, viral titer); value is a typed concentration composite. The analyte rides measured_property.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/temperature_observation.json b/schemas/V_epsilon/draft/core_temperature_observation.json similarity index 77% rename from schemas/V_epsilon/draft/temperature_observation.json rename to schemas/V_epsilon/draft/core_temperature_observation.json index bbfe670..8c3f435 100644 --- a/schemas/V_epsilon/draft/temperature_observation.json +++ b/schemas/V_epsilon/draft/core_temperature_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "temperature_observation", + "class_name": "core_temperature_observation", "class_version": "1.0.0", "superclasses": [ { @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed temperature composite.", + "documentation": "A body or tissue temperature reading; value is a typed temperature composite (canonical celsius). Site (core, brain, ...) rides measured_property/target_structure.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/developmental_stage_observation.json b/schemas/V_epsilon/draft/developmental_stage_observation.json new file mode 100644 index 0000000..9830bb8 --- /dev/null +++ b/schemas/V_epsilon/draft/developmental_stage_observation.json @@ -0,0 +1,43 @@ +{ + "document_class": { + "class_name": "developmental_stage_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "categorical_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Observed developmental / life-cycle stage of the subject; value is a bound concept under UBERON:0000105 (life cycle stage) and its species-specific descendants (FBdv, ZFS, HsapDv, ...).", + "constraints": { + "binding": { + "root": "UBERON:0000105", + "expansion": "self_and_descendants", + "node_kind": "class", + "strength": "preferred", + "source": "ontology" + } + } + } + ] +} diff --git a/schemas/V_epsilon/draft/estrous_stage_observation.json b/schemas/V_epsilon/draft/estrous_stage_observation.json new file mode 100644 index 0000000..10f78ed --- /dev/null +++ b/schemas/V_epsilon/draft/estrous_stage_observation.json @@ -0,0 +1,43 @@ +{ + "document_class": { + "class_name": "estrous_stage_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "categorical_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Observed estrous-cycle stage; value is a bound concept governed by the binding registry keyed on measured_property.", + "constraints": { + "binding": { + "keyed_by": "measured_property", + "expansion": "descendants", + "node_kind": "class", + "strength": "preferred", + "source": "ontology" + } + } + } + ] +} diff --git a/schemas/V_epsilon/draft/generic_categorical_observation.json b/schemas/V_epsilon/draft/generic_categorical_observation.json new file mode 100644 index 0000000..baeab49 --- /dev/null +++ b/schemas/V_epsilon/draft/generic_categorical_observation.json @@ -0,0 +1,35 @@ +{ + "document_class": { + "class_name": "generic_categorical_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "categorical_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Escape hatch for an observed categorical property with no minted class yet; value is a free ontology_term (no binding). Promote to a typed property class when the property stabilizes.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/health_status_observation.json b/schemas/V_epsilon/draft/health_status_observation.json new file mode 100644 index 0000000..d30b686 --- /dev/null +++ b/schemas/V_epsilon/draft/health_status_observation.json @@ -0,0 +1,43 @@ +{ + "document_class": { + "class_name": "health_status_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "categorical_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Observed health / clinical status of the subject; value is a bound concept governed by the binding registry keyed on measured_property.", + "constraints": { + "binding": { + "keyed_by": "measured_property", + "expansion": "descendants", + "node_kind": "class", + "strength": "preferred", + "source": "ontology" + } + } + } + ] +} diff --git a/schemas/V_epsilon/draft/mass_observation.json b/schemas/V_epsilon/draft/heart_rate_observation.json similarity index 79% rename from schemas/V_epsilon/draft/mass_observation.json rename to schemas/V_epsilon/draft/heart_rate_observation.json index 79aef2b..3cb9f2b 100644 --- a/schemas/V_epsilon/draft/mass_observation.json +++ b/schemas/V_epsilon/draft/heart_rate_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "mass_observation", + "class_name": "heart_rate_observation", "class_version": "1.0.0", "superclasses": [ { @@ -14,7 +14,7 @@ "fields": [ { "name": "value", - "type": "mass", + "type": "frequency", "blank_value": { "approximate": false, "source_unit": "", @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed mass composite.", + "documentation": "Heart rate; value is a typed frequency composite (canonical hertz; enter bpm as the source unit).", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/count_observation.json b/schemas/V_epsilon/draft/litter_size_observation.json similarity index 86% rename from schemas/V_epsilon/draft/count_observation.json rename to schemas/V_epsilon/draft/litter_size_observation.json index 2058148..a6618d1 100644 --- a/schemas/V_epsilon/draft/count_observation.json +++ b/schemas/V_epsilon/draft/litter_size_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "count_observation", + "class_name": "litter_size_observation", "class_version": "1.0.0", "superclasses": [ { @@ -36,7 +36,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed count composite.", + "documentation": "Litter size; value is a typed count composite (unit = individuals).", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/membrane_potential_observation.json b/schemas/V_epsilon/draft/membrane_potential_observation.json new file mode 100644 index 0000000..5df28eb --- /dev/null +++ b/schemas/V_epsilon/draft/membrane_potential_observation.json @@ -0,0 +1,37 @@ +{ + "document_class": { + "class_name": "membrane_potential_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "scalar_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "voltage", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A transcribed membrane-potential or other voltage reading; value is a typed voltage composite. DAQ voltage traces stay on element + measurement.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/volume_observation.json b/schemas/V_epsilon/draft/organ_volume_observation.json similarity index 80% rename from schemas/V_epsilon/draft/volume_observation.json rename to schemas/V_epsilon/draft/organ_volume_observation.json index f59e761..b3114d1 100644 --- a/schemas/V_epsilon/draft/volume_observation.json +++ b/schemas/V_epsilon/draft/organ_volume_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "volume_observation", + "class_name": "organ_volume_observation", "class_version": "1.0.0", "superclasses": [ { @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed volume composite.", + "documentation": "A volume reading of the subject or a structure (organ volume, urine or blood-draw volume); value is a typed volume composite.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/pigmentation_observation.json b/schemas/V_epsilon/draft/pigmentation_observation.json new file mode 100644 index 0000000..e44cec5 --- /dev/null +++ b/schemas/V_epsilon/draft/pigmentation_observation.json @@ -0,0 +1,43 @@ +{ + "document_class": { + "class_name": "pigmentation_observation", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "categorical_observation" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Observed coat / pigmentation state; value is a bound concept governed by the binding registry keyed on measured_property.", + "constraints": { + "binding": { + "keyed_by": "measured_property", + "expansion": "descendants", + "node_kind": "class", + "strength": "preferred", + "source": "ontology" + } + } + } + ] +} diff --git a/schemas/V_epsilon/draft/frequency_observation.json b/schemas/V_epsilon/draft/respiration_rate_observation.json similarity index 85% rename from schemas/V_epsilon/draft/frequency_observation.json rename to schemas/V_epsilon/draft/respiration_rate_observation.json index ec858fe..048d2a6 100644 --- a/schemas/V_epsilon/draft/frequency_observation.json +++ b/schemas/V_epsilon/draft/respiration_rate_observation.json @@ -1,6 +1,6 @@ { "document_class": { - "class_name": "frequency_observation", + "class_name": "respiration_rate_observation", "class_version": "1.0.0", "superclasses": [ { @@ -30,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The measured scalar quantity as a typed frequency composite.", + "documentation": "Respiration rate; value is a typed frequency composite.", "constraints": {} } ] diff --git a/schemas/V_epsilon/index.json b/schemas/V_epsilon/index.json index 5a454db..f8e62d8 100644 --- a/schemas/V_epsilon/index.json +++ b/schemas/V_epsilon/index.json @@ -1,2111 +1,2221 @@ { - "set_version": "V_epsilon", - "schema_version_value": "V_epsilon", - "based_on": "V_delta", - "tiers": [ - "stable", - "draft", - "deprecated" - ], - "legacy_schema_version_values": [ - "did_v1", - "V_delta" - ], - "notes": "Source of truth for class_name uniqueness and tier placement. V_epsilon implements the subject_interaction redesign (observation/manipulation/annotation families, time_reference family, dataseries bodies, reference/expression bodies) as draft/ additions, deprecates the treatment family and virus_injection/subject_group, and re-scopes stimulus_approach/stimulus_bath. Resolution-by-class_name only.", - "schemas": [ - { - "class_name": "CURIE_lookups_meta", - "tier": "stable", - "class_version": null, - "maturity_level": null, - "superclasses": [], - "path": "schemas/V_epsilon/stable/CURIE_lookups_meta.json", - "is_meta": true - }, - { - "class_name": "annotation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "subject_interaction" - ], - "path": "schemas/V_epsilon/draft/annotation.json", - "is_meta": false - }, - { - "class_name": "app", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/app.json", - "is_meta": false - }, - { - "class_name": "base", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [], - "path": "schemas/V_epsilon/stable/base.json", - "is_meta": false - }, - { - "class_name": "bath", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "pharmacological_manipulation" - ], - "path": "schemas/V_epsilon/draft/bath.json", - "is_meta": false - }, - { - "class_name": "binaryseries_parameters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/binaryseries_parameters.json", - "is_meta": false - }, - { - "class_name": "binnedspikeratevm", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/binnedspikeratevm.json", - "is_meta": false - }, - { - "class_name": "biological_transfer", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "procedural_manipulation" - ], - "path": "schemas/V_epsilon/draft/biological_transfer.json", - "is_meta": false - }, - { - "class_name": "calculator", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "app" - ], - "path": "schemas/V_epsilon/stable/calculator.json", - "is_meta": false - }, - { - "class_name": "categorical_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "observation" - ], - "path": "schemas/V_epsilon/draft/categorical_observation.json", - "is_meta": false - }, - { - "class_name": "concentration_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/concentration_observation.json", - "is_meta": false - }, - { - "class_name": "contrast_sensitivity_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "calculator" - ], - "path": "schemas/V_epsilon/stable/contrast_sensitivity_calc.json", - "is_meta": false - }, - { - "class_name": "contrast_tuning", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/contrast_tuning.json", - "is_meta": false - }, - { - "class_name": "contrast_tuning_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "contrast_tuning", - "tuning_fit" - ], - "path": "schemas/V_epsilon/stable/contrast_tuning_calc.json", - "is_meta": false - }, - { - "class_name": "control_stimulus_ids", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "app" - ], - "path": "schemas/V_epsilon/stable/control_stimulus_ids.json", - "is_meta": false - }, - { - "class_name": "count_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/count_observation.json", - "is_meta": false - }, - { - "class_name": "daqmetadatareader", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/daqmetadatareader.json", - "is_meta": false - }, - { - "class_name": "daqmetadatareader_epochdata_ingested", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "epochid" - ], - "path": "schemas/V_epsilon/stable/daqmetadatareader_epochdata_ingested.json", - "is_meta": false - }, - { - "class_name": "daqreader", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/daqreader.json", - "is_meta": false - }, - { - "class_name": "daqreader_epochdata_ingested", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/daqreader_epochdata_ingested.json", - "is_meta": false - }, - { - "class_name": "daqreader_mfdaq_epochdata_ingested", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "daqreader_epochdata_ingested", - "epochid" - ], - "path": "schemas/V_epsilon/stable/daqreader_mfdaq_epochdata_ingested.json", - "is_meta": false - }, - { - "class_name": "daqreader_ndr", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "daqreader" - ], - "path": "schemas/V_epsilon/stable/daqreader_ndr.json", - "is_meta": false - }, - { - "class_name": "daqsystem", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/daqsystem.json", - "is_meta": false - }, - { - "class_name": "dataseries_channel_map", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/dataseries_channel_map.json", - "is_meta": false - }, - { - "class_name": "dataseries_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/dataseries_data.json", - "is_meta": false - }, - { - "class_name": "dataseries_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "observation" - ], - "path": "schemas/V_epsilon/draft/dataseries_observation.json", - "is_meta": false - }, - { - "class_name": "dataseries_pyramid", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base", - "epochid" - ], - "path": "schemas/V_epsilon/draft/dataseries_pyramid.json", - "is_meta": false - }, - { - "class_name": "dataset_remote", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/dataset_remote.json", - "is_meta": false - }, - { - "class_name": "dataset_session_info", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/dataset_session_info.json", - "is_meta": false - }, - { - "class_name": "demo_ndi", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/demo_ndi.json", - "is_meta": false - }, - { - "class_name": "demo_ndi_mock", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/demo_ndi_mock.json", - "is_meta": false - }, - { - "class_name": "derivation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "manipulation" - ], - "path": "schemas/V_epsilon/draft/derivation.json", - "is_meta": false - }, - { - "class_name": "did_schema_meta", - "tier": "stable", - "class_version": null, - "maturity_level": null, - "superclasses": [], - "path": "schemas/V_epsilon/stable/did_schema_meta.json", - "is_meta": true - }, - { - "class_name": "directory", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/directory.json", - "is_meta": false - }, - { - "class_name": "distance_metadata", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/distance_metadata.json", - "is_meta": false - }, - { - "class_name": "duration_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/duration_observation.json", - "is_meta": false - }, - { - "class_name": "electrode_offset_voltage", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/electrode_offset_voltage.json", - "is_meta": false - }, - { - "class_name": "element", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/element.json", - "is_meta": false - }, - { - "class_name": "element_epoch", - "tier": "stable", - "class_version": "2.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "epochid" - ], - "path": "schemas/V_epsilon/stable/element_epoch.json", - "is_meta": false - }, - { - "class_name": "environmental_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "manipulation" - ], - "path": "schemas/V_epsilon/draft/environmental_manipulation.json", - "is_meta": false - }, - { - "class_name": "ephys_zarr", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "zarr" - ], - "path": "schemas/V_epsilon/stable/ephys_zarr.json", - "is_meta": false - }, - { - "class_name": "epoch_bounded_reference", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "time_reference", - "epochid" - ], - "path": "schemas/V_epsilon/draft/epoch_bounded_reference.json", - "is_meta": false - }, - { - "class_name": "epoch_relative_reference", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "time_reference", - "epochid" - ], - "path": "schemas/V_epsilon/draft/epoch_relative_reference.json", - "is_meta": false - }, - { - "class_name": "epochclocktimes", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "epochid" - ], - "path": "schemas/V_epsilon/stable/epochclocktimes.json", - "is_meta": false - }, - { - "class_name": "epochfiles_ingested", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/epochfiles_ingested.json", - "is_meta": false - }, - { - "class_name": "epochid", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/epochid.json", - "is_meta": false - }, - { - "class_name": "event_bounded_reference", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "time_reference" - ], - "path": "schemas/V_epsilon/draft/event_bounded_reference.json", - "is_meta": false - }, - { - "class_name": "event_relative_reference", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "time_reference" - ], - "path": "schemas/V_epsilon/draft/event_relative_reference.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_cellranger_h5", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_cellranger_h5.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_counts_table", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_counts_table.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_dia_report", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_dia_report.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_gef", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_gef.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_gem", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_gem.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_h5ad", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_h5ad.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_imzml", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_imzml.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_loom", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_loom.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_maxquant", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_maxquant.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_mtx", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_mtx.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_mzml", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_mzml.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_mztab", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_mztab.json", - "is_meta": false - }, - { - "class_name": "expression_matrix_data_visium", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_matrix_data" - ], - "path": "schemas/V_epsilon/draft/expression_matrix_data_visium.json", - "is_meta": false - }, - { - "class_name": "expression_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "observation" - ], - "path": "schemas/V_epsilon/draft/expression_observation.json", - "is_meta": false - }, - { - "class_name": "filenavigator", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/filenavigator.json", - "is_meta": false - }, - { - "class_name": "filter", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/filter.json", - "is_meta": false - }, - { - "class_name": "fitcurve", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/fitcurve.json", - "is_meta": false - }, - { - "class_name": "frequency_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_manipulation" - ], - "path": "schemas/V_epsilon/draft/frequency_manipulation.json", - "is_meta": false - }, - { - "class_name": "frequency_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/frequency_observation.json", - "is_meta": false - }, - { - "class_name": "generic_file", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/generic_file.json", - "is_meta": false - }, - { - "class_name": "generic_scalar_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_manipulation" - ], - "path": "schemas/V_epsilon/draft/generic_scalar_manipulation.json", - "is_meta": false - }, - { - "class_name": "generic_scalar_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/generic_scalar_observation.json", - "is_meta": false - }, - { - "class_name": "group_assignment", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "annotation" - ], - "path": "schemas/V_epsilon/draft/group_assignment.json", - "is_meta": false - }, - { - "class_name": "hartley_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "hartley_reverse_correlation", - "calculator" - ], - "path": "schemas/V_epsilon/stable/hartley_calc.json", - "is_meta": false - }, - { - "class_name": "hartley_reverse_correlation", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "reverse_correlation" - ], - "path": "schemas/V_epsilon/stable/hartley_reverse_correlation.json", - "is_meta": false - }, - { - "class_name": "image", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/image.json", - "is_meta": false - }, - { - "class_name": "image_collection", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/image_collection.json", - "is_meta": false - }, - { - "class_name": "image_stack", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "image_stack_parameters" - ], - "path": "schemas/V_epsilon/stable/image_stack.json", - "is_meta": false - }, - { - "class_name": "image_stack_parameters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/image_stack_parameters.json", - "is_meta": false - }, - { - "class_name": "image_zarr", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "zarr" - ], - "path": "schemas/V_epsilon/stable/image_zarr.json", - "is_meta": false - }, - { - "class_name": "imageseries_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "dataseries_data" - ], - "path": "schemas/V_epsilon/draft/imageseries_data.json", - "is_meta": false - }, - { - "class_name": "imageseries_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "dataseries_observation" - ], - "path": "schemas/V_epsilon/draft/imageseries_observation.json", - "is_meta": false - }, - { - "class_name": "injection", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "pharmacological_manipulation" - ], - "path": "schemas/V_epsilon/draft/injection.json", - "is_meta": false - }, - { - "class_name": "instrument", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/instrument.json", - "is_meta": false - }, - { - "class_name": "interaction_purpose", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/interaction_purpose.json", - "is_meta": false - }, - { - "class_name": "jrclust_clusters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "app" - ], - "path": "schemas/V_epsilon/stable/jrclust_clusters.json", - "is_meta": false - }, - { - "class_name": "length_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/length_observation.json", - "is_meta": false - }, - { - "class_name": "manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "subject_interaction" - ], - "path": "schemas/V_epsilon/draft/manipulation.json", - "is_meta": false - }, - { - "class_name": "mass_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/mass_observation.json", - "is_meta": false - }, - { - "class_name": "measurement", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "epochid" - ], - "path": "schemas/V_epsilon/stable/measurement.json", - "is_meta": false - }, - { - "class_name": "metadata_editor", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/metadata_editor.json", - "is_meta": false - }, - { - "class_name": "mock", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/mock.json", - "is_meta": false - }, - { - "class_name": "ndi_reserved_keys", - "tier": "stable", - "class_version": null, - "maturity_level": null, - "superclasses": [], - "path": "schemas/V_epsilon/stable/ndi_reserved_keys.json", - "is_meta": true - }, - { - "class_name": "neuron_extracellular", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "app" - ], - "path": "schemas/V_epsilon/stable/neuron_extracellular.json", - "is_meta": false - }, - { - "class_name": "ngrid", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/ngrid.json", - "is_meta": false - }, - { - "class_name": "observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "subject_interaction" - ], - "path": "schemas/V_epsilon/draft/observation.json", - "is_meta": false - }, - { - "class_name": "oneepoch", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "epochid" - ], - "path": "schemas/V_epsilon/stable/oneepoch.json", - "is_meta": false - }, - { - "class_name": "ontology_image", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/ontology_image.json", - "is_meta": false - }, - { - "class_name": "ontology_label", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/ontology_label.json", - "is_meta": false - }, - { - "class_name": "ontology_table_row", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/ontology_table_row.json", - "is_meta": false - }, - { - "class_name": "openminds", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/openminds.json", - "is_meta": false - }, - { - "class_name": "openminds_element", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "openminds" - ], - "path": "schemas/V_epsilon/stable/openminds_element.json", - "is_meta": false - }, - { - "class_name": "openminds_stimulus", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "openminds", - "epochid" - ], - "path": "schemas/V_epsilon/stable/openminds_stimulus.json", - "is_meta": false - }, - { - "class_name": "openminds_subject", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "openminds" - ], - "path": "schemas/V_epsilon/stable/openminds_subject.json", - "is_meta": false - }, - { - "class_name": "oridirtuning_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "orientation_direction_tuning", - "tuning_fit" - ], - "path": "schemas/V_epsilon/stable/oridirtuning_calc.json", - "is_meta": false - }, - { - "class_name": "orientation_direction_tuning", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/orientation_direction_tuning.json", - "is_meta": false - }, - { - "class_name": "pharmacological_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "manipulation" - ], - "path": "schemas/V_epsilon/draft/pharmacological_manipulation.json", - "is_meta": false - }, - { - "class_name": "placement", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "manipulation" - ], - "path": "schemas/V_epsilon/draft/placement.json", - "is_meta": false - }, - { - "class_name": "position_metadata", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/position_metadata.json", - "is_meta": false - }, - { - "class_name": "pressure_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_manipulation" - ], - "path": "schemas/V_epsilon/draft/pressure_manipulation.json", - "is_meta": false - }, - { - "class_name": "pressure_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/pressure_observation.json", - "is_meta": false - }, - { - "class_name": "probe_geometry", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/probe_geometry.json", - "is_meta": false - }, - { - "class_name": "probe_location", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/probe_location.json", - "is_meta": false - }, - { - "class_name": "procedural_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "manipulation" - ], - "path": "schemas/V_epsilon/draft/procedural_manipulation.json", - "is_meta": false - }, - { - "class_name": "projectvar", - "tier": "deprecated", - "class_version": "1.0.0", - "maturity_level": "deprecated", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/deprecated/projectvar.json", - "is_meta": false - }, - { - "class_name": "pyraview", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "epochclocktimes", - "filter", - "base", - "epochid" - ], - "path": "schemas/V_epsilon/stable/pyraview.json", - "is_meta": false - }, - { - "class_name": "reference_annotation_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "reference_data" - ], - "path": "schemas/V_epsilon/draft/reference_annotation_data.json", - "is_meta": false - }, - { - "class_name": "reference_annotation_data_gff3", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "reference_annotation_data" - ], - "path": "schemas/V_epsilon/draft/reference_annotation_data_gff3.json", - "is_meta": false - }, - { - "class_name": "reference_annotation_data_gtf", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "reference_annotation_data" - ], - "path": "schemas/V_epsilon/draft/reference_annotation_data_gtf.json", - "is_meta": false - }, - { - "class_name": "reference_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/reference_data.json", - "is_meta": false - }, - { - "class_name": "reference_sequence_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "reference_data" - ], - "path": "schemas/V_epsilon/draft/reference_sequence_data.json", - "is_meta": false - }, - { - "class_name": "reference_sequence_data_fasta_genome", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "reference_sequence_data" - ], - "path": "schemas/V_epsilon/draft/reference_sequence_data_fasta_genome.json", - "is_meta": false - }, - { - "class_name": "reference_sequence_data_fasta_protein", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "reference_sequence_data" - ], - "path": "schemas/V_epsilon/draft/reference_sequence_data_fasta_protein.json", - "is_meta": false - }, - { - "class_name": "reference_sequence_data_fasta_transcriptome", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "reference_sequence_data" - ], - "path": "schemas/V_epsilon/draft/reference_sequence_data_fasta_transcriptome.json", - "is_meta": false - }, - { - "class_name": "reverse_correlation", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "ngrid" - ], - "path": "schemas/V_epsilon/stable/reverse_correlation.json", - "is_meta": false - }, - { - "class_name": "scalar_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "manipulation" - ], - "path": "schemas/V_epsilon/draft/scalar_manipulation.json", - "is_meta": false - }, - { - "class_name": "scalar_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "observation" - ], - "path": "schemas/V_epsilon/draft/scalar_observation.json", - "is_meta": false - }, - { - "class_name": "score_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/score_observation.json", - "is_meta": false - }, - { - "class_name": "sequence_read_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/sequence_read_data.json", - "is_meta": false - }, - { - "class_name": "sequence_read_data_bam", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "sequence_read_data" - ], - "path": "schemas/V_epsilon/draft/sequence_read_data_bam.json", - "is_meta": false - }, - { - "class_name": "sequence_read_data_cram", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "sequence_read_data" - ], - "path": "schemas/V_epsilon/draft/sequence_read_data_cram.json", - "is_meta": false - }, - { - "class_name": "sequence_read_data_fastq", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "sequence_read_data" - ], - "path": "schemas/V_epsilon/draft/sequence_read_data_fastq.json", - "is_meta": false - }, - { - "class_name": "session", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/session.json", - "is_meta": false - }, - { - "class_name": "session_in_a_dataset", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/session_in_a_dataset.json", - "is_meta": false - }, - { - "class_name": "simple_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "calculator" - ], - "path": "schemas/V_epsilon/stable/simple_calc.json", - "is_meta": false - }, - { - "class_name": "site2channelmap", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/site2channelmap.json", - "is_meta": false - }, - { - "class_name": "sorting_parameters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/sorting_parameters.json", - "is_meta": false - }, - { - "class_name": "spatial_expression_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "expression_observation" - ], - "path": "schemas/V_epsilon/draft/spatial_expression_observation.json", - "is_meta": false - }, - { - "class_name": "spatial_frequency_tuning", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/spatial_frequency_tuning.json", - "is_meta": false - }, - { - "class_name": "spatial_frequency_tuning_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "spatial_frequency_tuning", - "tuning_fit" - ], - "path": "schemas/V_epsilon/stable/spatial_frequency_tuning_calc.json", - "is_meta": false - }, - { - "class_name": "speed_tuning", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/speed_tuning.json", - "is_meta": false - }, - { - "class_name": "speed_tuning_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "speed_tuning", - "tuning_fit" - ], - "path": "schemas/V_epsilon/stable/speed_tuning_calc.json", - "is_meta": false - }, - { - "class_name": "spike_clusters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/spike_clusters.json", - "is_meta": false - }, - { - "class_name": "spike_extraction_parameters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/spike_extraction_parameters.json", - "is_meta": false - }, - { - "class_name": "spike_extraction_parameters_modification", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/spike_extraction_parameters_modification.json", - "is_meta": false - }, - { - "class_name": "spike_interface_sorting_outputs", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/spike_interface_sorting_outputs.json", - "is_meta": false - }, - { - "class_name": "spikewaves", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/spikewaves.json", - "is_meta": false - }, - { - "class_name": "stimulus_approach", - "tier": "draft", - "class_version": "2.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/stimulus_approach.json", - "is_meta": false - }, - { - "class_name": "stimulus_bath", - "tier": "draft", - "class_version": "2.0.0", - "maturity_level": "draft", - "superclasses": [ - "bath" - ], - "path": "schemas/V_epsilon/draft/stimulus_bath.json", - "is_meta": false - }, - { - "class_name": "stimulus_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "manipulation" - ], - "path": "schemas/V_epsilon/draft/stimulus_manipulation.json", - "is_meta": false - }, - { - "class_name": "stimulus_parameter", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/stimulus_parameter.json", - "is_meta": false - }, - { - "class_name": "stimulus_parameter_table", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/stimulus_parameter_table.json", - "is_meta": false - }, - { - "class_name": "stimulus_presentation", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "app", - "epochid" - ], - "path": "schemas/V_epsilon/stable/stimulus_presentation.json", - "is_meta": false - }, - { - "class_name": "stimulus_response", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/stimulus_response.json", - "is_meta": false - }, - { - "class_name": "stimulus_response_scalar", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "stimulus_response" - ], - "path": "schemas/V_epsilon/stable/stimulus_response_scalar.json", - "is_meta": false - }, - { - "class_name": "stimulus_response_scalar_parameters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/stimulus_response_scalar_parameters.json", - "is_meta": false - }, - { - "class_name": "stimulus_response_scalar_parameters_basic", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "stimulus_response_scalar_parameters" - ], - "path": "schemas/V_epsilon/stable/stimulus_response_scalar_parameters_basic.json", - "is_meta": false - }, - { - "class_name": "stimulus_tuningcurve", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/stimulus_tuningcurve.json", - "is_meta": false - }, - { - "class_name": "subject", - "tier": "stable", - "class_version": "2.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/subject.json", - "is_meta": false - }, - { - "class_name": "subject_group", - "tier": "deprecated", - "class_version": "1.0.0", - "maturity_level": "deprecated", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/deprecated/subject_group.json", - "is_meta": false - }, - { - "class_name": "subject_interaction", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/subject_interaction.json", - "is_meta": false - }, - { - "class_name": "syncgraph", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/syncgraph.json", - "is_meta": false - }, - { - "class_name": "syncrule", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/syncrule.json", - "is_meta": false - }, - { - "class_name": "syncrule_mapping", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/syncrule_mapping.json", - "is_meta": false - }, - { - "class_name": "temperature_manipulation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_manipulation" - ], - "path": "schemas/V_epsilon/draft/temperature_manipulation.json", - "is_meta": false - }, - { - "class_name": "temperature_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/temperature_observation.json", - "is_meta": false - }, - { - "class_name": "temporal_frequency_tuning", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/temporal_frequency_tuning.json", - "is_meta": false - }, - { - "class_name": "temporal_frequency_tuning_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "temporal_frequency_tuning", - "tuning_fit" - ], - "path": "schemas/V_epsilon/stable/temporal_frequency_tuning_calc.json", - "is_meta": false - }, - { - "class_name": "time_reference", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/draft/time_reference.json", - "is_meta": false - }, - { - "class_name": "timeseries_data", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "dataseries_data" - ], - "path": "schemas/V_epsilon/draft/timeseries_data.json", - "is_meta": false - }, - { - "class_name": "timeseries_data_binary", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "timeseries_data" - ], - "path": "schemas/V_epsilon/draft/timeseries_data_binary.json", - "is_meta": false - }, - { - "class_name": "timeseries_data_csv", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "timeseries_data" - ], - "path": "schemas/V_epsilon/draft/timeseries_data_csv.json", - "is_meta": false - }, - { - "class_name": "timeseries_data_edf", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "timeseries_data" - ], - "path": "schemas/V_epsilon/draft/timeseries_data_edf.json", - "is_meta": false - }, - { - "class_name": "timeseries_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "dataseries_observation" - ], - "path": "schemas/V_epsilon/draft/timeseries_observation.json", - "is_meta": false - }, - { - "class_name": "treatment", - "tier": "deprecated", - "class_version": "1.0.0", - "maturity_level": "deprecated", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/deprecated/treatment.json", - "is_meta": false - }, - { - "class_name": "treatment_drug", - "tier": "deprecated", - "class_version": "1.0.0", - "maturity_level": "deprecated", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/deprecated/treatment_drug.json", - "is_meta": false - }, - { - "class_name": "treatment_transfer", - "tier": "deprecated", - "class_version": "1.0.0", - "maturity_level": "deprecated", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/deprecated/treatment_transfer.json", - "is_meta": false - }, - { - "class_name": "tuning_fit", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "calculator" - ], - "path": "schemas/V_epsilon/stable/tuning_fit.json", - "is_meta": false - }, - { - "class_name": "tuningcurve_calc", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base", - "calculator", - "stimulus_tuningcurve" - ], - "path": "schemas/V_epsilon/stable/tuningcurve_calc.json", - "is_meta": false - }, - { - "class_name": "utc_reference", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "time_reference" - ], - "path": "schemas/V_epsilon/draft/utc_reference.json", - "is_meta": false - }, - { - "class_name": "valid_interval", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/valid_interval.json", - "is_meta": false - }, - { - "class_name": "virus_injection", - "tier": "deprecated", - "class_version": "1.0.0", - "maturity_level": "deprecated", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/deprecated/virus_injection.json", - "is_meta": false - }, - { - "class_name": "vmneuralresponseresiduals", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/vmneuralresponseresiduals.json", - "is_meta": false - }, - { - "class_name": "vmspikefilteringparameters", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/vmspikefilteringparameters.json", - "is_meta": false - }, - { - "class_name": "vmspikefit", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/vmspikefit.json", - "is_meta": false - }, - { - "class_name": "vmspikesummary", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/vmspikesummary.json", - "is_meta": false - }, - { - "class_name": "volume_observation", - "tier": "draft", - "class_version": "1.0.0", - "maturity_level": "draft", - "superclasses": [ - "scalar_observation" - ], - "path": "schemas/V_epsilon/draft/volume_observation.json", - "is_meta": false - }, - { - "class_name": "zarr", - "tier": "stable", - "class_version": "1.0.0", - "maturity_level": "stable", - "superclasses": [ - "base" - ], - "path": "schemas/V_epsilon/stable/zarr.json", - "is_meta": false - } - ] + "set_version": "V_epsilon", + "schema_version_value": "V_epsilon", + "based_on": "V_delta", + "tiers": [ + "stable", + "draft", + "deprecated" + ], + "legacy_schema_version_values": [ + "did_v1", + "V_delta" + ], + "notes": "Source of truth for class_name uniqueness and tier placement. V_epsilon implements the subject_interaction redesign (observation/manipulation/annotation families, time_reference family, dataseries bodies, reference/expression bodies) as draft/ additions, deprecates the treatment family and virus_injection/subject_group, and re-scopes stimulus_approach/stimulus_bath. Resolution-by-class_name only.", + "schemas": [ + { + "class_name": "CURIE_lookups_meta", + "tier": "stable", + "class_version": null, + "maturity_level": null, + "superclasses": [], + "path": "schemas/V_epsilon/stable/CURIE_lookups_meta.json", + "is_meta": true + }, + { + "class_name": "age_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/age_observation.json", + "is_meta": false + }, + { + "class_name": "annotation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "subject_interaction" + ], + "path": "schemas/V_epsilon/draft/annotation.json", + "is_meta": false + }, + { + "class_name": "app", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/app.json", + "is_meta": false + }, + { + "class_name": "base", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [], + "path": "schemas/V_epsilon/stable/base.json", + "is_meta": false + }, + { + "class_name": "bath", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "pharmacological_manipulation" + ], + "path": "schemas/V_epsilon/draft/bath.json", + "is_meta": false + }, + { + "class_name": "behavioral_phenotype_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "categorical_observation" + ], + "path": "schemas/V_epsilon/draft/behavioral_phenotype_observation.json", + "is_meta": false + }, + { + "class_name": "behavioral_score_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/behavioral_score_observation.json", + "is_meta": false + }, + { + "class_name": "binaryseries_parameters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/binaryseries_parameters.json", + "is_meta": false + }, + { + "class_name": "binnedspikeratevm", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/binnedspikeratevm.json", + "is_meta": false + }, + { + "class_name": "biological_transfer", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "procedural_manipulation" + ], + "path": "schemas/V_epsilon/draft/biological_transfer.json", + "is_meta": false + }, + { + "class_name": "blood_pressure_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/blood_pressure_observation.json", + "is_meta": false + }, + { + "class_name": "body_condition_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/body_condition_observation.json", + "is_meta": false + }, + { + "class_name": "body_length_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/body_length_observation.json", + "is_meta": false + }, + { + "class_name": "body_weight_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/body_weight_observation.json", + "is_meta": false + }, + { + "class_name": "calculator", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "app" + ], + "path": "schemas/V_epsilon/stable/calculator.json", + "is_meta": false + }, + { + "class_name": "categorical_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "observation" + ], + "path": "schemas/V_epsilon/draft/categorical_observation.json", + "is_meta": false + }, + { + "class_name": "cell_count_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/cell_count_observation.json", + "is_meta": false + }, + { + "class_name": "concentration_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/concentration_observation.json", + "is_meta": false + }, + { + "class_name": "contrast_sensitivity_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "calculator" + ], + "path": "schemas/V_epsilon/stable/contrast_sensitivity_calc.json", + "is_meta": false + }, + { + "class_name": "contrast_tuning", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/contrast_tuning.json", + "is_meta": false + }, + { + "class_name": "contrast_tuning_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "contrast_tuning", + "tuning_fit" + ], + "path": "schemas/V_epsilon/stable/contrast_tuning_calc.json", + "is_meta": false + }, + { + "class_name": "control_stimulus_ids", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "app" + ], + "path": "schemas/V_epsilon/stable/control_stimulus_ids.json", + "is_meta": false + }, + { + "class_name": "core_temperature_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/core_temperature_observation.json", + "is_meta": false + }, + { + "class_name": "daqmetadatareader", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/daqmetadatareader.json", + "is_meta": false + }, + { + "class_name": "daqmetadatareader_epochdata_ingested", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "epochid" + ], + "path": "schemas/V_epsilon/stable/daqmetadatareader_epochdata_ingested.json", + "is_meta": false + }, + { + "class_name": "daqreader", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/daqreader.json", + "is_meta": false + }, + { + "class_name": "daqreader_epochdata_ingested", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/daqreader_epochdata_ingested.json", + "is_meta": false + }, + { + "class_name": "daqreader_mfdaq_epochdata_ingested", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "daqreader_epochdata_ingested", + "epochid" + ], + "path": "schemas/V_epsilon/stable/daqreader_mfdaq_epochdata_ingested.json", + "is_meta": false + }, + { + "class_name": "daqreader_ndr", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "daqreader" + ], + "path": "schemas/V_epsilon/stable/daqreader_ndr.json", + "is_meta": false + }, + { + "class_name": "daqsystem", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/daqsystem.json", + "is_meta": false + }, + { + "class_name": "dataseries_channel_map", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/dataseries_channel_map.json", + "is_meta": false + }, + { + "class_name": "dataseries_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/dataseries_data.json", + "is_meta": false + }, + { + "class_name": "dataseries_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "observation" + ], + "path": "schemas/V_epsilon/draft/dataseries_observation.json", + "is_meta": false + }, + { + "class_name": "dataseries_pyramid", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base", + "epochid" + ], + "path": "schemas/V_epsilon/draft/dataseries_pyramid.json", + "is_meta": false + }, + { + "class_name": "dataset_remote", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/dataset_remote.json", + "is_meta": false + }, + { + "class_name": "dataset_session_info", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/dataset_session_info.json", + "is_meta": false + }, + { + "class_name": "demo_ndi", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/demo_ndi.json", + "is_meta": false + }, + { + "class_name": "demo_ndi_mock", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/demo_ndi_mock.json", + "is_meta": false + }, + { + "class_name": "derivation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "manipulation" + ], + "path": "schemas/V_epsilon/draft/derivation.json", + "is_meta": false + }, + { + "class_name": "developmental_stage_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "categorical_observation" + ], + "path": "schemas/V_epsilon/draft/developmental_stage_observation.json", + "is_meta": false + }, + { + "class_name": "did_schema_meta", + "tier": "stable", + "class_version": null, + "maturity_level": null, + "superclasses": [], + "path": "schemas/V_epsilon/stable/did_schema_meta.json", + "is_meta": true + }, + { + "class_name": "directory", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/directory.json", + "is_meta": false + }, + { + "class_name": "distance_metadata", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/distance_metadata.json", + "is_meta": false + }, + { + "class_name": "electrode_offset_voltage", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/electrode_offset_voltage.json", + "is_meta": false + }, + { + "class_name": "element", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/element.json", + "is_meta": false + }, + { + "class_name": "element_epoch", + "tier": "stable", + "class_version": "2.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "epochid" + ], + "path": "schemas/V_epsilon/stable/element_epoch.json", + "is_meta": false + }, + { + "class_name": "environmental_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "manipulation" + ], + "path": "schemas/V_epsilon/draft/environmental_manipulation.json", + "is_meta": false + }, + { + "class_name": "ephys_zarr", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "zarr" + ], + "path": "schemas/V_epsilon/stable/ephys_zarr.json", + "is_meta": false + }, + { + "class_name": "epoch_bounded_reference", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "time_reference", + "epochid" + ], + "path": "schemas/V_epsilon/draft/epoch_bounded_reference.json", + "is_meta": false + }, + { + "class_name": "epoch_relative_reference", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "time_reference", + "epochid" + ], + "path": "schemas/V_epsilon/draft/epoch_relative_reference.json", + "is_meta": false + }, + { + "class_name": "epochclocktimes", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "epochid" + ], + "path": "schemas/V_epsilon/stable/epochclocktimes.json", + "is_meta": false + }, + { + "class_name": "epochfiles_ingested", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/epochfiles_ingested.json", + "is_meta": false + }, + { + "class_name": "epochid", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/epochid.json", + "is_meta": false + }, + { + "class_name": "estrous_stage_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "categorical_observation" + ], + "path": "schemas/V_epsilon/draft/estrous_stage_observation.json", + "is_meta": false + }, + { + "class_name": "event_bounded_reference", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "time_reference" + ], + "path": "schemas/V_epsilon/draft/event_bounded_reference.json", + "is_meta": false + }, + { + "class_name": "event_relative_reference", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "time_reference" + ], + "path": "schemas/V_epsilon/draft/event_relative_reference.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_cellranger_h5", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_cellranger_h5.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_counts_table", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_counts_table.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_dia_report", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_dia_report.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_gef", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_gef.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_gem", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_gem.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_h5ad", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_h5ad.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_imzml", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_imzml.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_loom", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_loom.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_maxquant", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_maxquant.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_mtx", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_mtx.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_mzml", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_mzml.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_mztab", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_mztab.json", + "is_meta": false + }, + { + "class_name": "expression_matrix_data_visium", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_matrix_data" + ], + "path": "schemas/V_epsilon/draft/expression_matrix_data_visium.json", + "is_meta": false + }, + { + "class_name": "expression_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "observation" + ], + "path": "schemas/V_epsilon/draft/expression_observation.json", + "is_meta": false + }, + { + "class_name": "filenavigator", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/filenavigator.json", + "is_meta": false + }, + { + "class_name": "filter", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/filter.json", + "is_meta": false + }, + { + "class_name": "fitcurve", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/fitcurve.json", + "is_meta": false + }, + { + "class_name": "frequency_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_manipulation" + ], + "path": "schemas/V_epsilon/draft/frequency_manipulation.json", + "is_meta": false + }, + { + "class_name": "generic_categorical_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "categorical_observation" + ], + "path": "schemas/V_epsilon/draft/generic_categorical_observation.json", + "is_meta": false + }, + { + "class_name": "generic_file", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/generic_file.json", + "is_meta": false + }, + { + "class_name": "generic_scalar_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_manipulation" + ], + "path": "schemas/V_epsilon/draft/generic_scalar_manipulation.json", + "is_meta": false + }, + { + "class_name": "generic_scalar_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/generic_scalar_observation.json", + "is_meta": false + }, + { + "class_name": "group_assignment", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "annotation" + ], + "path": "schemas/V_epsilon/draft/group_assignment.json", + "is_meta": false + }, + { + "class_name": "hartley_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "hartley_reverse_correlation", + "calculator" + ], + "path": "schemas/V_epsilon/stable/hartley_calc.json", + "is_meta": false + }, + { + "class_name": "hartley_reverse_correlation", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "reverse_correlation" + ], + "path": "schemas/V_epsilon/stable/hartley_reverse_correlation.json", + "is_meta": false + }, + { + "class_name": "health_status_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "categorical_observation" + ], + "path": "schemas/V_epsilon/draft/health_status_observation.json", + "is_meta": false + }, + { + "class_name": "heart_rate_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/heart_rate_observation.json", + "is_meta": false + }, + { + "class_name": "image", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/image.json", + "is_meta": false + }, + { + "class_name": "image_collection", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/image_collection.json", + "is_meta": false + }, + { + "class_name": "image_stack", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "image_stack_parameters" + ], + "path": "schemas/V_epsilon/stable/image_stack.json", + "is_meta": false + }, + { + "class_name": "image_stack_parameters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/image_stack_parameters.json", + "is_meta": false + }, + { + "class_name": "image_zarr", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "zarr" + ], + "path": "schemas/V_epsilon/stable/image_zarr.json", + "is_meta": false + }, + { + "class_name": "imageseries_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "dataseries_data" + ], + "path": "schemas/V_epsilon/draft/imageseries_data.json", + "is_meta": false + }, + { + "class_name": "imageseries_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "dataseries_observation" + ], + "path": "schemas/V_epsilon/draft/imageseries_observation.json", + "is_meta": false + }, + { + "class_name": "injection", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "pharmacological_manipulation" + ], + "path": "schemas/V_epsilon/draft/injection.json", + "is_meta": false + }, + { + "class_name": "instrument", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/instrument.json", + "is_meta": false + }, + { + "class_name": "interaction_purpose", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/interaction_purpose.json", + "is_meta": false + }, + { + "class_name": "jrclust_clusters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "app" + ], + "path": "schemas/V_epsilon/stable/jrclust_clusters.json", + "is_meta": false + }, + { + "class_name": "litter_size_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/litter_size_observation.json", + "is_meta": false + }, + { + "class_name": "manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "subject_interaction" + ], + "path": "schemas/V_epsilon/draft/manipulation.json", + "is_meta": false + }, + { + "class_name": "measurement", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "epochid" + ], + "path": "schemas/V_epsilon/stable/measurement.json", + "is_meta": false + }, + { + "class_name": "membrane_potential_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/membrane_potential_observation.json", + "is_meta": false + }, + { + "class_name": "metadata_editor", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/metadata_editor.json", + "is_meta": false + }, + { + "class_name": "mock", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/mock.json", + "is_meta": false + }, + { + "class_name": "ndi_reserved_keys", + "tier": "stable", + "class_version": null, + "maturity_level": null, + "superclasses": [], + "path": "schemas/V_epsilon/stable/ndi_reserved_keys.json", + "is_meta": true + }, + { + "class_name": "neuron_extracellular", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "app" + ], + "path": "schemas/V_epsilon/stable/neuron_extracellular.json", + "is_meta": false + }, + { + "class_name": "ngrid", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/ngrid.json", + "is_meta": false + }, + { + "class_name": "observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "subject_interaction" + ], + "path": "schemas/V_epsilon/draft/observation.json", + "is_meta": false + }, + { + "class_name": "oneepoch", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "epochid" + ], + "path": "schemas/V_epsilon/stable/oneepoch.json", + "is_meta": false + }, + { + "class_name": "ontology_image", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/ontology_image.json", + "is_meta": false + }, + { + "class_name": "ontology_label", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/ontology_label.json", + "is_meta": false + }, + { + "class_name": "ontology_table_row", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/ontology_table_row.json", + "is_meta": false + }, + { + "class_name": "openminds", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/openminds.json", + "is_meta": false + }, + { + "class_name": "openminds_element", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "openminds" + ], + "path": "schemas/V_epsilon/stable/openminds_element.json", + "is_meta": false + }, + { + "class_name": "openminds_stimulus", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "openminds", + "epochid" + ], + "path": "schemas/V_epsilon/stable/openminds_stimulus.json", + "is_meta": false + }, + { + "class_name": "openminds_subject", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "openminds" + ], + "path": "schemas/V_epsilon/stable/openminds_subject.json", + "is_meta": false + }, + { + "class_name": "organ_volume_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/organ_volume_observation.json", + "is_meta": false + }, + { + "class_name": "oridirtuning_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "orientation_direction_tuning", + "tuning_fit" + ], + "path": "schemas/V_epsilon/stable/oridirtuning_calc.json", + "is_meta": false + }, + { + "class_name": "orientation_direction_tuning", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/orientation_direction_tuning.json", + "is_meta": false + }, + { + "class_name": "pharmacological_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "manipulation" + ], + "path": "schemas/V_epsilon/draft/pharmacological_manipulation.json", + "is_meta": false + }, + { + "class_name": "pigmentation_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "categorical_observation" + ], + "path": "schemas/V_epsilon/draft/pigmentation_observation.json", + "is_meta": false + }, + { + "class_name": "placement", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "manipulation" + ], + "path": "schemas/V_epsilon/draft/placement.json", + "is_meta": false + }, + { + "class_name": "position_metadata", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/position_metadata.json", + "is_meta": false + }, + { + "class_name": "pressure_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_manipulation" + ], + "path": "schemas/V_epsilon/draft/pressure_manipulation.json", + "is_meta": false + }, + { + "class_name": "probe_geometry", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/probe_geometry.json", + "is_meta": false + }, + { + "class_name": "probe_location", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/probe_location.json", + "is_meta": false + }, + { + "class_name": "procedural_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "manipulation" + ], + "path": "schemas/V_epsilon/draft/procedural_manipulation.json", + "is_meta": false + }, + { + "class_name": "projectvar", + "tier": "deprecated", + "class_version": "1.0.0", + "maturity_level": "deprecated", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/deprecated/projectvar.json", + "is_meta": false + }, + { + "class_name": "pyraview", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "epochclocktimes", + "filter", + "base", + "epochid" + ], + "path": "schemas/V_epsilon/stable/pyraview.json", + "is_meta": false + }, + { + "class_name": "reference_annotation_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "reference_data" + ], + "path": "schemas/V_epsilon/draft/reference_annotation_data.json", + "is_meta": false + }, + { + "class_name": "reference_annotation_data_gff3", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "reference_annotation_data" + ], + "path": "schemas/V_epsilon/draft/reference_annotation_data_gff3.json", + "is_meta": false + }, + { + "class_name": "reference_annotation_data_gtf", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "reference_annotation_data" + ], + "path": "schemas/V_epsilon/draft/reference_annotation_data_gtf.json", + "is_meta": false + }, + { + "class_name": "reference_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/reference_data.json", + "is_meta": false + }, + { + "class_name": "reference_sequence_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "reference_data" + ], + "path": "schemas/V_epsilon/draft/reference_sequence_data.json", + "is_meta": false + }, + { + "class_name": "reference_sequence_data_fasta_genome", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "reference_sequence_data" + ], + "path": "schemas/V_epsilon/draft/reference_sequence_data_fasta_genome.json", + "is_meta": false + }, + { + "class_name": "reference_sequence_data_fasta_protein", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "reference_sequence_data" + ], + "path": "schemas/V_epsilon/draft/reference_sequence_data_fasta_protein.json", + "is_meta": false + }, + { + "class_name": "reference_sequence_data_fasta_transcriptome", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "reference_sequence_data" + ], + "path": "schemas/V_epsilon/draft/reference_sequence_data_fasta_transcriptome.json", + "is_meta": false + }, + { + "class_name": "respiration_rate_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_observation" + ], + "path": "schemas/V_epsilon/draft/respiration_rate_observation.json", + "is_meta": false + }, + { + "class_name": "reverse_correlation", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "ngrid" + ], + "path": "schemas/V_epsilon/stable/reverse_correlation.json", + "is_meta": false + }, + { + "class_name": "scalar_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "manipulation" + ], + "path": "schemas/V_epsilon/draft/scalar_manipulation.json", + "is_meta": false + }, + { + "class_name": "scalar_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "observation" + ], + "path": "schemas/V_epsilon/draft/scalar_observation.json", + "is_meta": false + }, + { + "class_name": "sequence_read_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/sequence_read_data.json", + "is_meta": false + }, + { + "class_name": "sequence_read_data_bam", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "sequence_read_data" + ], + "path": "schemas/V_epsilon/draft/sequence_read_data_bam.json", + "is_meta": false + }, + { + "class_name": "sequence_read_data_cram", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "sequence_read_data" + ], + "path": "schemas/V_epsilon/draft/sequence_read_data_cram.json", + "is_meta": false + }, + { + "class_name": "sequence_read_data_fastq", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "sequence_read_data" + ], + "path": "schemas/V_epsilon/draft/sequence_read_data_fastq.json", + "is_meta": false + }, + { + "class_name": "session", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/session.json", + "is_meta": false + }, + { + "class_name": "session_in_a_dataset", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/session_in_a_dataset.json", + "is_meta": false + }, + { + "class_name": "simple_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "calculator" + ], + "path": "schemas/V_epsilon/stable/simple_calc.json", + "is_meta": false + }, + { + "class_name": "site2channelmap", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/site2channelmap.json", + "is_meta": false + }, + { + "class_name": "sorting_parameters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/sorting_parameters.json", + "is_meta": false + }, + { + "class_name": "spatial_expression_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "expression_observation" + ], + "path": "schemas/V_epsilon/draft/spatial_expression_observation.json", + "is_meta": false + }, + { + "class_name": "spatial_frequency_tuning", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/spatial_frequency_tuning.json", + "is_meta": false + }, + { + "class_name": "spatial_frequency_tuning_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "spatial_frequency_tuning", + "tuning_fit" + ], + "path": "schemas/V_epsilon/stable/spatial_frequency_tuning_calc.json", + "is_meta": false + }, + { + "class_name": "speed_tuning", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/speed_tuning.json", + "is_meta": false + }, + { + "class_name": "speed_tuning_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "speed_tuning", + "tuning_fit" + ], + "path": "schemas/V_epsilon/stable/speed_tuning_calc.json", + "is_meta": false + }, + { + "class_name": "spike_clusters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/spike_clusters.json", + "is_meta": false + }, + { + "class_name": "spike_extraction_parameters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/spike_extraction_parameters.json", + "is_meta": false + }, + { + "class_name": "spike_extraction_parameters_modification", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/spike_extraction_parameters_modification.json", + "is_meta": false + }, + { + "class_name": "spike_interface_sorting_outputs", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/spike_interface_sorting_outputs.json", + "is_meta": false + }, + { + "class_name": "spikewaves", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/spikewaves.json", + "is_meta": false + }, + { + "class_name": "stimulus_approach", + "tier": "draft", + "class_version": "2.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/stimulus_approach.json", + "is_meta": false + }, + { + "class_name": "stimulus_bath", + "tier": "draft", + "class_version": "2.0.0", + "maturity_level": "draft", + "superclasses": [ + "bath" + ], + "path": "schemas/V_epsilon/draft/stimulus_bath.json", + "is_meta": false + }, + { + "class_name": "stimulus_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "manipulation" + ], + "path": "schemas/V_epsilon/draft/stimulus_manipulation.json", + "is_meta": false + }, + { + "class_name": "stimulus_parameter", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/stimulus_parameter.json", + "is_meta": false + }, + { + "class_name": "stimulus_parameter_table", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/stimulus_parameter_table.json", + "is_meta": false + }, + { + "class_name": "stimulus_presentation", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "app", + "epochid" + ], + "path": "schemas/V_epsilon/stable/stimulus_presentation.json", + "is_meta": false + }, + { + "class_name": "stimulus_response", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/stimulus_response.json", + "is_meta": false + }, + { + "class_name": "stimulus_response_scalar", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "stimulus_response" + ], + "path": "schemas/V_epsilon/stable/stimulus_response_scalar.json", + "is_meta": false + }, + { + "class_name": "stimulus_response_scalar_parameters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/stimulus_response_scalar_parameters.json", + "is_meta": false + }, + { + "class_name": "stimulus_response_scalar_parameters_basic", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "stimulus_response_scalar_parameters" + ], + "path": "schemas/V_epsilon/stable/stimulus_response_scalar_parameters_basic.json", + "is_meta": false + }, + { + "class_name": "stimulus_tuningcurve", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/stimulus_tuningcurve.json", + "is_meta": false + }, + { + "class_name": "subject", + "tier": "stable", + "class_version": "2.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/subject.json", + "is_meta": false + }, + { + "class_name": "subject_group", + "tier": "deprecated", + "class_version": "1.0.0", + "maturity_level": "deprecated", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/deprecated/subject_group.json", + "is_meta": false + }, + { + "class_name": "subject_interaction", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/subject_interaction.json", + "is_meta": false + }, + { + "class_name": "syncgraph", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/syncgraph.json", + "is_meta": false + }, + { + "class_name": "syncrule", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/syncrule.json", + "is_meta": false + }, + { + "class_name": "syncrule_mapping", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/syncrule_mapping.json", + "is_meta": false + }, + { + "class_name": "temperature_manipulation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "scalar_manipulation" + ], + "path": "schemas/V_epsilon/draft/temperature_manipulation.json", + "is_meta": false + }, + { + "class_name": "temporal_frequency_tuning", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/temporal_frequency_tuning.json", + "is_meta": false + }, + { + "class_name": "temporal_frequency_tuning_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "temporal_frequency_tuning", + "tuning_fit" + ], + "path": "schemas/V_epsilon/stable/temporal_frequency_tuning_calc.json", + "is_meta": false + }, + { + "class_name": "time_reference", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/time_reference.json", + "is_meta": false + }, + { + "class_name": "timeseries_data", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "dataseries_data" + ], + "path": "schemas/V_epsilon/draft/timeseries_data.json", + "is_meta": false + }, + { + "class_name": "timeseries_data_binary", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "timeseries_data" + ], + "path": "schemas/V_epsilon/draft/timeseries_data_binary.json", + "is_meta": false + }, + { + "class_name": "timeseries_data_csv", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "timeseries_data" + ], + "path": "schemas/V_epsilon/draft/timeseries_data_csv.json", + "is_meta": false + }, + { + "class_name": "timeseries_data_edf", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "timeseries_data" + ], + "path": "schemas/V_epsilon/draft/timeseries_data_edf.json", + "is_meta": false + }, + { + "class_name": "timeseries_observation", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "dataseries_observation" + ], + "path": "schemas/V_epsilon/draft/timeseries_observation.json", + "is_meta": false + }, + { + "class_name": "treatment", + "tier": "deprecated", + "class_version": "1.0.0", + "maturity_level": "deprecated", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/deprecated/treatment.json", + "is_meta": false + }, + { + "class_name": "treatment_drug", + "tier": "deprecated", + "class_version": "1.0.0", + "maturity_level": "deprecated", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/deprecated/treatment_drug.json", + "is_meta": false + }, + { + "class_name": "treatment_transfer", + "tier": "deprecated", + "class_version": "1.0.0", + "maturity_level": "deprecated", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/deprecated/treatment_transfer.json", + "is_meta": false + }, + { + "class_name": "tuning_fit", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "calculator" + ], + "path": "schemas/V_epsilon/stable/tuning_fit.json", + "is_meta": false + }, + { + "class_name": "tuningcurve_calc", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base", + "calculator", + "stimulus_tuningcurve" + ], + "path": "schemas/V_epsilon/stable/tuningcurve_calc.json", + "is_meta": false + }, + { + "class_name": "utc_reference", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "time_reference" + ], + "path": "schemas/V_epsilon/draft/utc_reference.json", + "is_meta": false + }, + { + "class_name": "valid_interval", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/valid_interval.json", + "is_meta": false + }, + { + "class_name": "virus_injection", + "tier": "deprecated", + "class_version": "1.0.0", + "maturity_level": "deprecated", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/deprecated/virus_injection.json", + "is_meta": false + }, + { + "class_name": "vmneuralresponseresiduals", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/vmneuralresponseresiduals.json", + "is_meta": false + }, + { + "class_name": "vmspikefilteringparameters", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/vmspikefilteringparameters.json", + "is_meta": false + }, + { + "class_name": "vmspikefit", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/vmspikefit.json", + "is_meta": false + }, + { + "class_name": "vmspikesummary", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/vmspikesummary.json", + "is_meta": false + }, + { + "class_name": "zarr", + "tier": "stable", + "class_version": "1.0.0", + "maturity_level": "stable", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/stable/zarr.json", + "is_meta": false + } + ] } diff --git a/schemas/V_epsilon/topics.json b/schemas/V_epsilon/topics.json index f460ca2..35cf130 100644 --- a/schemas/V_epsilon/topics.json +++ b/schemas/V_epsilon/topics.json @@ -1,336 +1,347 @@ { - "set_version": "V_epsilon", - "notes": "Topic tree for human navigation in the viewer. Independent of the class/superclass hierarchy and of any schema semantics; intended only to group related schemas by subject area, mirroring the directory layout used by the original NDI-matlab document_data tree. Editing this file does not affect schema validation or document classes. Classes not listed below appear under 'Uncategorized' in the viewer. The top-level 'classes' array holds classes that should appear as bare leaves at the root (no folder); 'topics' holds folder categories. Entries at each level are alphabetized, except that 'base' is pinned as the first top-level entry and 'meta' is pinned as the second.", - "classes": [ - "base" - ], - "topics": [ - { - "name": "meta", - "description": "Meta-schemas and reserved-keyword registries that describe the schema framework itself.", - "classes": [ - "CURIE_lookups_meta", - "did_schema_meta", - "ndi_reserved_keys" - ] - }, - { - "name": "annotations", - "description": "Annotation families: curatorial classifications such as group membership.", - "classes": [ - "group_assignment", - "interaction_purpose" - ] - }, - { - "name": "apps", - "description": "Application-specific documents and demos.", - "classes": [ - "app", - "demo_ndi", - "demo_ndi_mock", - "mock", - "pyraview" - ], - "children": [ + "set_version": "V_epsilon", + "notes": "Topic tree for human navigation in the viewer. Independent of the class/superclass hierarchy and of any schema semantics; intended only to group related schemas by subject area, mirroring the directory layout used by the original NDI-matlab document_data tree. Editing this file does not affect schema validation or document classes. Classes not listed below appear under 'Uncategorized' in the viewer. The top-level 'classes' array holds classes that should appear as bare leaves at the root (no folder); 'topics' holds folder categories. Entries at each level are alphabetized, except that 'base' is pinned as the first top-level entry and 'meta' is pinned as the second.", + "classes": [ + "base" + ], + "topics": [ { - "name": "markgarbage", - "description": "Valid-interval annotations from the markgarbage app.", - "classes": [ - "valid_interval" - ] + "name": "meta", + "description": "Meta-schemas and reserved-keyword registries that describe the schema framework itself.", + "classes": [ + "CURIE_lookups_meta", + "did_schema_meta", + "ndi_reserved_keys" + ] }, { - "name": "vhlab_voltage2firingrate", - "description": "Vm-to-firing-rate fitting and residuals (vhlab voltage2firingrate app).", - "classes": [ - "vmneuralresponseresiduals", - "vmspikefilteringparameters", - "vmspikefit", - "vmspikesummary" - ] - } - ] - }, - { - "name": "calculators", - "description": "Derived-quantity calculator documents (_calc). Most pair with a stimulus-response schema in stimulus/.", - "classes": [ - "calculator", - "contrast_sensitivity_calc", - "contrast_tuning_calc", - "hartley_calc", - "oridirtuning_calc", - "simple_calc", - "spatial_frequency_tuning_calc", - "speed_tuning_calc", - "temporal_frequency_tuning_calc", - "tuning_fit", - "tuningcurve_calc" - ] - }, - { - "name": "daq", - "description": "Data acquisition systems, readers, file navigation, sync, and epoch bookkeeping.", - "classes": [ - "daqmetadatareader", - "daqmetadatareader_epochdata_ingested", - "daqreader", - "daqreader_epochdata_ingested", - "daqreader_mfdaq_epochdata_ingested", - "daqreader_ndr", - "daqsystem", - "epochclocktimes", - "epochfiles_ingested", - "epochid", - "filenavigator", - "oneepoch", - "syncgraph", - "syncrule", - "syncrule_mapping" - ] - }, - { - "name": "data", - "description": "Generic data containers: time series, grids, images, fits, measurements, and generic file/directory wrappers.", - "classes": [ - "binaryseries_parameters", - "binnedspikeratevm", - "directory", - "distance_metadata", - "ephys_zarr", - "filter", - "fitcurve", - "generic_file", - "image", - "image_collection", - "image_stack", - "image_stack_parameters", - "image_zarr", - "measurement", - "ngrid", - "ontology_table_row", - "position_metadata", - "zarr" - ] - }, - { - "name": "dataseries_bodies", - "description": "Body-of-record documents carrying dataseries and expression/reference payloads.", - "classes": [ - "dataseries_data", - "timeseries_data", - "imageseries_data", - "timeseries_data_csv", - "timeseries_data_binary", - "timeseries_data_edf", - "dataseries_channel_map", - "dataseries_pyramid", - "instrument", - "expression_matrix_data", - "expression_matrix_data_h5ad", - "expression_matrix_data_mtx", - "expression_matrix_data_cellranger_h5", - "expression_matrix_data_loom", - "expression_matrix_data_counts_table", - "expression_matrix_data_gef", - "expression_matrix_data_gem", - "expression_matrix_data_visium", - "expression_matrix_data_mzml", - "expression_matrix_data_mztab", - "expression_matrix_data_maxquant", - "expression_matrix_data_dia_report", - "expression_matrix_data_imzml", - "reference_data", - "reference_sequence_data", - "reference_sequence_data_fasta_genome", - "reference_sequence_data_fasta_transcriptome", - "reference_sequence_data_fasta_protein", - "reference_annotation_data", - "reference_annotation_data_gtf", - "reference_annotation_data_gff3", - "sequence_read_data", - "sequence_read_data_bam", - "sequence_read_data_cram", - "sequence_read_data_fastq" - ] - }, - { - "name": "deprecated", - "description": "Classes deprecated in V_epsilon, retained for migration of legacy instances.", - "classes": [ - "projectvar", - "subject_group", - "treatment", - "treatment_drug", - "treatment_transfer", - "virus_injection" - ] - }, - { - "name": "element", - "description": "Logical recorded elements (channels, neurons) and their epoch data.", - "classes": [ - "element", - "element_epoch", - "neuron_extracellular" - ] - }, - { - "name": "manipulations", - "description": "Manipulation families: scalar, procedural, pharmacological, environmental, stimulus, placement, and derivation events.", - "classes": [ - "scalar_manipulation", - "temperature_manipulation", - "pressure_manipulation", - "frequency_manipulation", - "generic_scalar_manipulation", - "procedural_manipulation", - "biological_transfer", - "environmental_manipulation", - "pharmacological_manipulation", - "injection", - "bath", - "stimulus_manipulation", - "placement", - "derivation" - ] - }, - { - "name": "metadata", - "description": "External-ontology bindings (openMINDS, ontology lookups) and metadata editing.", - "classes": [ - "metadata_editor", - "ontology_image", - "ontology_label", - "openminds", - "openminds_element", - "openminds_stimulus", - "openminds_subject" - ] - }, - { - "name": "observations", - "description": "Observation families: scalar, categorical, dataseries, and expression measurements of subjects.", - "classes": [ - "scalar_observation", - "mass_observation", - "length_observation", - "duration_observation", - "temperature_observation", - "pressure_observation", - "count_observation", - "score_observation", - "frequency_observation", - "volume_observation", - "concentration_observation", - "generic_scalar_observation", - "categorical_observation", - "dataseries_observation", - "timeseries_observation", - "imageseries_observation", - "expression_observation", - "spatial_expression_observation" - ] - }, - { - "name": "probe", - "description": "Probe geometry, electrode mapping, and physical placement.", - "classes": [ - "electrode_offset_voltage", - "probe_geometry", - "probe_location", - "site2channelmap" - ] - }, - { - "name": "session", - "description": "Sessions, datasets, and project-scope variables.", - "classes": [ - "dataset_remote", - "dataset_session_info", - "projectvar", - "session", - "session_in_a_dataset" - ] - }, - { - "name": "sorting", - "description": "Spike extraction, sorting, clusters, and waveforms.", - "classes": [ - "jrclust_clusters", - "sorting_parameters", - "spike_clusters", - "spike_extraction_parameters", - "spike_extraction_parameters_modification", - "spike_interface_sorting_outputs", - "spikewaves" - ] - }, - { - "name": "stimulus", - "description": "Stimulus descriptions, presentations, and stimulus-locked responses.", - "classes": [ - "control_stimulus_ids", - "reverse_correlation", - "stimulus_approach", - "stimulus_bath", - "stimulus_parameter", - "stimulus_parameter_table", - "stimulus_presentation", - "stimulus_response", - "stimulus_response_scalar", - "stimulus_response_scalar_parameters", - "stimulus_response_scalar_parameters_basic", - "stimulus_tuningcurve" - ], - "children": [ + "name": "annotations", + "description": "Annotation families: curatorial classifications such as group membership.", + "classes": [ + "group_assignment", + "interaction_purpose" + ] + }, + { + "name": "apps", + "description": "Application-specific documents and demos.", + "classes": [ + "app", + "demo_ndi", + "demo_ndi_mock", + "mock", + "pyraview" + ], + "children": [ + { + "name": "markgarbage", + "description": "Valid-interval annotations from the markgarbage app.", + "classes": [ + "valid_interval" + ] + }, + { + "name": "vhlab_voltage2firingrate", + "description": "Vm-to-firing-rate fitting and residuals (vhlab voltage2firingrate app).", + "classes": [ + "vmneuralresponseresiduals", + "vmspikefilteringparameters", + "vmspikefit", + "vmspikesummary" + ] + } + ] + }, + { + "name": "calculators", + "description": "Derived-quantity calculator documents (_calc). Most pair with a stimulus-response schema in stimulus/.", + "classes": [ + "calculator", + "contrast_sensitivity_calc", + "contrast_tuning_calc", + "hartley_calc", + "oridirtuning_calc", + "simple_calc", + "spatial_frequency_tuning_calc", + "speed_tuning_calc", + "temporal_frequency_tuning_calc", + "tuning_fit", + "tuningcurve_calc" + ] + }, + { + "name": "daq", + "description": "Data acquisition systems, readers, file navigation, sync, and epoch bookkeeping.", + "classes": [ + "daqmetadatareader", + "daqmetadatareader_epochdata_ingested", + "daqreader", + "daqreader_epochdata_ingested", + "daqreader_mfdaq_epochdata_ingested", + "daqreader_ndr", + "daqsystem", + "epochclocktimes", + "epochfiles_ingested", + "epochid", + "filenavigator", + "oneepoch", + "syncgraph", + "syncrule", + "syncrule_mapping" + ] + }, + { + "name": "data", + "description": "Generic data containers: time series, grids, images, fits, measurements, and generic file/directory wrappers.", + "classes": [ + "binaryseries_parameters", + "binnedspikeratevm", + "directory", + "distance_metadata", + "ephys_zarr", + "filter", + "fitcurve", + "generic_file", + "image", + "image_collection", + "image_stack", + "image_stack_parameters", + "image_zarr", + "measurement", + "ngrid", + "ontology_table_row", + "position_metadata", + "zarr" + ] + }, + { + "name": "dataseries_bodies", + "description": "Body-of-record documents carrying dataseries and expression/reference payloads.", + "classes": [ + "dataseries_data", + "timeseries_data", + "imageseries_data", + "timeseries_data_csv", + "timeseries_data_binary", + "timeseries_data_edf", + "dataseries_channel_map", + "dataseries_pyramid", + "instrument", + "expression_matrix_data", + "expression_matrix_data_h5ad", + "expression_matrix_data_mtx", + "expression_matrix_data_cellranger_h5", + "expression_matrix_data_loom", + "expression_matrix_data_counts_table", + "expression_matrix_data_gef", + "expression_matrix_data_gem", + "expression_matrix_data_visium", + "expression_matrix_data_mzml", + "expression_matrix_data_mztab", + "expression_matrix_data_maxquant", + "expression_matrix_data_dia_report", + "expression_matrix_data_imzml", + "reference_data", + "reference_sequence_data", + "reference_sequence_data_fasta_genome", + "reference_sequence_data_fasta_transcriptome", + "reference_sequence_data_fasta_protein", + "reference_annotation_data", + "reference_annotation_data_gtf", + "reference_annotation_data_gff3", + "sequence_read_data", + "sequence_read_data_bam", + "sequence_read_data_cram", + "sequence_read_data_fastq" + ] + }, + { + "name": "deprecated", + "description": "Classes deprecated in V_epsilon, retained for migration of legacy instances.", + "classes": [ + "projectvar", + "subject_group", + "treatment", + "treatment_drug", + "treatment_transfer", + "virus_injection" + ] + }, + { + "name": "element", + "description": "Logical recorded elements (channels, neurons) and their epoch data.", + "classes": [ + "element", + "element_epoch", + "neuron_extracellular" + ] + }, + { + "name": "manipulations", + "description": "Manipulation families: scalar, procedural, pharmacological, environmental, stimulus, placement, and derivation events.", + "classes": [ + "scalar_manipulation", + "temperature_manipulation", + "pressure_manipulation", + "frequency_manipulation", + "generic_scalar_manipulation", + "procedural_manipulation", + "biological_transfer", + "environmental_manipulation", + "pharmacological_manipulation", + "injection", + "bath", + "stimulus_manipulation", + "placement", + "derivation" + ] + }, + { + "name": "metadata", + "description": "External-ontology bindings (openMINDS, ontology lookups) and metadata editing.", + "classes": [ + "metadata_editor", + "ontology_image", + "ontology_label", + "openminds", + "openminds_element", + "openminds_stimulus", + "openminds_subject" + ] + }, + { + "name": "observations", + "description": "Observation families (Brainstorm E): scalar observations named by property, categorical observations named by property, dataseries/image/expression measurements of subjects.", + "classes": [ + "observation", + "scalar_observation", + "body_weight_observation", + "body_length_observation", + "age_observation", + "core_temperature_observation", + "heart_rate_observation", + "respiration_rate_observation", + "blood_pressure_observation", + "litter_size_observation", + "cell_count_observation", + "body_condition_observation", + "behavioral_score_observation", + "concentration_observation", + "organ_volume_observation", + "membrane_potential_observation", + "generic_scalar_observation", + "categorical_observation", + "developmental_stage_observation", + "health_status_observation", + "behavioral_phenotype_observation", + "pigmentation_observation", + "estrous_stage_observation", + "generic_categorical_observation", + "dataseries_observation", + "timeseries_observation", + "imageseries_observation", + "expression_observation", + "spatial_expression_observation" + ] + }, + { + "name": "probe", + "description": "Probe geometry, electrode mapping, and physical placement.", + "classes": [ + "electrode_offset_voltage", + "probe_geometry", + "probe_location", + "site2channelmap" + ] + }, + { + "name": "session", + "description": "Sessions, datasets, and project-scope variables.", + "classes": [ + "dataset_remote", + "dataset_session_info", + "projectvar", + "session", + "session_in_a_dataset" + ] + }, + { + "name": "sorting", + "description": "Spike extraction, sorting, clusters, and waveforms.", + "classes": [ + "jrclust_clusters", + "sorting_parameters", + "spike_clusters", + "spike_extraction_parameters", + "spike_extraction_parameters_modification", + "spike_interface_sorting_outputs", + "spikewaves" + ] + }, + { + "name": "stimulus", + "description": "Stimulus descriptions, presentations, and stimulus-locked responses.", + "classes": [ + "control_stimulus_ids", + "reverse_correlation", + "stimulus_approach", + "stimulus_bath", + "stimulus_parameter", + "stimulus_parameter_table", + "stimulus_presentation", + "stimulus_response", + "stimulus_response_scalar", + "stimulus_response_scalar_parameters", + "stimulus_response_scalar_parameters_basic", + "stimulus_tuningcurve" + ], + "children": [ + { + "name": "visual", + "description": "Visual-stimulus tuning curves and reverse correlation.", + "classes": [ + "contrast_tuning", + "hartley_reverse_correlation", + "orientation_direction_tuning", + "spatial_frequency_tuning", + "speed_tuning", + "temporal_frequency_tuning" + ] + } + ] + }, + { + "name": "subject", + "description": "Subjects, subject groups, treatments, and interventions.", + "classes": [ + "subject", + "subject_group", + "treatment", + "treatment_drug", + "virus_injection" + ] + }, + { + "name": "subject_interaction", + "description": "The unified subject_interaction spine and its observation/manipulation/annotation tiers.", + "classes": [ + "subject_interaction", + "observation", + "manipulation", + "annotation" + ] + }, { - "name": "visual", - "description": "Visual-stimulus tuning curves and reverse correlation.", - "classes": [ - "contrast_tuning", - "hartley_reverse_correlation", - "orientation_direction_tuning", - "spatial_frequency_tuning", - "speed_tuning", - "temporal_frequency_tuning" - ] + "name": "time_reference", + "description": "Time reference documents that locate interactions in time.", + "classes": [ + "time_reference", + "utc_reference", + "event_relative_reference", + "epoch_relative_reference", + "epoch_bounded_reference", + "event_bounded_reference" + ] } - ] - }, - { - "name": "subject", - "description": "Subjects, subject groups, treatments, and interventions.", - "classes": [ - "subject", - "subject_group", - "treatment", - "treatment_drug", - "virus_injection" - ] - }, - { - "name": "subject_interaction", - "description": "The unified subject_interaction spine and its observation/manipulation/annotation tiers.", - "classes": [ - "subject_interaction", - "observation", - "manipulation", - "annotation" - ] - }, - { - "name": "time_reference", - "description": "Time reference documents that locate interactions in time.", - "classes": [ - "time_reference", - "utc_reference", - "event_relative_reference", - "epoch_relative_reference", - "epoch_bounded_reference", - "event_bounded_reference" - ] - } - ] + ] } diff --git a/schemas/V_epsilon_SPEC.md b/schemas/V_epsilon_SPEC.md index c774198..d4552f6 100644 --- a/schemas/V_epsilon_SPEC.md +++ b/schemas/V_epsilon_SPEC.md @@ -97,16 +97,25 @@ two epoch reference classes. ### 3. Observation families (new, `draft/`) -- `scalar_observation` (abstract, ← `observation`) with one typed-composite - concrete subclass per quantity: `mass_observation`, `length_observation`, - `duration_observation`, `temperature_observation`, `pressure_observation`, - `count_observation`, `score_observation`, `frequency_observation`, - `volume_observation`, `concentration_observation`, plus the escape hatch - `generic_scalar_observation` (untyped `{source_unit, source_value, - approximate}`). -- `categorical_observation` (concrete, ← `observation`): one generic class - whose `value` is an `ontology_term`, admissible set governed by the - binding registry keyed on `measured_property`. +- `scalar_observation` (abstract genus, ← `observation`) — shape is now only + an `isa` umbrella; the concrete classes under it are named by the **property + observed** (Brainstorm E), each pinning the typed composite its `value` + requires: `body_weight_observation`/`organ_volume_observation` (mass/volume), + `body_length_observation` (length), `age_observation` (duration), + `core_temperature_observation` (temperature), `heart_rate_observation`/ + `respiration_rate_observation` (frequency), `blood_pressure_observation` + (pressure), `litter_size_observation`/`cell_count_observation` (count), + `body_condition_observation`/`behavioral_score_observation` (score), + `concentration_observation` (concentration), `membrane_potential_observation` + (voltage), plus the escape hatch `generic_scalar_observation` (untyped + `{source_unit, source_value, approximate}`). +- `categorical_observation` (abstract genus, ← `observation`): concrete classes + named by the **property observed**, each with an `ontology_term` `value` + governed by the binding registry — `developmental_stage_observation` (pinned + root `UBERON:0000105`), `health_status_observation`, + `behavioral_phenotype_observation`, `pigmentation_observation`, + `estrous_stage_observation`, plus the escape hatch + `generic_categorical_observation` (free `ontology_term`, no binding). - `dataseries_observation` (abstract genus, ← `observation`) carrying the `axes[]` + `channels[]` header, with two **concrete** sub-genera: `timeseries_observation` (ordering-only axes → traces) and From 1a29164e8098d51e0612b4b283d23ae8aea31fc6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 20:49:50 +0000 Subject: [PATCH 02/16] V_epsilon: add Brainstorm E shape library as superclass mixins Promotes the typed value-composites to named abstract shape classes that own the `value` field, and rewires both tiers to inherit them as a second superclass (resolving E parent open issue #7): scalar_mass, scalar_length, scalar_duration, scalar_volume, scalar_temperature, scalar_pressure, scalar_frequency, scalar_voltage, scalar_current, scalar_concentration, scalar_count, scalar_score, generic_scalar, categorical_concept. Each scalar observation/manipulation now reads e.g. body_weight_observation isa scalar_observation, scalar_mass temperature_manipulation isa scalar_manipulation, scalar_temperature so the same shape class is shared by the read (observation) and write (manipulation) of that shape, `value` is defined once, and isa-by-shape sweeps both tiers. Categorical property classes inherit categorical_concept (developmental_stage and generic override the value binding). Uses the existing mixin pattern (cf. epochid in epoch_relative_reference); no meta-schema change. Updates index.json, topics.json (new shape_library group), and V_epsilon_SPEC.md. All 96 schema tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- schemas/V_epsilon/draft/age_observation.json | 27 +-- .../behavioral_phenotype_observation.json | 33 +-- .../draft/behavioral_score_observation.json | 37 +-- .../draft/blood_pressure_observation.json | 27 +-- .../draft/body_condition_observation.json | 37 +-- .../draft/body_length_observation.json | 27 +-- .../draft/body_weight_observation.json | 27 +-- .../V_epsilon/draft/categorical_concept.json | 44 ++++ .../draft/cell_count_observation.json | 33 +-- .../draft/concentration_observation.json | 27 +-- .../draft/core_temperature_observation.json | 27 +-- .../developmental_stage_observation.json | 5 +- .../draft/estrous_stage_observation.json | 33 +-- .../draft/frequency_manipulation.json | 27 +-- .../generic_categorical_observation.json | 5 +- schemas/V_epsilon/draft/generic_scalar.json | 71 ++++++ .../draft/generic_scalar_manipulation.json | 60 +---- .../draft/generic_scalar_observation.json | 60 +---- .../draft/health_status_observation.json | 33 +-- .../draft/heart_rate_observation.json | 27 +-- .../draft/litter_size_observation.json | 33 +-- .../draft/membrane_potential_observation.json | 27 +-- .../draft/organ_volume_observation.json | 27 +-- .../draft/pigmentation_observation.json | 33 +-- .../draft/pressure_manipulation.json | 27 +-- .../draft/respiration_rate_observation.json | 27 +-- .../V_epsilon/draft/scalar_concentration.json | 38 +++ schemas/V_epsilon/draft/scalar_count.json | 44 ++++ schemas/V_epsilon/draft/scalar_current.json | 38 +++ schemas/V_epsilon/draft/scalar_duration.json | 38 +++ schemas/V_epsilon/draft/scalar_frequency.json | 38 +++ schemas/V_epsilon/draft/scalar_length.json | 38 +++ schemas/V_epsilon/draft/scalar_mass.json | 38 +++ schemas/V_epsilon/draft/scalar_pressure.json | 38 +++ schemas/V_epsilon/draft/scalar_score.json | 48 ++++ .../V_epsilon/draft/scalar_temperature.json | 38 +++ schemas/V_epsilon/draft/scalar_voltage.json | 38 +++ schemas/V_epsilon/draft/scalar_volume.json | 38 +++ .../draft/temperature_manipulation.json | 27 +-- schemas/V_epsilon/index.json | 229 ++++++++++++++++-- schemas/V_epsilon/topics.json | 20 ++ schemas/V_epsilon_SPEC.md | 25 +- 42 files changed, 930 insertions(+), 684 deletions(-) create mode 100644 schemas/V_epsilon/draft/categorical_concept.json create mode 100644 schemas/V_epsilon/draft/generic_scalar.json create mode 100644 schemas/V_epsilon/draft/scalar_concentration.json create mode 100644 schemas/V_epsilon/draft/scalar_count.json create mode 100644 schemas/V_epsilon/draft/scalar_current.json create mode 100644 schemas/V_epsilon/draft/scalar_duration.json create mode 100644 schemas/V_epsilon/draft/scalar_frequency.json create mode 100644 schemas/V_epsilon/draft/scalar_length.json create mode 100644 schemas/V_epsilon/draft/scalar_mass.json create mode 100644 schemas/V_epsilon/draft/scalar_pressure.json create mode 100644 schemas/V_epsilon/draft/scalar_score.json create mode 100644 schemas/V_epsilon/draft/scalar_temperature.json create mode 100644 schemas/V_epsilon/draft/scalar_voltage.json create mode 100644 schemas/V_epsilon/draft/scalar_volume.json diff --git a/schemas/V_epsilon/draft/age_observation.json b/schemas/V_epsilon/draft/age_observation.json index c75c248..ef30fa1 100644 --- a/schemas/V_epsilon/draft/age_observation.json +++ b/schemas/V_epsilon/draft/age_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_duration" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "duration", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Age of the subject at the moment of measurement; value is a typed duration composite.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/behavioral_phenotype_observation.json b/schemas/V_epsilon/draft/behavioral_phenotype_observation.json index 8496b81..f11bc65 100644 --- a/schemas/V_epsilon/draft/behavioral_phenotype_observation.json +++ b/schemas/V_epsilon/draft/behavioral_phenotype_observation.json @@ -5,39 +5,14 @@ "superclasses": [ { "class_name": "categorical_observation" + }, + { + "class_name": "categorical_concept" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "ontology_term", - "blank_value": { - "node": "", - "name": "" - }, - "default_value": { - "node": "", - "name": "" - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "An observed (labeled) behavioral phenotype or state; value is a bound concept (e.g. NBO) governed by the binding registry keyed on measured_property. Scored behavior goes to behavioral_score_observation; behavioral traces go to a series observation.", - "constraints": { - "binding": { - "keyed_by": "measured_property", - "expansion": "descendants", - "node_kind": "class", - "strength": "preferred", - "source": "ontology" - } - } - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/behavioral_score_observation.json b/schemas/V_epsilon/draft/behavioral_score_observation.json index df86e5a..5e4fead 100644 --- a/schemas/V_epsilon/draft/behavioral_score_observation.json +++ b/schemas/V_epsilon/draft/behavioral_score_observation.json @@ -5,43 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_score" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "score", - "blank_value": { - "value": 0.0, - "scale": { - "node": "", - "name": "" - }, - "scale_min": 0.0, - "scale_max": 0.0, - "approximate": false - }, - "default_value": { - "value": 0.0, - "scale": { - "node": "", - "name": "" - }, - "scale_min": 0.0, - "scale_max": 0.0, - "approximate": false - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "A scored behavioral assessment (open-field anxiety, Likert, ...); value is a typed score composite.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/blood_pressure_observation.json b/schemas/V_epsilon/draft/blood_pressure_observation.json index 4082792..4a3ff02 100644 --- a/schemas/V_epsilon/draft/blood_pressure_observation.json +++ b/schemas/V_epsilon/draft/blood_pressure_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_pressure" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "pressure", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "A blood-pressure or related pressure reading (systolic/diastolic, intraocular, partial pressure); value is a typed pressure composite (canonical mmhg). Which pressure rides measured_property; site rides target_structure.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/body_condition_observation.json b/schemas/V_epsilon/draft/body_condition_observation.json index 6fbb015..238edd2 100644 --- a/schemas/V_epsilon/draft/body_condition_observation.json +++ b/schemas/V_epsilon/draft/body_condition_observation.json @@ -5,43 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_score" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "score", - "blank_value": { - "value": 0.0, - "scale": { - "node": "", - "name": "" - }, - "scale_min": 0.0, - "scale_max": 0.0, - "approximate": false - }, - "default_value": { - "value": 0.0, - "scale": { - "node": "", - "name": "" - }, - "scale_min": 0.0, - "scale_max": 0.0, - "approximate": false - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Body condition score; value is a typed score composite (rubric named in value.scale).", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/body_length_observation.json b/schemas/V_epsilon/draft/body_length_observation.json index 5c3b446..17c3a27 100644 --- a/schemas/V_epsilon/draft/body_length_observation.json +++ b/schemas/V_epsilon/draft/body_length_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_length" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "length", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "A length reading of the subject (body, tail, tibia, ...); value is a typed length composite. The specific length property rides measured_property; structure rides target_structure.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/body_weight_observation.json b/schemas/V_epsilon/draft/body_weight_observation.json index 94d0e2f..c5a3107 100644 --- a/schemas/V_epsilon/draft/body_weight_observation.json +++ b/schemas/V_epsilon/draft/body_weight_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_mass" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "mass", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Body weight or other body-mass reading; value is a typed mass composite. The specific mass property (body weight, wet brain mass, tumor mass) rides measured_property; anatomical localization rides target_structure.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/categorical_concept.json b/schemas/V_epsilon/draft/categorical_concept.json new file mode 100644 index 0000000..a48e68e --- /dev/null +++ b/schemas/V_epsilon/draft/categorical_concept.json @@ -0,0 +1,44 @@ +{ + "document_class": { + "class_name": "categorical_concept", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A bound concept value (shape-library mixin); admissible terms governed by the binding registry keyed on measured_property.", + "constraints": { + "binding": { + "keyed_by": "measured_property", + "expansion": "descendants", + "node_kind": "class", + "strength": "preferred", + "source": "ontology" + } + } + } + ] +} diff --git a/schemas/V_epsilon/draft/cell_count_observation.json b/schemas/V_epsilon/draft/cell_count_observation.json index ccc1a53..b4eaee9 100644 --- a/schemas/V_epsilon/draft/cell_count_observation.json +++ b/schemas/V_epsilon/draft/cell_count_observation.json @@ -5,39 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_count" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "count", - "blank_value": { - "value": 0, - "unit": { - "node": "", - "name": "" - }, - "approximate": false - }, - "default_value": { - "value": 0, - "unit": { - "node": "", - "name": "" - }, - "approximate": false - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "A cell or particle count in a region; value is a typed count composite. Region rides target_structure.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/concentration_observation.json b/schemas/V_epsilon/draft/concentration_observation.json index 465ab65..59f8783 100644 --- a/schemas/V_epsilon/draft/concentration_observation.json +++ b/schemas/V_epsilon/draft/concentration_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_concentration" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "concentration", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Concentration of an analyte in a sample (blood glucose, serum cortisol, CSF protein, viral titer); value is a typed concentration composite. The analyte rides measured_property.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/core_temperature_observation.json b/schemas/V_epsilon/draft/core_temperature_observation.json index 8c3f435..5c510ae 100644 --- a/schemas/V_epsilon/draft/core_temperature_observation.json +++ b/schemas/V_epsilon/draft/core_temperature_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_temperature" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "temperature", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "A body or tissue temperature reading; value is a typed temperature composite (canonical celsius). Site (core, brain, ...) rides measured_property/target_structure.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/developmental_stage_observation.json b/schemas/V_epsilon/draft/developmental_stage_observation.json index 9830bb8..a837f6d 100644 --- a/schemas/V_epsilon/draft/developmental_stage_observation.json +++ b/schemas/V_epsilon/draft/developmental_stage_observation.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "categorical_observation" + }, + { + "class_name": "categorical_concept" } ], "maturity_level": "draft" @@ -28,7 +31,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "Observed developmental / life-cycle stage of the subject; value is a bound concept under UBERON:0000105 (life cycle stage) and its species-specific descendants (FBdv, ZFS, HsapDv, ...).", + "documentation": "Observed developmental / life-cycle stage; value is a bound concept under UBERON:0000105 (life cycle stage) and its species-specific descendants (FBdv, ZFS, HsapDv, ...).", "constraints": { "binding": { "root": "UBERON:0000105", diff --git a/schemas/V_epsilon/draft/estrous_stage_observation.json b/schemas/V_epsilon/draft/estrous_stage_observation.json index 10f78ed..1ef8fcf 100644 --- a/schemas/V_epsilon/draft/estrous_stage_observation.json +++ b/schemas/V_epsilon/draft/estrous_stage_observation.json @@ -5,39 +5,14 @@ "superclasses": [ { "class_name": "categorical_observation" + }, + { + "class_name": "categorical_concept" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "ontology_term", - "blank_value": { - "node": "", - "name": "" - }, - "default_value": { - "node": "", - "name": "" - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Observed estrous-cycle stage; value is a bound concept governed by the binding registry keyed on measured_property.", - "constraints": { - "binding": { - "keyed_by": "measured_property", - "expansion": "descendants", - "node_kind": "class", - "strength": "preferred", - "source": "ontology" - } - } - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/frequency_manipulation.json b/schemas/V_epsilon/draft/frequency_manipulation.json index 9b93266..ff8ff82 100644 --- a/schemas/V_epsilon/draft/frequency_manipulation.json +++ b/schemas/V_epsilon/draft/frequency_manipulation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_manipulation" + }, + { + "class_name": "scalar_frequency" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "frequency", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "The imposed frequency magnitude.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/generic_categorical_observation.json b/schemas/V_epsilon/draft/generic_categorical_observation.json index baeab49..7443d78 100644 --- a/schemas/V_epsilon/draft/generic_categorical_observation.json +++ b/schemas/V_epsilon/draft/generic_categorical_observation.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "categorical_observation" + }, + { + "class_name": "categorical_concept" } ], "maturity_level": "draft" @@ -28,7 +31,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "Escape hatch for an observed categorical property with no minted class yet; value is a free ontology_term (no binding). Promote to a typed property class when the property stabilizes.", + "documentation": "Escape hatch for an observed categorical property with no minted class yet; value is a free ontology_term (no binding).", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/generic_scalar.json b/schemas/V_epsilon/draft/generic_scalar.json new file mode 100644 index 0000000..4947a30 --- /dev/null +++ b/schemas/V_epsilon/draft/generic_scalar.json @@ -0,0 +1,71 @@ +{ + "document_class": { + "class_name": "generic_scalar", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "structure", + "blank_value": {}, + "default_value": {}, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Escape-hatch scalar value (shape-library mixin): source_unit/source_value only, no canonical.", + "constraints": {}, + "fields": [ + { + "name": "source_unit", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Source unit as recorded.", + "constraints": {} + }, + { + "name": "source_value", + "type": "double", + "blank_value": 0.0, + "default_value": 0.0, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Source value as recorded.", + "constraints": {} + }, + { + "name": "approximate", + "type": "boolean", + "blank_value": false, + "default_value": false, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "True if the value is a rough estimate.", + "constraints": {} + } + ] + } + ] +} diff --git a/schemas/V_epsilon/draft/generic_scalar_manipulation.json b/schemas/V_epsilon/draft/generic_scalar_manipulation.json index 8b149f8..c317ed7 100644 --- a/schemas/V_epsilon/draft/generic_scalar_manipulation.json +++ b/schemas/V_epsilon/draft/generic_scalar_manipulation.json @@ -5,66 +5,14 @@ "superclasses": [ { "class_name": "scalar_manipulation" + }, + { + "class_name": "generic_scalar" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "structure", - "blank_value": {}, - "default_value": {}, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Escape-hatch imposed scalar when no typed composite exists yet.", - "constraints": {}, - "fields": [ - { - "name": "source_unit", - "type": "char", - "blank_value": "", - "default_value": "", - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Source unit as recorded.", - "constraints": {} - }, - { - "name": "source_value", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Source value as recorded.", - "constraints": {} - }, - { - "name": "approximate", - "type": "boolean", - "blank_value": false, - "default_value": false, - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "True if the value is a rough estimate.", - "constraints": {} - } - ] - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/generic_scalar_observation.json b/schemas/V_epsilon/draft/generic_scalar_observation.json index e5baca6..19aecc9 100644 --- a/schemas/V_epsilon/draft/generic_scalar_observation.json +++ b/schemas/V_epsilon/draft/generic_scalar_observation.json @@ -5,66 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "generic_scalar" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "structure", - "blank_value": {}, - "default_value": {}, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Escape-hatch scalar value when no typed composite exists yet (source_unit/source_value only).", - "constraints": {}, - "fields": [ - { - "name": "source_unit", - "type": "char", - "blank_value": "", - "default_value": "", - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Source unit as recorded.", - "constraints": {} - }, - { - "name": "source_value", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Source value as recorded.", - "constraints": {} - }, - { - "name": "approximate", - "type": "boolean", - "blank_value": false, - "default_value": false, - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "True if the value is a rough estimate.", - "constraints": {} - } - ] - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/health_status_observation.json b/schemas/V_epsilon/draft/health_status_observation.json index d30b686..4650bdc 100644 --- a/schemas/V_epsilon/draft/health_status_observation.json +++ b/schemas/V_epsilon/draft/health_status_observation.json @@ -5,39 +5,14 @@ "superclasses": [ { "class_name": "categorical_observation" + }, + { + "class_name": "categorical_concept" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "ontology_term", - "blank_value": { - "node": "", - "name": "" - }, - "default_value": { - "node": "", - "name": "" - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Observed health / clinical status of the subject; value is a bound concept governed by the binding registry keyed on measured_property.", - "constraints": { - "binding": { - "keyed_by": "measured_property", - "expansion": "descendants", - "node_kind": "class", - "strength": "preferred", - "source": "ontology" - } - } - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/heart_rate_observation.json b/schemas/V_epsilon/draft/heart_rate_observation.json index 3cb9f2b..62c5254 100644 --- a/schemas/V_epsilon/draft/heart_rate_observation.json +++ b/schemas/V_epsilon/draft/heart_rate_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_frequency" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "frequency", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Heart rate; value is a typed frequency composite (canonical hertz; enter bpm as the source unit).", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/litter_size_observation.json b/schemas/V_epsilon/draft/litter_size_observation.json index a6618d1..11bf62b 100644 --- a/schemas/V_epsilon/draft/litter_size_observation.json +++ b/schemas/V_epsilon/draft/litter_size_observation.json @@ -5,39 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_count" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "count", - "blank_value": { - "value": 0, - "unit": { - "node": "", - "name": "" - }, - "approximate": false - }, - "default_value": { - "value": 0, - "unit": { - "node": "", - "name": "" - }, - "approximate": false - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Litter size; value is a typed count composite (unit = individuals).", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/membrane_potential_observation.json b/schemas/V_epsilon/draft/membrane_potential_observation.json index 5df28eb..8478212 100644 --- a/schemas/V_epsilon/draft/membrane_potential_observation.json +++ b/schemas/V_epsilon/draft/membrane_potential_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_voltage" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "voltage", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "A transcribed membrane-potential or other voltage reading; value is a typed voltage composite. DAQ voltage traces stay on element + measurement.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/organ_volume_observation.json b/schemas/V_epsilon/draft/organ_volume_observation.json index b3114d1..72ded82 100644 --- a/schemas/V_epsilon/draft/organ_volume_observation.json +++ b/schemas/V_epsilon/draft/organ_volume_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_volume" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "volume", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "A volume reading of the subject or a structure (organ volume, urine or blood-draw volume); value is a typed volume composite.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/pigmentation_observation.json b/schemas/V_epsilon/draft/pigmentation_observation.json index e44cec5..6aae7ca 100644 --- a/schemas/V_epsilon/draft/pigmentation_observation.json +++ b/schemas/V_epsilon/draft/pigmentation_observation.json @@ -5,39 +5,14 @@ "superclasses": [ { "class_name": "categorical_observation" + }, + { + "class_name": "categorical_concept" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "ontology_term", - "blank_value": { - "node": "", - "name": "" - }, - "default_value": { - "node": "", - "name": "" - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Observed coat / pigmentation state; value is a bound concept governed by the binding registry keyed on measured_property.", - "constraints": { - "binding": { - "keyed_by": "measured_property", - "expansion": "descendants", - "node_kind": "class", - "strength": "preferred", - "source": "ontology" - } - } - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/pressure_manipulation.json b/schemas/V_epsilon/draft/pressure_manipulation.json index bb1c5a0..1d5640f 100644 --- a/schemas/V_epsilon/draft/pressure_manipulation.json +++ b/schemas/V_epsilon/draft/pressure_manipulation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_manipulation" + }, + { + "class_name": "scalar_pressure" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "pressure", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "The imposed pressure magnitude.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/respiration_rate_observation.json b/schemas/V_epsilon/draft/respiration_rate_observation.json index 048d2a6..51749a5 100644 --- a/schemas/V_epsilon/draft/respiration_rate_observation.json +++ b/schemas/V_epsilon/draft/respiration_rate_observation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_observation" + }, + { + "class_name": "scalar_frequency" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "frequency", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Respiration rate; value is a typed frequency composite.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/scalar_concentration.json b/schemas/V_epsilon/draft/scalar_concentration.json new file mode 100644 index 0000000..fd99b03 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_concentration.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_concentration", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "concentration", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed concentration value (shape-library mixin). Identity classes that read or impose a concentration inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_count.json b/schemas/V_epsilon/draft/scalar_count.json new file mode 100644 index 0000000..b976c94 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_count.json @@ -0,0 +1,44 @@ +{ + "document_class": { + "class_name": "scalar_count", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "count", + "blank_value": { + "value": 0, + "unit": { + "node": "", + "name": "" + }, + "approximate": false + }, + "default_value": { + "value": 0, + "unit": { + "node": "", + "name": "" + }, + "approximate": false + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed count value (shape-library mixin); value.unit names what is counted.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_current.json b/schemas/V_epsilon/draft/scalar_current.json new file mode 100644 index 0000000..35e3976 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_current.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_current", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "current", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed current value (shape-library mixin). Identity classes that read or impose a current inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_duration.json b/schemas/V_epsilon/draft/scalar_duration.json new file mode 100644 index 0000000..4933133 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_duration.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_duration", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "duration", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed duration value (shape-library mixin). Identity classes that read or impose a duration inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_frequency.json b/schemas/V_epsilon/draft/scalar_frequency.json new file mode 100644 index 0000000..b249f35 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_frequency.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_frequency", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "frequency", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed frequency value (shape-library mixin). Identity classes that read or impose a frequency inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_length.json b/schemas/V_epsilon/draft/scalar_length.json new file mode 100644 index 0000000..87b77b9 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_length.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_length", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "length", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed length value (shape-library mixin). Identity classes that read or impose a length inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_mass.json b/schemas/V_epsilon/draft/scalar_mass.json new file mode 100644 index 0000000..9c6ebad --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_mass.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_mass", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "mass", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed mass value (shape-library mixin). Identity classes that read or impose a mass inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_pressure.json b/schemas/V_epsilon/draft/scalar_pressure.json new file mode 100644 index 0000000..2d5acf2 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_pressure.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_pressure", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "pressure", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed pressure value (shape-library mixin). Identity classes that read or impose a pressure inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_score.json b/schemas/V_epsilon/draft/scalar_score.json new file mode 100644 index 0000000..4165f35 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_score.json @@ -0,0 +1,48 @@ +{ + "document_class": { + "class_name": "scalar_score", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "score", + "blank_value": { + "value": 0.0, + "scale": { + "node": "", + "name": "" + }, + "scale_min": 0.0, + "scale_max": 0.0, + "approximate": false + }, + "default_value": { + "value": 0.0, + "scale": { + "node": "", + "name": "" + }, + "scale_min": 0.0, + "scale_max": 0.0, + "approximate": false + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed score value (shape-library mixin); value.scale names the rubric.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_temperature.json b/schemas/V_epsilon/draft/scalar_temperature.json new file mode 100644 index 0000000..8cd966c --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_temperature.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_temperature", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "temperature", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed temperature value (shape-library mixin). Identity classes that read or impose a temperature inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_voltage.json b/schemas/V_epsilon/draft/scalar_voltage.json new file mode 100644 index 0000000..3f2b635 --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_voltage.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_voltage", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "voltage", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed voltage value (shape-library mixin). Identity classes that read or impose a voltage inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/scalar_volume.json b/schemas/V_epsilon/draft/scalar_volume.json new file mode 100644 index 0000000..2d5bb0a --- /dev/null +++ b/schemas/V_epsilon/draft/scalar_volume.json @@ -0,0 +1,38 @@ +{ + "document_class": { + "class_name": "scalar_volume", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "value", + "type": "volume", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "A typed volume value (shape-library mixin). Identity classes that read or impose a volume inherit this `value`.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/temperature_manipulation.json b/schemas/V_epsilon/draft/temperature_manipulation.json index 76e23eb..d33e618 100644 --- a/schemas/V_epsilon/draft/temperature_manipulation.json +++ b/schemas/V_epsilon/draft/temperature_manipulation.json @@ -5,33 +5,14 @@ "superclasses": [ { "class_name": "scalar_manipulation" + }, + { + "class_name": "scalar_temperature" } ], "maturity_level": "draft" }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "temperature", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "The imposed temperature magnitude (canonical 'celsius').", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/index.json b/schemas/V_epsilon/index.json index f8e62d8..8f8dbd4 100644 --- a/schemas/V_epsilon/index.json +++ b/schemas/V_epsilon/index.json @@ -28,7 +28,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_duration" ], "path": "schemas/V_epsilon/draft/age_observation.json", "is_meta": false @@ -81,7 +82,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "categorical_observation" + "categorical_observation", + "categorical_concept" ], "path": "schemas/V_epsilon/draft/behavioral_phenotype_observation.json", "is_meta": false @@ -92,7 +94,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_score" ], "path": "schemas/V_epsilon/draft/behavioral_score_observation.json", "is_meta": false @@ -136,7 +139,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_pressure" ], "path": "schemas/V_epsilon/draft/blood_pressure_observation.json", "is_meta": false @@ -147,7 +151,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_score" ], "path": "schemas/V_epsilon/draft/body_condition_observation.json", "is_meta": false @@ -158,7 +163,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_length" ], "path": "schemas/V_epsilon/draft/body_length_observation.json", "is_meta": false @@ -169,7 +175,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_mass" ], "path": "schemas/V_epsilon/draft/body_weight_observation.json", "is_meta": false @@ -186,6 +193,17 @@ "path": "schemas/V_epsilon/stable/calculator.json", "is_meta": false }, + { + "class_name": "categorical_concept", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/categorical_concept.json", + "is_meta": false + }, { "class_name": "categorical_observation", "tier": "draft", @@ -203,7 +221,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_count" ], "path": "schemas/V_epsilon/draft/cell_count_observation.json", "is_meta": false @@ -214,7 +233,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_concentration" ], "path": "schemas/V_epsilon/draft/concentration_observation.json", "is_meta": false @@ -273,7 +293,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_temperature" ], "path": "schemas/V_epsilon/draft/core_temperature_observation.json", "is_meta": false @@ -465,7 +486,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "categorical_observation" + "categorical_observation", + "categorical_concept" ], "path": "schemas/V_epsilon/draft/developmental_stage_observation.json", "is_meta": false @@ -621,7 +643,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "categorical_observation" + "categorical_observation", + "categorical_concept" ], "path": "schemas/V_epsilon/draft/estrous_stage_observation.json", "is_meta": false @@ -852,7 +875,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_manipulation" + "scalar_manipulation", + "scalar_frequency" ], "path": "schemas/V_epsilon/draft/frequency_manipulation.json", "is_meta": false @@ -863,7 +887,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "categorical_observation" + "categorical_observation", + "categorical_concept" ], "path": "schemas/V_epsilon/draft/generic_categorical_observation.json", "is_meta": false @@ -879,13 +904,25 @@ "path": "schemas/V_epsilon/stable/generic_file.json", "is_meta": false }, + { + "class_name": "generic_scalar", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/generic_scalar.json", + "is_meta": false + }, { "class_name": "generic_scalar_manipulation", "tier": "draft", "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_manipulation" + "scalar_manipulation", + "generic_scalar" ], "path": "schemas/V_epsilon/draft/generic_scalar_manipulation.json", "is_meta": false @@ -896,7 +933,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "generic_scalar" ], "path": "schemas/V_epsilon/draft/generic_scalar_observation.json", "is_meta": false @@ -943,7 +981,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "categorical_observation" + "categorical_observation", + "categorical_concept" ], "path": "schemas/V_epsilon/draft/health_status_observation.json", "is_meta": false @@ -954,7 +993,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_frequency" ], "path": "schemas/V_epsilon/draft/heart_rate_observation.json", "is_meta": false @@ -1088,7 +1128,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_count" ], "path": "schemas/V_epsilon/draft/litter_size_observation.json", "is_meta": false @@ -1122,7 +1163,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_voltage" ], "path": "schemas/V_epsilon/draft/membrane_potential_observation.json", "is_meta": false @@ -1291,7 +1333,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_volume" ], "path": "schemas/V_epsilon/draft/organ_volume_observation.json", "is_meta": false @@ -1337,7 +1380,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "categorical_observation" + "categorical_observation", + "categorical_concept" ], "path": "schemas/V_epsilon/draft/pigmentation_observation.json", "is_meta": false @@ -1370,7 +1414,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_manipulation" + "scalar_manipulation", + "scalar_pressure" ], "path": "schemas/V_epsilon/draft/pressure_manipulation.json", "is_meta": false @@ -1527,7 +1572,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_observation" + "scalar_observation", + "scalar_frequency" ], "path": "schemas/V_epsilon/draft/respiration_rate_observation.json", "is_meta": false @@ -1544,6 +1590,72 @@ "path": "schemas/V_epsilon/stable/reverse_correlation.json", "is_meta": false }, + { + "class_name": "scalar_concentration", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_concentration.json", + "is_meta": false + }, + { + "class_name": "scalar_count", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_count.json", + "is_meta": false + }, + { + "class_name": "scalar_current", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_current.json", + "is_meta": false + }, + { + "class_name": "scalar_duration", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_duration.json", + "is_meta": false + }, + { + "class_name": "scalar_frequency", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_frequency.json", + "is_meta": false + }, + { + "class_name": "scalar_length", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_length.json", + "is_meta": false + }, { "class_name": "scalar_manipulation", "tier": "draft", @@ -1555,6 +1667,17 @@ "path": "schemas/V_epsilon/draft/scalar_manipulation.json", "is_meta": false }, + { + "class_name": "scalar_mass", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_mass.json", + "is_meta": false + }, { "class_name": "scalar_observation", "tier": "draft", @@ -1566,6 +1689,61 @@ "path": "schemas/V_epsilon/draft/scalar_observation.json", "is_meta": false }, + { + "class_name": "scalar_pressure", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_pressure.json", + "is_meta": false + }, + { + "class_name": "scalar_score", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_score.json", + "is_meta": false + }, + { + "class_name": "scalar_temperature", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_temperature.json", + "is_meta": false + }, + { + "class_name": "scalar_voltage", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_voltage.json", + "is_meta": false + }, + { + "class_name": "scalar_volume", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/scalar_volume.json", + "is_meta": false + }, { "class_name": "sequence_read_data", "tier": "draft", @@ -1977,7 +2155,8 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "scalar_manipulation" + "scalar_manipulation", + "scalar_temperature" ], "path": "schemas/V_epsilon/draft/temperature_manipulation.json", "is_meta": false diff --git a/schemas/V_epsilon/topics.json b/schemas/V_epsilon/topics.json index 35cf130..e0d244d 100644 --- a/schemas/V_epsilon/topics.json +++ b/schemas/V_epsilon/topics.json @@ -209,6 +209,26 @@ "openminds_subject" ] }, + { + "name": "shape_library", + "description": "Brainstorm E shared shape library: typed value-composite mixin classes. Identity classes (observations by property, scalar manipulations by action) inherit one of these as a superclass to acquire their typed `value` field.", + "classes": [ + "scalar_mass", + "scalar_length", + "scalar_duration", + "scalar_volume", + "scalar_temperature", + "scalar_pressure", + "scalar_frequency", + "scalar_voltage", + "scalar_current", + "scalar_concentration", + "scalar_count", + "scalar_score", + "generic_scalar", + "categorical_concept" + ] + }, { "name": "observations", "description": "Observation families (Brainstorm E): scalar observations named by property, categorical observations named by property, dataseries/image/expression measurements of subjects.", diff --git a/schemas/V_epsilon_SPEC.md b/schemas/V_epsilon_SPEC.md index d4552f6..8929099 100644 --- a/schemas/V_epsilon_SPEC.md +++ b/schemas/V_epsilon_SPEC.md @@ -97,18 +97,31 @@ two epoch reference classes. ### 3. Observation families (new, `draft/`) -- `scalar_observation` (abstract genus, ← `observation`) — shape is now only - an `isa` umbrella; the concrete classes under it are named by the **property - observed** (Brainstorm E), each pinning the typed composite its `value` - requires: `body_weight_observation`/`organ_volume_observation` (mass/volume), +- **Shape library (Brainstorm E, abstract mixins ← `base`).** The typed + value-composites are promoted to named classes that *own* the `value` field + and are mixed into the identity classes as a second superclass: + `scalar_mass`, `scalar_length`, `scalar_duration`, `scalar_volume`, + `scalar_temperature`, `scalar_pressure`, `scalar_frequency`, `scalar_voltage`, + `scalar_current`, `scalar_concentration`, `scalar_count`, `scalar_score`, + `generic_scalar` (source-only struct), and `categorical_concept` + (`ontology_term` + advisory binding). The **same** shape class is inherited by + the observation that reads it and the manipulation that imposes it (e.g. + `scalar_temperature` ← `core_temperature_observation` *and* + `temperature_manipulation`), so `value` is defined once and + `isa scalar_temperature` sweeps both tiers. +- `scalar_observation` (abstract genus, ← `observation`) — shape is only an + `isa` umbrella; the concrete classes under it are named by the **property + observed** (Brainstorm E) and acquire their typed `value` by also inheriting + the matching shape mixin (`class isa scalar_observation, scalar_`): + `body_weight_observation`/`organ_volume_observation` (mass/volume), `body_length_observation` (length), `age_observation` (duration), `core_temperature_observation` (temperature), `heart_rate_observation`/ `respiration_rate_observation` (frequency), `blood_pressure_observation` (pressure), `litter_size_observation`/`cell_count_observation` (count), `body_condition_observation`/`behavioral_score_observation` (score), `concentration_observation` (concentration), `membrane_potential_observation` - (voltage), plus the escape hatch `generic_scalar_observation` (untyped - `{source_unit, source_value, approximate}`). + (voltage), plus the escape hatch `generic_scalar_observation` + (← `generic_scalar`). - `categorical_observation` (abstract genus, ← `observation`): concrete classes named by the **property observed**, each with an `ontology_term` `value` governed by the binding registry — `developmental_stage_observation` (pinned From cb0e347a6167461af8727a38f133370cad49be78 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 19 Jun 2026 10:51:04 +0000 Subject: [PATCH 03/16] V_epsilon: prototype series-as-cardinality on core_temperature_observation Brainstorm E Part 2: a series is a higher cardinality of the same observation, not a new class. Prototype (contained to one class): - core_temperature_observation overrides `value` to an ARRAY of the temperature composite (mustBeScalar: false); a single reading is the length-1 case. - adds `sample_time`, an array of duration offsets from the anchoring time_reference, element-aligned with value (value[i] at time_reference + sample_time[i]). This keeps the depends_on time_reference meaning "one moment, many frames" and puts the per-sample axis in embedded data. - worked example: examples/core_temperature_observation_series.json (a 3-point cooling curve). - tests/test_series_cardinality.py: asserts the array-of-structures shape and ships the len(value)==len(sample_time) check (D3) that JSON Schema cannot express on a single field. The array-of-composite shape (not a bare numeric matrix) preserves the query model's existential [*] search; same-sample value/time correlation is the documented limit. No meta-schema change (mustBeScalar is already an independent boolean). Full design + rollout: Series_As_Cardinality_Proposal.md (ndi-next-steps). All 103 tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../draft/core_temperature_observation.json | 43 ++++++- .../core_temperature_observation_series.json | 36 ++++++ tests/test_series_cardinality.py | 107 ++++++++++++++++++ 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 schemas/V_epsilon/examples/core_temperature_observation_series.json create mode 100644 tests/test_series_cardinality.py diff --git a/schemas/V_epsilon/draft/core_temperature_observation.json b/schemas/V_epsilon/draft/core_temperature_observation.json index 5c510ae..b0412eb 100644 --- a/schemas/V_epsilon/draft/core_temperature_observation.json +++ b/schemas/V_epsilon/draft/core_temperature_observation.json @@ -14,5 +14,46 @@ }, "depends_on": [], "file": [], - "fields": [] + "fields": [ + { + "name": "value", + "type": "temperature", + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0, + "celsius": 0.0 + } + ], + "mustBeNonEmpty": true, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Series-as-cardinality (Brainstorm E Part 2): an array of the temperature shape composite. A single reading is the length-1 case; a curve is length N. Element-aligned with sample_time. value[i] observed at time_reference + sample_time[i].", + "constraints": {} + }, + { + "name": "sample_time", + "type": "duration", + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0, + "seconds": 0.0 + } + ], + "mustBeNonEmpty": true, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Per-sample time offsets from the anchoring time_reference, as an array of the duration composite, element-aligned with value (len(sample_time) == len(value); enforced as a consumer/tooling check). For a single reading, a length-1 array with offset 0.", + "constraints": {} + } + ] } diff --git a/schemas/V_epsilon/examples/core_temperature_observation_series.json b/schemas/V_epsilon/examples/core_temperature_observation_series.json new file mode 100644 index 0000000..5300f00 --- /dev/null +++ b/schemas/V_epsilon/examples/core_temperature_observation_series.json @@ -0,0 +1,36 @@ +{ + "document_class": { + "class_name": "core_temperature_observation", + "class_version": "1.0.0", + "superclasses": [ + { "class_name": "scalar_observation" }, + { "class_name": "scalar_temperature" } + ] + }, + "depends_on": [ + { "name": "subject_id", "value": "aabb1122ccdd3344_aabb1122ccdd3344" }, + { "name": "time_reference_1", "value": "aabb1122ccdd3344_1100220033004400" } + ], + "base": { + "id": "aabb1122ccdd3344_1122334455667788", + "session_id": "aabb1122ccdd3344_9900aabbccddeeff", + "name": "mouse042_cooling_curve", + "datestamp": "2024-06-01T12:00:00.000Z" + }, + "observation": { + "measured_property": { "node": "ncit:C174446", "name": "core body temperature" }, + "target_structure": [] + }, + "core_temperature_observation": { + "value": [ + { "celsius": 37.1, "source_unit": "°C", "source_value": 37.1, "approximate": false }, + { "celsius": 36.4, "source_unit": "°C", "source_value": 36.4, "approximate": false }, + { "celsius": 35.0, "source_unit": "°C", "source_value": 35.0, "approximate": false } + ], + "sample_time": [ + { "seconds": 0, "source_unit": "min", "source_value": 0, "approximate": false }, + { "seconds": 600, "source_unit": "min", "source_value": 10, "approximate": false }, + { "seconds": 1200, "source_unit": "min", "source_value": 20, "approximate": false } + ] + } +} diff --git a/tests/test_series_cardinality.py b/tests/test_series_cardinality.py new file mode 100644 index 0000000..8deaa23 --- /dev/null +++ b/tests/test_series_cardinality.py @@ -0,0 +1,107 @@ +"""Series-as-cardinality prototype tests (Brainstorm E, Part 2). + +Exercises the prototype on `core_temperature_observation`: +- the schema declares `value` and `sample_time` as arrays (mustBeScalar: false) + of typed composites (D1/D4), and +- the worked example document satisfies the element-aligned-length invariant + `len(value) == len(sample_time)` (D3) — which JSON Schema cannot express on a + single field, so it ships here as the consumer/tooling check. + +See Series_As_Cardinality_Proposal.md for the design. +""" + +import json +import os + +import pytest + +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +DRAFT = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "draft") +EXAMPLES = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "examples") +EXAMPLE_DOC = os.path.join(EXAMPLES, "core_temperature_observation_series.json") + + +def _load(path): + with open(path) as f: + return json.load(f) + + +def _field(schema, name): + for fld in schema.get("fields", []): + if fld.get("name") == name: + return fld + return None + + +def check_series_lengths(doc, value_path=("core_temperature_observation", "value"), + time_path=("core_temperature_observation", "sample_time")): + """Consumer/tooling check for D3: the per-sample arrays are element-aligned. + + Returns a list of error strings (empty == valid). This is the validator + JSON Schema cannot express, because it spans two fields. + """ + errors = [] + vblock, vname = value_path + tblock, tname = time_path + value = doc.get(vblock, {}).get(vname) + sample_time = doc.get(tblock, {}).get(tname) + if not isinstance(value, list): + errors.append(f"{vblock}.{vname} must be an array (series-as-cardinality)") + if not isinstance(sample_time, list): + errors.append(f"{tblock}.{tname} must be an array (series-as-cardinality)") + if isinstance(value, list) and isinstance(sample_time, list): + if len(value) != len(sample_time): + errors.append( + f"len({vname})={len(value)} != len({tname})={len(sample_time)} " + "(arrays must be element-aligned)" + ) + return errors + + +class TestSeriesSchema: + def test_value_is_array_of_temperature(self): + schema = _load(os.path.join(DRAFT, "core_temperature_observation.json")) + value = _field(schema, "value") + assert value is not None, "core_temperature_observation must declare value" + assert value["type"] == "temperature" + assert value["mustBeScalar"] is False, "value must be an array (cardinality)" + + def test_sample_time_is_array_of_duration(self): + schema = _load(os.path.join(DRAFT, "core_temperature_observation.json")) + st = _field(schema, "sample_time") + assert st is not None, "core_temperature_observation must declare sample_time" + assert st["type"] == "duration" + assert st["mustBeScalar"] is False, "sample_time must be an array (cardinality)" + + +class TestSeriesExampleDocument: + def test_example_exists_and_parses(self): + assert os.path.exists(EXAMPLE_DOC) + _load(EXAMPLE_DOC) + + def test_example_is_array_of_structures(self): + doc = _load(EXAMPLE_DOC) + value = doc["core_temperature_observation"]["value"] + assert isinstance(value, list) and len(value) >= 1 + for sample in value: + assert isinstance(sample, dict) and "celsius" in sample, ( + "value must be an array OF COMPOSITES (structures), not a bare " + "numeric matrix, so existential [*] search stays available (D4)" + ) + + def test_example_satisfies_length_invariant(self): + doc = _load(EXAMPLE_DOC) + assert check_series_lengths(doc) == [] + + def test_length_mismatch_is_caught(self): + doc = _load(EXAMPLE_DOC) + doc["core_temperature_observation"]["sample_time"].pop() # break alignment + errors = check_series_lengths(doc) + assert errors and "element-aligned" in errors[0] + + def test_single_reading_is_cardinality_one(self): + """A spot reading is the length-1 case of the same class.""" + doc = _load(EXAMPLE_DOC) + doc["core_temperature_observation"]["value"] = [{"celsius": 37.0}] + doc["core_temperature_observation"]["sample_time"] = [{"seconds": 0}] + assert check_series_lengths(doc) == [] From 2341b675c7019d3008f68c902626358a573e73da Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 19 Jun 2026 10:52:17 +0000 Subject: [PATCH 04/16] Fix lint: remove unused pytest import in test_series_cardinality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ruff F401 — the new test module uses plain assertions, no pytest API. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- tests/test_series_cardinality.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_series_cardinality.py b/tests/test_series_cardinality.py index 8deaa23..3965ec2 100644 --- a/tests/test_series_cardinality.py +++ b/tests/test_series_cardinality.py @@ -13,8 +13,6 @@ import json import os -import pytest - REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DRAFT = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "draft") EXAMPLES = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "examples") From 239779a9893906d00ed9d82c211f140b69c3e2f9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 19 Jun 2026 11:26:39 +0000 Subject: [PATCH 05/16] =?UTF-8?q?conversions:=20add=20Brainstorm=20E=20spl?= =?UTF-8?q?it=20specs=20(treatment=E2=86=92manip,=20ontology=5Ftable=5Frow?= =?UTF-8?q?=E2=86=92obs)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #1 of the migration work — textual conversion specifications for the E split: - treatment.md: rewritten from the conservative class-preserving conversion to the E SPLIT — treatment dispatches by ontology branch to injection / bath / procedural_manipulation / temperature_manipulation (and other scalar_manip) / environmental_manipulation, with focal-vs-ambient and structure as data (target_structure), numeric_value → typed value or companion observation, the Dab string_value→target_structure edge case, and out-of-tier routing for non-manipulation rows. Mostly 1→1 with branch dispatch. - ontology_table_row.md (new): the 1→N observation-tier split — each row → a scalar/categorical observation property class (or generic escape hatch), with subject-intrinsic and relational rows routed out of tier. Flags the required 1→N migrator engine capability. - _index.md: registers both split specs. These are the spec the migration code (#2, DID-matlab) implements; they are version-/engine-agnostic. Schema tests unaffected (103 pass). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../conversions/from_did_v1/_index.md | 2 + .../from_did_v1/ontology_table_row.md | 116 +++++++++ .../conversions/from_did_v1/treatment.md | 221 ++++++------------ 3 files changed, 189 insertions(+), 150 deletions(-) create mode 100644 schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md diff --git a/schemas/V_epsilon/conversions/from_did_v1/_index.md b/schemas/V_epsilon/conversions/from_did_v1/_index.md index 453d264..06055e4 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/_index.md +++ b/schemas/V_epsilon/conversions/from_did_v1/_index.md @@ -45,6 +45,8 @@ field-level changes on top. | `hartley_calc` | NDIcalc-vis-matlab `calc/hartley_calc` | drafted | [hartley_calc.md](hartley_calc.md) | | `probe_location` | legacy NDI/DID `probe_location` (V_alpha shape) | drafted | [probe_location.md](probe_location.md) | | `treatment` | legacy NDI/DID `treatment` (V_alpha shape) | drafted | [treatment.md](treatment.md) | +| `treatment` → manipulation tiers (Brainstorm E **split**) | legacy `treatment` → `injection`/`bath`/`procedural_manipulation`/`temperature_manipulation`/`environmental_manipulation` (+ out-of-tier) | drafted | [treatment.md](treatment.md) | +| `ontology_table_row` → observation tiers (Brainstorm E **split**, 1→N) | legacy `ontology_table_row` → scalar/categorical observation property classes (+ out-of-tier) | drafted | [ontology_table_row.md](ontology_table_row.md) | | `ontology_image` | legacy NDI/DID `ontologyImage` (V_alpha shape) | drafted | [ontology_image.md](ontology_image.md) | | `ontology_label` | legacy NDI/DID `ontologyLabel` (V_alpha shape) | drafted | [ontology_label.md](ontology_label.md) | diff --git a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md new file mode 100644 index 0000000..c8bc937 --- /dev/null +++ b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md @@ -0,0 +1,116 @@ +# Conversion: did_v1 → V_epsilon — `ontology_table_row` → observation tiers (Brainstorm E split) + +> The observation-tier companion to [`treatment.md`](treatment.md). The legacy `ontology_table_row` open key/value bag is **retired** and **split** across the Brainstorm E observation property classes (and, for non-observation rows, out of the tier). This is the genuinely **one-to-many** migration: one `ontology_table_row` document → N destination documents. + +## Identity + +- **Target tier:** V_epsilon observation families (`schemas/V_epsilon/draft/`). +- **did_v1 source:** legacy NDI/DID `ontology_table_row` (open table of `(ontology term, value[, unit])` rows attached to a subject at a time). +- **Status:** `drafted` — needs the 1→N migrator capability (see [Engine note](#engine-note)) and the per-term dispatch table (finalized in discovery mode). +- **Cardinality:** **1 → N.** Each row dispatches independently; a single source document fans out to several destinations across tiers. + +## Summary + +Each row names a property (an ontology term) and a value. Brainstorm E dispatches per row by **what the property is** and **what shape its value takes**: +- a **scalar** measurement → the matching scalar property class (`body_weight_observation`, `core_temperature_observation`, …), value as the typed composite; +- a **categorical** label → the matching categorical property class (`developmental_stage_observation`, …), value as a bound `ontology_term`; +- a **subject-intrinsic, set-once** fact (species, strain, sex) → **not an observation** → the `subject` document / `openminds_subject`; +- a **relational/assigned** fact (cohort, housing, derivation source) → the relevant **event/annotation** class (`group_assignment`, `placement`, `derivation`); +- a fact with **no minted property class yet** → the escape hatch (`generic_scalar_observation` / `generic_categorical_observation`), promoted later. + +## Per-row dispatch table + +First match wins, on the row's property term (branch) and value shape. + +| Row property (branch) + value shape | Destination | Mapping | +|---|---|---| +| Mass-dimensioned, numeric (body weight, brain/tumor mass) | `body_weight_observation` (`value : scalar_mass`) | term → `measured_property`; structure → `target_structure`; value+unit → `scalar_mass` composite | +| Length-dimensioned | `body_length_observation` (`scalar_length`) | as above | +| Duration / age | `age_observation` (`scalar_duration`) | | +| Temperature | `core_temperature_observation` (`scalar_temperature`) | | +| Frequency (heart/respiration rate) | `heart_rate_observation` / `respiration_rate_observation` (`scalar_frequency`) | | +| Pressure (BP, IOP, partial pressure) | `blood_pressure_observation` (`scalar_pressure`) | | +| Count (litter size, cell count) | `litter_size_observation` / `cell_count_observation` (`scalar_count`) | | +| Score (body condition, behavioral) | `body_condition_observation` / `behavioral_score_observation` (`scalar_score`) | | +| Concentration (glucose, cortisol, titer) | `concentration_observation` (`scalar_concentration`) | | +| Voltage (transcribed Vm) | `membrane_potential_observation` (`scalar_voltage`) | | +| **Scalar with no minted property class** | `generic_scalar_observation` (`generic_scalar`) | value → `{source_unit, source_value, approximate}`; promote later | +| Categorical: developmental/life stage | `developmental_stage_observation` (bound under `UBERON:0000105`) | term → `value`; property → `measured_property` | +| Categorical: health status / coat / estrous / behavioral label | `health_status_observation` / `pigmentation_observation` / `estrous_stage_observation` / `behavioral_phenotype_observation` | term → `value` | +| **Categorical with no minted property class** | `generic_categorical_observation` (free `ontology_term`, no binding) | term → `value`; promote later | +| **Subject-intrinsic, set-once** (species, strain, sex, DOB) | **out of tier** → `subject` / `openminds_subject` (merge) | not an observation | +| **Relational / assigned** (cohort, housing, derivation source) | **out of tier** → `group_assignment` / `placement` / `derivation` | event/annotation tiers | +| Empty / unresolvable term | **curator review queue** (routing off) | flagged | + +## Common field mapping (per generated observation) + +| did_v1 row element | V_epsilon field | Transformation | +|---|---|---| +| row property term | `measured_property` (inherited from `observation`) | `ontology_term` | +| anatomical qualifier (if any) | `target_structure` | `ontology_term[]`; else `[]` | +| row value (+ unit) | `value` on the destination shape block | typed composite (scalar) or bound `ontology_term` (categorical) per shape | +| source `subject_id` | inherited `subject_id` | identity, shared by all generated docs | +| source time anchor | inherited `time_reference_#` | shared by all generated docs (the whole row burst is one moment) | + +## Engine note + +This conversion is **1 → N** and so requires the converter to support a migrator that **returns multiple bodies** (the current `+did2.+convert.+migrators.` contract returns one body). The migrator emits one destination document per row, all sharing the source `subject_id` + synthesized `time_reference`, and routes non-observation rows out of tier. See [DID-matlab] `+did2/+convert/` for where the pipeline fans out. Until the 1→N capability lands, this conversion stays `drafted`. + +## Worked example — a 2-row intake burst → two observations + +### Before (did_v1, one document, two rows) +```json +{ + "document_class": { "class_name": "ontology_table_row", "class_version": "1.0.0", + "superclasses": [ { "class_name": "base", "class_version": "1.0.0" } ] }, + "depends_on": [ { "name": "subject_id", "document_id": "aabb1122ccdd3344_aabb1122ccdd3344" } ], + "base": { "id": "aabb1122ccdd3344_1122334455667788", "session_id": "aabb1122ccdd3344_9900aabbccddeeff", + "name": "intake_row", "datestamp": "2024-05-15T09:30:00.000Z" }, + "ontology_table_row": { + "rows": [ + { "ontologyName": "schema:weight", "name": "weight", "value": 22.5, "unit": "g" }, + { "ontologyName": "uberon:0000105", "name": "life cycle stage", "value": "FBdv:00005336" } + ] + } +} +``` + +### After (V_epsilon, two documents) +```json +[ + { + "document_class": { "class_name": "body_weight_observation", "class_version": "1.0.0", + "superclasses": [ { "class_name": "scalar_observation" }, { "class_name": "scalar_mass" } ] }, + "depends_on": [ + { "name": "subject_id", "value": "aabb1122ccdd3344_aabb1122ccdd3344" }, + { "name": "time_reference_1", "value": "aabb1122ccdd3344_synthesized" } ], + "base": { "id": "aabb1122ccdd3344_aaaa000000000001", "session_id": "aabb1122ccdd3344_9900aabbccddeeff", + "name": "intake_weight", "datestamp": "2024-05-15T09:30:00.000Z" }, + "observation": { "measured_property": { "node": "schema:weight", "name": "weight" }, "target_structure": [] }, + "scalar_mass": { "value": { "kilograms": 0.0225, "source_unit": "g", "source_value": 22.5, "approximate": false } } + }, + { + "document_class": { "class_name": "developmental_stage_observation", "class_version": "1.0.0", + "superclasses": [ { "class_name": "categorical_observation" }, { "class_name": "categorical_concept" } ] }, + "depends_on": [ + { "name": "subject_id", "value": "aabb1122ccdd3344_aabb1122ccdd3344" }, + { "name": "time_reference_1", "value": "aabb1122ccdd3344_synthesized" } ], + "base": { "id": "aabb1122ccdd3344_aaaa000000000002", "session_id": "aabb1122ccdd3344_9900aabbccddeeff", + "name": "intake_stage", "datestamp": "2024-05-15T09:30:00.000Z" }, + "observation": { "measured_property": { "node": "uberon:0000105", "name": "life cycle stage" }, "target_structure": [] }, + "developmental_stage_observation": { "value": { "node": "fbdv:00005336", "name": "larval stage" } } + } +] +``` + +## Open questions + +- **Per-term dispatch table** — the property-term → property-class map is finalized in discovery mode against real corpora (the same report-only loop as `treatment`). Terms with no minted class fall to the generic escape hatches. +- **New `base.id` per generated doc** — N new documents need N stable ids; define the derivation (e.g. source id + row index) so re-runs are idempotent. +- **1→N engine capability** — prerequisite; see [Engine note](#engine-note). + +## Cross-references + +- Manipulation-tier split: [`treatment.md`](treatment.md) +- Universal renames: [`_universal_renames.md`](_universal_renames.md) +- Design sources (ndi-next-steps): `Scalar_Observation_Proposal.md`, `Categorical_Observation_Proposal.md`, `20260615/Brainstorm_E_Class_Catalog.md` §3, `Pulakat_Datatype_Homes.md`. diff --git a/schemas/V_epsilon/conversions/from_did_v1/treatment.md b/schemas/V_epsilon/conversions/from_did_v1/treatment.md index 5929481..4c7a025 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/treatment.md +++ b/schemas/V_epsilon/conversions/from_did_v1/treatment.md @@ -1,187 +1,108 @@ -# Conversion: did_v1 → V_delta — `treatment` +# Conversion: did_v1 → V_epsilon — `treatment` → manipulation tiers (Brainstorm E split) + +> **Supersedes the conservative class-preserving `treatment` → V_delta `treatment` conversion** (kept in git history). Under Brainstorm E the legacy `treatment` catch-all is **retired** and **split** across the manipulation tier (and, for non-manipulation rows, out of the tier entirely). This doc is the dispatch spec for that split. Companion: [`ontology_table_row.md`](ontology_table_row.md) (the observation-tier split). ## Identity -- **V_delta `class_name`:** `treatment` -- **V_delta tier:** `stable` -- **V_delta schema path:** `schemas/V_delta/stable/treatment.json` -- **did_v1 source:** legacy NDI/DID `treatment` document type - (`_classname: "treatment"`). Schema-shape ancestor in this repository - is `schemas/V_alpha/treatment.json`; `schemas/V_beta/treatment.json` - is the same shape with naming-convention housekeeping applied - (`ontologyName` → `ontology_name`). -- **Status:** `drafted` +- **Target tier:** V_epsilon manipulation families (`schemas/V_epsilon/draft/`). +- **did_v1 source:** legacy NDI/DID `treatment` (`_classname: "treatment"`; shape ancestor `schemas/V_alpha/treatment.json`). Fields: `treatment.ontologyName` + `treatment.name` (ontology identity), `treatment.numeric_value` (matrix), `treatment.string_value` (char); `depends_on`: `subject_id`, `manipulation_id`, `protocol_id`. +- **Status:** `drafted` (dispatch table seeded from real corpora; per-term branch list finalized in discovery mode — see [Open questions](#open-questions)). +- **Cardinality:** **1 → 1** in the common case (one `treatment` → one manipulation document), **1 → 2** when a recognizable `numeric_value` spawns a companion `scalar_observation`. Genuinely-not-a-manipulation rows route **out of tier** (1 → 1 into observation/annotation/session metadata). ## Summary -`treatment` records a treatment applied to a subject (drug, stimulation, -etc.) keyed by ontology term and carrying an optional numeric value and -an optional free-form string value. did_v1 stored the ontology identity -as a pair of `char` fields (`ontologyName` + `name`); V_delta collapses -those into a single `treatment_name` field of the `ontology_term` -composite type. The `numeric_value` and `string_value` fields carry over -unchanged. - -## Field mapping - -Beyond these fields, the universal renames listed in -[`_universal_renames.md`](_universal_renames.md) apply (snake-case -ontology-annotation reshape, superclass-reference reshape, class-scoped -property block keyed by `treatment`). - -| did_v1 field | V_delta field | Transformation | Notes | -|---|---|---|---| -| `treatment.ontologyName` (char) | `treatment.treatment_name.node` | composed into `ontology_term`; snake-case rename of the carrier field | CURIE. See "Transformations in detail". | -| `treatment.name` (char) | `treatment.treatment_name.name` | composed into `ontology_term` | Human-readable label snapshot. | -| — | `treatment.treatment_name` (ontology_term) | new composite field | Created by composing the two did_v1 chars above. | -| `treatment.numeric_value` (matrix) | `treatment.numeric_value` (matrix) | identity | | -| `treatment.string_value` (char) | `treatment.string_value` (char) | identity | | -| `depends_on[subject_id]` | `depends_on[subject_id]` | identity | | -| `depends_on[manipulation_id]` | `depends_on[manipulation_id]` | identity | | -| `depends_on[protocol_id]` | `depends_on[protocol_id]` | identity | | - -## Transformations in detail - -- **Collapse two coordinated chars into one `ontology_term`.** did_v1's - `ontologyName` (the ontology CURIE-or-name) and `name` (the - human-readable label) merge into V_delta's `treatment_name` composite: - - treatment_name = { - "node": , - "name": - } - - This is the same merge rule as `probe_location` (see - [`probe_location.md`](probe_location.md)); the *carrier* field is - renamed from `.name` to `.treatment_name` so it does - not collide with `base.name`. (Under V_delta's class-scoped property - blocks, `base.name` and `treatment.name` would in principle be - distinct, but renaming the carrier here makes the migrated documents - easier to read and matches the V_gamma `class_version: 2.0.0` shape - the V_delta schemas inherit — see `V_gamma_notes.md` § "Class-version - bumps".) - -- **camelCase → snake_case of the source field name.** did_v1's - `ontologyName` is camelCase; the V_beta-era housekeeping snake-cased - field names. The migrator reads the value from either spelling and - writes it to `treatment_name.node`. See - [`_universal_renames.md`](_universal_renames.md) for the - cross-cutting snake_case rule. - -- **`numeric_value` and `string_value` are identity passes.** Both are - declared identically in did_v1 and V_delta (matrix and char, - respectively). No type or semantic change. - -- **Document-instance shape.** V_delta uses class-scoped property - blocks. The three carrier fields live at `treatment.treatment_name`, - `treatment.numeric_value`, `treatment.string_value`. +A `treatment` row carries an ontology identity + an optional number + optional prose. Brainstorm E reads that identity and dispatches the row to the manipulation family whose **action** it names — substance delivery → `injection`/`bath`; physical operation on the body → `procedural_manipulation`; imposed typed quantity → a `scalar_manipulation` (e.g. `temperature_manipulation`); changed condition/regime → `environmental_manipulation` — with focal-vs-ambient and structure carried as **data** (`target_structure`), not as classes. Rows that are not manipulations at all (date of birth, experiment time) are routed out of the manipulation tier. + +## Dispatch table (on `treatment.ontologyName` branch) + +First match wins; resolved against the term's ontology branch, not a string match. + +| `ontologyName` branch | Destination class | Key field mapping | +|---|---|---| +| Drug / vehicle / virus / tracer / contrast **delivered by injection** (CHEBI drug branch; OBI injection) | **`injection`** (← `pharmacological_manipulation`) | identity → `mixture` agent; `numeric_value` (if volume) → `volume`; route/coords → curator backfill; `kind` ∈ {drug,virus,tracer,vehicle,contrast} | +| Substance applied **as a bath** | **`bath`** / **`stimulus_bath`** | identity → `mixture`; `location` from prose/backfill | +| Surgical / minor physical **operation on the body** (OBI/NCIT procedure branch — craniotomy, implant, lesion, eye-opening, ear-notch, perfusion) | **`procedural_manipulation`** | identity → `procedure`; structure → `target_structure`; prose → `notes` | +| **Heating / cooling** (thermal) | **`temperature_manipulation`** (← `scalar_manipulation`, `scalar_temperature`) | identity → `applied_property`; thermal `numeric_value` → `value` (typed temperature); focal site → `target_structure` (empty ⇒ ambient) | +| Other **imposed typed quantity** (applied pressure/force, field, frequency) | matching `scalar_manipulation` subclass (`pressure_manipulation`, …) or `generic_scalar_manipulation` | identity → `applied_property`; `numeric_value` → `value` | +| **Environmental / husbandry / behavioral regime** with no typed value (dark rearing, deprivation regime, social isolation, enrichment, light cycle, diet/water restriction, training) | **`environmental_manipulation`** | identity → `factor`; structure (lateralized) → `target_structure`; prose → `notes`; duration → bounded `time_reference` | +| **Not a manipulation** (`Treatment: Date of birth`, `Treatment: Non-survival experiment time`, …) | **out of tier** → `age_observation`/`categorical_observation` (DOB) or session metadata/annotation | per [`ontology_table_row.md`](ontology_table_row.md) routing | +| Empty / unresolvable `ontologyName` | **curator review queue** (default routing **off**) | flagged, never silently forced into a residual family | + +### Edge cases captured from real corpora + +- **`string_value` carrying an ontology target, not prose** (the `Dab` treeshrew optogenetic-tetanus rows: `ontologyName = EMPTY:0000074`, `name = "…Target Location"`, `string_value = UBERON CURIE`). Route `string_value` → **`target_structure`** (as `ontology_term`), strip the "Target Location" role-suffix from the procedure/action name, register an NDIC term for the `EMPTY:` placeholder (curator backfill until then). Detection rule: `name` ends in "Target Location" **and/or** `string_value` matches a CURIE pattern. +- **`numeric_value` → companion observation.** A recognizable typed quantity that is *measured*, not the manipulation's own payload (e.g. a training-exposure duration), becomes a companion `scalar_observation` sharing `subject_id` + `time_reference`. Unrecognizable numbers are **flagged, never silently kept** (the `numeric_value` grab-bag is exactly what E retires). + +## Common field mapping (all manipulation destinations) + +| did_v1 field | V_epsilon field | Transformation | +|---|---|---| +| `treatment.ontologyName` + `treatment.name` | the family identity slot (`procedure` / `factor` / `applied_property`; or `mixture` agent) | collapse the two chars into one `ontology_term` (same merge rule as `probe_location`), then place per the dispatch table | +| `treatment.numeric_value` | typed `value` **or** companion `scalar_observation` **or** flagged | per dispatch; thermal/pressure/etc. → typed `value`; measured quantity → companion; else flag | +| `treatment.string_value` | `notes` (prose) **or** `target_structure` (Dab case) | default prose → `notes`; CURIE/Target-Location → `target_structure` | +| `depends_on[subject_id]` | inherited `subject_id` | identity | +| — | inherited `time_reference_#` | **synthesized** from session/epoch metadata (point-in-time for procedures; bounded for regimes/imposed quantities); curator widens | +| `depends_on[manipulation_id]` | — | **dropped** (stale in v1) | +| `depends_on[protocol_id]` | — | **dropped + flagged** for the tier-level `protocol_id` commonality (issue #8 Option C / #10) | ## Default values for new fields -V_delta introduces no required field on this class beyond what did_v1 -documents already supply. The global `schema_version` tag lives at -`document_class.schema_version` (see `_universal_renames.md` § 10) and -is set to `"V_delta"` by the dispatcher rather than the per-class -migrator. +- `target_structure`: `[]` (empty ⇒ whole-subject/ambient) unless recoverable. +- `kind` (injection): inferred from the agent branch where possible; else curator backfill. +- `time_reference_#`: synthesized; required, so the migrator must produce at least one (a point-in-time reference anchored to the session) and flag for widening. -## Worked example +## Worked example — thermal `treatment` → `temperature_manipulation` ### Before (did_v1) - ```json { - "document_class": { - "class_name": "treatment", - "class_version": "1.0.0", - "superclasses": [ - { "class_name": "base", "class_version": "1.0.0" } - ] - }, + "document_class": { "class_name": "treatment", "class_version": "1.0.0", + "superclasses": [ { "class_name": "base", "class_version": "1.0.0" } ] }, "depends_on": [ { "name": "subject_id", "document_id": "aabb1122ccdd3344_aabb1122ccdd3344" }, { "name": "manipulation_id", "document_id": "" }, - { "name": "protocol_id", "document_id": "" } + { "name": "protocol_id", "document_id": "ccdd_protocol" } ], - "base": { - "id": "aabb1122ccdd3344_1122334455667788", - "session_id": "aabb1122ccdd3344_9900aabbccddeeff", - "name": "isoflurane_induction", - "datestamp": "2024-06-01T12:00:00.000Z" - }, - "treatment": { - "ontologyName": "chebi:6015", - "name": "isoflurane", - "numeric_value": [2.0], - "string_value": "2 percent in O2" - } + "base": { "id": "aabb1122ccdd3344_1122334455667788", "session_id": "aabb1122ccdd3344_9900aabbccddeeff", + "name": "v1_cooling", "datestamp": "2024-06-01T12:00:00.000Z" }, + "treatment": { "ontologyName": "ndic:0000nnnn", "name": "focal cortical cooling", + "numeric_value": [12.0], "string_value": "Peltier, V1" } } ``` -### After (V_delta) - +### After (V_epsilon) ```json { - "document_class": { - "class_name": "treatment", - "class_version": "1.0.0", - "superclasses": [ - { "class_name": "base", "class_version": "1.0.0" } - ] - }, + "document_class": { "class_name": "temperature_manipulation", "class_version": "1.0.0", + "superclasses": [ { "class_name": "scalar_manipulation" }, { "class_name": "scalar_temperature" } ] }, "depends_on": [ - { "name": "subject_id", "document_id": "aabb1122ccdd3344_aabb1122ccdd3344" }, - { "name": "manipulation_id", "document_id": "" }, - { "name": "protocol_id", "document_id": "" } + { "name": "subject_id", "value": "aabb1122ccdd3344_aabb1122ccdd3344" }, + { "name": "time_reference_1", "value": "aabb1122ccdd3344_synthesized" } ], - "base": { - "id": "aabb1122ccdd3344_1122334455667788", - "session_id": "aabb1122ccdd3344_9900aabbccddeeff", - "name": "isoflurane_induction", - "datestamp": "2024-06-01T12:00:00.000Z" + "base": { "id": "aabb1122ccdd3344_1122334455667788", "session_id": "aabb1122ccdd3344_9900aabbccddeeff", + "name": "v1_cooling", "datestamp": "2024-06-01T12:00:00.000Z" }, + "scalar_manipulation": { + "applied_property": { "node": "ndic:0000nnnn", "name": "focal cortical cooling" }, + "target_structure": [ { "node": "uberon:0002436", "name": "primary visual cortex" } ], + "notes": "Peltier, V1" }, - "treatment": { - "treatment_name": { - "node": "chebi:6015", - "name": "isoflurane" - }, - "numeric_value": [2.0], - "string_value": "2 percent in O2" - } + "scalar_temperature": { "value": { "celsius": 12.0, "source_unit": "°C", "source_value": 12.0, "approximate": false } } } ``` +(`target_structure` here was recovered from `string_value`; `protocol_id`/`manipulation_id` dropped; `time_reference` synthesized.) ## File handling -This document type does not reference files. The generic file-handling -rules in [`_files.md`](_files.md) do not apply. +`treatment` references no files. [`_files.md`](_files.md) does not apply. ## Open questions -- **TODO-domain:** what is the canonical CURIE prefix family for - treatments? Drugs typically resolve under `chebi:` or `drugbank:`; - stimulation protocols may not have a single canonical source. The - V_delta schema's `ontology` slot for `treatment_name` is `null`, - leaving the choice to documents. -- **TODO-domain:** `numeric_value` is a matrix and `mustBeScalar: - false`. Confirm whether did_v1 documents in the wild ever carry - multi-element matrices here, or only scalars / 1-element arrays. The - migrator should pass the value through unchanged in either case, but - knowing the shape distribution affects downstream tooling - assumptions. -- **TODO-domain:** the relationship between `numeric_value` / - `string_value` and `treatment_name` is not enforced (any of the - three can be empty). Confirm whether the V1 freeze should add a - semantic constraint (at least one non-empty), or leave it to - consumer policy. +- **Per-term branch list.** The dispatch table is branch-level; the concrete `ontologyName` → destination mapping per corpus is finalized in **discovery mode** (run the corpus through the converter, read the quarantine/review report, extend the branch list). Report-only before any rewrite. +- **`time_reference` synthesis fidelity.** What session/epoch anchor each corpus exposes; bounded vs point default per family. +- **`protocol_id` carryover.** Dropped now; belongs to the tier-level commonality decision (#8 Option C / #10). ## Cross-references -- General file-handling rules: [`_files.md`](_files.md) -- Universal did_v1 → V_delta renames: [`_universal_renames.md`](_universal_renames.md) -- V_delta schema file: [`schemas/V_delta/stable/treatment.json`](../../stable/treatment.json) -- Related conversions that follow the same two-char-to-`ontology_term` - pattern: [`probe_location.md`](probe_location.md), - [`ontology_image.md`](ontology_image.md), - [`ontology_label.md`](ontology_label.md) -- Subclass: `treatment_drug` (still at `class_version: 1.0.0`; this - conversion doc's rules apply to its `treatment` block). +- Observation-tier split: [`ontology_table_row.md`](ontology_table_row.md) +- Universal renames: [`_universal_renames.md`](_universal_renames.md) +- Design sources (ndi-next-steps): `Procedural_Manipulation_Proposal.md`, `Environmental_Manipulation_Proposal.md`, `Scalar_Manipulation_Proposal.md`, `Injection_Proposal.md`, `Bath_Proposal.md`, `20260615/Brainstorm_E_Class_Catalog.md` §4. From c1676c61dbe69f1dab4f8933cd7f96a5d6e40181 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 19 Jun 2026 23:54:14 +0000 Subject: [PATCH 06/16] V_epsilon: add subject_statement/subject_assertion tier + session_relative_reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two independent additions: 1. subject_statement / subject_assertion (Subject_Statement_Decision): - subject_statement (abstract, ← base): owns the subject_id anchor; timeless (no time_reference). - subject_assertion (concrete): timeless asserted facts — asserted_property + value + source (species/strain/sex/genotype). - subject_interaction re-parented under subject_statement; it adds the required time_reference_# (subject_id now inherited). Subclasses tighten (timed) the timeless parent; leaves still resolve subject_id + time_reference (verified by inheritance flatten). 2. session_relative_reference (← time_reference): an ORDINAL anchor relative to the session — dep session_id → session, relation enum {before, after, at_start_of, at_end_of, concurrent_with, during}, no metric offset. For interactions with neither a device clock nor a wall-clock date (e.g. an awake behavioral test "at the end of the session"). This is the ordinal, session-anchored sibling of event_relative (which is metric and targets a subject_interaction, neither of which fits the no-clock/no-date case). Updates index.json, topics.json (new subject_statement group; session_relative added to time_reference group), and V_epsilon_SPEC.md. All 103 tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../draft/session_relative_reference.json | 45 ++++++++++++ .../V_epsilon/draft/subject_assertion.json | 73 +++++++++++++++++++ .../V_epsilon/draft/subject_interaction.json | 8 +- .../V_epsilon/draft/subject_statement.json | 23 ++++++ schemas/V_epsilon/index.json | 35 ++++++++- schemas/V_epsilon/topics.json | 11 ++- schemas/V_epsilon_SPEC.md | 33 ++++++--- 7 files changed, 207 insertions(+), 21 deletions(-) create mode 100644 schemas/V_epsilon/draft/session_relative_reference.json create mode 100644 schemas/V_epsilon/draft/subject_assertion.json create mode 100644 schemas/V_epsilon/draft/subject_statement.json diff --git a/schemas/V_epsilon/draft/session_relative_reference.json b/schemas/V_epsilon/draft/session_relative_reference.json new file mode 100644 index 0000000..af9ae38 --- /dev/null +++ b/schemas/V_epsilon/draft/session_relative_reference.json @@ -0,0 +1,45 @@ +{ + "document_class": { + "class_name": "session_relative_reference", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "time_reference" + } + ], + "maturity_level": "draft" + }, + "depends_on": [ + { + "name": "session_id", + "mustBeNonEmpty": true, + "documentation": "The session this reference is ordinally relative to.", + "must_refer_to_document_class": "session" + } + ], + "file": [], + "fields": [ + { + "name": "relation", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Ordinal relation of the interaction to the session, with no metric offset (the case where there is neither a device clock nor a wall-clock date).", + "constraints": { + "enum": [ + "before", + "after", + "at_start_of", + "at_end_of", + "concurrent_with", + "during" + ] + } + } + ] +} diff --git a/schemas/V_epsilon/draft/subject_assertion.json b/schemas/V_epsilon/draft/subject_assertion.json new file mode 100644 index 0000000..b27b42d --- /dev/null +++ b/schemas/V_epsilon/draft/subject_assertion.json @@ -0,0 +1,73 @@ +{ + "document_class": { + "class_name": "subject_assertion", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "subject_statement" + } + ], + "maturity_level": "draft" + }, + "depends_on": [], + "file": [], + "fields": [ + { + "name": "asserted_property", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Semantic identity of the asserted, timeless property (e.g. species, strain, sex, genotype).", + "constraints": {} + }, + { + "name": "value", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "The asserted value as a bound concept (e.g. an NCBITaxon species term). Typed/date values are a follow-up.", + "constraints": {} + }, + { + "name": "source", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Provenance/authority of the assertion (e.g. curator, vendor, openMINDS record). Optional.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/draft/subject_interaction.json b/schemas/V_epsilon/draft/subject_interaction.json index 9939299..3eedc2f 100644 --- a/schemas/V_epsilon/draft/subject_interaction.json +++ b/schemas/V_epsilon/draft/subject_interaction.json @@ -4,19 +4,13 @@ "class_version": "1.0.0", "superclasses": [ { - "class_name": "base" + "class_name": "subject_statement" } ], "maturity_level": "draft", "abstract": true }, "depends_on": [ - { - "name": "subject_id", - "mustBeNonEmpty": true, - "documentation": "The subject this interaction involves.", - "must_refer_to_document_class": "subject" - }, { "name": "time_reference_#", "mustBeNonEmpty": true, diff --git a/schemas/V_epsilon/draft/subject_statement.json b/schemas/V_epsilon/draft/subject_statement.json new file mode 100644 index 0000000..2b9456e --- /dev/null +++ b/schemas/V_epsilon/draft/subject_statement.json @@ -0,0 +1,23 @@ +{ + "document_class": { + "class_name": "subject_statement", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft", + "abstract": true + }, + "depends_on": [ + { + "name": "subject_id", + "mustBeNonEmpty": true, + "documentation": "The subject this statement is about.", + "must_refer_to_document_class": "subject" + } + ], + "file": [], + "fields": [] +} diff --git a/schemas/V_epsilon/index.json b/schemas/V_epsilon/index.json index 8f8dbd4..730b323 100644 --- a/schemas/V_epsilon/index.json +++ b/schemas/V_epsilon/index.json @@ -1810,6 +1810,17 @@ "path": "schemas/V_epsilon/stable/session_in_a_dataset.json", "is_meta": false }, + { + "class_name": "session_relative_reference", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "time_reference" + ], + "path": "schemas/V_epsilon/draft/session_relative_reference.json", + "is_meta": false + }, { "class_name": "simple_calc", "tier": "stable", @@ -2094,6 +2105,17 @@ "path": "schemas/V_epsilon/stable/subject.json", "is_meta": false }, + { + "class_name": "subject_assertion", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "subject_statement" + ], + "path": "schemas/V_epsilon/draft/subject_assertion.json", + "is_meta": false + }, { "class_name": "subject_group", "tier": "deprecated", @@ -2111,11 +2133,22 @@ "class_version": "1.0.0", "maturity_level": "draft", "superclasses": [ - "base" + "subject_statement" ], "path": "schemas/V_epsilon/draft/subject_interaction.json", "is_meta": false }, + { + "class_name": "subject_statement", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/subject_statement.json", + "is_meta": false + }, { "class_name": "syncgraph", "tier": "stable", diff --git a/schemas/V_epsilon/topics.json b/schemas/V_epsilon/topics.json index e0d244d..4da27ba 100644 --- a/schemas/V_epsilon/topics.json +++ b/schemas/V_epsilon/topics.json @@ -341,6 +341,14 @@ "virus_injection" ] }, + { + "name": "subject_statement", + "description": "Timeless documented claims about a subject (Subject_Statement_Decision): the abstract subject_statement supertype and the concrete subject_assertion (asserted_property + value + source).", + "classes": [ + "subject_statement", + "subject_assertion" + ] + }, { "name": "subject_interaction", "description": "The unified subject_interaction spine and its observation/manipulation/annotation tiers.", @@ -360,7 +368,8 @@ "event_relative_reference", "epoch_relative_reference", "epoch_bounded_reference", - "event_bounded_reference" + "event_bounded_reference", + "session_relative_reference" ] } ] diff --git a/schemas/V_epsilon_SPEC.md b/schemas/V_epsilon_SPEC.md index 8929099..85e2745 100644 --- a/schemas/V_epsilon_SPEC.md +++ b/schemas/V_epsilon_SPEC.md @@ -54,20 +54,28 @@ while V_epsilon remains a sandbox. ### 1. The `subject_interaction` spine (new, `draft/`) -A three-tier abstract hierarchy unifying everything that happens to a -subject: +A hierarchy unifying everything documented about a subject. The shared +anchor is lifted to an abstract **`subject_statement`** supertype +(`Subject_Statement_Decision.md`), so timeless claims and timed events +share `subject_id` and one `isa subject_statement` query: ``` -subject_interaction (abstract) depends_on: subject_id, time_reference (>=1) -├── observation (abstract) fields: measured_property, target_structure -├── manipulation (abstract) -└── annotation (abstract) +subject_statement (abstract) depends_on: subject_id ← any claim about a subject +├── subject_assertion (concrete) fields: asserted_property, value, source ← timeless facts +└── subject_interaction(abstract) depends_on: time_reference (>=1) ← timed events + ├── observation (abstract) fields: measured_property, target_structure + ├── manipulation (abstract) + └── annotation (abstract) ``` -- `subject_interaction` inherits from `base`. Its dependencies are - `subject_id` (required, → `subject`) and `time_reference_#` (required, - `multiple: true`, → the abstract `time_reference` class — the same - moment may be expressed in several reference frames). +- `subject_statement` owns `subject_id` (required, → `subject`). Timing is + the split between the two subtrees: `subject_assertion` is **timeless** + (no `time_reference`); `subject_interaction` adds `time_reference_#` + (required, `multiple: true`). Subclasses tighten, never relax — so the + timeless concept lives on the parent, the timed one on the child. +- `subject_assertion` is the home for timeless asserted facts (species, + strain, sex, genotype). One generic class: `asserted_property` + `value` + + `source`. (Typed/date values are a follow-up.) - There is **no `direction` field**: class membership in `observation` / `manipulation` / `annotation` carries that information, and `isa` queries replace `direction`-filter queries. @@ -78,16 +86,17 @@ subject_interaction (abstract) depends_on: subject_id, time_reference (>=1) ### 2. Timing as a dependency: the `time_reference` family (new, `draft/`) Timing is a referenced document, not an inline field. The abstract -`time_reference` (← `base`, field `is_approximate`) has five concrete +`time_reference` (← `base`, field `is_approximate`) has these concrete subclasses: | class | extends | carries | |---|---|---| | `utc_reference` | `time_reference` | `start` (timestamp, req), `end` (timestamp, opt ⇒ interval) | -| `event_relative_reference` | `time_reference` | dep `reference_event` → `subject_interaction`; `start`/`end` as signed `duration` offsets | +| `event_relative_reference` | `time_reference` | dep `reference_event` → `subject_interaction`; `start`/`end` as signed `duration` offsets (metric) | | `epoch_relative_reference` | `time_reference`, `epochid` | dep `element_id` → `element`; `epoch_clock`, `t0`, `start`, `end` | | `epoch_bounded_reference` | `time_reference`, `epochid` | dep `element_id` → `element`; `epoch_clock` (extent = the named epoch) | | `event_bounded_reference` | `time_reference` | dep `bounding_event` → `subject_interaction` | +| `session_relative_reference` | `time_reference` | dep `session_id` → `session`; `relation` enum {before, after, at_start_of, at_end_of, concurrent_with, during} — **ordinal, no metric**; for interactions with neither a device clock nor a wall-clock date (e.g. an awake behavioral test "at the end of the session") | `epoch_clock` is a `char` constrained to the NDI-matlab clocktype set (carried as an advisory `binding` in `constraints`). The former From 2e326889525cf3edca25d8794c668f323cecc3e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 00:08:32 +0000 Subject: [PATCH 07/16] conversions: document session_relative_reference anchor emission in the split specs treatment.md and ontology_table_row.md now describe the implemented anchor: each migrated interaction emits/links a session_relative_reference (relation=during, -> session via base.session_id) instead of a synthesized empty time_reference. Notes the 1->2 (treatment) and 1->N+1 (table, shared anchor) cardinality and that the 1->N engine capability has landed. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../V_epsilon/conversions/from_did_v1/ontology_table_row.md | 4 ++-- schemas/V_epsilon/conversions/from_did_v1/treatment.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md index c8bc937..f323ed1 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md +++ b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md @@ -50,11 +50,11 @@ First match wins, on the row's property term (branch) and value shape. | anatomical qualifier (if any) | `target_structure` | `ontology_term[]`; else `[]` | | row value (+ unit) | `value` on the destination shape block | typed composite (scalar) or bound `ontology_term` (categorical) per shape | | source `subject_id` | inherited `subject_id` | identity, shared by all generated docs | -| source time anchor | inherited `time_reference_#` | shared by all generated docs (the whole row burst is one moment) | +| source time anchor | inherited `time_reference_#` | one **`session_relative_reference`** (`relation: during`, → `session` from `base.session_id`) is emitted and **shared** by all observations from the table (the whole row burst is one session); each obs `time_reference_1` points at it | ## Engine note -This conversion is **1 → N** and so requires the converter to support a migrator that **returns multiple bodies** (the current `+did2.+convert.+migrators.` contract returns one body). The migrator emits one destination document per row, all sharing the source `subject_id` + synthesized `time_reference`, and routes non-observation rows out of tier. See [DID-matlab] `+did2/+convert/` for where the pipeline fans out. Until the 1→N capability lands, this conversion stays `drafted`. +This conversion is **1 → N+1** (N observations + one shared session anchor). The 1→N capability **is implemented**: `did2.convert.v1_to_v2` (under `TargetVersion='V_epsilon'`) routes the class to `+did2.+convert.+migrators_e.ontology_table_row`, which may return a cell of bodies; the dispatcher lands each. The migrator emits one observation per row (each with a fresh `did.ido.unique_id()`), all sharing the source `subject_id` and one `session_relative_reference` anchor, and routes non-observation rows out of tier. ## Worked example — a 2-row intake burst → two observations diff --git a/schemas/V_epsilon/conversions/from_did_v1/treatment.md b/schemas/V_epsilon/conversions/from_did_v1/treatment.md index 4c7a025..42f2d56 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/treatment.md +++ b/schemas/V_epsilon/conversions/from_did_v1/treatment.md @@ -41,7 +41,7 @@ First match wins; resolved against the term's ontology branch, not a string matc | `treatment.numeric_value` | typed `value` **or** companion `scalar_observation` **or** flagged | per dispatch; thermal/pressure/etc. → typed `value`; measured quantity → companion; else flag | | `treatment.string_value` | `notes` (prose) **or** `target_structure` (Dab case) | default prose → `notes`; CURIE/Target-Location → `target_structure` | | `depends_on[subject_id]` | inherited `subject_id` | identity | -| — | inherited `time_reference_#` | **synthesized** from session/epoch metadata (point-in-time for procedures; bounded for regimes/imposed quantities); curator widens | +| — | inherited `time_reference_#` | **emits a `session_relative_reference`** document (`relation: during`, `depends_on session_id → session` from `base.session_id`) and points `time_reference_1` at it. v1 treatment rows have no epoch and (often) no UTC date, so the honest anchor is ordinal-against-the-session; `during` is the universal fallback (the act happened within the session), `at_end_of` reserved for known-terminal cases. Makes the migration **1 → 2**. | | `depends_on[manipulation_id]` | — | **dropped** (stale in v1) | | `depends_on[protocol_id]` | — | **dropped + flagged** for the tier-level `protocol_id` commonality (issue #8 Option C / #10) | From a89140d8779af3bf39bda27c2107c2561a9e5b83 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 14:20:15 +0000 Subject: [PATCH 08/16] V_epsilon: add session_extent (declared/derived session bounds, the daq-less anchor) session_extent (<- base): depends_on session_id -> session; start/end timestamps (UTC, at least one present), grounding enum {declared, epoch_derived, reference_derived, developmental}, is_approximate. Lets a curator say 'the session began/ended at UTC x' for daq-less sessions; the same record is derived from epochs when they exist. session_relative_reference resolves through it (at_start_of->start, at_end_of->end, during->[start,end]), grounding ordinal claims onto UTC. All 103 tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- schemas/V_epsilon/draft/session_extent.json | 82 +++++++++++++++++++++ schemas/V_epsilon/index.json | 11 +++ schemas/V_epsilon/topics.json | 3 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 schemas/V_epsilon/draft/session_extent.json diff --git a/schemas/V_epsilon/draft/session_extent.json b/schemas/V_epsilon/draft/session_extent.json new file mode 100644 index 0000000..ec933f7 --- /dev/null +++ b/schemas/V_epsilon/draft/session_extent.json @@ -0,0 +1,82 @@ +{ + "document_class": { + "class_name": "session_extent", + "class_version": "1.0.0", + "superclasses": [ + { + "class_name": "base" + } + ], + "maturity_level": "draft" + }, + "depends_on": [ + { + "name": "session_id", + "mustBeNonEmpty": true, + "documentation": "The session whose temporal extent this record declares.", + "must_refer_to_document_class": "session" + } + ], + "file": [], + "fields": [ + { + "name": "start", + "type": "timestamp", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "UTC start of the session (optional; at least one of start/end must be present).", + "constraints": {} + }, + { + "name": "end", + "type": "timestamp", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "UTC end of the session (optional; at least one of start/end must be present).", + "constraints": {} + }, + { + "name": "grounding", + "type": "char", + "blank_value": "declared", + "default_value": "declared", + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "How the extent was determined. 'declared' = curator-asserted (e.g. daq-less session); the others are derived/recomputable from the session's evidence.", + "constraints": { + "enum": [ + "declared", + "epoch_derived", + "reference_derived", + "developmental" + ] + } + }, + { + "name": "is_approximate", + "type": "boolean", + "blank_value": false, + "default_value": false, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Binary precision tier for the declared/derived bounds.", + "constraints": {} + } + ] +} diff --git a/schemas/V_epsilon/index.json b/schemas/V_epsilon/index.json index 730b323..346a074 100644 --- a/schemas/V_epsilon/index.json +++ b/schemas/V_epsilon/index.json @@ -1799,6 +1799,17 @@ "path": "schemas/V_epsilon/stable/session.json", "is_meta": false }, + { + "class_name": "session_extent", + "tier": "draft", + "class_version": "1.0.0", + "maturity_level": "draft", + "superclasses": [ + "base" + ], + "path": "schemas/V_epsilon/draft/session_extent.json", + "is_meta": false + }, { "class_name": "session_in_a_dataset", "tier": "stable", diff --git a/schemas/V_epsilon/topics.json b/schemas/V_epsilon/topics.json index 4da27ba..f4c2d86 100644 --- a/schemas/V_epsilon/topics.json +++ b/schemas/V_epsilon/topics.json @@ -282,7 +282,8 @@ "dataset_session_info", "projectvar", "session", - "session_in_a_dataset" + "session_in_a_dataset", + "session_extent" ] }, { From 3be7a32b15a72392125e804b42be355da6839f54 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 14:22:50 +0000 Subject: [PATCH 09/16] conversions: note real ontology_table_row v1 layout (char fields) + fallback Discovery showed the dominant form is parallel char fields (names/ variable_names/ontology_nodes/data), not a rows array; migrator falls back to migrating unchanged as ontology_table_row pending the per-row split. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../V_epsilon/conversions/from_did_v1/ontology_table_row.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md index f323ed1..04ce660 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md +++ b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md @@ -103,6 +103,10 @@ This conversion is **1 → N+1** (N observations + one shared session anchor). T ] ``` +## Real v1 row layout (follow-up) + +Corpus discovery showed the dominant `ontology_table_row` form is **not** a `rows` array but **parallel char fields** (`names`, `variable_names`, `ontology_nodes`, `data`). The migrator currently parses the `rows`/single-row shapes and, for the char-field layout it doesn't yet split, **falls back to migrating the document unchanged** as an `ontology_table_row` (the class still exists in V_epsilon, so it validates) rather than quarantining. Parsing the `names`/`variable_names`/`ontology_nodes`/`data` layout into per-row observations is the remaining work. + ## Open questions - **Per-term dispatch table** — the property-term → property-class map is finalized in discovery mode against real corpora (the same report-only loop as `treatment`). Terms with no minted class fall to the generic escape hatches. From 09db7908bb565e026873d2761d411e6cb747e409 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 14:48:25 +0000 Subject: [PATCH 10/16] conversions: ontology_table_row char-field split now implemented (per-column observations) Update the spec note from 'follow-up' to 'implemented': the parallel char-field layout (names/variable_names/ontology_nodes/data) splits one row into per-column observations; unrecognised layouts still fall back to migrating unchanged. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../V_epsilon/conversions/from_did_v1/ontology_table_row.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md index 04ce660..0ed2d5e 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md +++ b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md @@ -103,9 +103,9 @@ This conversion is **1 → N+1** (N observations + one shared session anchor). T ] ``` -## Real v1 row layout (follow-up) +## Real v1 row layout (implemented) -Corpus discovery showed the dominant `ontology_table_row` form is **not** a `rows` array but **parallel char fields** (`names`, `variable_names`, `ontology_nodes`, `data`). The migrator currently parses the `rows`/single-row shapes and, for the char-field layout it doesn't yet split, **falls back to migrating the document unchanged** as an `ontology_table_row` (the class still exists in V_epsilon, so it validates) rather than quarantining. Parsing the `names`/`variable_names`/`ontology_nodes`/`data` layout into per-row observations is the remaining work. +The dominant `ontology_table_row` form is **parallel char fields** — comma-separated `names`, `variable_names`, `ontology_nodes` plus a `data` struct keyed by `variable_names`. One document is one table **row**; each **column** is a measured property. The migrator splits it accordingly: column *i* → one observation (`measured_property` = `ontology_nodes[i]` + `names[i]`; value = `data.(variable_names[i])`), dispatched scalar-vs-categorical on the value type. Columns with no usable value (missing key, empty, `NaN`) are skipped. Anything whose layout still isn't recognised falls back to migrating unchanged as an `ontology_table_row` (the class exists in V_epsilon) rather than quarantining. ## Open questions From ef9c452320e1c142f84a014e8a7e97b351100764 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 11:11:16 +0000 Subject: [PATCH 11/16] V_epsilon: flatten categorical value onto the concrete observation block The dominant V_epsilon corpus quarantine (~47K docs: 41,095 JH + 6,205 Dab) was "Required field categorical_concept.value is missing". Root cause: categorical_concept (the shape mixin) declared a required `value` in its own block, but the overrider classes (developmental_stage_ observation, generic_categorical_observation) re-declared their own `value`, so a migrated doc filled the concrete block and left the inherited categorical_concept.value empty. Resolve by flattening: categorical_concept.value now declares placement: concrete_class, so `value` lives in each categorical observation's OWN block and categorical_concept contributes no block. The two re-declared `value` fields are removed (one value per concrete class, no same-block name collision). developmental_stage_observation's UBERON:0000105 root is now a documented convention rather than a schema-enforced binding (the trade-off of the flatten approach). Docs updated to match: from_did_v1/ontology_table_row.md and V_epsilon_SPEC.md. All 103 schema tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../from_did_v1/ontology_table_row.md | 4 +-- .../V_epsilon/draft/categorical_concept.json | 3 +- .../developmental_stage_observation.json | 30 +------------------ .../generic_categorical_observation.json | 22 +------------- schemas/V_epsilon_SPEC.md | 12 ++++++-- 5 files changed, 15 insertions(+), 56 deletions(-) diff --git a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md index 0ed2d5e..9a91c17 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md +++ b/schemas/V_epsilon/conversions/from_did_v1/ontology_table_row.md @@ -35,7 +35,7 @@ First match wins, on the row's property term (branch) and value shape. | Concentration (glucose, cortisol, titer) | `concentration_observation` (`scalar_concentration`) | | | Voltage (transcribed Vm) | `membrane_potential_observation` (`scalar_voltage`) | | | **Scalar with no minted property class** | `generic_scalar_observation` (`generic_scalar`) | value → `{source_unit, source_value, approximate}`; promote later | -| Categorical: developmental/life stage | `developmental_stage_observation` (bound under `UBERON:0000105`) | term → `value`; property → `measured_property` | +| Categorical: developmental/life stage | `developmental_stage_observation` (life/developmental stage under `UBERON:0000105`, by convention — not schema-enforced) | term → `value`; property → `measured_property` | | Categorical: health status / coat / estrous / behavioral label | `health_status_observation` / `pigmentation_observation` / `estrous_stage_observation` / `behavioral_phenotype_observation` | term → `value` | | **Categorical with no minted property class** | `generic_categorical_observation` (free `ontology_term`, no binding) | term → `value`; promote later | | **Subject-intrinsic, set-once** (species, strain, sex, DOB) | **out of tier** → `subject` / `openminds_subject` (merge) | not an observation | @@ -48,7 +48,7 @@ First match wins, on the row's property term (branch) and value shape. |---|---|---| | row property term | `measured_property` (inherited from `observation`) | `ontology_term` | | anatomical qualifier (if any) | `target_structure` | `ontology_term[]`; else `[]` | -| row value (+ unit) | `value` on the destination shape block | typed composite (scalar) or bound `ontology_term` (categorical) per shape | +| row value (+ unit) | `value` on the destination block | scalar: typed composite in the shape-mixin block (`scalar_mass`, …). categorical: bound `ontology_term` in the **concrete class's own block** (`categorical_concept.value` has `placement: concrete_class`, so `categorical_concept` contributes no block) | | source `subject_id` | inherited `subject_id` | identity, shared by all generated docs | | source time anchor | inherited `time_reference_#` | one **`session_relative_reference`** (`relation: during`, → `session` from `base.session_id`) is emitted and **shared** by all observations from the table (the whole row burst is one session); each obs `time_reference_1` points at it | diff --git a/schemas/V_epsilon/draft/categorical_concept.json b/schemas/V_epsilon/draft/categorical_concept.json index a48e68e..70708da 100644 --- a/schemas/V_epsilon/draft/categorical_concept.json +++ b/schemas/V_epsilon/draft/categorical_concept.json @@ -16,6 +16,7 @@ { "name": "value", "type": "ontology_term", + "placement": "concrete_class", "blank_value": { "node": "", "name": "" @@ -29,7 +30,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A bound concept value (shape-library mixin); admissible terms governed by the binding registry keyed on measured_property.", + "documentation": "A bound concept value (shape-library mixin). Placed on the concrete observation class's block (placement: concrete_class), so each categorical observation carries `value` in its own block and categorical_concept contributes no block. Admissible terms governed by the binding registry keyed on measured_property.", "constraints": { "binding": { "keyed_by": "measured_property", diff --git a/schemas/V_epsilon/draft/developmental_stage_observation.json b/schemas/V_epsilon/draft/developmental_stage_observation.json index a837f6d..6c78282 100644 --- a/schemas/V_epsilon/draft/developmental_stage_observation.json +++ b/schemas/V_epsilon/draft/developmental_stage_observation.json @@ -14,33 +14,5 @@ }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "ontology_term", - "blank_value": { - "node": "", - "name": "" - }, - "default_value": { - "node": "", - "name": "" - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Observed developmental / life-cycle stage; value is a bound concept under UBERON:0000105 (life cycle stage) and its species-specific descendants (FBdv, ZFS, HsapDv, ...).", - "constraints": { - "binding": { - "root": "UBERON:0000105", - "expansion": "self_and_descendants", - "node_kind": "class", - "strength": "preferred", - "source": "ontology" - } - } - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/generic_categorical_observation.json b/schemas/V_epsilon/draft/generic_categorical_observation.json index 7443d78..80850f4 100644 --- a/schemas/V_epsilon/draft/generic_categorical_observation.json +++ b/schemas/V_epsilon/draft/generic_categorical_observation.json @@ -14,25 +14,5 @@ }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "ontology_term", - "blank_value": { - "node": "", - "name": "" - }, - "default_value": { - "node": "", - "name": "" - }, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Escape hatch for an observed categorical property with no minted class yet; value is a free ontology_term (no binding).", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon_SPEC.md b/schemas/V_epsilon_SPEC.md index 85e2745..28e4af6 100644 --- a/schemas/V_epsilon_SPEC.md +++ b/schemas/V_epsilon_SPEC.md @@ -117,7 +117,12 @@ two epoch reference classes. the observation that reads it and the manipulation that imposes it (e.g. `scalar_temperature` ← `core_temperature_observation` *and* `temperature_manipulation`), so `value` is defined once and - `isa scalar_temperature` sweeps both tiers. + `isa scalar_temperature` sweeps both tiers. The scalar mixins host `value` in + their own block (default placement). `categorical_concept` is the one + exception: its `value` declares `placement: concrete_class`, so each + categorical observation carries `value` in its **own** block and + `categorical_concept` contributes no block — this keeps a single `value` per + concrete class even when a class wants to narrow the term's admissible root. - `scalar_observation` (abstract genus, ← `observation`) — shape is only an `isa` umbrella; the concrete classes under it are named by the **property observed** (Brainstorm E) and acquire their typed `value` by also inheriting @@ -133,8 +138,9 @@ two epoch reference classes. (← `generic_scalar`). - `categorical_observation` (abstract genus, ← `observation`): concrete classes named by the **property observed**, each with an `ontology_term` `value` - governed by the binding registry — `developmental_stage_observation` (pinned - root `UBERON:0000105`), `health_status_observation`, + governed by the binding registry — `developmental_stage_observation` (life / + developmental stage under `UBERON:0000105`, by convention), + `health_status_observation`, `behavioral_phenotype_observation`, `pigmentation_observation`, `estrous_stage_observation`, plus the escape hatch `generic_categorical_observation` (free `ontology_term`, no binding). From 0ed6a6a200ef16d3ed5aff21c572bf5b97189037 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 13:17:12 +0000 Subject: [PATCH 12/16] V_epsilon: document subject_group -> subject(is_group) conversion subject_group is deprecated in V_epsilon and folds into the subject tier (subject with is_group: true; membership becomes group_assignment events assembled in the NDI layer). Add the conversion doc and index row; the migrator lands in DID-matlab. No schema JSON change (subject.is_group and group_assignment already exist). 103 schema tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../conversions/from_did_v1/_index.md | 1 + .../conversions/from_did_v1/subject_group.md | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 schemas/V_epsilon/conversions/from_did_v1/subject_group.md diff --git a/schemas/V_epsilon/conversions/from_did_v1/_index.md b/schemas/V_epsilon/conversions/from_did_v1/_index.md index 06055e4..9ba9ede 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/_index.md +++ b/schemas/V_epsilon/conversions/from_did_v1/_index.md @@ -47,6 +47,7 @@ field-level changes on top. | `treatment` | legacy NDI/DID `treatment` (V_alpha shape) | drafted | [treatment.md](treatment.md) | | `treatment` → manipulation tiers (Brainstorm E **split**) | legacy `treatment` → `injection`/`bath`/`procedural_manipulation`/`temperature_manipulation`/`environmental_manipulation` (+ out-of-tier) | drafted | [treatment.md](treatment.md) | | `ontology_table_row` → observation tiers (Brainstorm E **split**, 1→N) | legacy `ontology_table_row` → scalar/categorical observation property classes (+ out-of-tier) | drafted | [ontology_table_row.md](ontology_table_row.md) | +| `subject_group` → `subject` (`is_group`) (Brainstorm E **fold**) | legacy `subject_group` → `subject` flagged `is_group` (+ `group_assignment` in NDI layer) | drafted | [subject_group.md](subject_group.md) | | `ontology_image` | legacy NDI/DID `ontologyImage` (V_alpha shape) | drafted | [ontology_image.md](ontology_image.md) | | `ontology_label` | legacy NDI/DID `ontologyLabel` (V_alpha shape) | drafted | [ontology_label.md](ontology_label.md) | diff --git a/schemas/V_epsilon/conversions/from_did_v1/subject_group.md b/schemas/V_epsilon/conversions/from_did_v1/subject_group.md new file mode 100644 index 0000000..e034204 --- /dev/null +++ b/schemas/V_epsilon/conversions/from_did_v1/subject_group.md @@ -0,0 +1,38 @@ +# `subject_group` → `subject` (`is_group: true`) [Brainstorm E] + +Status: **drafted** + +`subject_group` is **deprecated** in V_epsilon (see `V_epsilon_SPEC.md`, +"Deprecated / folded" table). A group of subjects is modeled as a +`subject` flagged `is_group: true`, and membership becomes +`group_assignment` events. + +## Mapping (per document, 1 → 1) + +| did_v1 `subject_group` | V_epsilon `subject` | Transformation | +|---|---|---| +| (class) `subject_group` | (class) `subject`, `is_group: true` | class fold | +| `subject_group.group_name` (optional; absent in v1 corpus) | `subject.local_identifier` | char copy | +| `subject_group.description` (optional) | `subject.description` | char copy | +| — | `subject.is_biological` | `false` (a group is not a biological individual) | +| `base.*` | `base.*` | carried unchanged (same document id) | + +The legacy `subject_group` document is an (essentially empty) marker; it +carries **no members** — membership is expressed by member subjects +referencing the group. So the per-document migration produces only the +group `subject`. + +## Membership → `group_assignment` (relational, NDI layer) + +The member→group edges become `group_assignment` events. Those are +**relational**: they require the member subjects that point at this group, +which a single `subject_group` document does not carry. They are therefore +assembled in the NDI layer (`ndi.migrate.local`), the same boundary used +for `stimulus_bath → bath`, not manufactured here. This per-document +migrator emits the group `subject` only; the assignments are a follow-up. + +## Engine + +Routed by `did2.convert.v1_to_v2` under `TargetVersion='V_epsilon'` to +`+did2/+convert/+migrators_e/subject_group.m`. A 1 → 1 fold; the default +`V_delta` target is unaffected (it keeps `subject_group` as-is). From 0b978dc71081d997570b4bdec8b7e24296a06868 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 13:32:13 +0000 Subject: [PATCH 13/16] V_epsilon: roll out series-as-cardinality to the scalar shape library Step 2 of Series_As_Cardinality_Proposal.md (accepted). Every scalar shape mixin's `value` is now an array of its composite (mustBeScalar: false) -- a single reading is the length-1 case, a curve is length N of the same class -- and the scalar_observation / scalar_manipulation genera carry a parallel, element-aligned `sample_time` array (optional; absent => single reading at the anchor). core_temperature_observation no longer overrides value/sample_time; it inherits the cardinality form from scalar_temperature / scalar_observation like every other scalar property class. This also clears the JH corpus quarantine "core_temperature_observation.value missing" (691): value now lives in the inherited scalar_temperature block that the migrator already fills, and mustBeScalar:false is strictly more permissive, so a single reading validates as the length-1 case (same scalar-struct-is-length-1 convention target_structure already uses -- no migrator change needed). Updates: 13 scalar mixins, scalar_observation/scalar_manipulation, core_temperature_observation (override removed), the worked example (value -> scalar_temperature block, sample_time -> scalar_observation block), test_series_cardinality.py (assert the mixin-level array shape), and V_epsilon_SPEC.md. 104 schema tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../draft/core_temperature_observation.json | 43 +--------- schemas/V_epsilon/draft/generic_scalar.json | 10 ++- .../V_epsilon/draft/scalar_concentration.json | 22 +++-- schemas/V_epsilon/draft/scalar_count.json | 31 +++---- schemas/V_epsilon/draft/scalar_current.json | 22 +++-- schemas/V_epsilon/draft/scalar_duration.json | 22 +++-- schemas/V_epsilon/draft/scalar_frequency.json | 22 +++-- schemas/V_epsilon/draft/scalar_length.json | 22 +++-- .../V_epsilon/draft/scalar_manipulation.json | 13 +++ schemas/V_epsilon/draft/scalar_mass.json | 22 +++-- .../V_epsilon/draft/scalar_observation.json | 16 +++- schemas/V_epsilon/draft/scalar_pressure.json | 22 +++-- schemas/V_epsilon/draft/scalar_score.json | 37 ++++---- .../V_epsilon/draft/scalar_temperature.json | 22 +++-- schemas/V_epsilon/draft/scalar_voltage.json | 22 +++-- schemas/V_epsilon/draft/scalar_volume.json | 22 +++-- .../core_temperature_observation_series.json | 14 +-- schemas/V_epsilon_SPEC.md | 13 ++- tests/test_series_cardinality.py | 85 ++++++++++++------- 19 files changed, 235 insertions(+), 247 deletions(-) diff --git a/schemas/V_epsilon/draft/core_temperature_observation.json b/schemas/V_epsilon/draft/core_temperature_observation.json index b0412eb..5c510ae 100644 --- a/schemas/V_epsilon/draft/core_temperature_observation.json +++ b/schemas/V_epsilon/draft/core_temperature_observation.json @@ -14,46 +14,5 @@ }, "depends_on": [], "file": [], - "fields": [ - { - "name": "value", - "type": "temperature", - "blank_value": [], - "default_value": [ - { - "approximate": false, - "source_unit": "", - "source_value": 0.0, - "celsius": 0.0 - } - ], - "mustBeNonEmpty": true, - "mustBeScalar": false, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Series-as-cardinality (Brainstorm E Part 2): an array of the temperature shape composite. A single reading is the length-1 case; a curve is length N. Element-aligned with sample_time. value[i] observed at time_reference + sample_time[i].", - "constraints": {} - }, - { - "name": "sample_time", - "type": "duration", - "blank_value": [], - "default_value": [ - { - "approximate": false, - "source_unit": "", - "source_value": 0.0, - "seconds": 0.0 - } - ], - "mustBeNonEmpty": true, - "mustBeScalar": false, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "Per-sample time offsets from the anchoring time_reference, as an array of the duration composite, element-aligned with value (len(sample_time) == len(value); enforced as a consumer/tooling check). For a single reading, a length-1 array with offset 0.", - "constraints": {} - } - ] + "fields": [] } diff --git a/schemas/V_epsilon/draft/generic_scalar.json b/schemas/V_epsilon/draft/generic_scalar.json index 4947a30..9da8a8a 100644 --- a/schemas/V_epsilon/draft/generic_scalar.json +++ b/schemas/V_epsilon/draft/generic_scalar.json @@ -16,14 +16,16 @@ { "name": "value", "type": "structure", - "blank_value": {}, - "default_value": {}, + "blank_value": [], + "default_value": [ + {} + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "Escape-hatch scalar value (shape-library mixin): source_unit/source_value only, no canonical.", + "documentation": "Escape-hatch scalar value (shape-library mixin): source_unit/source_value only, no canonical. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {}, "fields": [ { diff --git a/schemas/V_epsilon/draft/scalar_concentration.json b/schemas/V_epsilon/draft/scalar_concentration.json index fd99b03..3f38948 100644 --- a/schemas/V_epsilon/draft/scalar_concentration.json +++ b/schemas/V_epsilon/draft/scalar_concentration.json @@ -16,22 +16,20 @@ { "name": "value", "type": "concentration", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed concentration value (shape-library mixin). Identity classes that read or impose a concentration inherit this `value`.", + "documentation": "A typed concentration value (shape-library mixin). Identity classes that read or impose a concentration inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_count.json b/schemas/V_epsilon/draft/scalar_count.json index b976c94..0ff8cff 100644 --- a/schemas/V_epsilon/draft/scalar_count.json +++ b/schemas/V_epsilon/draft/scalar_count.json @@ -16,28 +16,23 @@ { "name": "value", "type": "count", - "blank_value": { - "value": 0, - "unit": { - "node": "", - "name": "" - }, - "approximate": false - }, - "default_value": { - "value": 0, - "unit": { - "node": "", - "name": "" - }, - "approximate": false - }, + "blank_value": [], + "default_value": [ + { + "value": 0, + "unit": { + "node": "", + "name": "" + }, + "approximate": false + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed count value (shape-library mixin); value.unit names what is counted.", + "documentation": "A typed count value (shape-library mixin); value.unit names what is counted. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_current.json b/schemas/V_epsilon/draft/scalar_current.json index 35e3976..ac89218 100644 --- a/schemas/V_epsilon/draft/scalar_current.json +++ b/schemas/V_epsilon/draft/scalar_current.json @@ -16,22 +16,20 @@ { "name": "value", "type": "current", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed current value (shape-library mixin). Identity classes that read or impose a current inherit this `value`.", + "documentation": "A typed current value (shape-library mixin). Identity classes that read or impose a current inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_duration.json b/schemas/V_epsilon/draft/scalar_duration.json index 4933133..fbedc7b 100644 --- a/schemas/V_epsilon/draft/scalar_duration.json +++ b/schemas/V_epsilon/draft/scalar_duration.json @@ -16,22 +16,20 @@ { "name": "value", "type": "duration", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed duration value (shape-library mixin). Identity classes that read or impose a duration inherit this `value`.", + "documentation": "A typed duration value (shape-library mixin). Identity classes that read or impose a duration inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_frequency.json b/schemas/V_epsilon/draft/scalar_frequency.json index b249f35..e2a5de2 100644 --- a/schemas/V_epsilon/draft/scalar_frequency.json +++ b/schemas/V_epsilon/draft/scalar_frequency.json @@ -16,22 +16,20 @@ { "name": "value", "type": "frequency", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed frequency value (shape-library mixin). Identity classes that read or impose a frequency inherit this `value`.", + "documentation": "A typed frequency value (shape-library mixin). Identity classes that read or impose a frequency inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_length.json b/schemas/V_epsilon/draft/scalar_length.json index 87b77b9..524830a 100644 --- a/schemas/V_epsilon/draft/scalar_length.json +++ b/schemas/V_epsilon/draft/scalar_length.json @@ -16,22 +16,20 @@ { "name": "value", "type": "length", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed length value (shape-library mixin). Identity classes that read or impose a length inherit this `value`.", + "documentation": "A typed length value (shape-library mixin). Identity classes that read or impose a length inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_manipulation.json b/schemas/V_epsilon/draft/scalar_manipulation.json index 5c7b9b0..0d13590 100644 --- a/schemas/V_epsilon/draft/scalar_manipulation.json +++ b/schemas/V_epsilon/draft/scalar_manipulation.json @@ -59,6 +59,19 @@ "constraints": { "maxLength": 4096 } + }, + { + "name": "sample_time", + "type": "duration", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Per-sample time offsets from the anchoring time_reference, as an ARRAY of the duration composite, element-aligned with the shape value (len(sample_time) == len(value); enforced as a consumer/tooling check, Series-as-cardinality D3). Empty/absent => a single reading at the anchor (the length-1, offset-0 case).", + "constraints": {} } ] } diff --git a/schemas/V_epsilon/draft/scalar_mass.json b/schemas/V_epsilon/draft/scalar_mass.json index 9c6ebad..f5e397b 100644 --- a/schemas/V_epsilon/draft/scalar_mass.json +++ b/schemas/V_epsilon/draft/scalar_mass.json @@ -16,22 +16,20 @@ { "name": "value", "type": "mass", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed mass value (shape-library mixin). Identity classes that read or impose a mass inherit this `value`.", + "documentation": "A typed mass value (shape-library mixin). Identity classes that read or impose a mass inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_observation.json b/schemas/V_epsilon/draft/scalar_observation.json index 4d0c204..c0c9295 100644 --- a/schemas/V_epsilon/draft/scalar_observation.json +++ b/schemas/V_epsilon/draft/scalar_observation.json @@ -12,5 +12,19 @@ }, "depends_on": [], "file": [], - "fields": [] + "fields": [ + { + "name": "sample_time", + "type": "duration", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Per-sample time offsets from the anchoring time_reference, as an ARRAY of the duration composite, element-aligned with the shape value (len(sample_time) == len(value); enforced as a consumer/tooling check, Series-as-cardinality D3). Empty/absent => a single reading at the anchor (the length-1, offset-0 case).", + "constraints": {} + } + ] } diff --git a/schemas/V_epsilon/draft/scalar_pressure.json b/schemas/V_epsilon/draft/scalar_pressure.json index 2d5acf2..084389f 100644 --- a/schemas/V_epsilon/draft/scalar_pressure.json +++ b/schemas/V_epsilon/draft/scalar_pressure.json @@ -16,22 +16,20 @@ { "name": "value", "type": "pressure", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed pressure value (shape-library mixin). Identity classes that read or impose a pressure inherit this `value`.", + "documentation": "A typed pressure value (shape-library mixin). Identity classes that read or impose a pressure inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_score.json b/schemas/V_epsilon/draft/scalar_score.json index 4165f35..4d37e61 100644 --- a/schemas/V_epsilon/draft/scalar_score.json +++ b/schemas/V_epsilon/draft/scalar_score.json @@ -16,32 +16,25 @@ { "name": "value", "type": "score", - "blank_value": { - "value": 0.0, - "scale": { - "node": "", - "name": "" - }, - "scale_min": 0.0, - "scale_max": 0.0, - "approximate": false - }, - "default_value": { - "value": 0.0, - "scale": { - "node": "", - "name": "" - }, - "scale_min": 0.0, - "scale_max": 0.0, - "approximate": false - }, + "blank_value": [], + "default_value": [ + { + "value": 0.0, + "scale": { + "node": "", + "name": "" + }, + "scale_min": 0.0, + "scale_max": 0.0, + "approximate": false + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed score value (shape-library mixin); value.scale names the rubric.", + "documentation": "A typed score value (shape-library mixin); value.scale names the rubric. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_temperature.json b/schemas/V_epsilon/draft/scalar_temperature.json index 8cd966c..a0e03f6 100644 --- a/schemas/V_epsilon/draft/scalar_temperature.json +++ b/schemas/V_epsilon/draft/scalar_temperature.json @@ -16,22 +16,20 @@ { "name": "value", "type": "temperature", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed temperature value (shape-library mixin). Identity classes that read or impose a temperature inherit this `value`.", + "documentation": "A typed temperature value (shape-library mixin). Identity classes that read or impose a temperature inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_voltage.json b/schemas/V_epsilon/draft/scalar_voltage.json index 3f2b635..669f0c9 100644 --- a/schemas/V_epsilon/draft/scalar_voltage.json +++ b/schemas/V_epsilon/draft/scalar_voltage.json @@ -16,22 +16,20 @@ { "name": "value", "type": "voltage", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed voltage value (shape-library mixin). Identity classes that read or impose a voltage inherit this `value`.", + "documentation": "A typed voltage value (shape-library mixin). Identity classes that read or impose a voltage inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/draft/scalar_volume.json b/schemas/V_epsilon/draft/scalar_volume.json index 2d5bb0a..8c484c8 100644 --- a/schemas/V_epsilon/draft/scalar_volume.json +++ b/schemas/V_epsilon/draft/scalar_volume.json @@ -16,22 +16,20 @@ { "name": "value", "type": "volume", - "blank_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, - "default_value": { - "approximate": false, - "source_unit": "", - "source_value": 0.0 - }, + "blank_value": [], + "default_value": [ + { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + } + ], "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "A typed volume value (shape-library mixin). Identity classes that read or impose a volume inherit this `value`.", + "documentation": "A typed volume value (shape-library mixin). Identity classes that read or impose a volume inherit this `value`. Series-as-cardinality (Brainstorm E Part 2): an ARRAY of the composite; a single reading is the length-1 case, element-aligned with scalar_observation.sample_time.", "constraints": {} } ] diff --git a/schemas/V_epsilon/examples/core_temperature_observation_series.json b/schemas/V_epsilon/examples/core_temperature_observation_series.json index 5300f00..a327bce 100644 --- a/schemas/V_epsilon/examples/core_temperature_observation_series.json +++ b/schemas/V_epsilon/examples/core_temperature_observation_series.json @@ -21,16 +21,18 @@ "measured_property": { "node": "ncit:C174446", "name": "core body temperature" }, "target_structure": [] }, - "core_temperature_observation": { - "value": [ - { "celsius": 37.1, "source_unit": "°C", "source_value": 37.1, "approximate": false }, - { "celsius": 36.4, "source_unit": "°C", "source_value": 36.4, "approximate": false }, - { "celsius": 35.0, "source_unit": "°C", "source_value": 35.0, "approximate": false } - ], + "scalar_observation": { "sample_time": [ { "seconds": 0, "source_unit": "min", "source_value": 0, "approximate": false }, { "seconds": 600, "source_unit": "min", "source_value": 10, "approximate": false }, { "seconds": 1200, "source_unit": "min", "source_value": 20, "approximate": false } ] + }, + "scalar_temperature": { + "value": [ + { "celsius": 37.1, "source_unit": "°C", "source_value": 37.1, "approximate": false }, + { "celsius": 36.4, "source_unit": "°C", "source_value": 36.4, "approximate": false }, + { "celsius": 35.0, "source_unit": "°C", "source_value": 35.0, "approximate": false } + ] } } diff --git a/schemas/V_epsilon_SPEC.md b/schemas/V_epsilon_SPEC.md index 28e4af6..da060fc 100644 --- a/schemas/V_epsilon_SPEC.md +++ b/schemas/V_epsilon_SPEC.md @@ -118,9 +118,16 @@ two epoch reference classes. `scalar_temperature` ← `core_temperature_observation` *and* `temperature_manipulation`), so `value` is defined once and `isa scalar_temperature` sweeps both tiers. The scalar mixins host `value` in - their own block (default placement). `categorical_concept` is the one - exception: its `value` declares `placement: concrete_class`, so each - categorical observation carries `value` in its **own** block and + their own block (default placement). **Series-as-cardinality (Part 2, rolled + out):** every scalar mixin's `value` is an **array** of its composite + (`mustBeScalar: false`) — a single reading is the length-1 case, a curve is + length N of the *same* class — and the `scalar_observation` / + `scalar_manipulation` genera carry a parallel `sample_time` array (offsets + from the anchoring `time_reference`, element-aligned with `value`; the + `len(value) == len(sample_time)` invariant is a consumer/tooling check, not a + meta-schema keyword). `categorical_concept` is the one + exception to the hosting rule: its `value` declares `placement: concrete_class`, + so each categorical observation carries `value` in its **own** block and `categorical_concept` contributes no block — this keeps a single `value` per concrete class even when a class wants to narrow the term's admissible root. - `scalar_observation` (abstract genus, ← `observation`) — shape is only an diff --git a/tests/test_series_cardinality.py b/tests/test_series_cardinality.py index 3965ec2..593543b 100644 --- a/tests/test_series_cardinality.py +++ b/tests/test_series_cardinality.py @@ -1,11 +1,16 @@ -"""Series-as-cardinality prototype tests (Brainstorm E, Part 2). - -Exercises the prototype on `core_temperature_observation`: -- the schema declares `value` and `sample_time` as arrays (mustBeScalar: false) - of typed composites (D1/D4), and -- the worked example document satisfies the element-aligned-length invariant - `len(value) == len(sample_time)` (D3) — which JSON Schema cannot express on a - single field, so it ships here as the consumer/tooling check. +"""Series-as-cardinality tests (Brainstorm E, Part 2). + +After the step-2 rollout, series-as-cardinality is a property of the SHAPE +MIXINS, not a single prototype class: +- every scalar shape mixin (`scalar_temperature`, `scalar_mass`, ...) declares + `value` as an array of typed composites (mustBeScalar: false, D1/D4), and +- the `scalar_observation` / `scalar_manipulation` genera carry the parallel + `sample_time` array. +So a concrete class like `core_temperature_observation` inherits the +cardinality form (its own `fields` are empty); a single reading is the length-1 +case. The element-aligned-length invariant `len(value) == len(sample_time)` +(D3) is a consumer/tooling check (JSON Schema cannot express it on one field), +shipped here. See Series_As_Cardinality_Proposal.md for the design. """ @@ -18,6 +23,13 @@ EXAMPLES = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "examples") EXAMPLE_DOC = os.path.join(EXAMPLES, "core_temperature_observation_series.json") +SCALAR_MIXINS = [ + "scalar_mass", "scalar_length", "scalar_duration", "scalar_volume", + "scalar_temperature", "scalar_pressure", "scalar_frequency", "scalar_voltage", + "scalar_current", "scalar_concentration", "scalar_count", "scalar_score", + "generic_scalar", +] + def _load(path): with open(path) as f: @@ -31,12 +43,14 @@ def _field(schema, name): return None -def check_series_lengths(doc, value_path=("core_temperature_observation", "value"), - time_path=("core_temperature_observation", "sample_time")): +def check_series_lengths(doc, value_path=("scalar_temperature", "value"), + time_path=("scalar_observation", "sample_time")): """Consumer/tooling check for D3: the per-sample arrays are element-aligned. Returns a list of error strings (empty == valid). This is the validator - JSON Schema cannot express, because it spans two fields. + JSON Schema cannot express, because it spans two fields. sample_time is + optional (a single reading may omit it); the length check applies only + when it is present. """ errors = [] vblock, vname = value_path @@ -45,10 +59,10 @@ def check_series_lengths(doc, value_path=("core_temperature_observation", "value sample_time = doc.get(tblock, {}).get(tname) if not isinstance(value, list): errors.append(f"{vblock}.{vname} must be an array (series-as-cardinality)") - if not isinstance(sample_time, list): - errors.append(f"{tblock}.{tname} must be an array (series-as-cardinality)") - if isinstance(value, list) and isinstance(sample_time, list): - if len(value) != len(sample_time): + if sample_time is not None: + if not isinstance(sample_time, list): + errors.append(f"{tblock}.{tname} must be an array (series-as-cardinality)") + elif isinstance(value, list) and len(value) != len(sample_time): errors.append( f"len({vname})={len(value)} != len({tname})={len(sample_time)} " "(arrays must be element-aligned)" @@ -57,19 +71,28 @@ def check_series_lengths(doc, value_path=("core_temperature_observation", "value class TestSeriesSchema: - def test_value_is_array_of_temperature(self): - schema = _load(os.path.join(DRAFT, "core_temperature_observation.json")) - value = _field(schema, "value") - assert value is not None, "core_temperature_observation must declare value" - assert value["type"] == "temperature" - assert value["mustBeScalar"] is False, "value must be an array (cardinality)" - - def test_sample_time_is_array_of_duration(self): + def test_every_scalar_mixin_value_is_an_array(self): + for m in SCALAR_MIXINS: + schema = _load(os.path.join(DRAFT, m + ".json")) + value = _field(schema, "value") + assert value is not None, f"{m} must declare value" + assert value["mustBeScalar"] is False, \ + f"{m}.value must be an array (series-as-cardinality)" + + def test_sample_time_is_array_of_duration_on_genus(self): + for genus in ("scalar_observation", "scalar_manipulation"): + schema = _load(os.path.join(DRAFT, genus + ".json")) + st = _field(schema, "sample_time") + assert st is not None, f"{genus} must declare sample_time" + assert st["type"] == "duration" + assert st["mustBeScalar"] is False, "sample_time must be an array" + + def test_concrete_temperature_class_inherits_the_shape(self): + # The concrete property class no longer overrides value/sample_time; + # it inherits the array form from scalar_temperature / scalar_observation. schema = _load(os.path.join(DRAFT, "core_temperature_observation.json")) - st = _field(schema, "sample_time") - assert st is not None, "core_temperature_observation must declare sample_time" - assert st["type"] == "duration" - assert st["mustBeScalar"] is False, "sample_time must be an array (cardinality)" + assert _field(schema, "value") is None + assert _field(schema, "sample_time") is None class TestSeriesExampleDocument: @@ -79,7 +102,7 @@ def test_example_exists_and_parses(self): def test_example_is_array_of_structures(self): doc = _load(EXAMPLE_DOC) - value = doc["core_temperature_observation"]["value"] + value = doc["scalar_temperature"]["value"] assert isinstance(value, list) and len(value) >= 1 for sample in value: assert isinstance(sample, dict) and "celsius" in sample, ( @@ -93,13 +116,13 @@ def test_example_satisfies_length_invariant(self): def test_length_mismatch_is_caught(self): doc = _load(EXAMPLE_DOC) - doc["core_temperature_observation"]["sample_time"].pop() # break alignment + doc["scalar_observation"]["sample_time"].pop() # break alignment errors = check_series_lengths(doc) assert errors and "element-aligned" in errors[0] def test_single_reading_is_cardinality_one(self): """A spot reading is the length-1 case of the same class.""" doc = _load(EXAMPLE_DOC) - doc["core_temperature_observation"]["value"] = [{"celsius": 37.0}] - doc["core_temperature_observation"]["sample_time"] = [{"seconds": 0}] + doc["scalar_temperature"]["value"] = [{"celsius": 37.0}] + doc["scalar_observation"]["sample_time"] = [{"seconds": 0}] assert check_series_lengths(doc) == [] From 5e88f0cde7e5a10880e619d06b8d7c83a0849f02 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 19:07:55 +0000 Subject: [PATCH 14/16] V_epsilon: conversion docs for treatment_drug / virus_injection / treatment_transfer folds Document the three remaining deprecated-class folds (the migrators land in DID-matlab): treatment_drug -> injection(kind:drug), virus_injection -> injection(kind:virus, dilution in the mixture concentration), and treatment_transfer -> biological_transfer (recipient->subject, donor carried). Target classes already exist in draft; no schema JSON change. 104 schema tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../conversions/from_did_v1/_index.md | 3 ++ .../conversions/from_did_v1/treatment_drug.md | 29 +++++++++++++++++++ .../from_did_v1/treatment_transfer.md | 27 +++++++++++++++++ .../from_did_v1/virus_injection.md | 28 ++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 schemas/V_epsilon/conversions/from_did_v1/treatment_drug.md create mode 100644 schemas/V_epsilon/conversions/from_did_v1/treatment_transfer.md create mode 100644 schemas/V_epsilon/conversions/from_did_v1/virus_injection.md diff --git a/schemas/V_epsilon/conversions/from_did_v1/_index.md b/schemas/V_epsilon/conversions/from_did_v1/_index.md index 9ba9ede..88f3160 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/_index.md +++ b/schemas/V_epsilon/conversions/from_did_v1/_index.md @@ -48,6 +48,9 @@ field-level changes on top. | `treatment` → manipulation tiers (Brainstorm E **split**) | legacy `treatment` → `injection`/`bath`/`procedural_manipulation`/`temperature_manipulation`/`environmental_manipulation` (+ out-of-tier) | drafted | [treatment.md](treatment.md) | | `ontology_table_row` → observation tiers (Brainstorm E **split**, 1→N) | legacy `ontology_table_row` → scalar/categorical observation property classes (+ out-of-tier) | drafted | [ontology_table_row.md](ontology_table_row.md) | | `subject_group` → `subject` (`is_group`) (Brainstorm E **fold**) | legacy `subject_group` → `subject` flagged `is_group` (+ `group_assignment` in NDI layer) | drafted | [subject_group.md](subject_group.md) | +| `treatment_drug` → `injection` (`kind: drug`) (Brainstorm E **fold**) | legacy `treatment_drug` → `injection` (mixture from `mixture_table`) | drafted | [treatment_drug.md](treatment_drug.md) | +| `virus_injection` → `injection` (`kind: virus`) (Brainstorm E **fold**) | legacy `virus_injection` → `injection` (virus+dilution in mixture) | drafted | [virus_injection.md](virus_injection.md) | +| `treatment_transfer` → `biological_transfer` (Brainstorm E **fold**) | legacy `treatment_transfer` → `biological_transfer` (recipient→subject, donor carried) | drafted | [treatment_transfer.md](treatment_transfer.md) | | `ontology_image` | legacy NDI/DID `ontologyImage` (V_alpha shape) | drafted | [ontology_image.md](ontology_image.md) | | `ontology_label` | legacy NDI/DID `ontologyLabel` (V_alpha shape) | drafted | [ontology_label.md](ontology_label.md) | diff --git a/schemas/V_epsilon/conversions/from_did_v1/treatment_drug.md b/schemas/V_epsilon/conversions/from_did_v1/treatment_drug.md new file mode 100644 index 0000000..13ef0d8 --- /dev/null +++ b/schemas/V_epsilon/conversions/from_did_v1/treatment_drug.md @@ -0,0 +1,29 @@ +# `treatment_drug` → `injection` (`kind: "drug"`) [Brainstorm E] + +Status: **drafted** + +`treatment_drug` is **deprecated** in V_epsilon and folds into `injection` +(a `pharmacological_manipulation`). + +## Mapping (per document, 1 → 2) + +| did_v1 `treatment_drug` | V_epsilon | Transformation | +|---|---|---| +| (class) `treatment_drug` | (class) `injection`, `injection.kind = "drug"` | class fold | +| `mixture_table` (CSV) | `pharmacological_manipulation.mixture[]` (`{chemical, amount}`) | best-effort CSV parse; ≥1 record (blank if unparseable) | +| `location_ontologyNode` / `location_name` | `injection.target_structure[]` | ontology_term | +| `administration_*` times | (timing) | ordinal `session_relative_reference` (`during`) for now; UTC/event refinement is a follow-up | +| `subject_id` | `subject_id` | carried | +| `base.*` | `base.*` | carried (same id) | + +The second emitted document is the shared `session_relative_reference` +anchor (`subject_interaction` requires a `time_reference`). + +`injection.volume` / `injection.route` are required but absent in v1; they +are emitted as blank composites (curator-fillable). Branch/field mapping is +a **heuristic seed**, finalised in discovery mode. + +## Engine +Routed by `did2.convert.v1_to_v2` under `TargetVersion='V_epsilon'` to +`+did2/+convert/+migrators_e/treatment_drug.m`. Default `V_delta` target is +unaffected. diff --git a/schemas/V_epsilon/conversions/from_did_v1/treatment_transfer.md b/schemas/V_epsilon/conversions/from_did_v1/treatment_transfer.md new file mode 100644 index 0000000..418386b --- /dev/null +++ b/schemas/V_epsilon/conversions/from_did_v1/treatment_transfer.md @@ -0,0 +1,27 @@ +# `treatment_transfer` → `biological_transfer` [Brainstorm E] + +Status: **drafted** + +`treatment_transfer` is **deprecated** in V_epsilon and folds into +`biological_transfer` (a `procedural_manipulation`). + +## Mapping (per document, 1 → 2) + +| did_v1 `treatment_transfer` | V_epsilon | Transformation | +|---|---|---| +| (class) `treatment_transfer` | (class) `biological_transfer` | class fold | +| `recipient_id` (depends_on) | `subject_id` | the recipient is the subject | +| `donor_id` (depends_on) | `biological_transfer` donor dependency (`donor_id`) | carried | +| `entity_ontologyNode` / `entity_name` | `biological_transfer.entity` | ontology_term | +| `method_ontologyNode` / `method_name` | `procedural_manipulation.procedure` | ontology_term | +| `method_name` | `biological_transfer.kind` | char (fallback `"transfer"`) | +| `timestamp` / `clocktype` | (timing) | ordinal `session_relative_reference` (`during`) for now; UTC/event refinement is a follow-up | +| `base.*` | `base.*` | carried (same id) | + +The second emitted document is the shared `session_relative_reference` +anchor (`subject_interaction` requires a `time_reference`). + +## Engine +Routed by `did2.convert.v1_to_v2` under `TargetVersion='V_epsilon'` to +`+did2/+convert/+migrators_e/treatment_transfer.m`. Default `V_delta` +target is unaffected. diff --git a/schemas/V_epsilon/conversions/from_did_v1/virus_injection.md b/schemas/V_epsilon/conversions/from_did_v1/virus_injection.md new file mode 100644 index 0000000..c7b95dd --- /dev/null +++ b/schemas/V_epsilon/conversions/from_did_v1/virus_injection.md @@ -0,0 +1,28 @@ +# `virus_injection` → `injection` (`kind: "virus"`) [Brainstorm E] + +Status: **drafted** + +`virus_injection` is **deprecated** in V_epsilon and folds into `injection` +(a `pharmacological_manipulation`). Serotype/identity ride in the mixture +ontology term; dilution rides in its concentration amount. + +## Mapping (per document, 1 → 2) + +| did_v1 `virus_injection` | V_epsilon | Transformation | +|---|---|---| +| (class) `virus_injection` | (class) `injection`, `injection.kind = "virus"` | class fold | +| `virus_OntologyName` / `virus_name` | `mixture[1].chemical` | ontology_term | +| `dilution` | `mixture[1].amount` | concentration (`source_value`, `source_unit="dilution"`) | +| `diluent_OntologyName` / `diluent_name` | `mixture[2].chemical` (if named) | ontology_term | +| `virusLocation_OntologyName` / `virusLocation_name` | `injection.target_structure[]` | ontology_term | +| `virus_AdministrationDate` / `virus_AdministrationPND` | (timing) | ordinal `session_relative_reference` (`during`) for now; UTC/developmental refinement is a follow-up | +| `subject_id` | `subject_id` | carried | +| `base.*` | `base.*` | carried (same id) | + +The second emitted document is the shared `session_relative_reference` +anchor. `injection.volume` / `route` are emitted blank (curator-fillable). + +## Engine +Routed by `did2.convert.v1_to_v2` under `TargetVersion='V_epsilon'` to +`+did2/+convert/+migrators_e/virus_injection.m`. Default `V_delta` target +is unaffected. From 5ca708350fbab92b26568c7ae82d00888b8ce0d0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 23:43:09 +0000 Subject: [PATCH 15/16] V_epsilon: document that subject_group membership has no did_v1 source Investigated the did_v1 document set: the subject_group body is empty and no v1 document depends on a subject_group, so group membership is not recorded anywhere in v1. There is therefore no source to migrate into group_assignment events -- the subject_group -> subject(is_group) fold is the complete migration, and group_assignment is a forward-looking class for newly authored data, not a migration target. Update the conversion doc so this is a recorded decision rather than a dangling TODO. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- .../conversions/from_did_v1/subject_group.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/schemas/V_epsilon/conversions/from_did_v1/subject_group.md b/schemas/V_epsilon/conversions/from_did_v1/subject_group.md index e034204..e77f3df 100644 --- a/schemas/V_epsilon/conversions/from_did_v1/subject_group.md +++ b/schemas/V_epsilon/conversions/from_did_v1/subject_group.md @@ -24,12 +24,16 @@ group `subject`. ## Membership → `group_assignment` (relational, NDI layer) -The member→group edges become `group_assignment` events. Those are -**relational**: they require the member subjects that point at this group, -which a single `subject_group` document does not carry. They are therefore -assembled in the NDI layer (`ndi.migrate.local`), the same boundary used -for `stimulus_bath → bath`, not manufactured here. This per-document -migrator emits the group `subject` only; the assignments are a follow-up. +In V_epsilon, member→group membership is event-sourced as `group_assignment` +annotations (member `subject_id` + `group_id`). **However, did_v1 does not +record group membership anywhere**: the `subject_group` body is empty and no +v1 document depends on a `subject_group` (verified across the did_v1 document +set). There is therefore **no v1 source to migrate into `group_assignment`** +— synthesizing edges would invent data. The migration is complete with the +group `subject` alone; `group_assignment` is a forward-looking class for +newly authored data, not a migration target. If a specific corpus turns out +to encode membership out-of-band (e.g., a lab-specific table), that becomes +a targeted, corpus-specific NDI-layer pass at that time. ## Engine From 978a2ae39d20bc3b10ff5d156928ba3d092539ff Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 23 Jun 2026 12:50:08 +0000 Subject: [PATCH 16/16] V_epsilon: promote Brainstorm-E migration classes draft -> stable (#3) Move the 69 family-A migration classes from draft/ to stable/ and set maturity_level: "stable": the subject_interaction spine, the time_reference family, the scalar/categorical observation tiers + shape mixins, the manipulation tiers, and the annotation/event classes (group_assignment, placement, derivation, session_extent, interaction_purpose, stimulus_approach). These run clean against the discovery corpora (0 quarantine), so they are frozen for cutover. Left in draft/ (40 classes): the genomics/omics + file-backed dataseries data-format families (expression_*, sequence_read_data_*, reference_sequence_data_* / reference_annotation_data_*, dataseries_* / timeseries_* / imageseries_*, instrument) -- a separate effort not exercised by the physiology corpora. index.json tier/maturity/path updated for all 69; test_series_cardinality resolves classes across tiers; SPEC tier-status note added. The assembled epsilon-schemas set (stable + draft) is unchanged, so corpus validation is unaffected. 104 schema tests pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ABEeDJ83r9Hq9PaiSije8o --- schemas/V_epsilon/index.json | 414 +++++++++--------- .../{draft => stable}/age_observation.json | 2 +- .../{draft => stable}/annotation.json | 2 +- schemas/V_epsilon/{draft => stable}/bath.json | 2 +- .../behavioral_phenotype_observation.json | 2 +- .../behavioral_score_observation.json | 2 +- .../biological_transfer.json | 2 +- .../blood_pressure_observation.json | 2 +- .../body_condition_observation.json | 2 +- .../body_length_observation.json | 2 +- .../body_weight_observation.json | 2 +- .../categorical_concept.json | 2 +- .../categorical_observation.json | 2 +- .../cell_count_observation.json | 2 +- .../concentration_observation.json | 2 +- .../core_temperature_observation.json | 2 +- .../{draft => stable}/derivation.json | 2 +- .../developmental_stage_observation.json | 2 +- .../environmental_manipulation.json | 2 +- .../epoch_bounded_reference.json | 2 +- .../epoch_relative_reference.json | 2 +- .../estrous_stage_observation.json | 2 +- .../event_bounded_reference.json | 2 +- .../event_relative_reference.json | 2 +- .../frequency_manipulation.json | 2 +- .../generic_categorical_observation.json | 2 +- .../{draft => stable}/generic_scalar.json | 2 +- .../generic_scalar_manipulation.json | 2 +- .../generic_scalar_observation.json | 2 +- .../{draft => stable}/group_assignment.json | 2 +- .../health_status_observation.json | 2 +- .../heart_rate_observation.json | 2 +- .../{draft => stable}/injection.json | 2 +- .../interaction_purpose.json | 2 +- .../litter_size_observation.json | 2 +- .../{draft => stable}/manipulation.json | 2 +- .../membrane_potential_observation.json | 2 +- .../{draft => stable}/observation.json | 2 +- .../organ_volume_observation.json | 2 +- .../pharmacological_manipulation.json | 2 +- .../pigmentation_observation.json | 2 +- .../{draft => stable}/placement.json | 2 +- .../pressure_manipulation.json | 2 +- .../procedural_manipulation.json | 2 +- .../respiration_rate_observation.json | 2 +- .../scalar_concentration.json | 2 +- .../{draft => stable}/scalar_count.json | 2 +- .../{draft => stable}/scalar_current.json | 2 +- .../{draft => stable}/scalar_duration.json | 2 +- .../{draft => stable}/scalar_frequency.json | 2 +- .../{draft => stable}/scalar_length.json | 2 +- .../scalar_manipulation.json | 2 +- .../{draft => stable}/scalar_mass.json | 2 +- .../{draft => stable}/scalar_observation.json | 2 +- .../{draft => stable}/scalar_pressure.json | 2 +- .../{draft => stable}/scalar_score.json | 2 +- .../{draft => stable}/scalar_temperature.json | 2 +- .../{draft => stable}/scalar_voltage.json | 2 +- .../{draft => stable}/scalar_volume.json | 2 +- .../{draft => stable}/session_extent.json | 2 +- .../session_relative_reference.json | 2 +- .../{draft => stable}/stimulus_approach.json | 2 +- .../{draft => stable}/stimulus_bath.json | 2 +- .../stimulus_manipulation.json | 2 +- .../{draft => stable}/subject_assertion.json | 2 +- .../subject_interaction.json | 2 +- .../{draft => stable}/subject_statement.json | 2 +- .../temperature_manipulation.json | 2 +- .../{draft => stable}/time_reference.json | 2 +- .../{draft => stable}/utc_reference.json | 2 +- schemas/V_epsilon_SPEC.md | 14 + tests/test_series_cardinality.py | 20 +- 72 files changed, 307 insertions(+), 279 deletions(-) rename schemas/V_epsilon/{draft => stable}/age_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/annotation.json (89%) rename schemas/V_epsilon/{draft => stable}/bath.json (97%) rename schemas/V_epsilon/{draft => stable}/behavioral_phenotype_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/behavioral_score_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/biological_transfer.json (98%) rename schemas/V_epsilon/{draft => stable}/blood_pressure_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/body_condition_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/body_length_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/body_weight_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/categorical_concept.json (97%) rename schemas/V_epsilon/{draft => stable}/categorical_observation.json (89%) rename schemas/V_epsilon/{draft => stable}/cell_count_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/concentration_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/core_temperature_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/derivation.json (98%) rename schemas/V_epsilon/{draft => stable}/developmental_stage_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/environmental_manipulation.json (98%) rename schemas/V_epsilon/{draft => stable}/epoch_bounded_reference.json (98%) rename schemas/V_epsilon/{draft => stable}/epoch_relative_reference.json (99%) rename schemas/V_epsilon/{draft => stable}/estrous_stage_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/event_bounded_reference.json (94%) rename schemas/V_epsilon/{draft => stable}/event_relative_reference.json (98%) rename schemas/V_epsilon/{draft => stable}/frequency_manipulation.json (91%) rename schemas/V_epsilon/{draft => stable}/generic_categorical_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/generic_scalar.json (98%) rename schemas/V_epsilon/{draft => stable}/generic_scalar_manipulation.json (91%) rename schemas/V_epsilon/{draft => stable}/generic_scalar_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/group_assignment.json (96%) rename schemas/V_epsilon/{draft => stable}/health_status_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/heart_rate_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/injection.json (99%) rename schemas/V_epsilon/{draft => stable}/interaction_purpose.json (97%) rename schemas/V_epsilon/{draft => stable}/litter_size_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/manipulation.json (89%) rename schemas/V_epsilon/{draft => stable}/membrane_potential_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/observation.json (97%) rename schemas/V_epsilon/{draft => stable}/organ_volume_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/pharmacological_manipulation.json (98%) rename schemas/V_epsilon/{draft => stable}/pigmentation_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/placement.json (96%) rename schemas/V_epsilon/{draft => stable}/pressure_manipulation.json (91%) rename schemas/V_epsilon/{draft => stable}/procedural_manipulation.json (98%) rename schemas/V_epsilon/{draft => stable}/respiration_rate_observation.json (91%) rename schemas/V_epsilon/{draft => stable}/scalar_concentration.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_count.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_current.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_duration.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_frequency.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_length.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_manipulation.json (98%) rename schemas/V_epsilon/{draft => stable}/scalar_mass.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_observation.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_pressure.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_score.json (97%) rename schemas/V_epsilon/{draft => stable}/scalar_temperature.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_voltage.json (96%) rename schemas/V_epsilon/{draft => stable}/scalar_volume.json (96%) rename schemas/V_epsilon/{draft => stable}/session_extent.json (98%) rename schemas/V_epsilon/{draft => stable}/session_relative_reference.json (97%) rename schemas/V_epsilon/{draft => stable}/stimulus_approach.json (98%) rename schemas/V_epsilon/{draft => stable}/stimulus_bath.json (93%) rename schemas/V_epsilon/{draft => stable}/stimulus_manipulation.json (96%) rename schemas/V_epsilon/{draft => stable}/subject_assertion.json (98%) rename schemas/V_epsilon/{draft => stable}/subject_interaction.json (94%) rename schemas/V_epsilon/{draft => stable}/subject_statement.json (93%) rename schemas/V_epsilon/{draft => stable}/temperature_manipulation.json (91%) rename schemas/V_epsilon/{draft => stable}/time_reference.json (95%) rename schemas/V_epsilon/{draft => stable}/utc_reference.json (97%) diff --git a/schemas/V_epsilon/index.json b/schemas/V_epsilon/index.json index 346a074..af5b18a 100644 --- a/schemas/V_epsilon/index.json +++ b/schemas/V_epsilon/index.json @@ -24,25 +24,25 @@ }, { "class_name": "age_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_duration" ], - "path": "schemas/V_epsilon/draft/age_observation.json", + "path": "schemas/V_epsilon/stable/age_observation.json", "is_meta": false }, { "class_name": "annotation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "subject_interaction" ], - "path": "schemas/V_epsilon/draft/annotation.json", + "path": "schemas/V_epsilon/stable/annotation.json", "is_meta": false }, { @@ -67,37 +67,37 @@ }, { "class_name": "bath", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "pharmacological_manipulation" ], - "path": "schemas/V_epsilon/draft/bath.json", + "path": "schemas/V_epsilon/stable/bath.json", "is_meta": false }, { "class_name": "behavioral_phenotype_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "categorical_observation", "categorical_concept" ], - "path": "schemas/V_epsilon/draft/behavioral_phenotype_observation.json", + "path": "schemas/V_epsilon/stable/behavioral_phenotype_observation.json", "is_meta": false }, { "class_name": "behavioral_score_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_score" ], - "path": "schemas/V_epsilon/draft/behavioral_score_observation.json", + "path": "schemas/V_epsilon/stable/behavioral_score_observation.json", "is_meta": false }, { @@ -124,61 +124,61 @@ }, { "class_name": "biological_transfer", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "procedural_manipulation" ], - "path": "schemas/V_epsilon/draft/biological_transfer.json", + "path": "schemas/V_epsilon/stable/biological_transfer.json", "is_meta": false }, { "class_name": "blood_pressure_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_pressure" ], - "path": "schemas/V_epsilon/draft/blood_pressure_observation.json", + "path": "schemas/V_epsilon/stable/blood_pressure_observation.json", "is_meta": false }, { "class_name": "body_condition_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_score" ], - "path": "schemas/V_epsilon/draft/body_condition_observation.json", + "path": "schemas/V_epsilon/stable/body_condition_observation.json", "is_meta": false }, { "class_name": "body_length_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_length" ], - "path": "schemas/V_epsilon/draft/body_length_observation.json", + "path": "schemas/V_epsilon/stable/body_length_observation.json", "is_meta": false }, { "class_name": "body_weight_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_mass" ], - "path": "schemas/V_epsilon/draft/body_weight_observation.json", + "path": "schemas/V_epsilon/stable/body_weight_observation.json", "is_meta": false }, { @@ -195,48 +195,48 @@ }, { "class_name": "categorical_concept", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/categorical_concept.json", + "path": "schemas/V_epsilon/stable/categorical_concept.json", "is_meta": false }, { "class_name": "categorical_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "observation" ], - "path": "schemas/V_epsilon/draft/categorical_observation.json", + "path": "schemas/V_epsilon/stable/categorical_observation.json", "is_meta": false }, { "class_name": "cell_count_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_count" ], - "path": "schemas/V_epsilon/draft/cell_count_observation.json", + "path": "schemas/V_epsilon/stable/cell_count_observation.json", "is_meta": false }, { "class_name": "concentration_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_concentration" ], - "path": "schemas/V_epsilon/draft/concentration_observation.json", + "path": "schemas/V_epsilon/stable/concentration_observation.json", "is_meta": false }, { @@ -289,14 +289,14 @@ }, { "class_name": "core_temperature_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_temperature" ], - "path": "schemas/V_epsilon/draft/core_temperature_observation.json", + "path": "schemas/V_epsilon/stable/core_temperature_observation.json", "is_meta": false }, { @@ -471,25 +471,25 @@ }, { "class_name": "derivation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "manipulation" ], - "path": "schemas/V_epsilon/draft/derivation.json", + "path": "schemas/V_epsilon/stable/derivation.json", "is_meta": false }, { "class_name": "developmental_stage_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "categorical_observation", "categorical_concept" ], - "path": "schemas/V_epsilon/draft/developmental_stage_observation.json", + "path": "schemas/V_epsilon/stable/developmental_stage_observation.json", "is_meta": false }, { @@ -559,13 +559,13 @@ }, { "class_name": "environmental_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "manipulation" ], - "path": "schemas/V_epsilon/draft/environmental_manipulation.json", + "path": "schemas/V_epsilon/stable/environmental_manipulation.json", "is_meta": false }, { @@ -581,26 +581,26 @@ }, { "class_name": "epoch_bounded_reference", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "time_reference", "epochid" ], - "path": "schemas/V_epsilon/draft/epoch_bounded_reference.json", + "path": "schemas/V_epsilon/stable/epoch_bounded_reference.json", "is_meta": false }, { "class_name": "epoch_relative_reference", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "time_reference", "epochid" ], - "path": "schemas/V_epsilon/draft/epoch_relative_reference.json", + "path": "schemas/V_epsilon/stable/epoch_relative_reference.json", "is_meta": false }, { @@ -639,36 +639,36 @@ }, { "class_name": "estrous_stage_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "categorical_observation", "categorical_concept" ], - "path": "schemas/V_epsilon/draft/estrous_stage_observation.json", + "path": "schemas/V_epsilon/stable/estrous_stage_observation.json", "is_meta": false }, { "class_name": "event_bounded_reference", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "time_reference" ], - "path": "schemas/V_epsilon/draft/event_bounded_reference.json", + "path": "schemas/V_epsilon/stable/event_bounded_reference.json", "is_meta": false }, { "class_name": "event_relative_reference", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "time_reference" ], - "path": "schemas/V_epsilon/draft/event_relative_reference.json", + "path": "schemas/V_epsilon/stable/event_relative_reference.json", "is_meta": false }, { @@ -871,26 +871,26 @@ }, { "class_name": "frequency_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_manipulation", "scalar_frequency" ], - "path": "schemas/V_epsilon/draft/frequency_manipulation.json", + "path": "schemas/V_epsilon/stable/frequency_manipulation.json", "is_meta": false }, { "class_name": "generic_categorical_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "categorical_observation", "categorical_concept" ], - "path": "schemas/V_epsilon/draft/generic_categorical_observation.json", + "path": "schemas/V_epsilon/stable/generic_categorical_observation.json", "is_meta": false }, { @@ -906,48 +906,48 @@ }, { "class_name": "generic_scalar", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/generic_scalar.json", + "path": "schemas/V_epsilon/stable/generic_scalar.json", "is_meta": false }, { "class_name": "generic_scalar_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_manipulation", "generic_scalar" ], - "path": "schemas/V_epsilon/draft/generic_scalar_manipulation.json", + "path": "schemas/V_epsilon/stable/generic_scalar_manipulation.json", "is_meta": false }, { "class_name": "generic_scalar_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "generic_scalar" ], - "path": "schemas/V_epsilon/draft/generic_scalar_observation.json", + "path": "schemas/V_epsilon/stable/generic_scalar_observation.json", "is_meta": false }, { "class_name": "group_assignment", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "annotation" ], - "path": "schemas/V_epsilon/draft/group_assignment.json", + "path": "schemas/V_epsilon/stable/group_assignment.json", "is_meta": false }, { @@ -977,26 +977,26 @@ }, { "class_name": "health_status_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "categorical_observation", "categorical_concept" ], - "path": "schemas/V_epsilon/draft/health_status_observation.json", + "path": "schemas/V_epsilon/stable/health_status_observation.json", "is_meta": false }, { "class_name": "heart_rate_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_frequency" ], - "path": "schemas/V_epsilon/draft/heart_rate_observation.json", + "path": "schemas/V_epsilon/stable/heart_rate_observation.json", "is_meta": false }, { @@ -1079,13 +1079,13 @@ }, { "class_name": "injection", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "pharmacological_manipulation" ], - "path": "schemas/V_epsilon/draft/injection.json", + "path": "schemas/V_epsilon/stable/injection.json", "is_meta": false }, { @@ -1101,13 +1101,13 @@ }, { "class_name": "interaction_purpose", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/interaction_purpose.json", + "path": "schemas/V_epsilon/stable/interaction_purpose.json", "is_meta": false }, { @@ -1124,25 +1124,25 @@ }, { "class_name": "litter_size_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_count" ], - "path": "schemas/V_epsilon/draft/litter_size_observation.json", + "path": "schemas/V_epsilon/stable/litter_size_observation.json", "is_meta": false }, { "class_name": "manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "subject_interaction" ], - "path": "schemas/V_epsilon/draft/manipulation.json", + "path": "schemas/V_epsilon/stable/manipulation.json", "is_meta": false }, { @@ -1159,14 +1159,14 @@ }, { "class_name": "membrane_potential_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_voltage" ], - "path": "schemas/V_epsilon/draft/membrane_potential_observation.json", + "path": "schemas/V_epsilon/stable/membrane_potential_observation.json", "is_meta": false }, { @@ -1225,13 +1225,13 @@ }, { "class_name": "observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "subject_interaction" ], - "path": "schemas/V_epsilon/draft/observation.json", + "path": "schemas/V_epsilon/stable/observation.json", "is_meta": false }, { @@ -1329,14 +1329,14 @@ }, { "class_name": "organ_volume_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_volume" ], - "path": "schemas/V_epsilon/draft/organ_volume_observation.json", + "path": "schemas/V_epsilon/stable/organ_volume_observation.json", "is_meta": false }, { @@ -1365,36 +1365,36 @@ }, { "class_name": "pharmacological_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "manipulation" ], - "path": "schemas/V_epsilon/draft/pharmacological_manipulation.json", + "path": "schemas/V_epsilon/stable/pharmacological_manipulation.json", "is_meta": false }, { "class_name": "pigmentation_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "categorical_observation", "categorical_concept" ], - "path": "schemas/V_epsilon/draft/pigmentation_observation.json", + "path": "schemas/V_epsilon/stable/pigmentation_observation.json", "is_meta": false }, { "class_name": "placement", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "manipulation" ], - "path": "schemas/V_epsilon/draft/placement.json", + "path": "schemas/V_epsilon/stable/placement.json", "is_meta": false }, { @@ -1410,14 +1410,14 @@ }, { "class_name": "pressure_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_manipulation", "scalar_pressure" ], - "path": "schemas/V_epsilon/draft/pressure_manipulation.json", + "path": "schemas/V_epsilon/stable/pressure_manipulation.json", "is_meta": false }, { @@ -1444,13 +1444,13 @@ }, { "class_name": "procedural_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "manipulation" ], - "path": "schemas/V_epsilon/draft/procedural_manipulation.json", + "path": "schemas/V_epsilon/stable/procedural_manipulation.json", "is_meta": false }, { @@ -1568,14 +1568,14 @@ }, { "class_name": "respiration_rate_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_observation", "scalar_frequency" ], - "path": "schemas/V_epsilon/draft/respiration_rate_observation.json", + "path": "schemas/V_epsilon/stable/respiration_rate_observation.json", "is_meta": false }, { @@ -1592,156 +1592,156 @@ }, { "class_name": "scalar_concentration", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_concentration.json", + "path": "schemas/V_epsilon/stable/scalar_concentration.json", "is_meta": false }, { "class_name": "scalar_count", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_count.json", + "path": "schemas/V_epsilon/stable/scalar_count.json", "is_meta": false }, { "class_name": "scalar_current", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_current.json", + "path": "schemas/V_epsilon/stable/scalar_current.json", "is_meta": false }, { "class_name": "scalar_duration", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_duration.json", + "path": "schemas/V_epsilon/stable/scalar_duration.json", "is_meta": false }, { "class_name": "scalar_frequency", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_frequency.json", + "path": "schemas/V_epsilon/stable/scalar_frequency.json", "is_meta": false }, { "class_name": "scalar_length", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_length.json", + "path": "schemas/V_epsilon/stable/scalar_length.json", "is_meta": false }, { "class_name": "scalar_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "manipulation" ], - "path": "schemas/V_epsilon/draft/scalar_manipulation.json", + "path": "schemas/V_epsilon/stable/scalar_manipulation.json", "is_meta": false }, { "class_name": "scalar_mass", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_mass.json", + "path": "schemas/V_epsilon/stable/scalar_mass.json", "is_meta": false }, { "class_name": "scalar_observation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "observation" ], - "path": "schemas/V_epsilon/draft/scalar_observation.json", + "path": "schemas/V_epsilon/stable/scalar_observation.json", "is_meta": false }, { "class_name": "scalar_pressure", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_pressure.json", + "path": "schemas/V_epsilon/stable/scalar_pressure.json", "is_meta": false }, { "class_name": "scalar_score", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_score.json", + "path": "schemas/V_epsilon/stable/scalar_score.json", "is_meta": false }, { "class_name": "scalar_temperature", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_temperature.json", + "path": "schemas/V_epsilon/stable/scalar_temperature.json", "is_meta": false }, { "class_name": "scalar_voltage", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_voltage.json", + "path": "schemas/V_epsilon/stable/scalar_voltage.json", "is_meta": false }, { "class_name": "scalar_volume", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/scalar_volume.json", + "path": "schemas/V_epsilon/stable/scalar_volume.json", "is_meta": false }, { @@ -1801,13 +1801,13 @@ }, { "class_name": "session_extent", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/session_extent.json", + "path": "schemas/V_epsilon/stable/session_extent.json", "is_meta": false }, { @@ -1823,13 +1823,13 @@ }, { "class_name": "session_relative_reference", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "time_reference" ], - "path": "schemas/V_epsilon/draft/session_relative_reference.json", + "path": "schemas/V_epsilon/stable/session_relative_reference.json", "is_meta": false }, { @@ -1982,35 +1982,35 @@ }, { "class_name": "stimulus_approach", - "tier": "draft", + "tier": "stable", "class_version": "2.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/stimulus_approach.json", + "path": "schemas/V_epsilon/stable/stimulus_approach.json", "is_meta": false }, { "class_name": "stimulus_bath", - "tier": "draft", + "tier": "stable", "class_version": "2.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "bath" ], - "path": "schemas/V_epsilon/draft/stimulus_bath.json", + "path": "schemas/V_epsilon/stable/stimulus_bath.json", "is_meta": false }, { "class_name": "stimulus_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "manipulation" ], - "path": "schemas/V_epsilon/draft/stimulus_manipulation.json", + "path": "schemas/V_epsilon/stable/stimulus_manipulation.json", "is_meta": false }, { @@ -2118,13 +2118,13 @@ }, { "class_name": "subject_assertion", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "subject_statement" ], - "path": "schemas/V_epsilon/draft/subject_assertion.json", + "path": "schemas/V_epsilon/stable/subject_assertion.json", "is_meta": false }, { @@ -2140,24 +2140,24 @@ }, { "class_name": "subject_interaction", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "subject_statement" ], - "path": "schemas/V_epsilon/draft/subject_interaction.json", + "path": "schemas/V_epsilon/stable/subject_interaction.json", "is_meta": false }, { "class_name": "subject_statement", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/subject_statement.json", + "path": "schemas/V_epsilon/stable/subject_statement.json", "is_meta": false }, { @@ -2195,14 +2195,14 @@ }, { "class_name": "temperature_manipulation", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "scalar_manipulation", "scalar_temperature" ], - "path": "schemas/V_epsilon/draft/temperature_manipulation.json", + "path": "schemas/V_epsilon/stable/temperature_manipulation.json", "is_meta": false }, { @@ -2231,13 +2231,13 @@ }, { "class_name": "time_reference", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "base" ], - "path": "schemas/V_epsilon/draft/time_reference.json", + "path": "schemas/V_epsilon/stable/time_reference.json", "is_meta": false }, { @@ -2354,13 +2354,13 @@ }, { "class_name": "utc_reference", - "tier": "draft", + "tier": "stable", "class_version": "1.0.0", - "maturity_level": "draft", + "maturity_level": "stable", "superclasses": [ "time_reference" ], - "path": "schemas/V_epsilon/draft/utc_reference.json", + "path": "schemas/V_epsilon/stable/utc_reference.json", "is_meta": false }, { diff --git a/schemas/V_epsilon/draft/age_observation.json b/schemas/V_epsilon/stable/age_observation.json similarity index 91% rename from schemas/V_epsilon/draft/age_observation.json rename to schemas/V_epsilon/stable/age_observation.json index ef30fa1..79b8a71 100644 --- a/schemas/V_epsilon/draft/age_observation.json +++ b/schemas/V_epsilon/stable/age_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_duration" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/annotation.json b/schemas/V_epsilon/stable/annotation.json similarity index 89% rename from schemas/V_epsilon/draft/annotation.json rename to schemas/V_epsilon/stable/annotation.json index ad15f7a..9fd130c 100644 --- a/schemas/V_epsilon/draft/annotation.json +++ b/schemas/V_epsilon/stable/annotation.json @@ -7,7 +7,7 @@ "class_name": "subject_interaction" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/bath.json b/schemas/V_epsilon/stable/bath.json similarity index 97% rename from schemas/V_epsilon/draft/bath.json rename to schemas/V_epsilon/stable/bath.json index bfef996..fbb4750 100644 --- a/schemas/V_epsilon/draft/bath.json +++ b/schemas/V_epsilon/stable/bath.json @@ -7,7 +7,7 @@ "class_name": "pharmacological_manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/behavioral_phenotype_observation.json b/schemas/V_epsilon/stable/behavioral_phenotype_observation.json similarity index 91% rename from schemas/V_epsilon/draft/behavioral_phenotype_observation.json rename to schemas/V_epsilon/stable/behavioral_phenotype_observation.json index f11bc65..38aa9cb 100644 --- a/schemas/V_epsilon/draft/behavioral_phenotype_observation.json +++ b/schemas/V_epsilon/stable/behavioral_phenotype_observation.json @@ -10,7 +10,7 @@ "class_name": "categorical_concept" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/behavioral_score_observation.json b/schemas/V_epsilon/stable/behavioral_score_observation.json similarity index 91% rename from schemas/V_epsilon/draft/behavioral_score_observation.json rename to schemas/V_epsilon/stable/behavioral_score_observation.json index 5e4fead..b0a8536 100644 --- a/schemas/V_epsilon/draft/behavioral_score_observation.json +++ b/schemas/V_epsilon/stable/behavioral_score_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_score" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/biological_transfer.json b/schemas/V_epsilon/stable/biological_transfer.json similarity index 98% rename from schemas/V_epsilon/draft/biological_transfer.json rename to schemas/V_epsilon/stable/biological_transfer.json index 5ba6b92..2bd88f8 100644 --- a/schemas/V_epsilon/draft/biological_transfer.json +++ b/schemas/V_epsilon/stable/biological_transfer.json @@ -7,7 +7,7 @@ "class_name": "procedural_manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/blood_pressure_observation.json b/schemas/V_epsilon/stable/blood_pressure_observation.json similarity index 91% rename from schemas/V_epsilon/draft/blood_pressure_observation.json rename to schemas/V_epsilon/stable/blood_pressure_observation.json index 4a3ff02..ecae6c3 100644 --- a/schemas/V_epsilon/draft/blood_pressure_observation.json +++ b/schemas/V_epsilon/stable/blood_pressure_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_pressure" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/body_condition_observation.json b/schemas/V_epsilon/stable/body_condition_observation.json similarity index 91% rename from schemas/V_epsilon/draft/body_condition_observation.json rename to schemas/V_epsilon/stable/body_condition_observation.json index 238edd2..398ae49 100644 --- a/schemas/V_epsilon/draft/body_condition_observation.json +++ b/schemas/V_epsilon/stable/body_condition_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_score" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/body_length_observation.json b/schemas/V_epsilon/stable/body_length_observation.json similarity index 91% rename from schemas/V_epsilon/draft/body_length_observation.json rename to schemas/V_epsilon/stable/body_length_observation.json index 17c3a27..82fd3c2 100644 --- a/schemas/V_epsilon/draft/body_length_observation.json +++ b/schemas/V_epsilon/stable/body_length_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_length" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/body_weight_observation.json b/schemas/V_epsilon/stable/body_weight_observation.json similarity index 91% rename from schemas/V_epsilon/draft/body_weight_observation.json rename to schemas/V_epsilon/stable/body_weight_observation.json index c5a3107..d2a184d 100644 --- a/schemas/V_epsilon/draft/body_weight_observation.json +++ b/schemas/V_epsilon/stable/body_weight_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_mass" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/categorical_concept.json b/schemas/V_epsilon/stable/categorical_concept.json similarity index 97% rename from schemas/V_epsilon/draft/categorical_concept.json rename to schemas/V_epsilon/stable/categorical_concept.json index 70708da..5aa588c 100644 --- a/schemas/V_epsilon/draft/categorical_concept.json +++ b/schemas/V_epsilon/stable/categorical_concept.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/categorical_observation.json b/schemas/V_epsilon/stable/categorical_observation.json similarity index 89% rename from schemas/V_epsilon/draft/categorical_observation.json rename to schemas/V_epsilon/stable/categorical_observation.json index bef521e..eaf1910 100644 --- a/schemas/V_epsilon/draft/categorical_observation.json +++ b/schemas/V_epsilon/stable/categorical_observation.json @@ -7,7 +7,7 @@ "class_name": "observation" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/cell_count_observation.json b/schemas/V_epsilon/stable/cell_count_observation.json similarity index 91% rename from schemas/V_epsilon/draft/cell_count_observation.json rename to schemas/V_epsilon/stable/cell_count_observation.json index b4eaee9..9d91093 100644 --- a/schemas/V_epsilon/draft/cell_count_observation.json +++ b/schemas/V_epsilon/stable/cell_count_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_count" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/concentration_observation.json b/schemas/V_epsilon/stable/concentration_observation.json similarity index 91% rename from schemas/V_epsilon/draft/concentration_observation.json rename to schemas/V_epsilon/stable/concentration_observation.json index 59f8783..6f6dd9d 100644 --- a/schemas/V_epsilon/draft/concentration_observation.json +++ b/schemas/V_epsilon/stable/concentration_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_concentration" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/core_temperature_observation.json b/schemas/V_epsilon/stable/core_temperature_observation.json similarity index 91% rename from schemas/V_epsilon/draft/core_temperature_observation.json rename to schemas/V_epsilon/stable/core_temperature_observation.json index 5c510ae..a03e212 100644 --- a/schemas/V_epsilon/draft/core_temperature_observation.json +++ b/schemas/V_epsilon/stable/core_temperature_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_temperature" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/derivation.json b/schemas/V_epsilon/stable/derivation.json similarity index 98% rename from schemas/V_epsilon/draft/derivation.json rename to schemas/V_epsilon/stable/derivation.json index 8fa3a23..c431a38 100644 --- a/schemas/V_epsilon/draft/derivation.json +++ b/schemas/V_epsilon/stable/derivation.json @@ -7,7 +7,7 @@ "class_name": "manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/developmental_stage_observation.json b/schemas/V_epsilon/stable/developmental_stage_observation.json similarity index 91% rename from schemas/V_epsilon/draft/developmental_stage_observation.json rename to schemas/V_epsilon/stable/developmental_stage_observation.json index 6c78282..0ace299 100644 --- a/schemas/V_epsilon/draft/developmental_stage_observation.json +++ b/schemas/V_epsilon/stable/developmental_stage_observation.json @@ -10,7 +10,7 @@ "class_name": "categorical_concept" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/environmental_manipulation.json b/schemas/V_epsilon/stable/environmental_manipulation.json similarity index 98% rename from schemas/V_epsilon/draft/environmental_manipulation.json rename to schemas/V_epsilon/stable/environmental_manipulation.json index ef40315..ce3932e 100644 --- a/schemas/V_epsilon/draft/environmental_manipulation.json +++ b/schemas/V_epsilon/stable/environmental_manipulation.json @@ -7,7 +7,7 @@ "class_name": "manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/epoch_bounded_reference.json b/schemas/V_epsilon/stable/epoch_bounded_reference.json similarity index 98% rename from schemas/V_epsilon/draft/epoch_bounded_reference.json rename to schemas/V_epsilon/stable/epoch_bounded_reference.json index 358aab2..ff8cf4a 100644 --- a/schemas/V_epsilon/draft/epoch_bounded_reference.json +++ b/schemas/V_epsilon/stable/epoch_bounded_reference.json @@ -10,7 +10,7 @@ "class_name": "epochid" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/epoch_relative_reference.json b/schemas/V_epsilon/stable/epoch_relative_reference.json similarity index 99% rename from schemas/V_epsilon/draft/epoch_relative_reference.json rename to schemas/V_epsilon/stable/epoch_relative_reference.json index 24f5b49..e26efbb 100644 --- a/schemas/V_epsilon/draft/epoch_relative_reference.json +++ b/schemas/V_epsilon/stable/epoch_relative_reference.json @@ -10,7 +10,7 @@ "class_name": "epochid" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/estrous_stage_observation.json b/schemas/V_epsilon/stable/estrous_stage_observation.json similarity index 91% rename from schemas/V_epsilon/draft/estrous_stage_observation.json rename to schemas/V_epsilon/stable/estrous_stage_observation.json index 1ef8fcf..27ea177 100644 --- a/schemas/V_epsilon/draft/estrous_stage_observation.json +++ b/schemas/V_epsilon/stable/estrous_stage_observation.json @@ -10,7 +10,7 @@ "class_name": "categorical_concept" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/event_bounded_reference.json b/schemas/V_epsilon/stable/event_bounded_reference.json similarity index 94% rename from schemas/V_epsilon/draft/event_bounded_reference.json rename to schemas/V_epsilon/stable/event_bounded_reference.json index f250c0c..9f8bf1f 100644 --- a/schemas/V_epsilon/draft/event_bounded_reference.json +++ b/schemas/V_epsilon/stable/event_bounded_reference.json @@ -7,7 +7,7 @@ "class_name": "time_reference" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/event_relative_reference.json b/schemas/V_epsilon/stable/event_relative_reference.json similarity index 98% rename from schemas/V_epsilon/draft/event_relative_reference.json rename to schemas/V_epsilon/stable/event_relative_reference.json index e4fd328..9f44a8b 100644 --- a/schemas/V_epsilon/draft/event_relative_reference.json +++ b/schemas/V_epsilon/stable/event_relative_reference.json @@ -7,7 +7,7 @@ "class_name": "time_reference" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/frequency_manipulation.json b/schemas/V_epsilon/stable/frequency_manipulation.json similarity index 91% rename from schemas/V_epsilon/draft/frequency_manipulation.json rename to schemas/V_epsilon/stable/frequency_manipulation.json index ff8ff82..03afc8b 100644 --- a/schemas/V_epsilon/draft/frequency_manipulation.json +++ b/schemas/V_epsilon/stable/frequency_manipulation.json @@ -10,7 +10,7 @@ "class_name": "scalar_frequency" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/generic_categorical_observation.json b/schemas/V_epsilon/stable/generic_categorical_observation.json similarity index 91% rename from schemas/V_epsilon/draft/generic_categorical_observation.json rename to schemas/V_epsilon/stable/generic_categorical_observation.json index 80850f4..b73ccae 100644 --- a/schemas/V_epsilon/draft/generic_categorical_observation.json +++ b/schemas/V_epsilon/stable/generic_categorical_observation.json @@ -10,7 +10,7 @@ "class_name": "categorical_concept" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/generic_scalar.json b/schemas/V_epsilon/stable/generic_scalar.json similarity index 98% rename from schemas/V_epsilon/draft/generic_scalar.json rename to schemas/V_epsilon/stable/generic_scalar.json index 9da8a8a..fa08265 100644 --- a/schemas/V_epsilon/draft/generic_scalar.json +++ b/schemas/V_epsilon/stable/generic_scalar.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/generic_scalar_manipulation.json b/schemas/V_epsilon/stable/generic_scalar_manipulation.json similarity index 91% rename from schemas/V_epsilon/draft/generic_scalar_manipulation.json rename to schemas/V_epsilon/stable/generic_scalar_manipulation.json index c317ed7..75e39d7 100644 --- a/schemas/V_epsilon/draft/generic_scalar_manipulation.json +++ b/schemas/V_epsilon/stable/generic_scalar_manipulation.json @@ -10,7 +10,7 @@ "class_name": "generic_scalar" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/generic_scalar_observation.json b/schemas/V_epsilon/stable/generic_scalar_observation.json similarity index 91% rename from schemas/V_epsilon/draft/generic_scalar_observation.json rename to schemas/V_epsilon/stable/generic_scalar_observation.json index 19aecc9..3a51bd5 100644 --- a/schemas/V_epsilon/draft/generic_scalar_observation.json +++ b/schemas/V_epsilon/stable/generic_scalar_observation.json @@ -10,7 +10,7 @@ "class_name": "generic_scalar" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/group_assignment.json b/schemas/V_epsilon/stable/group_assignment.json similarity index 96% rename from schemas/V_epsilon/draft/group_assignment.json rename to schemas/V_epsilon/stable/group_assignment.json index 792d467..42a3e2d 100644 --- a/schemas/V_epsilon/draft/group_assignment.json +++ b/schemas/V_epsilon/stable/group_assignment.json @@ -7,7 +7,7 @@ "class_name": "annotation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/health_status_observation.json b/schemas/V_epsilon/stable/health_status_observation.json similarity index 91% rename from schemas/V_epsilon/draft/health_status_observation.json rename to schemas/V_epsilon/stable/health_status_observation.json index 4650bdc..e8cbb82 100644 --- a/schemas/V_epsilon/draft/health_status_observation.json +++ b/schemas/V_epsilon/stable/health_status_observation.json @@ -10,7 +10,7 @@ "class_name": "categorical_concept" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/heart_rate_observation.json b/schemas/V_epsilon/stable/heart_rate_observation.json similarity index 91% rename from schemas/V_epsilon/draft/heart_rate_observation.json rename to schemas/V_epsilon/stable/heart_rate_observation.json index 62c5254..bbaafb2 100644 --- a/schemas/V_epsilon/draft/heart_rate_observation.json +++ b/schemas/V_epsilon/stable/heart_rate_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_frequency" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/injection.json b/schemas/V_epsilon/stable/injection.json similarity index 99% rename from schemas/V_epsilon/draft/injection.json rename to schemas/V_epsilon/stable/injection.json index 2f47f0f..9ea1d5f 100644 --- a/schemas/V_epsilon/draft/injection.json +++ b/schemas/V_epsilon/stable/injection.json @@ -7,7 +7,7 @@ "class_name": "pharmacological_manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/interaction_purpose.json b/schemas/V_epsilon/stable/interaction_purpose.json similarity index 97% rename from schemas/V_epsilon/draft/interaction_purpose.json rename to schemas/V_epsilon/stable/interaction_purpose.json index 64bc8c9..a9cd1da 100644 --- a/schemas/V_epsilon/draft/interaction_purpose.json +++ b/schemas/V_epsilon/stable/interaction_purpose.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/litter_size_observation.json b/schemas/V_epsilon/stable/litter_size_observation.json similarity index 91% rename from schemas/V_epsilon/draft/litter_size_observation.json rename to schemas/V_epsilon/stable/litter_size_observation.json index 11bf62b..2b85e7a 100644 --- a/schemas/V_epsilon/draft/litter_size_observation.json +++ b/schemas/V_epsilon/stable/litter_size_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_count" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/manipulation.json b/schemas/V_epsilon/stable/manipulation.json similarity index 89% rename from schemas/V_epsilon/draft/manipulation.json rename to schemas/V_epsilon/stable/manipulation.json index d06d31f..0022442 100644 --- a/schemas/V_epsilon/draft/manipulation.json +++ b/schemas/V_epsilon/stable/manipulation.json @@ -7,7 +7,7 @@ "class_name": "subject_interaction" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/membrane_potential_observation.json b/schemas/V_epsilon/stable/membrane_potential_observation.json similarity index 91% rename from schemas/V_epsilon/draft/membrane_potential_observation.json rename to schemas/V_epsilon/stable/membrane_potential_observation.json index 8478212..c8ceb4c 100644 --- a/schemas/V_epsilon/draft/membrane_potential_observation.json +++ b/schemas/V_epsilon/stable/membrane_potential_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_voltage" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/observation.json b/schemas/V_epsilon/stable/observation.json similarity index 97% rename from schemas/V_epsilon/draft/observation.json rename to schemas/V_epsilon/stable/observation.json index c7c5d9b..525e4d8 100644 --- a/schemas/V_epsilon/draft/observation.json +++ b/schemas/V_epsilon/stable/observation.json @@ -7,7 +7,7 @@ "class_name": "subject_interaction" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/organ_volume_observation.json b/schemas/V_epsilon/stable/organ_volume_observation.json similarity index 91% rename from schemas/V_epsilon/draft/organ_volume_observation.json rename to schemas/V_epsilon/stable/organ_volume_observation.json index 72ded82..2ec04f0 100644 --- a/schemas/V_epsilon/draft/organ_volume_observation.json +++ b/schemas/V_epsilon/stable/organ_volume_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_volume" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/pharmacological_manipulation.json b/schemas/V_epsilon/stable/pharmacological_manipulation.json similarity index 98% rename from schemas/V_epsilon/draft/pharmacological_manipulation.json rename to schemas/V_epsilon/stable/pharmacological_manipulation.json index 036a447..4996796 100644 --- a/schemas/V_epsilon/draft/pharmacological_manipulation.json +++ b/schemas/V_epsilon/stable/pharmacological_manipulation.json @@ -7,7 +7,7 @@ "class_name": "manipulation" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/pigmentation_observation.json b/schemas/V_epsilon/stable/pigmentation_observation.json similarity index 91% rename from schemas/V_epsilon/draft/pigmentation_observation.json rename to schemas/V_epsilon/stable/pigmentation_observation.json index 6aae7ca..51ec34c 100644 --- a/schemas/V_epsilon/draft/pigmentation_observation.json +++ b/schemas/V_epsilon/stable/pigmentation_observation.json @@ -10,7 +10,7 @@ "class_name": "categorical_concept" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/placement.json b/schemas/V_epsilon/stable/placement.json similarity index 96% rename from schemas/V_epsilon/draft/placement.json rename to schemas/V_epsilon/stable/placement.json index 9d83326..f34db83 100644 --- a/schemas/V_epsilon/draft/placement.json +++ b/schemas/V_epsilon/stable/placement.json @@ -7,7 +7,7 @@ "class_name": "manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/pressure_manipulation.json b/schemas/V_epsilon/stable/pressure_manipulation.json similarity index 91% rename from schemas/V_epsilon/draft/pressure_manipulation.json rename to schemas/V_epsilon/stable/pressure_manipulation.json index 1d5640f..27f878c 100644 --- a/schemas/V_epsilon/draft/pressure_manipulation.json +++ b/schemas/V_epsilon/stable/pressure_manipulation.json @@ -10,7 +10,7 @@ "class_name": "scalar_pressure" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/procedural_manipulation.json b/schemas/V_epsilon/stable/procedural_manipulation.json similarity index 98% rename from schemas/V_epsilon/draft/procedural_manipulation.json rename to schemas/V_epsilon/stable/procedural_manipulation.json index b5a2448..3a58ffc 100644 --- a/schemas/V_epsilon/draft/procedural_manipulation.json +++ b/schemas/V_epsilon/stable/procedural_manipulation.json @@ -7,7 +7,7 @@ "class_name": "manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/respiration_rate_observation.json b/schemas/V_epsilon/stable/respiration_rate_observation.json similarity index 91% rename from schemas/V_epsilon/draft/respiration_rate_observation.json rename to schemas/V_epsilon/stable/respiration_rate_observation.json index 51749a5..e1f41e5 100644 --- a/schemas/V_epsilon/draft/respiration_rate_observation.json +++ b/schemas/V_epsilon/stable/respiration_rate_observation.json @@ -10,7 +10,7 @@ "class_name": "scalar_frequency" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/scalar_concentration.json b/schemas/V_epsilon/stable/scalar_concentration.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_concentration.json rename to schemas/V_epsilon/stable/scalar_concentration.json index 3f38948..a421f91 100644 --- a/schemas/V_epsilon/draft/scalar_concentration.json +++ b/schemas/V_epsilon/stable/scalar_concentration.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_count.json b/schemas/V_epsilon/stable/scalar_count.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_count.json rename to schemas/V_epsilon/stable/scalar_count.json index 0ff8cff..2b5831a 100644 --- a/schemas/V_epsilon/draft/scalar_count.json +++ b/schemas/V_epsilon/stable/scalar_count.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_current.json b/schemas/V_epsilon/stable/scalar_current.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_current.json rename to schemas/V_epsilon/stable/scalar_current.json index ac89218..ec5f50a 100644 --- a/schemas/V_epsilon/draft/scalar_current.json +++ b/schemas/V_epsilon/stable/scalar_current.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_duration.json b/schemas/V_epsilon/stable/scalar_duration.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_duration.json rename to schemas/V_epsilon/stable/scalar_duration.json index fbedc7b..0f7de5a 100644 --- a/schemas/V_epsilon/draft/scalar_duration.json +++ b/schemas/V_epsilon/stable/scalar_duration.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_frequency.json b/schemas/V_epsilon/stable/scalar_frequency.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_frequency.json rename to schemas/V_epsilon/stable/scalar_frequency.json index e2a5de2..70b38fd 100644 --- a/schemas/V_epsilon/draft/scalar_frequency.json +++ b/schemas/V_epsilon/stable/scalar_frequency.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_length.json b/schemas/V_epsilon/stable/scalar_length.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_length.json rename to schemas/V_epsilon/stable/scalar_length.json index 524830a..0d7108c 100644 --- a/schemas/V_epsilon/draft/scalar_length.json +++ b/schemas/V_epsilon/stable/scalar_length.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_manipulation.json b/schemas/V_epsilon/stable/scalar_manipulation.json similarity index 98% rename from schemas/V_epsilon/draft/scalar_manipulation.json rename to schemas/V_epsilon/stable/scalar_manipulation.json index 0d13590..14b2561 100644 --- a/schemas/V_epsilon/draft/scalar_manipulation.json +++ b/schemas/V_epsilon/stable/scalar_manipulation.json @@ -7,7 +7,7 @@ "class_name": "manipulation" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_mass.json b/schemas/V_epsilon/stable/scalar_mass.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_mass.json rename to schemas/V_epsilon/stable/scalar_mass.json index f5e397b..d31fd50 100644 --- a/schemas/V_epsilon/draft/scalar_mass.json +++ b/schemas/V_epsilon/stable/scalar_mass.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_observation.json b/schemas/V_epsilon/stable/scalar_observation.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_observation.json rename to schemas/V_epsilon/stable/scalar_observation.json index c0c9295..1b6a98b 100644 --- a/schemas/V_epsilon/draft/scalar_observation.json +++ b/schemas/V_epsilon/stable/scalar_observation.json @@ -7,7 +7,7 @@ "class_name": "observation" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_pressure.json b/schemas/V_epsilon/stable/scalar_pressure.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_pressure.json rename to schemas/V_epsilon/stable/scalar_pressure.json index 084389f..a571e1a 100644 --- a/schemas/V_epsilon/draft/scalar_pressure.json +++ b/schemas/V_epsilon/stable/scalar_pressure.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_score.json b/schemas/V_epsilon/stable/scalar_score.json similarity index 97% rename from schemas/V_epsilon/draft/scalar_score.json rename to schemas/V_epsilon/stable/scalar_score.json index 4d37e61..4b881ba 100644 --- a/schemas/V_epsilon/draft/scalar_score.json +++ b/schemas/V_epsilon/stable/scalar_score.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_temperature.json b/schemas/V_epsilon/stable/scalar_temperature.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_temperature.json rename to schemas/V_epsilon/stable/scalar_temperature.json index a0e03f6..426eea0 100644 --- a/schemas/V_epsilon/draft/scalar_temperature.json +++ b/schemas/V_epsilon/stable/scalar_temperature.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_voltage.json b/schemas/V_epsilon/stable/scalar_voltage.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_voltage.json rename to schemas/V_epsilon/stable/scalar_voltage.json index 669f0c9..7bca81a 100644 --- a/schemas/V_epsilon/draft/scalar_voltage.json +++ b/schemas/V_epsilon/stable/scalar_voltage.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/scalar_volume.json b/schemas/V_epsilon/stable/scalar_volume.json similarity index 96% rename from schemas/V_epsilon/draft/scalar_volume.json rename to schemas/V_epsilon/stable/scalar_volume.json index 8c484c8..6d0f421 100644 --- a/schemas/V_epsilon/draft/scalar_volume.json +++ b/schemas/V_epsilon/stable/scalar_volume.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/session_extent.json b/schemas/V_epsilon/stable/session_extent.json similarity index 98% rename from schemas/V_epsilon/draft/session_extent.json rename to schemas/V_epsilon/stable/session_extent.json index ec933f7..23a84de 100644 --- a/schemas/V_epsilon/draft/session_extent.json +++ b/schemas/V_epsilon/stable/session_extent.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/session_relative_reference.json b/schemas/V_epsilon/stable/session_relative_reference.json similarity index 97% rename from schemas/V_epsilon/draft/session_relative_reference.json rename to schemas/V_epsilon/stable/session_relative_reference.json index af9ae38..5da709d 100644 --- a/schemas/V_epsilon/draft/session_relative_reference.json +++ b/schemas/V_epsilon/stable/session_relative_reference.json @@ -7,7 +7,7 @@ "class_name": "time_reference" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/stimulus_approach.json b/schemas/V_epsilon/stable/stimulus_approach.json similarity index 98% rename from schemas/V_epsilon/draft/stimulus_approach.json rename to schemas/V_epsilon/stable/stimulus_approach.json index 75039ee..016b1fb 100644 --- a/schemas/V_epsilon/draft/stimulus_approach.json +++ b/schemas/V_epsilon/stable/stimulus_approach.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/stimulus_bath.json b/schemas/V_epsilon/stable/stimulus_bath.json similarity index 93% rename from schemas/V_epsilon/draft/stimulus_bath.json rename to schemas/V_epsilon/stable/stimulus_bath.json index 1ac1734..56d2f0c 100644 --- a/schemas/V_epsilon/draft/stimulus_bath.json +++ b/schemas/V_epsilon/stable/stimulus_bath.json @@ -7,7 +7,7 @@ "class_name": "bath" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/stimulus_manipulation.json b/schemas/V_epsilon/stable/stimulus_manipulation.json similarity index 96% rename from schemas/V_epsilon/draft/stimulus_manipulation.json rename to schemas/V_epsilon/stable/stimulus_manipulation.json index 75eb70d..157bb2f 100644 --- a/schemas/V_epsilon/draft/stimulus_manipulation.json +++ b/schemas/V_epsilon/stable/stimulus_manipulation.json @@ -7,7 +7,7 @@ "class_name": "manipulation" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [ { diff --git a/schemas/V_epsilon/draft/subject_assertion.json b/schemas/V_epsilon/stable/subject_assertion.json similarity index 98% rename from schemas/V_epsilon/draft/subject_assertion.json rename to schemas/V_epsilon/stable/subject_assertion.json index b27b42d..31772a7 100644 --- a/schemas/V_epsilon/draft/subject_assertion.json +++ b/schemas/V_epsilon/stable/subject_assertion.json @@ -7,7 +7,7 @@ "class_name": "subject_statement" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/subject_interaction.json b/schemas/V_epsilon/stable/subject_interaction.json similarity index 94% rename from schemas/V_epsilon/draft/subject_interaction.json rename to schemas/V_epsilon/stable/subject_interaction.json index 3eedc2f..739777d 100644 --- a/schemas/V_epsilon/draft/subject_interaction.json +++ b/schemas/V_epsilon/stable/subject_interaction.json @@ -7,7 +7,7 @@ "class_name": "subject_statement" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [ diff --git a/schemas/V_epsilon/draft/subject_statement.json b/schemas/V_epsilon/stable/subject_statement.json similarity index 93% rename from schemas/V_epsilon/draft/subject_statement.json rename to schemas/V_epsilon/stable/subject_statement.json index 2b9456e..b1571aa 100644 --- a/schemas/V_epsilon/draft/subject_statement.json +++ b/schemas/V_epsilon/stable/subject_statement.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [ diff --git a/schemas/V_epsilon/draft/temperature_manipulation.json b/schemas/V_epsilon/stable/temperature_manipulation.json similarity index 91% rename from schemas/V_epsilon/draft/temperature_manipulation.json rename to schemas/V_epsilon/stable/temperature_manipulation.json index d33e618..df0374e 100644 --- a/schemas/V_epsilon/draft/temperature_manipulation.json +++ b/schemas/V_epsilon/stable/temperature_manipulation.json @@ -10,7 +10,7 @@ "class_name": "scalar_temperature" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon/draft/time_reference.json b/schemas/V_epsilon/stable/time_reference.json similarity index 95% rename from schemas/V_epsilon/draft/time_reference.json rename to schemas/V_epsilon/stable/time_reference.json index f151edc..dae6ae8 100644 --- a/schemas/V_epsilon/draft/time_reference.json +++ b/schemas/V_epsilon/stable/time_reference.json @@ -7,7 +7,7 @@ "class_name": "base" } ], - "maturity_level": "draft", + "maturity_level": "stable", "abstract": true }, "depends_on": [], diff --git a/schemas/V_epsilon/draft/utc_reference.json b/schemas/V_epsilon/stable/utc_reference.json similarity index 97% rename from schemas/V_epsilon/draft/utc_reference.json rename to schemas/V_epsilon/stable/utc_reference.json index 7b87854..b1401b3 100644 --- a/schemas/V_epsilon/draft/utc_reference.json +++ b/schemas/V_epsilon/stable/utc_reference.json @@ -7,7 +7,7 @@ "class_name": "time_reference" } ], - "maturity_level": "draft" + "maturity_level": "stable" }, "depends_on": [], "file": [], diff --git a/schemas/V_epsilon_SPEC.md b/schemas/V_epsilon_SPEC.md index da060fc..d0a377d 100644 --- a/schemas/V_epsilon_SPEC.md +++ b/schemas/V_epsilon_SPEC.md @@ -278,3 +278,17 @@ copy `schemas/V_epsilon/` to `schemas/V1/`, freeze it, replace the `"V_epsilon"` value in `schema_version` fields and `index.json`, and tag the repository. Before promotion, the `draft/` families are expected to be exercised against real curations and re-tiered to `stable/`. + +**Tier status.** The Brainstorm-E migration families — the +`subject_interaction` spine, the `time_reference` family, the scalar/ +categorical observation tiers and their shape mixins, the manipulation +tiers, and the annotation/event classes (`group_assignment`, `placement`, +`derivation`, `session_extent`, `interaction_purpose`, `stimulus_approach`) +— have been **promoted to `stable/`** after running clean against the +discovery corpora (0 quarantine). The section headers below still read +"new, `draft/`" to record where each family was *added*; `index.json` is +the authoritative tier placement. The genomics/omics + file-backed +dataseries data-format families (`expression_*`, `sequence_read_data_*`, +`reference_sequence_data_*` / `reference_annotation_data_*`, `dataseries_*` +/ `timeseries_*` / `imageseries_*`, `instrument`) remain in `draft/` as a +separate effort not exercised by the physiology corpora. diff --git a/tests/test_series_cardinality.py b/tests/test_series_cardinality.py index 593543b..a2e0c17 100644 --- a/tests/test_series_cardinality.py +++ b/tests/test_series_cardinality.py @@ -20,9 +20,23 @@ REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DRAFT = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "draft") +STABLE = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "stable") EXAMPLES = os.path.join(REPO_ROOT, "schemas", "V_epsilon", "examples") EXAMPLE_DOC = os.path.join(EXAMPLES, "core_temperature_observation_series.json") + +def _schema_path(name): + """Locate a class schema by name across tiers (stable or draft). + + The series classes were promoted draft -> stable; resolving by tier + keeps this test correct regardless of which tier a class lives in. + """ + for tier in (STABLE, DRAFT): + p = os.path.join(tier, name + ".json") + if os.path.exists(p): + return p + raise FileNotFoundError(name + ".json (stable or draft)") + SCALAR_MIXINS = [ "scalar_mass", "scalar_length", "scalar_duration", "scalar_volume", "scalar_temperature", "scalar_pressure", "scalar_frequency", "scalar_voltage", @@ -73,7 +87,7 @@ def check_series_lengths(doc, value_path=("scalar_temperature", "value"), class TestSeriesSchema: def test_every_scalar_mixin_value_is_an_array(self): for m in SCALAR_MIXINS: - schema = _load(os.path.join(DRAFT, m + ".json")) + schema = _load(_schema_path(m)) value = _field(schema, "value") assert value is not None, f"{m} must declare value" assert value["mustBeScalar"] is False, \ @@ -81,7 +95,7 @@ def test_every_scalar_mixin_value_is_an_array(self): def test_sample_time_is_array_of_duration_on_genus(self): for genus in ("scalar_observation", "scalar_manipulation"): - schema = _load(os.path.join(DRAFT, genus + ".json")) + schema = _load(_schema_path(genus)) st = _field(schema, "sample_time") assert st is not None, f"{genus} must declare sample_time" assert st["type"] == "duration" @@ -90,7 +104,7 @@ def test_sample_time_is_array_of_duration_on_genus(self): def test_concrete_temperature_class_inherits_the_shape(self): # The concrete property class no longer overrides value/sample_time; # it inherits the array form from scalar_temperature / scalar_observation. - schema = _load(os.path.join(DRAFT, "core_temperature_observation.json")) + schema = _load(_schema_path("core_temperature_observation")) assert _field(schema, "value") is None assert _field(schema, "sample_time") is None