diff --git a/schemas/V_delta/stable/app.json b/schemas/V_delta/stable/app.json index f7f06bb..2780404 100644 --- a/schemas/V_delta/stable/app.json +++ b/schemas/V_delta/stable/app.json @@ -17,7 +17,7 @@ "type": "char", "blank_value": "", "default_value": "ndi.app", - "mustBeNonEmpty": true, + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, diff --git a/schemas/V_delta/stable/control_stimulus_ids.json b/schemas/V_delta/stable/control_stimulus_ids.json index 85f8a74..5f54048 100644 --- a/schemas/V_delta/stable/control_stimulus_ids.json +++ b/schemas/V_delta/stable/control_stimulus_ids.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "app" } ], "maturity_level": "stable" @@ -12,38 +15,91 @@ "depends_on": [ { "name": "stimulus_presentation_id", - "mustBeNonEmpty": true, - "documentation": "The document ID of the stimulus presentation these control IDs describe.", + "mustBeNonEmpty": false, + "documentation": "Optional pointer to the stimulus_presentation document these control IDs annotate.", "must_refer_to_document_class": "" } ], "file": [], "fields": [ { - "name": "control_ids", - "type": "char", - "blank_value": "", - "default_value": "", + "name": "control_stimulus_ids", + "type": "matrix", + "blank_value": [], + "default_value": [], "mustBeNonEmpty": false, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "Comma-separated list of control stimulus identifiers (e.g., 'blank,gray_screen'). These identify which stimulus conditions serve as controls.", + "documentation": "Integer identifier(s) of the stimulus condition(s) that serve as the control reference for the linked stimulus_presentation. v1 sometimes ships NaN when no control was recorded; sometimes a scalar; sometimes an array.", "constraints": {} }, { - "name": "num_control_ids", - "type": "integer", - "blank_value": 0, - "default_value": 0, + "name": "control_stimulus_id_method", + "type": "structure", + "blank_value": { + "method": "", + "controlid": "", + "controlid_value": 0 + }, + "default_value": { + "method": "", + "controlid": "", + "controlid_value": 0 + }, "mustBeNonEmpty": false, "mustBeScalar": true, - "mustNotHaveNaN": true, + "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The number of unique control stimulus identifiers.", - "constraints": {} + "documentation": "How the control_stimulus_ids were derived. v1 uniformly ships a 3-field struct: method (e.g., 'pseudorandom'), controlid (e.g., 'isblank'), and controlid_value (numeric tag, e.g., 1).", + "constraints": {}, + "fields": [ + { + "name": "method", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Name of the algorithm used to identify which stimuli are controls (e.g., 'pseudorandom', 'explicit_list').", + "constraints": { + "maxLength": 64 + } + }, + { + "name": "controlid", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Name of the per-stimulus key that flags control trials (e.g., 'isblank').", + "constraints": { + "maxLength": 64 + } + }, + { + "name": "controlid_value", + "type": "double", + "blank_value": 0, + "default_value": 0, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Value of `controlid` that marks a trial as a control (e.g., 1).", + "constraints": {} + } + ] } ] } diff --git a/schemas/V_delta/stable/daqmetadatareader_epochdata_ingested.json b/schemas/V_delta/stable/daqmetadatareader_epochdata_ingested.json index 7a387fe..c6e4762 100644 --- a/schemas/V_delta/stable/daqmetadatareader_epochdata_ingested.json +++ b/schemas/V_delta/stable/daqmetadatareader_epochdata_ingested.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "epochid" } ], "maturity_level": "stable" @@ -15,30 +18,8 @@ "mustBeNonEmpty": true, "documentation": "The document ID of the DAQ metadata reader whose epoch data has been ingested.", "must_refer_to_document_class": "" - }, - { - "name": "epochid", - "mustBeNonEmpty": true, - "documentation": "The document ID of the epoch whose data was ingested.", - "must_refer_to_document_class": "" } ], "file": [], - "fields": [ - { - "name": "ingestion_status", - "type": "char", - "blank_value": "", - "default_value": "complete", - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "The status of the ingestion ('complete', 'partial', 'failed').", - "constraints": { - "maxLength": 32 - } - } - ] + "fields": [] } diff --git a/schemas/V_delta/stable/daqreader_epochdata_ingested.json b/schemas/V_delta/stable/daqreader_epochdata_ingested.json index 5166677..21ba839 100644 --- a/schemas/V_delta/stable/daqreader_epochdata_ingested.json +++ b/schemas/V_delta/stable/daqreader_epochdata_ingested.json @@ -26,19 +26,51 @@ "file": [], "fields": [ { - "name": "ingestion_status", - "type": "char", - "blank_value": "", - "default_value": "complete", - "mustBeNonEmpty": true, + "name": "epochtable", + "type": "structure", + "blank_value": { + "epochclock": [], + "t0_t1": [] + }, + "default_value": { + "epochclock": [], + "t0_t1": [] + }, + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, - "queryable": true, + "queryable": false, "ontology": null, - "documentation": "The status of the ingestion ('complete', 'partial', 'failed').", - "constraints": { - "maxLength": 32 - } + "documentation": "Captured epoch-table snapshot for the ingested epoch. v1 ships {epochclock: [], t0_t1: [t0, t1]} — clock identifier(s) and the corresponding start/stop time pair, both in the units of that clock.", + "constraints": {}, + "fields": [ + { + "name": "epochclock", + "type": "string", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Cell array of clock identifier strings (e.g., {'dev_local_time'}) that index the t0_t1 row(s).", + "constraints": {} + }, + { + "name": "t0_t1", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Two-element [t0, t1] start/stop time pair in the units of the matching epochclock entry.", + "constraints": {} + } + ] } ] } diff --git a/schemas/V_delta/stable/daqreader_mfdaq_epochdata_ingested.json b/schemas/V_delta/stable/daqreader_mfdaq_epochdata_ingested.json index cbba6f2..e441450 100644 --- a/schemas/V_delta/stable/daqreader_mfdaq_epochdata_ingested.json +++ b/schemas/V_delta/stable/daqreader_mfdaq_epochdata_ingested.json @@ -5,40 +5,65 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "daqreader_epochdata_ingested" + }, + { + "class_name": "epochid" } ], "maturity_level": "stable" }, - "depends_on": [ - { - "name": "daqreader_id", - "mustBeNonEmpty": true, - "documentation": "The document ID of the MFDAQ reader whose epoch data has been ingested.", - "must_refer_to_document_class": "" - }, - { - "name": "epochid", - "mustBeNonEmpty": true, - "documentation": "The document ID of the epoch whose data was ingested.", - "must_refer_to_document_class": "" - } - ], + "depends_on": [], "file": [], "fields": [ { - "name": "ingestion_status", - "type": "char", - "blank_value": "", - "default_value": "complete", - "mustBeNonEmpty": true, + "name": "parameters", + "type": "structure", + "blank_value": { + "sample_analog_segment": 0.0, + "sample_digital_segment": 0.0 + }, + "default_value": { + "sample_analog_segment": 0.0, + "sample_digital_segment": 0.0 + }, + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The status of the ingestion ('complete', 'partial', 'failed').", - "constraints": { - "maxLength": 32 - } + "documentation": "Reader-specific parameters captured at the time the epoch was ingested. The two sub-fields seen in the v1 corpora are sample-count cutoffs the MFDAQ reader used to slice the source recording.", + "constraints": {}, + "fields": [ + { + "name": "sample_analog_segment", + "type": "double", + "blank_value": 0.0, + "default_value": 0.0, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Maximum sample count per analog segment used during ingestion.", + "constraints": {} + }, + { + "name": "sample_digital_segment", + "type": "double", + "blank_value": 0.0, + "default_value": 0.0, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Maximum sample count per digital segment used during ingestion.", + "constraints": {} + } + ] } ] } diff --git a/schemas/V_delta/stable/dataset_remote.json b/schemas/V_delta/stable/dataset_remote.json index c98cb49..55d7a48 100644 --- a/schemas/V_delta/stable/dataset_remote.json +++ b/schemas/V_delta/stable/dataset_remote.json @@ -13,22 +13,22 @@ "file": [], "fields": [ { - "name": "remote_url", + "name": "remote_type", "type": "char", "blank_value": "", "default_value": "", - "mustBeNonEmpty": true, + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The URL of the remote dataset location.", + "documentation": "The type of remote storage (e.g., 's3', 'http', 'globus', 'git').", "constraints": { - "maxLength": 1024 + "maxLength": 64 } }, { - "name": "remote_type", + "name": "dataset_id", "type": "char", "blank_value": "", "default_value": "", @@ -37,13 +37,13 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The type of remote storage (e.g., 's3', 'http', 'globus', 'git').", + "documentation": "The dataset identifier at the remote location.", "constraints": { - "maxLength": 64 + "maxLength": 256 } }, { - "name": "dataset_id", + "name": "organization_id", "type": "char", "blank_value": "", "default_value": "", @@ -52,7 +52,7 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The dataset identifier at the remote location.", + "documentation": "Organization identifier at the remote service (e.g., the lab or owning group whose namespace the dataset lives under).", "constraints": { "maxLength": 256 } diff --git a/schemas/V_delta/stable/did_schema_meta.json b/schemas/V_delta/stable/did_schema_meta.json index 1c5d3ed..76f68ce 100644 --- a/schemas/V_delta/stable/did_schema_meta.json +++ b/schemas/V_delta/stable/did_schema_meta.json @@ -2,7 +2,7 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://did-schema.example.org/V_delta/did_schema_meta.json", "title": "DID/NDI Schema Meta-Schema (V_delta)", - "description": "Validates the structure of DID/NDI schema files for V_delta. V_delta introduces named composite types 'duration', 'ontology_term', 'volume', 'mass', 'length', 'voltage', 'current', and 'frequency', and a redesigned field-level 'ontology' annotation shape with keys 'node' (CURIE) and 'name' (label); the CURIE prefix is resolved against CURIE_lookups_meta.json. The six SI-dimensioned types share the same sub-field layout as 'duration' (a canonical-unit double, 'approximate' boolean, 'source_unit' char, 'source_value' double); only the canonical sub-field name and the allowed source units differ. NAMING CONVENTION: V_delta drops the V_beta underscore prefix on NDI-extension keys. Every reserved key \u2014 JSON Schema vocabulary or NDI extension \u2014 is used without an underscore prefix; the authoritative enumeration of NDI-reserved names lives in ndi_reserved_keys.json and is enforced by this meta-schema. Schema authors must not reuse a reserved name as their own data field name.", + "description": "Validates the structure of DID/NDI schema files for V_delta. V_delta introduces named composite types 'duration', 'ontology_term', 'volume', 'mass', 'length', 'voltage', 'current', 'frequency', and 'concentration', and a redesigned field-level 'ontology' annotation shape with keys 'node' (CURIE) and 'name' (label); the CURIE prefix is resolved against CURIE_lookups_meta.json. The six SI-dimensioned types ('duration', 'volume', 'mass', 'length', 'voltage', 'current', 'frequency') share the same sub-field layout (a canonical-unit double, 'approximate' boolean, 'source_unit' char, 'source_value' double); only the canonical sub-field name and the allowed source units differ. 'concentration' breaks the single-canonical pattern because concentration units do not collapse to a single canonical (mass/volume cannot be converted to molar without molecular weight, and vice versa); instead it offers multiple OPTIONAL canonical sub-fields ('molar', 'grams_per_liter', 'mass_fraction', 'volume_fraction') and the migrator populates whichever the source unit is computable into, alongside the same 'approximate' / 'source_unit' / 'source_value' triple. NAMING CONVENTION: V_delta drops the V_beta underscore prefix on NDI-extension keys. Every reserved key \u2014 JSON Schema vocabulary or NDI extension \u2014 is used without an underscore prefix; the authoritative enumeration of NDI-reserved names lives in ndi_reserved_keys.json and is enforced by this meta-schema. Schema authors must not reuse a reserved name as their own data field name.", "type": "object", "required": [ "document_class", @@ -227,7 +227,8 @@ "length", "voltage", "current", - "frequency" + "frequency", + "concentration" ], "description": "Data type of the field. Uses the standard JSON Schema keyword 'type'; values are NDI-specific." }, diff --git a/schemas/V_delta/stable/distance_metadata.json b/schemas/V_delta/stable/distance_metadata.json index 2a6701b..01f581e 100644 --- a/schemas/V_delta/stable/distance_metadata.json +++ b/schemas/V_delta/stable/distance_metadata.json @@ -11,47 +11,122 @@ }, "depends_on": [ { - "name": "element_id_1", + "name": "element_id", "mustBeNonEmpty": true, - "documentation": "The document ID of the first element.", - "must_refer_to_document_class": "" - }, - { - "name": "element_id_2", - "mustBeNonEmpty": true, - "documentation": "The document ID of the second element.", + "documentation": "The document ID of the element whose endpoints' distance is described by this metadata.", "must_refer_to_document_class": "" } ], "file": [], "fields": [ { - "name": "distance", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, + "name": "endpoints", + "type": "structure", + "blank_value": [], + "default_value": [], "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, "ontology": null, - "documentation": "The distance between the two elements, in distance_units.", - "constraints": {} + "documentation": "Array of per-endpoint records describing the entities whose pairwise distance is being measured. v1 stored exactly two endpoints labelled 'A' and 'B'; V_delta keeps those labels explicit on each record's `label` field but generalises the container to an array so future N-endpoint distance schemes can reuse the same shape. Each endpoint carries: an ontology classification (`measurement`), a set of integer indices and document-id strings identifying which items at the linked element the endpoint covers, and an optional numeric-values vector. v1's `ontologyStringValues_X` (comma-separated did_uid list) becomes `string_ids` as a string array; v1's `integerIDs_X` (scalar or array) becomes `integer_ids` as a matrix.", + "constraints": {}, + "fields": [ + { + "name": "label", + "type": "char", + "blank_value": "", + "default_value": "A", + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Per-endpoint identifier preserved verbatim from v1 (e.g., 'A', 'B'). Consumers can filter by label without resolving the ontology classification.", + "constraints": { + "maxLength": 64 + } + }, + { + "name": "measurement", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Ontology term classifying what kind of entity this endpoint refers to (e.g., a probe contact, a stimulation site). `node` is the v1 `ontologyNode_X` CURIE verbatim; `name` is resolved via ndi.ontology.lookup at conversion time.", + "constraints": {} + }, + { + "name": "integer_ids", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": true, + "queryable": false, + "ontology": null, + "documentation": "Per-endpoint integer indices (e.g., contact numbers, item indices). v1 stored this as a scalar or array of integers; V_delta keeps it as a flat matrix of integers.", + "constraints": { + "element_type": "integer" + } + }, + { + "name": "string_ids", + "type": "string", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Per-endpoint document-id strings identifying the items the endpoint covers. v1 stored this as a single comma-separated did_uid string; V_delta represents it as a string array (one entry per id). Indexed in parallel with `integer_ids` when both are populated.", + "constraints": {} + }, + { + "name": "numeric_values", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Optional per-endpoint numeric values (often empty in v1 corpora; reserved for calibrations or per-item measurements that the endpoint definition needs to carry inline).", + "constraints": {} + } + ] }, { - "name": "distance_units", - "type": "char", - "blank_value": "", - "default_value": "um", + "name": "units", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, "mustBeNonEmpty": true, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The units for the distance value (e.g., 'um', 'mm', 'cm').", - "constraints": { - "maxLength": 32 - } + "documentation": "Ontology term naming the measurement unit for the distance (e.g., 'micrometer'). Resolved via ndi.ontology.lookup.", + "constraints": {} } ] } diff --git a/schemas/V_delta/stable/element_epoch.json b/schemas/V_delta/stable/element_epoch.json index 601fbaf..0a09d1b 100644 --- a/schemas/V_delta/stable/element_epoch.json +++ b/schemas/V_delta/stable/element_epoch.json @@ -23,45 +23,60 @@ "file": [], "fields": [ { - "name": "epoch_clock", - "type": "char", - "blank_value": "", - "default_value": "dev_local_time", + "name": "clocks", + "type": "structure", + "blank_value": [], + "default_value": [], "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "The clock type that describes this epoch (e.g., 'dev_local_time', 'utc', 'exp_global_time').", - "constraints": { - "maxLength": 256 - } - }, - { - "name": "t0", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, - "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": true, - "queryable": false, - "ontology": null, - "documentation": "The start time of this epoch, in time units of epoch_clock.", - "constraints": {} - }, - { - "name": "t1", - "type": "double", - "blank_value": 1.0, - "default_value": 1.0, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": false, + "queryable": true, "ontology": null, - "documentation": "The stop time of this epoch, in time units of epoch_clock.", - "constraints": {} + "documentation": "Array-of-records: one entry per clock reference frame in which this element's epoch is timed. Each entry carries the clock identifier (`name`) and the start/stop times (`t0`, `t1`) in that clock's units. The single-clock case (most v1 documents) is a 1-element array; v1 documents that recorded the same epoch in multiple clocks (e.g., 'dev_local_time' + 'exp_global_time') become multi-element arrays. Comma-separated v1 `epoch_clock` strings split on `,` to populate clocks[i].name; v1's N×2 `t0_t1` splits row-wise to populate clocks[i].t0 and clocks[i].t1.", + "constraints": {}, + "fields": [ + { + "name": "name", + "type": "char", + "blank_value": "", + "default_value": "dev_local_time", + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Clock identifier (e.g., 'dev_local_time', 'utc', 'exp_global_time').", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "t0", + "type": "double", + "blank_value": 0.0, + "default_value": 0.0, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": true, + "queryable": false, + "ontology": null, + "documentation": "Start time of this epoch in the units of the clock named in this record.", + "constraints": {} + }, + { + "name": "t1", + "type": "double", + "blank_value": 1.0, + "default_value": 1.0, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": true, + "queryable": false, + "ontology": null, + "documentation": "Stop time of this epoch in the units of the clock named in this record.", + "constraints": {} + } + ] } ] } diff --git a/schemas/V_delta/stable/epochfiles_ingested.json b/schemas/V_delta/stable/epochfiles_ingested.json index ade29e4..2c6bf57 100644 --- a/schemas/V_delta/stable/epochfiles_ingested.json +++ b/schemas/V_delta/stable/epochfiles_ingested.json @@ -20,31 +20,47 @@ "file": [], "fields": [ { - "name": "ingestion_status", + "name": "epoch_id", "type": "char", "blank_value": "", - "default_value": "complete", - "mustBeNonEmpty": true, + "default_value": "", + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, - "ontology": null, - "documentation": "The status of the epoch files ingestion ('complete', 'partial', 'failed').", + "ontology": { + "node": "iao:0000578", + "name": "centrally registered identifier" + }, + "documentation": "Epoch identifier within the owning session (e.g., 't00001'). v1-faithful inline copy of the epoch's local name; the document-id link to the epoch lives in `depends_on[epochid]`.", "constraints": { - "maxLength": 32 + "maxLength": 256 } }, { - "name": "num_files_ingested", - "type": "integer", - "blank_value": 0, - "default_value": 0, + "name": "files", + "type": "string", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "List of file references ingested for this epoch. Entries are either NDI-scheme URIs (e.g., 'epochid://t00001') or absolute filesystem paths to the source files. Length varies per epoch (3-6 entries seen in the discovery corpora).", + "constraints": {} + }, + { + "name": "epochprobemap", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": true, + "mustNotHaveNaN": false, + "queryable": false, "ontology": null, - "documentation": "The number of files ingested for this epoch.", + "documentation": "Tab-separated epoch-probe-map text describing the probe configuration at ingest time. Free-form pass-through from v1; structure is `name\\treference\\ttype\\tdevicestring\\tsubjectstring\\n\\n...`.", "constraints": {} } ] diff --git a/schemas/V_delta/stable/image_stack.json b/schemas/V_delta/stable/image_stack.json index 012535e..e992d56 100644 --- a/schemas/V_delta/stable/image_stack.json +++ b/schemas/V_delta/stable/image_stack.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "image_stack_parameters" } ], "maturity_level": "stable" @@ -25,46 +28,20 @@ ], "fields": [ { - "name": "num_frames", - "type": "integer", - "blank_value": 0, - "default_value": 0, + "name": "label", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, - "mustNotHaveNaN": true, + "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The number of frames (slices) in the image stack.", - "constraints": {} - }, - { - "name": "x_pixels", - "type": "integer", - "blank_value": 0, - "default_value": 0, - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": false, - "ontology": null, - "documentation": "The number of pixels in the x-dimension per frame.", - "constraints": {} - }, - { - "name": "y_pixels", - "type": "integer", - "blank_value": 0, - "default_value": 0, - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": false, - "ontology": null, - "documentation": "The number of pixels in the y-dimension per frame.", + "documentation": "Free-text label or caption describing the image stack (e.g., 'An image of fluorescently labeled bacterial patches that has been processed to ...').", "constraints": {} }, { - "name": "image_format", + "name": "format_ontology", "type": "char", "blank_value": "", "default_value": "", @@ -73,9 +50,9 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The file format of the image stack (e.g., 'tiff', 'nifti').", + "documentation": "Ontology CURIE describing the image format / content type (e.g., 'NCIT:C70631' for a particular imaging modality). v1 corpora ship the CURIE directly as a char; consumers resolve via ndi.ontology.lookup when a human-readable name is needed.", "constraints": { - "maxLength": 32 + "maxLength": 256 } } ] diff --git a/schemas/V_delta/stable/image_stack_parameters.json b/schemas/V_delta/stable/image_stack_parameters.json index f221c59..ffbbaea 100644 --- a/schemas/V_delta/stable/image_stack_parameters.json +++ b/schemas/V_delta/stable/image_stack_parameters.json @@ -12,7 +12,7 @@ "depends_on": [ { "name": "imagestack_id", - "mustBeNonEmpty": true, + "mustBeNonEmpty": false, "documentation": "The document ID of the image stack these parameters describe.", "must_refer_to_document_class": "" } @@ -20,72 +20,132 @@ "file": [], "fields": [ { - "name": "z_step", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, + "name": "dimension_order", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "String encoding the spatial dimension order of the stack, one character per axis (e.g., 'YX' for a 2-D height-by-width image, 'ZYX' or 'TZYX' for higher-dimensional stacks).", + "constraints": { + "maxLength": 16 + } + }, + { + "name": "dimension_labels", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Comma-separated human-readable labels for each axis (e.g., 'height,width', 'depth,height,width'). One label per character in dimension_order.", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "dimension_size", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": true, + "queryable": false, + "ontology": null, + "documentation": "Pixel/sample count along each axis. Length equals number of characters in dimension_order (e.g., [2208, 2752] for a 'YX' stack).", + "constraints": { + "element_type": "integer" + } + }, + { + "name": "dimension_scale", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "The step size in the z-dimension between frames.", + "documentation": "Physical scale per axis (e.g., 94.89 micrometers per Y pixel). Same length as dimension_size; units captured in dimension_scale_units.", "constraints": {} }, { - "name": "z_units", + "name": "dimension_scale_units", "type": "char", "blank_value": "", - "default_value": "um", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, - "queryable": false, + "queryable": true, "ontology": null, - "documentation": "The units for the z-step (e.g., 'um', 'mm').", + "documentation": "Comma-separated unit names for each axis (e.g., 'micrometer,micrometer', 'micrometer,micrometer,micrometer').", "constraints": { - "maxLength": 32 + "maxLength": 256 } }, { - "name": "x_pixel_size", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, + "name": "data_type", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "The numeric data type of pixel values (e.g., 'uint16', 'single', 'double').", + "constraints": { + "maxLength": 32 + } + }, + { + "name": "data_limits", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "The physical size of a pixel in the x-dimension.", + "documentation": "2-element [min, max] range of valid pixel values for the declared data_type (e.g., [0, 65535] for uint16).", "constraints": {} }, { - "name": "y_pixel_size", + "name": "timestamp", "type": "double", "blank_value": 0.0, "default_value": 0.0, "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, - "queryable": false, + "queryable": true, "ontology": null, - "documentation": "The physical size of a pixel in the y-dimension.", + "documentation": "Acquisition timestamp of this image stack in the units of clocktype.", "constraints": {} }, { - "name": "pixel_units", + "name": "clocktype", "type": "char", "blank_value": "", - "default_value": "um", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, - "queryable": false, + "queryable": true, "ontology": null, - "documentation": "The units for the pixel size (e.g., 'um', 'mm').", + "documentation": "Clock identifier in whose units `timestamp` is expressed (e.g., 'exp_global_time', 'dev_local_time'). Same vocabulary as the epochclocktimes/element_epoch clock names.", "constraints": { - "maxLength": 32 + "maxLength": 256 } } ] diff --git a/schemas/V_delta/stable/jrclust_clusters.json b/schemas/V_delta/stable/jrclust_clusters.json index 7eb7597..cdba834 100644 --- a/schemas/V_delta/stable/jrclust_clusters.json +++ b/schemas/V_delta/stable/jrclust_clusters.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "app" } ], "maturity_level": "stable" @@ -25,20 +28,7 @@ ], "fields": [ { - "name": "num_clusters", - "type": "integer", - "blank_value": 0, - "default_value": 0, - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": true, - "ontology": null, - "documentation": "The number of clusters found by JRCLUST.", - "constraints": {} - }, - { - "name": "jrclust_version", + "name": "res_mat_md5_checksum", "type": "char", "blank_value": "", "default_value": "", @@ -47,9 +37,9 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The version of JRCLUST used for sorting.", + "documentation": "MD5 checksum of the JRCLUST *_res.mat results file, recorded at ingestion so downstream consumers can detect resort/reanalysis.", "constraints": { - "maxLength": 32 + "maxLength": 64 } } ] diff --git a/schemas/V_delta/stable/metadata_editor.json b/schemas/V_delta/stable/metadata_editor.json index 4a4d63e..2c44cc9 100644 --- a/schemas/V_delta/stable/metadata_editor.json +++ b/schemas/V_delta/stable/metadata_editor.json @@ -13,34 +13,18 @@ "file": [], "fields": [ { - "name": "editor_class", - "type": "char", - "blank_value": "", - "default_value": "", - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": true, - "ontology": null, - "documentation": "The class name of the metadata editor implementation.", - "constraints": { - "maxLength": 256 - } - }, - { - "name": "target_classname", - "type": "char", - "blank_value": "", - "default_value": "", + "name": "metadata_structure", + "type": "structure", + "blank_value": {}, + "default_value": {}, "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, - "queryable": true, + "queryable": false, "ontology": null, - "documentation": "The DID classname of the documents this editor can modify.", - "constraints": { - "maxLength": 256 - } + "documentation": "Arbitrary key/value metadata describing the dataset this document was authored against. v1 documents in the Soph corpus carry dataset-level descriptors here (VersionIdentifier, License, DataType, and others). The shape is intentionally open: keys and inner structure depend on the editor and the dataset.", + "constraints": {}, + "fields": [] } ] } diff --git a/schemas/V_delta/stable/neuron_extracellular.json b/schemas/V_delta/stable/neuron_extracellular.json index 1a44258..2186be2 100644 --- a/schemas/V_delta/stable/neuron_extracellular.json +++ b/schemas/V_delta/stable/neuron_extracellular.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "app" } ], "maturity_level": "stable" @@ -32,11 +35,63 @@ "node": "iao:0000578", "name": "centrally registered identifier" }, - "documentation": "The cluster index assigned to this neuron by a spike sorter. Matches the did_v1 field name; an earlier V_delta draft renamed it to `cluster_id` but the v1 source uses `cluster_index`, so the original name is preserved.", + "documentation": "The cluster index assigned to this neuron by a spike sorter.", + "constraints": {} + }, + { + "name": "number_of_channels", + "type": "integer", + "blank_value": 0, + "default_value": 0, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": true, + "queryable": true, + "ontology": null, + "documentation": "Number of recording channels contributing to this unit's waveform (e.g., the tetrode/probe channel count).", "constraints": {} }, { - "name": "quality", + "name": "number_of_samples_per_channel", + "type": "integer", + "blank_value": 0, + "default_value": 0, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": true, + "queryable": true, + "ontology": null, + "documentation": "Number of time samples per channel in mean_waveform / waveform_sample_times.", + "constraints": {} + }, + { + "name": "mean_waveform", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Mean spike-waveform matrix shaped (number_of_samples_per_channel x number_of_channels) -- samples down rows, channels across columns. Recorded in the original A/D units of the source data.", + "constraints": {} + }, + { + "name": "waveform_sample_times", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Time stamp of each sample in mean_waveform (seconds, in the element's local clock); length equals number_of_samples_per_channel.", + "constraints": {} + }, + { + "name": "quality_label", "type": "char", "blank_value": "", "default_value": "", @@ -48,13 +103,13 @@ "node": "placeholder:spike_sorting_quality_label", "name": "spike-sorting quality label" }, - "documentation": "Quality label for this unit (e.g., 'good', 'mua', 'noise'). Candidate for promotion to ontology_term once a controlled vocabulary (e.g., a spike-sorting quality branch in NIFSTD) is registered.", + "documentation": "Human-readable spike-sorting quality label (e.g., 'good', 'multi', 'noise'). Candidate for promotion to ontology_term once a controlled vocabulary (e.g., a spike-sorting quality branch in NIFSTD) is registered.", "constraints": { "maxLength": 64 } }, { - "name": "num_spikes", + "name": "quality_number", "type": "integer", "blank_value": 0, "default_value": 0, @@ -62,27 +117,8 @@ "mustBeScalar": true, "mustNotHaveNaN": true, "queryable": true, - "ontology": { - "node": "placeholder:action_potential_count", - "name": "action potential count" - }, - "documentation": "The total number of spikes assigned to this neuron.", - "constraints": {} - }, - { - "name": "mean_firing_rate", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": false, - "ontology": { - "node": "pato:0000044", - "name": "frequency" - }, - "documentation": "The mean firing rate of this neuron in Hz. Candidate for promotion to the V_gamma 'frequency' composite type.", + "ontology": null, + "documentation": "Numeric spike-sorting quality grade (e.g., 1-4) paired with quality_label. Sorter-specific scale.", "constraints": {} } ] diff --git a/schemas/V_delta/stable/openminds.json b/schemas/V_delta/stable/openminds.json index 14106c1..0c1891f 100644 --- a/schemas/V_delta/stable/openminds.json +++ b/schemas/V_delta/stable/openminds.json @@ -22,41 +22,57 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The openMINDS schema type (e.g., 'core.DatasetVersion', 'core.Person').", + "documentation": "Full openMINDS type IRI identifying which openMINDS schema this document carries (e.g., 'https://openminds.om-i.org/types/GeneticStrainType').", "constraints": { - "maxLength": 256 + "maxLength": 1024 } }, { - "name": "openminds_data", - "type": "structure", - "blank_value": {}, - "default_value": {}, + "name": "matlab_type", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, - "queryable": false, + "queryable": true, "ontology": null, - "documentation": "Structure containing the openMINDS metadata fields conforming to the schema type specified in openminds_type. Keys and value types follow the openMINDS specification for that type.", + "documentation": "Fully-qualified MATLAB class name of the corresponding openMINDS object (e.g., 'openminds.controlledterms.GeneticStrainType'). Paired with openminds_type for tooling that needs to reconstitute the MATLAB object.", "constraints": { - "conforms_to": "openminds_type" - }, - "fields": [] + "maxLength": 512 + } }, { - "name": "openminds_version", + "name": "openminds_id", "type": "char", "blank_value": "", - "default_value": "v3", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, - "ontology": null, - "documentation": "The version of the openMINDS specification used.", + "ontology": { + "node": "iao:0000578", + "name": "centrally registered identifier" + }, + "documentation": "openMINDS instance IRI (e.g., 'https://openminds.om-i.org/instances/geneticStrainType/wildtype'). Identifies a particular openMINDS object instance rather than its type.", "constraints": { - "maxLength": 16 + "maxLength": 1024 } + }, + { + "name": "fields", + "type": "structure", + "blank_value": {}, + "default_value": {}, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Open-shape struct carrying the openMINDS object's payload fields. Keys are openMINDS-type-specific (e.g., GeneticStrainType uses {definition, description, interlexIdentifier, knowledgeSpaceLink, name}); V_delta does not constrain them so each openMINDS type can contribute its own.", + "constraints": {}, + "fields": [] } ] } diff --git a/schemas/V_delta/stable/openminds_element.json b/schemas/V_delta/stable/openminds_element.json index bf50a78..dd903b4 100644 --- a/schemas/V_delta/stable/openminds_element.json +++ b/schemas/V_delta/stable/openminds_element.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "openminds" } ], "maturity_level": "stable" diff --git a/schemas/V_delta/stable/openminds_stimulus.json b/schemas/V_delta/stable/openminds_stimulus.json index f6cdba8..c791cfb 100644 --- a/schemas/V_delta/stable/openminds_stimulus.json +++ b/schemas/V_delta/stable/openminds_stimulus.json @@ -5,6 +5,12 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "openminds" + }, + { + "class_name": "epochid" } ], "maturity_level": "stable" diff --git a/schemas/V_delta/stable/openminds_subject.json b/schemas/V_delta/stable/openminds_subject.json index 201b49a..5efdaf5 100644 --- a/schemas/V_delta/stable/openminds_subject.json +++ b/schemas/V_delta/stable/openminds_subject.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "openminds" } ], "maturity_level": "stable" diff --git a/schemas/V_delta/stable/position_metadata.json b/schemas/V_delta/stable/position_metadata.json index 2e7b85a..774ca50 100644 --- a/schemas/V_delta/stable/position_metadata.json +++ b/schemas/V_delta/stable/position_metadata.json @@ -13,80 +13,110 @@ { "name": "element_id", "mustBeNonEmpty": true, - "documentation": "The document ID of the element whose position is described.", + "documentation": "The document ID of the element whose position is described by this metadata.", "must_refer_to_document_class": "" } ], "file": [], "fields": [ { - "name": "x", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, + "name": "measurement", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, "mustBeNonEmpty": true, "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": false, - "ontology": null, - "documentation": "The x-coordinate of the element position.", - "constraints": {} - }, - { - "name": "y", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": false, - "ontology": null, - "documentation": "The y-coordinate of the element position.", - "constraints": {} - }, - { - "name": "z", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, - "mustBeNonEmpty": true, - "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": false, - "ontology": null, - "documentation": "The z-coordinate of the element position.", + "mustNotHaveNaN": false, + "queryable": true, + "ontology": { + "node": "schema:location", + "name": "location" + }, + "documentation": "Ontology term classifying what kind of position is recorded by the linked element (e.g., a midpoint position, an anatomical landmark, a probe tip). The `node` is the v1 `ontologyNode` CURIE verbatim; `name` is resolved via ndi.ontology.lookup at conversion time.", "constraints": {} }, { - "name": "position_units", - "type": "char", - "blank_value": "", - "default_value": "um", + "name": "units", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, "mustBeNonEmpty": true, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The units for the position coordinates (e.g., 'um', 'mm', 'cm').", - "constraints": { - "maxLength": 32 - } + "documentation": "Ontology term naming the measurement unit for the position values (e.g., 'micrometer'). Resolved via ndi.ontology.lookup.", + "constraints": {} }, { - "name": "coordinate_system", - "type": "char", - "blank_value": "", - "default_value": "", + "name": "dimensions", + "type": "structure", + "blank_value": [], + "default_value": [], "mustBeNonEmpty": false, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The coordinate system or reference frame for this position.", - "constraints": { - "maxLength": 256 - } + "documentation": "Array of per-axis records describing each spatial dimension of the position measurement. v1 stored dimensions as a comma-separated CURIE list with implicit positional ordering; V_delta makes the ordering explicit via the `axis` field while preserving the ontology classification. The migrator labels axes as `axis_1`, `axis_2`, ... by default; an explicit `x`/`y`/`z` convention can be applied per-document where the spatial mapping is known.", + "constraints": {}, + "fields": [ + { + "name": "axis", + "type": "char", + "blank_value": "", + "default_value": "axis_1", + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Per-record axis identifier. Defaults to positional labels (`axis_1`, `axis_2`, ...); consumers may rewrite to a spatial convention (e.g., `x`, `y`, `z`) when known.", + "constraints": { + "maxLength": 64 + } + }, + { + "name": "node", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Ontology CURIE classifying this axis (e.g., a directional or anatomical-axis ontology node).", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "name", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Human-readable label resolved from `node` via ndi.ontology.lookup at conversion time. Empty when the lookup is unavailable.", + "constraints": {} + } + ] } ] } diff --git a/schemas/V_delta/stable/probe_location.json b/schemas/V_delta/stable/probe_location.json index e6c222c..478b7e5 100644 --- a/schemas/V_delta/stable/probe_location.json +++ b/schemas/V_delta/stable/probe_location.json @@ -20,20 +20,34 @@ "file": [], "fields": [ { - "name": "location", - "type": "ontology_term", - "blank_value": null, - "default_value": null, + "name": "ontology_name", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, - "ontology": { - "node": "schema:location", - "name": "location" - }, - "documentation": "Anatomical or functional location where the probe is sampling, as an ontology term (e.g., UBERON:0002436 'primary visual cortex').", - "constraints": {} + "ontology": null, + "documentation": "Ontology identifier of the probe's anatomical/functional location (e.g., 'UBERON:0002436', 'UBERON:0001880'). v1 ships this as a flat char field alongside `name`.", + "constraints": { + "maxLength": 128 + } + }, + { + "name": "name", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Human-readable name for the location (e.g., 'primary visual cortex', 'bed nucleus of stria terminalis (BNST)'). Paired with `ontology_name`.", + "constraints": { + "maxLength": 256 + } } ] } diff --git a/schemas/V_delta/stable/session_in_a_dataset.json b/schemas/V_delta/stable/session_in_a_dataset.json index b59c808..c737a5c 100644 --- a/schemas/V_delta/stable/session_in_a_dataset.json +++ b/schemas/V_delta/stable/session_in_a_dataset.json @@ -9,30 +9,148 @@ ], "maturity_level": "stable" }, - "depends_on": [ + "depends_on": [], + "file": [], + "fields": [ { "name": "session_id", + "type": "did_uid", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": true, - "documentation": "The document ID of the session.", - "must_refer_to_document_class": "" - } - ], - "file": [], - "fields": [ + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": { + "node": "iao:0000578", + "name": "centrally registered identifier" + }, + "documentation": "Document ID of the session referenced by this record. Note: this is the *referenced* session, not the dataset's session (which lives on base.session_id and serves as the dataset identifier).", + "constraints": {} + }, { - "name": "dataset_id", + "name": "session_reference", "type": "char", "blank_value": "", "default_value": "", - "mustBeNonEmpty": true, + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The identifier of the dataset this session belongs to.", + "documentation": "Human-readable label for the session (e.g., a recording date string like '2008-05-22').", "constraints": { "maxLength": 256 } + }, + { + "name": "is_linked", + "type": "integer", + "blank_value": 0, + "default_value": 0, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": true, + "queryable": true, + "ontology": null, + "documentation": "1 if the session is linked into the dataset (i.e., its underlying directory or remote is currently reachable); 0 if it is only referenced by metadata.", + "constraints": { + "min": 0, + "max": 1 + } + }, + { + "name": "session_creator", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Fully-qualified name of the NDI session class that produced this session (e.g., 'ndi.session.dir', 'ndi.session.cloud'). Used together with session_creator_input1..6 to reconstitute the session object.", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "session_creator_input1", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "First positional argument passed to session_creator when reconstituting the session.", + "constraints": {} + }, + { + "name": "session_creator_input2", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Second positional argument passed to session_creator when reconstituting the session.", + "constraints": {} + }, + { + "name": "session_creator_input3", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Third positional argument passed to session_creator when reconstituting the session.", + "constraints": {} + }, + { + "name": "session_creator_input4", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Fourth positional argument passed to session_creator when reconstituting the session.", + "constraints": {} + }, + { + "name": "session_creator_input5", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Fifth positional argument passed to session_creator when reconstituting the session.", + "constraints": {} + }, + { + "name": "session_creator_input6", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Sixth positional argument passed to session_creator when reconstituting the session.", + "constraints": {} } ] } diff --git a/schemas/V_delta/stable/spatial_frequency_tuning.json b/schemas/V_delta/stable/spatial_frequency_tuning.json index a3771c1..7366a3d 100644 --- a/schemas/V_delta/stable/spatial_frequency_tuning.json +++ b/schemas/V_delta/stable/spatial_frequency_tuning.json @@ -797,7 +797,7 @@ ] }, { - "name": "fit_sgauss", + "name": "fit_gausslog", "type": "structure", "blank_value": {}, "default_value": {}, @@ -931,7 +931,7 @@ "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "Mirror of all preceding blocks (tuning_curve, significance, fitless, fit_dog, fit_movshon, fit_movshon_c, fit_spline, fit_sgauss) recomputed on the absolute value of the responses. Empty in NDIcalc-vis-matlab v1; sub-fields to be populated as the calc implementation matures.", + "documentation": "Mirror of all preceding blocks (tuning_curve, significance, fitless, fit_dog, fit_movshon, fit_movshon_c, fit_spline, fit_gausslog) recomputed on the absolute value of the responses. Empty in NDIcalc-vis-matlab v1; sub-fields to be populated as the calc implementation matures.", "constraints": {}, "fields": [] } diff --git a/schemas/V_delta/stable/stimulus_bath.json b/schemas/V_delta/stable/stimulus_bath.json index e6fb884..5101fa6 100644 --- a/schemas/V_delta/stable/stimulus_bath.json +++ b/schemas/V_delta/stable/stimulus_bath.json @@ -5,71 +5,99 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "epochid" } ], "maturity_level": "stable" }, "depends_on": [ { - "name": "element_id", + "name": "stimulus_element_id", "mustBeNonEmpty": true, - "documentation": "The document ID of the element receiving this bath stimulus.", + "documentation": "The document ID of the stimulus element this bath records.", "must_refer_to_document_class": "" } ], "file": [], "fields": [ { - "name": "solution_name", - "type": "char", - "blank_value": "", - "default_value": "", + "name": "location", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, "mustBeNonEmpty": true, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": { - "node": "iao:0000219", - "name": "denotes" - }, - "documentation": "The name of the bath solution (e.g., 'ACSF', 'TTX'). The field denotes a chemical entity / drug; candidate for promotion to ontology_term once a chemistry namespace (e.g., ChEBI, DrON) is registered.", - "constraints": { - "maxLength": 256 - } - }, - { - "name": "concentration", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": false, - "ontology": { - "node": "pato:0000033", - "name": "concentration of" + "node": "schema:location", + "name": "location" }, - "documentation": "The concentration of the active compound.", + "documentation": "Ontology term naming the type of bath the stimulus was applied in (e.g., NCIm:C0179246, 'Baths, Water, Laboratory'). v1 already stored this as an ontology-term-shaped sub-object; the migrator renames `ontologyNode` -> `node` in lockstep with the V_delta ontology_term convention.", "constraints": {} }, { - "name": "concentration_units", - "type": "char", - "blank_value": "", - "default_value": "", + "name": "mixture", + "type": "structure", + "blank_value": [], + "default_value": [], "mustBeNonEmpty": false, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, - "ontology": { - "node": "iao:0000003", - "name": "measurement unit label" - }, - "documentation": "The units of the concentration (e.g., 'mM', 'uM', 'nM').", - "constraints": { - "maxLength": 32 - } + "ontology": null, + "documentation": "Array of per-chemical records describing the chemical mixture the bath delivered. v1 stored this as an inline CSV (`mixture_table`) with header row `ontologyName,name,value,ontologyUnit,unitName`; V_delta parses each data row into a structured record. Each record carries the chemical identity as an ontology_term and the concentration as a `concentration` composite (multiple optional canonical sub-fields plus source-unit/source-value tracking).", + "constraints": {}, + "fields": [ + { + "name": "chemical", + "type": "ontology_term", + "blank_value": { + "node": "", + "name": "" + }, + "default_value": { + "node": "", + "name": "" + }, + "mustBeNonEmpty": true, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Ontology term identifying this chemical species. `node` comes from v1 `ontologyName`; `name` comes from v1 `name`.", + "constraints": {} + }, + { + "name": "amount", + "type": "concentration", + "blank_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "default_value": { + "approximate": false, + "source_unit": "", + "source_value": 0.0 + }, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Concentration of this chemical in the bath. Carries source_unit / source_value (v1 `unitName` and `value`) and zero or more canonical sub-fields (`molar`, `grams_per_liter`, `mass_fraction`, `volume_fraction`) populated whenever the source unit is computable into them. For v1 docs in the Dab corpus the source unit is uniformly 'Molar' so `molar = source_value`.", + "constraints": {} + } + ] } ] } diff --git a/schemas/V_delta/stable/stimulus_presentation.json b/schemas/V_delta/stable/stimulus_presentation.json index 53e0525..1dde021 100644 --- a/schemas/V_delta/stable/stimulus_presentation.json +++ b/schemas/V_delta/stable/stimulus_presentation.json @@ -5,6 +5,12 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "app" + }, + { + "class_name": "epochid" } ], "maturity_level": "stable" @@ -32,26 +38,41 @@ "node": "placeholder:stimulus_presentation_order", "name": "stimulus presentation order" }, - "documentation": "Array of integer stimulus indices (1-based) in the order they were presented. Length equals num_trials.", - "constraints": { - "element_type": "integer" - } + "documentation": "Stimulus presentation index/order. v1 commonly ships a scalar 1; consumers that need a per-trial array fill it as a 1-based integer vector whose length equals the number of trials.", + "constraints": {} }, { - "name": "num_trials", - "type": "integer", - "blank_value": 0, - "default_value": 0, + "name": "stimuli", + "type": "structure", + "blank_value": { + "parameters": {} + }, + "default_value": { + "parameters": {} + }, "mustBeNonEmpty": false, "mustBeScalar": true, - "mustNotHaveNaN": true, - "queryable": true, - "ontology": { - "node": "placeholder:trial_count", - "name": "trial count" - }, - "documentation": "The total number of stimulus trials.", - "constraints": {} + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Stimulus configuration captured at presentation time. The sole sub-field that all v1 corpora ship is `parameters`, an open-shape struct whose keys depend on the stimulus type (Hartley basis, sparse-noise grid, oriented gratings, etc.) and on the generating library version. V_delta does not constrain inner field names because each stimulus type contributes its own; the validator only verifies that `stimuli` is itself a struct. Consumers that need to interpret specific parameter values should branch on the stimulus class context (e.g., the linked `app.app_name`) before reading.", + "constraints": {}, + "fields": [ + { + "name": "parameters", + "type": "structure", + "blank_value": {}, + "default_value": {}, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Stimulus-type-specific parameter object. Open-shape: keys and value types depend on the stimulus generator. v1 corpora include Hartley-basis (rect, windowShape, M, K_absmax, randState, ...), sparse-noise (BG, value, random, repeat, pixSize, randState, ...), and many other variants.", + "constraints": {}, + "fields": [] + } + ] } ] } diff --git a/schemas/V_delta/stable/stimulus_response.json b/schemas/V_delta/stable/stimulus_response.json index 12644eb..530e8ad 100644 --- a/schemas/V_delta/stable/stimulus_response.json +++ b/schemas/V_delta/stable/stimulus_response.json @@ -31,7 +31,7 @@ ], "fields": [ { - "name": "response_type", + "name": "stimulator_epochid", "type": "char", "blank_value": "", "default_value": "", @@ -40,9 +40,24 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The type of response measured (e.g., 'spikes', 'calcium', 'voltage').", + "documentation": "Epoch identifier on the stimulator element whose presentation produced this response (e.g., 't00002'). Mirrors the v1 stimulus_response field.", "constraints": { - "maxLength": 128 + "maxLength": 64 + } + }, + { + "name": "element_epochid", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Epoch identifier on the responding element (the element_id this document depends on) that aligns with the stimulator epoch above.", + "constraints": { + "maxLength": 64 } } ] diff --git a/schemas/V_delta/stable/stimulus_response_scalar.json b/schemas/V_delta/stable/stimulus_response_scalar.json index baae2cf..9a3d638 100644 --- a/schemas/V_delta/stable/stimulus_response_scalar.json +++ b/schemas/V_delta/stable/stimulus_response_scalar.json @@ -5,6 +5,9 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "stimulus_response" } ], "maturity_level": "stable" @@ -12,45 +15,15 @@ "depends_on": [ { "name": "stimulus_response_id", - "mustBeNonEmpty": true, - "documentation": "The document ID of the stimulus_response this scalar summary belongs to.", + "mustBeNonEmpty": false, + "documentation": "Optional pointer to the underlying stimulus_response document.", "must_refer_to_document_class": "" } ], "file": [], "fields": [ { - "name": "stimulus_values", - "type": "matrix", - "blank_value": [], - "default_value": [], - "mustBeNonEmpty": false, - "mustBeScalar": false, - "mustNotHaveNaN": false, - "queryable": false, - "ontology": null, - "documentation": "Array of independent stimulus parameter values, one per stimulus condition. Must be the same length as response_values.", - "constraints": { - "element_type": "double" - } - }, - { - "name": "response_values", - "type": "matrix", - "blank_value": [], - "default_value": [], - "mustBeNonEmpty": false, - "mustBeScalar": false, - "mustNotHaveNaN": false, - "queryable": false, - "ontology": null, - "documentation": "Array of scalar response values in response_units, one per stimulus condition. Must be the same length as stimulus_values.", - "constraints": { - "element_type": "double" - } - }, - { - "name": "response_units", + "name": "response_type", "type": "char", "blank_value": "", "default_value": "", @@ -59,10 +32,24 @@ "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The units of the response values (e.g., 'spikes/s', 'dF/F').", + "documentation": "How the per-trial scalar response was reduced from the source signal (e.g., 'mean', 'peak', 'frequency'). v1 ships this directly on the stimulus_response_scalar block; declared here so per-class queries see it without joining to the parent.", "constraints": { "maxLength": 64 } + }, + { + "name": "responses", + "type": "structure", + "blank_value": {}, + "default_value": {}, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Per-trial scalar responses. v1 ships this as a struct with sub-fields {stimid (integer), response_real, response_imaginary, control_response_real, control_response_imaginary}; V_delta keeps the open-shape convention so callers can add bookkeeping fields without a schema bump.", + "constraints": {}, + "fields": [] } ] } diff --git a/schemas/V_delta/stable/stimulus_response_scalar_parameters_basic.json b/schemas/V_delta/stable/stimulus_response_scalar_parameters_basic.json index 0b413fe..aa189ca 100644 --- a/schemas/V_delta/stable/stimulus_response_scalar_parameters_basic.json +++ b/schemas/V_delta/stable/stimulus_response_scalar_parameters_basic.json @@ -5,48 +5,75 @@ "superclasses": [ { "class_name": "base" + }, + { + "class_name": "stimulus_response_scalar_parameters" } ], "maturity_level": "stable" }, - "depends_on": [ - { - "name": "stimulus_response_scalar_id", - "mustBeNonEmpty": true, - "documentation": "The document ID of the stimulus_response_scalar these basic parameters describe.", - "must_refer_to_document_class": "" - } - ], + "depends_on": [], "file": [], "fields": [ { - "name": "response_window_start", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, + "name": "temporalfreqfunc", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Fully-qualified NDI function name that produced the temporal-frequency component of the scalar response (e.g., 'ndi.fun.stimulustemporalfrequency'). Identifies the analysis routine.", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "freq_response", + "type": "integer", + "blank_value": 0, + "default_value": 0, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": true, + "queryable": true, + "ontology": null, + "documentation": "1 if this scalar response is a frequency-domain measurement, 0 otherwise. v1 corpora ship integer flags here.", + "constraints": { + "min": 0, + "max": 1 + } + }, + { + "name": "prestimulus_time", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "Start of the response window in seconds after stimulus onset.", + "documentation": "Optional pre-stimulus baseline window. v1 ships either an empty array (no baseline subtraction) or a [start, stop] pair in seconds before stimulus onset.", "constraints": {} }, { - "name": "response_window_end", - "type": "double", - "blank_value": 0.0, - "default_value": 0.0, + "name": "prestimulus_normalization", + "type": "matrix", + "blank_value": [], + "default_value": [], "mustBeNonEmpty": false, - "mustBeScalar": true, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "End of the response window in seconds after stimulus onset.", + "documentation": "Optional normalization vector applied during the prestimulus baseline computation. v1 commonly ships an empty array; populated when a non-trivial baseline scheme is in use.", "constraints": {} }, { - "name": "freq_response", + "name": "isspike", "type": "integer", "blank_value": 0, "default_value": 0, @@ -55,7 +82,23 @@ "mustNotHaveNaN": true, "queryable": true, "ontology": null, - "documentation": "The frequency component used for the response computation (0 = mean, 1 = F1, 2 = F2).", + "documentation": "1 if the source signal is a spike train (analysed at spiketrain_dt resolution), 0 if it is a continuous signal.", + "constraints": { + "min": 0, + "max": 1 + } + }, + { + "name": "spiketrain_dt", + "type": "double", + "blank_value": 0.0, + "default_value": 0.001, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Time step (seconds) at which a spike train is discretised before computing the scalar response (e.g., 0.001 for 1 ms bins). Only meaningful when isspike == 1.", "constraints": {} } ] diff --git a/schemas/V_delta/stable/stimulus_tuningcurve.json b/schemas/V_delta/stable/stimulus_tuningcurve.json index ac57158..0910d69 100644 --- a/schemas/V_delta/stable/stimulus_tuningcurve.json +++ b/schemas/V_delta/stable/stimulus_tuningcurve.json @@ -20,25 +20,23 @@ "file": [], "fields": [ { - "name": "independent_variable", - "type": "char", + "name": "independent_variable_label", + "type": "string", "blank_value": "", "default_value": "", - "mustBeNonEmpty": true, - "mustBeScalar": true, + "mustBeNonEmpty": false, + "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": true, "ontology": { "node": "obi:0000750", "name": "independent variable" }, - "documentation": "The name of the independent stimulus variable (e.g., 'angle', 'spatial_frequency'). Candidate for promotion to ontology_term.", - "constraints": { - "maxLength": 256 - } + "documentation": "String label(s) for the independent variable(s) the tuning curve was computed across. v1 ships this as a 1-element list whose single entry is a comma-separated list of variable names when more than one variable was crossed (e.g., 'spatial_frequency,temporal_frequency'). V_delta keeps it as a string array; callers split the comma-separated form themselves if needed.", + "constraints": {} }, { - "name": "independent_values", + "name": "independent_variable_value", "type": "matrix", "blank_value": [], "default_value": [], @@ -46,13 +44,23 @@ "mustBeScalar": false, "mustNotHaveNaN": false, "queryable": false, - "ontology": { - "node": "iao:0000027", - "name": "data item" - }, - "documentation": "Array of numeric values of the independent variable, one per tuning curve point. Must be the same length as response_mean and response_stderr.", + "ontology": null, + "documentation": "Matrix of independent-variable values, one row per stimulus condition. Shape is (N_stimuli x N_independent_variables). For a single-variable tuning curve each row is length 1; for the 2D case (e.g., spatial-by-temporal frequency) each row is length 2.", + "constraints": {} + }, + { + "name": "stimid", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": true, + "queryable": false, + "ontology": null, + "documentation": "Integer stimulus identifiers (1-based) for each row of independent_variable_value. Length equals number of stimulus conditions.", "constraints": { - "element_type": "double" + "element_type": "integer" } }, { @@ -68,10 +76,21 @@ "node": "ncit:C53319", "name": "Arithmetic Mean" }, - "documentation": "Array of mean response values at each point in independent_values. Must be the same length as independent_values.", - "constraints": { - "element_type": "double" - } + "documentation": "Per-stimulus mean of the scalar responses (length equals number of stimuli).", + "constraints": {} + }, + { + "name": "response_stddev", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Per-stimulus standard deviation of the scalar responses.", + "constraints": {} }, { "name": "response_stderr", @@ -86,10 +105,142 @@ "node": "stato:0000037", "name": "standard error of the mean" }, - "documentation": "Array of standard error of the mean for each response value. Must be the same length as independent_values. Each element is itself a SEM; the array dimension is across independent_values.", + "documentation": "Per-stimulus standard error of the mean (length equals number of stimuli).", + "constraints": {} + }, + { + "name": "response_units", + "type": "string", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Units of the scalar response values. v1 often ships an empty array; populated when the source recording's units are known.", + "constraints": {} + }, + { + "name": "individual_responses_real", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Real component of each individual trial response. Shape (N_trials x N_stimuli). Paired with individual_responses_imaginary for complex-valued responses; for real-valued responses individual_responses_imaginary is zero or absent.", + "constraints": {} + }, + { + "name": "individual_responses_imaginary", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Imaginary component of each individual trial response. Same shape as individual_responses_real.", + "constraints": {} + }, + { + "name": "stimulus_presentation_number", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": true, + "queryable": false, + "ontology": null, + "documentation": "Per-trial, per-stimulus index of the original stimulus presentation. Shape (N_trials x N_stimuli). Lets callers map an individual_responses_real[t,s] back to the original stimulus_presentation document.", "constraints": { - "element_type": "double" + "element_type": "integer" } + }, + { + "name": "control_stimid", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": true, + "queryable": false, + "ontology": null, + "documentation": "Stimulus identifiers for the control (blank/baseline) condition(s). Often empty when no control was recorded.", + "constraints": { + "element_type": "integer" + } + }, + { + "name": "control_response_mean", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Mean response on the control condition(s). Same length as response_mean (typically broadcasts a single control value across stimuli).", + "constraints": {} + }, + { + "name": "control_response_stddev", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Standard deviation of the response on the control condition(s).", + "constraints": {} + }, + { + "name": "control_response_stderr", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Standard error of the mean for the response on the control condition(s).", + "constraints": {} + }, + { + "name": "control_individual_responses_real", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Real component of individual trial responses on the control condition(s). Same shape conventions as individual_responses_real.", + "constraints": {} + }, + { + "name": "control_individual_responses_imaginary", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Imaginary component of individual trial responses on the control condition(s).", + "constraints": {} } ] } diff --git a/schemas/V_delta/stable/subject_group.json b/schemas/V_delta/stable/subject_group.json index 22a9217..fb2de07 100644 --- a/schemas/V_delta/stable/subject_group.json +++ b/schemas/V_delta/stable/subject_group.json @@ -17,7 +17,7 @@ "type": "char", "blank_value": "", "default_value": "", - "mustBeNonEmpty": true, + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, @@ -25,7 +25,7 @@ "node": "schema:name", "name": "name" }, - "documentation": "The name of the subject group (e.g., 'control', 'treatment'). Candidate for promotion to ontology_term once a study-arm vocabulary (e.g., NCIT 'Study Arm' branch) is registered.", + "documentation": "Optional human-readable name for this subject group (e.g., 'control', 'treatment'). v1 docs did not carry a name and migrate with this field absent; new documents may populate it for ad-hoc labeling. Candidate for promotion to ontology_term once a study-arm vocabulary (e.g., NCIT 'Study Arm' branch) is registered.", "constraints": { "maxLength": 256 } @@ -43,26 +43,10 @@ "node": "schema:description", "name": "description" }, - "documentation": "A free-text description of this subject group.", + "documentation": "Optional free-text description of this subject group.", "constraints": { "maxLength": 1024 } - }, - { - "name": "subject_ids", - "type": "char", - "blank_value": "", - "default_value": "", - "mustBeNonEmpty": false, - "mustBeScalar": true, - "mustNotHaveNaN": false, - "queryable": false, - "ontology": { - "node": "iao:0000578", - "name": "centrally registered identifier" - }, - "documentation": "Comma-separated list of subject document IDs belonging to this group (e.g., 'id1,id2,id3').", - "constraints": {} } ] } diff --git a/schemas/V_delta/stable/syncrule_mapping.json b/schemas/V_delta/stable/syncrule_mapping.json index 64c5f7a..49ce6fc 100644 --- a/schemas/V_delta/stable/syncrule_mapping.json +++ b/schemas/V_delta/stable/syncrule_mapping.json @@ -26,33 +26,226 @@ "file": [], "fields": [ { - "name": "mapping_data", - "type": "structure", - "blank_value": {}, - "default_value": {}, + "name": "cost", + "type": "double", + "blank_value": 0, + "default_value": 0, "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Numeric cost / score of this mapping (lower is typically better). v1 ships an integer; V_delta uses `double` to admit fractional costs from future rules.", + "constraints": {} + }, + { + "name": "mapping", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "Structure representing the time mapping between clocks for this epoch. Keys are implementation-defined by the sync rule; typically includes the clock names being mapped and the corresponding sample timestamps.", + "documentation": "Numeric mapping vector relating the two endpoints in clock space. v1 ships a 2-element numeric vector (int or float depending on the rule); V_delta keeps the shape open as a matrix.", + "constraints": {} + }, + { + "name": "epochnode_a", + "type": "structure", + "blank_value": { + "epoch_clock": "", + "epoch_id": "", + "epoch_session_id": "", + "epochprobemap": "", + "objectclass": "" + }, + "default_value": { + "epoch_clock": "", + "epoch_id": "", + "epoch_session_id": "", + "epochprobemap": "", + "objectclass": "" + }, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "First endpoint of the mapping. Identifies the source epoch in clock space. Preserved verbatim from v1; the same shape applies to epochnode_b.", "constraints": {}, - "fields": [] + "fields": [ + { + "name": "epoch_clock", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Clock identifier for this endpoint (e.g., 'dev_local_time').", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "epoch_id", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Epoch identifier within the endpoint's session (e.g., 't00001').", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "epoch_session_id", + "type": "did_uid", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Document id of the session this endpoint's epoch lives in.", + "constraints": {} + }, + { + "name": "epochprobemap", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Tab-separated epoch-probe-map text describing the probe configuration at this endpoint. Free-form pass-through from v1.", + "constraints": {} + }, + { + "name": "objectclass", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Fully-qualified NDI epochprobemap class name (e.g., 'ndi.epoch.epochprobemap_daqsystem').", + "constraints": { + "maxLength": 256 + } + } + ] }, { - "name": "mapping_status", - "type": "char", - "blank_value": "", - "default_value": "complete", - "mustBeNonEmpty": true, + "name": "epochnode_b", + "type": "structure", + "blank_value": { + "epoch_clock": "", + "epoch_id": "", + "epoch_session_id": "", + "epochprobemap": "", + "objectclass": "" + }, + "default_value": { + "epoch_clock": "", + "epoch_id": "", + "epoch_session_id": "", + "epochprobemap": "", + "objectclass": "" + }, + "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The status of the mapping computation ('complete', 'failed').", - "constraints": { - "maxLength": 32 - } + "documentation": "Second endpoint of the mapping. Same shape as epochnode_a.", + "constraints": {}, + "fields": [ + { + "name": "epoch_clock", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Clock identifier for this endpoint.", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "epoch_id", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Epoch identifier within the endpoint's session.", + "constraints": { + "maxLength": 256 + } + }, + { + "name": "epoch_session_id", + "type": "did_uid", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Document id of the session this endpoint's epoch lives in.", + "constraints": {} + }, + { + "name": "epochprobemap", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Tab-separated epoch-probe-map text. Free-form pass-through from v1.", + "constraints": {} + }, + { + "name": "objectclass", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Fully-qualified NDI epochprobemap class name.", + "constraints": { + "maxLength": 256 + } + } + ] } ] } diff --git a/schemas/V_delta/stable/temporal_frequency_tuning.json b/schemas/V_delta/stable/temporal_frequency_tuning.json index b620db5..abc8e06 100644 --- a/schemas/V_delta/stable/temporal_frequency_tuning.json +++ b/schemas/V_delta/stable/temporal_frequency_tuning.json @@ -797,7 +797,7 @@ ] }, { - "name": "fit_sgauss", + "name": "fit_gausslog", "type": "structure", "blank_value": {}, "default_value": {}, @@ -931,7 +931,7 @@ "mustNotHaveNaN": false, "queryable": false, "ontology": null, - "documentation": "Mirror of all preceding blocks (tuning_curve, significance, fitless, fit_dog, fit_movshon, fit_movshon_c, fit_spline, fit_sgauss) recomputed on the absolute value of the responses. Empty in NDIcalc-vis-matlab v1; sub-fields to be populated as the calc implementation matures.", + "documentation": "Mirror of all preceding blocks (tuning_curve, significance, fitless, fit_dog, fit_movshon, fit_movshon_c, fit_spline, fit_gausslog) recomputed on the absolute value of the responses. Empty in NDIcalc-vis-matlab v1; sub-fields to be populated as the calc implementation matures.", "constraints": {}, "fields": [] } diff --git a/schemas/V_delta/stable/treatment.json b/schemas/V_delta/stable/treatment.json index 39c912f..fd506f0 100644 --- a/schemas/V_delta/stable/treatment.json +++ b/schemas/V_delta/stable/treatment.json @@ -32,17 +32,34 @@ "file": [], "fields": [ { - "name": "treatment_name", - "type": "ontology_term", - "blank_value": null, - "default_value": null, + "name": "ontology_name", + "type": "char", + "blank_value": "", + "default_value": "", "mustBeNonEmpty": false, "mustBeScalar": true, "mustNotHaveNaN": false, "queryable": true, "ontology": null, - "documentation": "The treatment, identified as an ontology term.", - "constraints": {} + "documentation": "Ontology identifier of the treatment (e.g., 'EMPTY:0000074'). v1 ships this as a flat char field alongside `name`.", + "constraints": { + "maxLength": 128 + } + }, + { + "name": "name", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Human-readable name for the treatment. Paired with `ontology_name`.", + "constraints": { + "maxLength": 256 + } }, { "name": "numeric_value", diff --git a/schemas/V_delta/stable/tuningcurve_calc.json b/schemas/V_delta/stable/tuningcurve_calc.json index 1bbec92..ede266b 100644 --- a/schemas/V_delta/stable/tuningcurve_calc.json +++ b/schemas/V_delta/stable/tuningcurve_calc.json @@ -8,6 +8,9 @@ }, { "class_name": "calculator" + }, + { + "class_name": "stimulus_tuningcurve" } ], "maturity_level": "stable" @@ -37,6 +40,66 @@ "dynamic_keys_from": "calculator_name" }, "fields": [] + }, + { + "name": "log", + "type": "char", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Free-text log entry summarising the tuning-curve calculation (e.g., 'angle best value is 135.', 'sFrequency = 0.04'). Captured verbatim from v1 documents that carried a `log` field.", + "constraints": {} + }, + { + "name": "stim_property_list", + "type": "structure", + "blank_value": { + "names": [], + "values": [] + }, + "default_value": { + "names": [], + "values": [] + }, + "mustBeNonEmpty": false, + "mustBeScalar": true, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Stimulus-property name/value pairs that conditioned this tuning-curve calculation. v1 stored this as `{names: [, ...], values: }`; V_delta preserves the same shape. `names` is the list of independent stimulus parameter names selected for the curve (most commonly a single name such as 'sFrequency'); `values` is the corresponding value(s).", + "constraints": {}, + "fields": [ + { + "name": "names", + "type": "string", + "blank_value": "", + "default_value": "", + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": true, + "ontology": null, + "documentation": "Array of stimulus parameter names (e.g., {'sFrequency', 'tFrequency'}). Empty array when no stimulus property was held; v1 most often ships a 1-element array.", + "constraints": {} + }, + { + "name": "values", + "type": "matrix", + "blank_value": [], + "default_value": [], + "mustBeNonEmpty": false, + "mustBeScalar": false, + "mustNotHaveNaN": false, + "queryable": false, + "ontology": null, + "documentation": "Numeric value(s) paralleling `names`. v1 ships either a scalar (when names is 1-element) or an empty array.", + "constraints": {} + } + ] } ] }