From 06b68e8b4257854b7d6b708738f4a74b64548853 Mon Sep 17 00:00:00 2001 From: sneakers-the-rat Date: Wed, 2 Oct 2024 20:20:50 -0700 Subject: [PATCH] model rebuild --- .../pydantic/core/v2_2_0/core_nwb_base.py | 15 +- .../pydantic/core/v2_2_0/core_nwb_behavior.py | 60 +++- .../pydantic/core/v2_2_0/core_nwb_ecephys.py | 118 ++++-- .../pydantic/core/v2_2_0/core_nwb_epoch.py | 3 - .../pydantic/core/v2_2_0/core_nwb_file.py | 50 +-- .../pydantic/core/v2_2_0/core_nwb_icephys.py | 133 +++++-- .../pydantic/core/v2_2_0/core_nwb_image.py | 113 ++++-- .../pydantic/core/v2_2_0/core_nwb_misc.py | 236 +++++++++--- .../pydantic/core/v2_2_0/core_nwb_ogen.py | 38 +- .../pydantic/core/v2_2_0/core_nwb_ophys.py | 76 +++- .../core/v2_2_0/core_nwb_retinotopy.py | 4 +- .../models/pydantic/core/v2_2_0/namespace.py | 15 +- .../pydantic/core/v2_2_1/core_nwb_base.py | 15 +- .../pydantic/core/v2_2_1/core_nwb_behavior.py | 60 +++- .../pydantic/core/v2_2_1/core_nwb_ecephys.py | 118 ++++-- .../pydantic/core/v2_2_1/core_nwb_epoch.py | 3 - .../pydantic/core/v2_2_1/core_nwb_file.py | 50 +-- .../pydantic/core/v2_2_1/core_nwb_icephys.py | 133 +++++-- .../pydantic/core/v2_2_1/core_nwb_image.py | 113 ++++-- .../pydantic/core/v2_2_1/core_nwb_misc.py | 236 +++++++++--- .../pydantic/core/v2_2_1/core_nwb_ogen.py | 38 +- .../pydantic/core/v2_2_1/core_nwb_ophys.py | 76 +++- .../core/v2_2_1/core_nwb_retinotopy.py | 4 +- .../models/pydantic/core/v2_2_1/namespace.py | 15 +- .../pydantic/core/v2_2_2/core_nwb_base.py | 15 +- .../pydantic/core/v2_2_2/core_nwb_behavior.py | 60 +++- .../pydantic/core/v2_2_2/core_nwb_ecephys.py | 118 ++++-- .../pydantic/core/v2_2_2/core_nwb_epoch.py | 3 - .../pydantic/core/v2_2_2/core_nwb_file.py | 50 +-- .../pydantic/core/v2_2_2/core_nwb_icephys.py | 133 +++++-- .../pydantic/core/v2_2_2/core_nwb_image.py | 145 ++++++-- .../pydantic/core/v2_2_2/core_nwb_misc.py | 252 ++++++++++--- .../pydantic/core/v2_2_2/core_nwb_ogen.py | 38 +- .../pydantic/core/v2_2_2/core_nwb_ophys.py | 76 +++- .../models/pydantic/core/v2_2_2/namespace.py | 16 +- .../pydantic/core/v2_2_4/core_nwb_base.py | 15 +- .../pydantic/core/v2_2_4/core_nwb_behavior.py | 60 +++- .../pydantic/core/v2_2_4/core_nwb_ecephys.py | 118 ++++-- .../pydantic/core/v2_2_4/core_nwb_epoch.py | 3 - .../pydantic/core/v2_2_4/core_nwb_file.py | 56 +-- .../pydantic/core/v2_2_4/core_nwb_icephys.py | 133 +++++-- .../pydantic/core/v2_2_4/core_nwb_image.py | 145 ++++++-- .../pydantic/core/v2_2_4/core_nwb_misc.py | 252 ++++++++++--- .../pydantic/core/v2_2_4/core_nwb_ogen.py | 38 +- .../pydantic/core/v2_2_4/core_nwb_ophys.py | 129 ++++--- .../models/pydantic/core/v2_2_4/namespace.py | 17 +- .../pydantic/core/v2_2_5/core_nwb_base.py | 15 +- .../pydantic/core/v2_2_5/core_nwb_behavior.py | 60 +++- .../pydantic/core/v2_2_5/core_nwb_ecephys.py | 118 ++++-- .../pydantic/core/v2_2_5/core_nwb_epoch.py | 3 - .../pydantic/core/v2_2_5/core_nwb_file.py | 56 +-- .../pydantic/core/v2_2_5/core_nwb_icephys.py | 133 +++++-- .../pydantic/core/v2_2_5/core_nwb_image.py | 145 ++++++-- .../pydantic/core/v2_2_5/core_nwb_misc.py | 252 ++++++++++--- .../pydantic/core/v2_2_5/core_nwb_ogen.py | 38 +- .../pydantic/core/v2_2_5/core_nwb_ophys.py | 129 ++++--- .../models/pydantic/core/v2_2_5/namespace.py | 17 +- .../hdmf_common/v1_1_0/hdmf_common_table.py | 9 +- .../hdmf_common/v1_1_2/hdmf_common_table.py | 9 +- .../hdmf_common/v1_1_3/hdmf_common_table.py | 9 +- .../hdmf_common/v1_2_0/hdmf_common_table.py | 6 +- .../hdmf_common/v1_2_1/hdmf_common_base.py | 4 +- .../hdmf_common/v1_2_1/hdmf_common_table.py | 6 +- .../hdmf_common/v1_3_0/hdmf_common_base.py | 4 +- .../hdmf_common/v1_3_0/hdmf_common_sparse.py | 20 +- .../hdmf_common/v1_3_0/hdmf_common_table.py | 6 +- .../pydantic/hdmf_common/v1_3_0/namespace.py | 2 +- .../v0_1_0/hdmf_experimental_experimental.py | 4 +- .../v0_1_0/hdmf_experimental_resources.py | 4 +- .../hdmf_experimental/v0_1_0/namespace.py | 7 +- .../linkml/core/v2_2_0/core.nwb.base.yaml | 43 ++- .../linkml/core/v2_2_0/core.nwb.behavior.yaml | 162 ++++++--- .../linkml/core/v2_2_0/core.nwb.device.yaml | 1 + .../linkml/core/v2_2_0/core.nwb.ecephys.yaml | 266 ++++++++++---- .../linkml/core/v2_2_0/core.nwb.epoch.yaml | 18 +- .../linkml/core/v2_2_0/core.nwb.file.yaml | 150 ++++---- .../linkml/core/v2_2_0/core.nwb.icephys.yaml | 324 +++++++++++------ .../linkml/core/v2_2_0/core.nwb.image.yaml | 149 ++++++-- .../linkml/core/v2_2_0/core.nwb.language.yaml | 4 + .../linkml/core/v2_2_0/core.nwb.misc.yaml | 335 +++++++++++++----- .../linkml/core/v2_2_0/core.nwb.ogen.yaml | 63 +++- .../linkml/core/v2_2_0/core.nwb.ophys.yaml | 175 ++++++--- .../core/v2_2_0/core.nwb.retinotopy.yaml | 21 +- .../linkml/core/v2_2_1/core.nwb.base.yaml | 43 ++- .../linkml/core/v2_2_1/core.nwb.behavior.yaml | 162 ++++++--- .../linkml/core/v2_2_1/core.nwb.device.yaml | 1 + .../linkml/core/v2_2_1/core.nwb.ecephys.yaml | 266 ++++++++++---- .../linkml/core/v2_2_1/core.nwb.epoch.yaml | 18 +- .../linkml/core/v2_2_1/core.nwb.file.yaml | 150 ++++---- .../linkml/core/v2_2_1/core.nwb.icephys.yaml | 324 +++++++++++------ .../linkml/core/v2_2_1/core.nwb.image.yaml | 149 ++++++-- .../linkml/core/v2_2_1/core.nwb.language.yaml | 4 + .../linkml/core/v2_2_1/core.nwb.misc.yaml | 335 +++++++++++++----- .../linkml/core/v2_2_1/core.nwb.ogen.yaml | 63 +++- .../linkml/core/v2_2_1/core.nwb.ophys.yaml | 175 ++++++--- .../core/v2_2_1/core.nwb.retinotopy.yaml | 21 +- .../linkml/core/v2_2_2/core.nwb.base.yaml | 43 ++- .../linkml/core/v2_2_2/core.nwb.behavior.yaml | 162 ++++++--- .../linkml/core/v2_2_2/core.nwb.device.yaml | 1 + .../linkml/core/v2_2_2/core.nwb.ecephys.yaml | 266 ++++++++++---- .../linkml/core/v2_2_2/core.nwb.epoch.yaml | 18 +- .../linkml/core/v2_2_2/core.nwb.file.yaml | 150 ++++---- .../linkml/core/v2_2_2/core.nwb.icephys.yaml | 324 +++++++++++------ .../linkml/core/v2_2_2/core.nwb.image.yaml | 215 ++++++++--- .../linkml/core/v2_2_2/core.nwb.language.yaml | 4 + .../linkml/core/v2_2_2/core.nwb.misc.yaml | 335 +++++++++++++----- .../linkml/core/v2_2_2/core.nwb.ogen.yaml | 63 +++- .../linkml/core/v2_2_2/core.nwb.ophys.yaml | 174 ++++++--- .../core/v2_2_2/core.nwb.retinotopy.yaml | 26 +- .../linkml/core/v2_2_4/core.nwb.base.yaml | 43 ++- .../linkml/core/v2_2_4/core.nwb.behavior.yaml | 162 ++++++--- .../linkml/core/v2_2_4/core.nwb.device.yaml | 1 + .../linkml/core/v2_2_4/core.nwb.ecephys.yaml | 266 ++++++++++---- .../linkml/core/v2_2_4/core.nwb.epoch.yaml | 18 +- .../linkml/core/v2_2_4/core.nwb.file.yaml | 164 ++++----- .../linkml/core/v2_2_4/core.nwb.icephys.yaml | 324 +++++++++++------ .../linkml/core/v2_2_4/core.nwb.image.yaml | 215 ++++++++--- .../linkml/core/v2_2_4/core.nwb.language.yaml | 4 + .../linkml/core/v2_2_4/core.nwb.misc.yaml | 335 +++++++++++++----- .../linkml/core/v2_2_4/core.nwb.ogen.yaml | 63 +++- .../linkml/core/v2_2_4/core.nwb.ophys.yaml | 263 ++++++++------ .../core/v2_2_4/core.nwb.retinotopy.yaml | 26 +- .../linkml/core/v2_2_5/core.nwb.base.yaml | 43 ++- .../linkml/core/v2_2_5/core.nwb.behavior.yaml | 162 ++++++--- .../linkml/core/v2_2_5/core.nwb.device.yaml | 1 + .../linkml/core/v2_2_5/core.nwb.ecephys.yaml | 266 ++++++++++---- .../linkml/core/v2_2_5/core.nwb.epoch.yaml | 18 +- .../linkml/core/v2_2_5/core.nwb.file.yaml | 164 ++++----- .../linkml/core/v2_2_5/core.nwb.icephys.yaml | 324 +++++++++++------ .../linkml/core/v2_2_5/core.nwb.image.yaml | 215 ++++++++--- .../linkml/core/v2_2_5/core.nwb.language.yaml | 4 + .../linkml/core/v2_2_5/core.nwb.misc.yaml | 335 +++++++++++++----- .../linkml/core/v2_2_5/core.nwb.ogen.yaml | 63 +++- .../linkml/core/v2_2_5/core.nwb.ophys.yaml | 263 ++++++++------ .../core/v2_2_5/core.nwb.retinotopy.yaml | 26 +- .../v1_1_0/hdmf-common.nwb.language.yaml | 4 + .../v1_1_0/hdmf-common.sparse.yaml | 10 +- .../hdmf_common/v1_1_0/hdmf-common.table.yaml | 33 +- .../v1_1_2/hdmf-common.nwb.language.yaml | 4 + .../v1_1_2/hdmf-common.sparse.yaml | 10 +- .../hdmf_common/v1_1_2/hdmf-common.table.yaml | 33 +- .../v1_1_3/hdmf-common.nwb.language.yaml | 4 + .../v1_1_3/hdmf-common.sparse.yaml | 10 +- .../hdmf_common/v1_1_3/hdmf-common.table.yaml | 33 +- .../hdmf_common/v1_2_0/hdmf-common.base.yaml | 2 + .../v1_2_0/hdmf-common.nwb.language.yaml | 4 + .../v1_2_0/hdmf-common.sparse.yaml | 10 +- .../hdmf_common/v1_2_0/hdmf-common.table.yaml | 24 +- .../hdmf_common/v1_2_1/hdmf-common.base.yaml | 20 +- .../v1_2_1/hdmf-common.nwb.language.yaml | 4 + .../v1_2_1/hdmf-common.sparse.yaml | 10 +- .../hdmf_common/v1_2_1/hdmf-common.table.yaml | 24 +- .../hdmf_common/v1_3_0/hdmf-common.base.yaml | 20 +- .../v1_3_0/hdmf-common.nwb.language.yaml | 4 + .../v1_3_0/hdmf-common.resources.yaml | 22 +- .../v1_3_0/hdmf-common.sparse.yaml | 16 +- .../hdmf_common/v1_3_0/hdmf-common.table.yaml | 24 +- .../hdmf-experimental.experimental.yaml | 2 +- .../v0_1_0/hdmf-experimental.resources.yaml | 2 +- 159 files changed, 9820 insertions(+), 4130 deletions(-) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py index b1c670c..ad72a48 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py @@ -170,9 +170,9 @@ class Image(NWBData): description: Optional[str] = Field(None, description="""Description of the image.""") value: Optional[ Union[ - NDArray[Shape["* x, * y"], float], - NDArray[Shape["* x, * y, 3 r_g_b"], float], - NDArray[Shape["* x, * y, 4 r_g_b_a"], float], + NDArray[Shape["* x, * y"], float | int], + NDArray[Shape["* x, * y, 3 r_g_b"], float | int], + NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int], ] ] = Field(None) @@ -333,13 +333,16 @@ class ProcessingModule(NWBContainer): {"from_schema": "core.nwb.base", "tree_root": True} ) - value: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + name: str = Field(...) + description: str = Field( + ..., description="""Description of this collection of processed data.""" + ) + value: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - name: str = Field(...) class Images(NWBDataInterface): @@ -353,7 +356,7 @@ class Images(NWBDataInterface): name: str = Field("Images", json_schema_extra={"linkml_meta": {"ifabsent": "string(Images)"}}) description: str = Field(..., description="""Description of this collection of images.""") - image: List[Image] = Field(..., description="""Images stored in this collection.""") + image: List[str] = Field(..., description="""Images stored in this collection.""") # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py index 5a63426..7c30179 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py @@ -213,6 +213,16 @@ class SpatialSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "meters", description="""Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -220,8 +230,8 @@ class SpatialSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -235,10 +245,13 @@ class BehavioralEpochs(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[IntervalSeries]] = Field( + name: str = Field( + "BehavioralEpochs", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEpochs)"}}, + ) + value: Optional[Dict[str, IntervalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "IntervalSeries"}]}} ) - name: str = Field(...) class BehavioralEvents(NWBDataInterface): @@ -250,10 +263,13 @@ class BehavioralEvents(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralEvents", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEvents)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class BehavioralTimeSeries(NWBDataInterface): @@ -265,10 +281,13 @@ class BehavioralTimeSeries(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralTimeSeries", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralTimeSeries)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class PupilTracking(NWBDataInterface): @@ -280,10 +299,12 @@ class PupilTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "PupilTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(PupilTracking)"}} + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class EyeTracking(NWBDataInterface): @@ -295,10 +316,12 @@ class EyeTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "EyeTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(EyeTracking)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class CompassDirection(NWBDataInterface): @@ -310,10 +333,13 @@ class CompassDirection(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "CompassDirection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(CompassDirection)"}}, + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class Position(NWBDataInterface): @@ -325,10 +351,12 @@ class Position(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "Position", json_schema_extra={"linkml_meta": {"ifabsent": "string(Position)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py index a3d315d..8009ce6 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py @@ -190,11 +190,12 @@ class ElectricalSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_channels"], float], - NDArray[Shape["* num_times, * num_channels, * num_samples"], float], - ] = Field(..., description="""Recorded voltage data.""") + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) + data: ElectricalSeriesData = Field(..., description="""Recorded voltage data.""") electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -207,11 +208,6 @@ class ElectricalSeries(TimeSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -249,6 +245,41 @@ class ElectricalSeries(TimeSeries): ) +class ElectricalSeriesData(ConfiguredBaseModel): + """ + Recorded voltage data. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_channels"], float | int], + NDArray[Shape["* num_times, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class SpikeEventSeries(ElectricalSeries): """ Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode). @@ -259,15 +290,17 @@ class SpikeEventSeries(ElectricalSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_events, * num_samples"], float], - NDArray[Shape["* num_events, * num_channels, * num_samples"], float], - ] = Field(..., description="""Spike waveforms.""") + data: SpikeEventSeriesData = Field(..., description="""Spike waveforms.""") timestamps: NDArray[Shape["* num_times"], float] = Field( ..., description="""Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, ) + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -280,11 +313,6 @@ class SpikeEventSeries(ElectricalSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -317,6 +345,40 @@ class SpikeEventSeries(ElectricalSeries): ) +class SpikeEventSeriesData(ConfiguredBaseModel): + """ + Spike waveforms. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Unit of measurement for waveforms, which is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_events, * num_samples"], float | int], + NDArray[Shape["* num_events, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class FeatureExtraction(NWBDataInterface): """ Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source. @@ -415,10 +477,12 @@ class EventWaveform(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[SpikeEventSeries]] = Field( + name: str = Field( + "EventWaveform", json_schema_extra={"linkml_meta": {"ifabsent": "string(EventWaveform)"}} + ) + value: Optional[Dict[str, SpikeEventSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpikeEventSeries"}]}} ) - name: str = Field(...) class FilteredEphys(NWBDataInterface): @@ -430,10 +494,12 @@ class FilteredEphys(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field( + "FilteredEphys", json_schema_extra={"linkml_meta": {"ifabsent": "string(FilteredEphys)"}} + ) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class LFP(NWBDataInterface): @@ -445,10 +511,10 @@ class LFP(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field("LFP", json_schema_extra={"linkml_meta": {"ifabsent": "string(LFP)"}}) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class ElectrodeGroup(NWBContainer): @@ -591,7 +657,9 @@ class Clustering(NWBDataInterface): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model ElectricalSeries.model_rebuild() +ElectricalSeriesData.model_rebuild() SpikeEventSeries.model_rebuild() +SpikeEventSeriesData.model_rebuild() FeatureExtraction.model_rebuild() EventDetection.model_rebuild() EventWaveform.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py index 2a4db9b..a834fd5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py @@ -247,9 +247,6 @@ class TimeIntervals(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class TimeIntervalsTimeseries(VectorData): diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py index 5cc40db..6803fec 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py @@ -211,28 +211,28 @@ class NWBFile(NWBContainer): ..., description="""Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).""", ) - acquisition: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + acquisition: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, description="""Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - analysis: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + analysis: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - scratch: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + scratch: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - processing: Optional[List[ProcessingModule]] = Field( + processing: Optional[Dict[str, ProcessingModule]] = Field( None, description="""The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ProcessingModule"}]}}, @@ -250,6 +250,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -265,12 +268,12 @@ class NWBFileStimulus(ConfiguredBaseModel): "linkml_meta": {"equals_string": "stimulus", "ifabsent": "string(stimulus)"} }, ) - presentation: Optional[List[TimeSeries]] = Field( + presentation: Optional[Dict[str, TimeSeries]] = Field( None, description="""Stimuli presented during the experiment.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, ) - templates: Optional[List[TimeSeries]] = Field( + templates: Optional[Dict[str, TimeSeries]] = Field( None, description="""Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, @@ -348,11 +351,11 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - nwb_container: Optional[List[NWBContainer]] = Field( + nwb_container: Optional[Dict[str, NWBContainer]] = Field( None, description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", ) - devices: Optional[List[Device]] = Field( + devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "Device"}]}}, @@ -367,12 +370,12 @@ class NWBFileGeneral(ConfiguredBaseModel): intracellular_ephys: Optional[GeneralIntracellularEphys] = Field( None, description="""Metadata related to intracellular electrophysiology.""" ) - optogenetics: Optional[List[OptogeneticStimulusSite]] = Field( + optogenetics: Optional[Dict[str, OptogeneticStimulusSite]] = Field( None, description="""Metadata describing optogenetic stimuluation.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "OptogeneticStimulusSite"}]}}, ) - optophysiology: Optional[List[ImagingPlane]] = Field( + optophysiology: Optional[Dict[str, ImagingPlane]] = Field( None, description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, @@ -450,12 +453,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -525,8 +528,14 @@ class ExtracellularEphysElectrodes(DynamicTable): } }, ) - group: List[ElectrodeGroup] = Field( - ..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" + group: VectorData[NDArray[Any, ElectrodeGroup]] = Field( + ..., + description="""Reference to the ElectrodeGroup this electrode is a part of.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, ) group_name: VectorData[NDArray[Any, str]] = Field( ..., @@ -583,9 +592,6 @@ class ExtracellularEphysElectrodes(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class GeneralIntracellularEphys(ConfiguredBaseModel): @@ -608,12 +614,12 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[List[IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""The table which groups different PatchClampSeries together.""" ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -639,7 +645,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[List[TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py index e4213de..e8a9403 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py @@ -262,11 +262,21 @@ class PatchClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( ..., description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", ) - value: Optional[NDArray[Shape["* num_times"], float]] = Field( + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} ) @@ -281,12 +291,12 @@ class CurrentClampSeries(PatchClampSeries): ) name: str = Field(...) - data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") bias_current: Optional[float] = Field(None, description="""Bias current, in amps.""") bridge_balance: Optional[float] = Field(None, description="""Bridge balance, in ohms.""") capacitance_compensation: Optional[float] = Field( None, description="""Capacitance compensation, in farads.""" ) + data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") stimulus_description: str = Field( ..., description="""Protocol/stimulus name for this patch-clamp dataset.""" ) @@ -354,12 +364,24 @@ class CurrentClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IZeroClampSeries(CurrentClampSeries): @@ -512,6 +534,16 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["amperes"] = Field( "amperes", description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -519,7 +551,9 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} }, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class VoltageClampSeries(PatchClampSeries): @@ -532,13 +566,13 @@ class VoltageClampSeries(PatchClampSeries): ) name: str = Field(...) - data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") capacitance_fast: Optional[VoltageClampSeriesCapacitanceFast] = Field( None, description="""Fast capacitance, in farads.""" ) capacitance_slow: Optional[VoltageClampSeriesCapacitanceSlow] = Field( None, description="""Slow capacitance, in farads.""" ) + data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") resistance_comp_bandwidth: Optional[VoltageClampSeriesResistanceCompBandwidth] = Field( None, description="""Resistance compensation bandwidth, in hertz.""" ) @@ -610,27 +644,6 @@ class VoltageClampSeries(PatchClampSeries): ) -class VoltageClampSeriesData(ConfiguredBaseModel): - """ - Recorded current. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) - - name: Literal["data"] = Field( - "data", - json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, - ) - unit: Literal["amperes"] = Field( - "amperes", - description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", - json_schema_extra={ - "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} - }, - ) - value: Any = Field(...) - - class VoltageClampSeriesCapacitanceFast(ConfiguredBaseModel): """ Fast capacitance, in farads. @@ -683,6 +696,39 @@ class VoltageClampSeriesCapacitanceSlow(ConfiguredBaseModel): value: float = Field(...) +class VoltageClampSeriesData(ConfiguredBaseModel): + """ + Recorded current. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["amperes"] = Field( + "amperes", + description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + json_schema_extra={ + "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} + }, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class VoltageClampSeriesResistanceCompBandwidth(ConfiguredBaseModel): """ Resistance compensation bandwidth, in hertz. @@ -887,12 +933,24 @@ class VoltageClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IntracellularElectrode(NWBContainer): @@ -942,18 +1000,15 @@ class SweepTable(DynamicTable): ) name: str = Field(...) - sweep_number: VectorData[NDArray[Any, int]] = Field( + series: VectorData[NDArray[Any, PatchClampSeries]] = Field( ..., - description="""Sweep number of the PatchClampSeries in that row.""", + description="""The PatchClampSeries with the sweep number in that row.""", json_schema_extra={ "linkml_meta": { "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} } }, ) - series: List[PatchClampSeries] = Field( - ..., description="""The PatchClampSeries with the sweep number in that row.""" - ) series_index: Named[VectorIndex] = Field( ..., description="""Index for series.""", @@ -966,6 +1021,15 @@ class SweepTable(DynamicTable): } }, ) + sweep_number: VectorData[NDArray[Any, int]] = Field( + ..., + description="""Sweep number of the PatchClampSeries in that row.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -976,9 +1040,6 @@ class SweepTable(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild @@ -991,9 +1052,9 @@ IZeroClampSeries.model_rebuild() CurrentClampStimulusSeries.model_rebuild() CurrentClampStimulusSeriesData.model_rebuild() VoltageClampSeries.model_rebuild() -VoltageClampSeriesData.model_rebuild() VoltageClampSeriesCapacitanceFast.model_rebuild() VoltageClampSeriesCapacitanceSlow.model_rebuild() +VoltageClampSeriesData.model_rebuild() VoltageClampSeriesResistanceCompBandwidth.model_rebuild() VoltageClampSeriesResistanceCompCorrection.model_rebuild() VoltageClampSeriesResistanceCompPrediction.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py index a42cad3..b4073a6 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py @@ -152,7 +152,7 @@ class GrayscaleImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} @@ -174,7 +174,7 @@ class RGBImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -204,7 +204,7 @@ class RGBAImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -234,12 +234,9 @@ class ImageSeries(TimeSeries): ) name: str = Field(...) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -250,8 +247,9 @@ class ImageSeries(TimeSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -290,6 +288,39 @@ class ImageSeries(TimeSeries): ) +class ImageSeriesData(ConfiguredBaseModel): + """ + Binary data representing images across frames. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, * z"], float | int], + ] + ] = Field(None) + + class ImageSeriesExternalFile(ConfiguredBaseModel): """ Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file. @@ -331,12 +362,9 @@ class ImageMaskSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -347,8 +375,9 @@ class ImageMaskSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -409,12 +438,9 @@ class OpticalSeries(ImageSeries): None, description="""Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.""", ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -425,8 +451,9 @@ class OpticalSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -475,10 +502,8 @@ class IndexSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Index of the frame in the referenced ImageSeries.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IndexSeriesData = Field( + ..., description="""Index of the frame in the referenced ImageSeries.""" ) indexed_timeseries: Union[ImageSeries, str] = Field( ..., @@ -526,13 +551,45 @@ class IndexSeries(TimeSeries): ) +class IndexSeriesData(ConfiguredBaseModel): + """ + Index of the frame in the referenced ImageSeries. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model GrayscaleImage.model_rebuild() RGBImage.model_rebuild() RGBAImage.model_rebuild() ImageSeries.model_rebuild() +ImageSeriesData.model_rebuild() ImageSeriesExternalFile.model_rebuild() ImageMaskSeries.model_rebuild() OpticalSeries.model_rebuild() IndexSeries.model_rebuild() +IndexSeriesData.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py index 021de7b..341bd80 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py @@ -251,6 +251,16 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "see ", description="""Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".""", @@ -258,8 +268,8 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -274,10 +284,8 @@ class AnnotationSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], str] = Field( - ..., - description="""Annotations made during an experiment.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: AnnotationSeriesData = Field( + ..., description="""Annotations made during an experiment.""" ) description: Optional[str] = Field( "no description", @@ -316,6 +324,39 @@ class AnnotationSeries(TimeSeries): ) +class AnnotationSeriesData(ConfiguredBaseModel): + """ + Annotations made during an experiment. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], str]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class IntervalSeries(TimeSeries): """ Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. @@ -326,10 +367,8 @@ class IntervalSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Use values >0 if interval started, <0 if interval ended.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IntervalSeriesData = Field( + ..., description="""Use values >0 if interval started, <0 if interval ended.""" ) description: Optional[str] = Field( "no description", @@ -368,6 +407,39 @@ class IntervalSeries(TimeSeries): ) +class IntervalSeriesData(ConfiguredBaseModel): + """ + Use values >0 if interval started, <0 if interval ended. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class DecompositionSeries(TimeSeries): """ Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -443,24 +515,36 @@ class DecompositionSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( "no unit", description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"ifabsent": "string(no unit)"}}, ) - value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float]] = Field( - None, - json_schema_extra={ - "linkml_meta": { - "array": { - "dimensions": [ - {"alias": "num_times"}, - {"alias": "num_channels"}, - {"alias": "num_bands"}, - ] + value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float | int]] = ( + Field( + None, + json_schema_extra={ + "linkml_meta": { + "array": { + "dimensions": [ + {"alias": "num_times"}, + {"alias": "num_channels"}, + {"alias": "num_bands"}, + ] + } } - } - }, + }, + ) ) @@ -518,9 +602,6 @@ class DecompositionSeriesBands(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class Units(DynamicTable): @@ -533,9 +614,18 @@ class Units(DynamicTable): ) name: str = Field("Units", json_schema_extra={"linkml_meta": {"ifabsent": "string(Units)"}}) - spike_times_index: Optional[Named[VectorIndex]] = Field( + electrode_group: Optional[VectorData[NDArray[Any, ElectrodeGroup]]] = Field( None, - description="""Index into the spike_times dataset.""", + description="""Electrode group that each spike unit came from.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) + electrodes: Optional[Named[DynamicTableRegion]] = Field( + None, + description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -545,12 +635,9 @@ class Units(DynamicTable): } }, ) - spike_times: Optional[UnitsSpikeTimes] = Field( - None, description="""Spike times for each unit.""" - ) - obs_intervals_index: Optional[Named[VectorIndex]] = Field( + electrodes_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into the obs_intervals dataset.""", + description="""Index into electrodes.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -576,9 +663,9 @@ class Units(DynamicTable): }, ) ) - electrodes_index: Optional[Named[VectorIndex]] = Field( + obs_intervals_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into electrodes.""", + description="""Index into the obs_intervals dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -588,9 +675,12 @@ class Units(DynamicTable): } }, ) - electrodes: Optional[Named[DynamicTableRegion]] = Field( + spike_times: Optional[UnitsSpikeTimes] = Field( + None, description="""Spike times for each unit.""" + ) + spike_times_index: Optional[Named[VectorIndex]] = Field( None, - description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", + description="""Index into the spike_times dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -600,25 +690,12 @@ class Units(DynamicTable): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Electrode group that each spike unit came from.""" + waveform_mean: Optional[UnitsWaveformMean] = Field( + None, description="""Spike waveform mean for each spike unit.""" + ) + waveform_sd: Optional[UnitsWaveformSd] = Field( + None, description="""Spike waveform standard deviation for each spike unit.""" ) - waveform_mean: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform mean for each spike unit.""") - waveform_sd: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""") colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -629,9 +706,6 @@ class Units(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class UnitsSpikeTimes(VectorData): @@ -654,14 +728,62 @@ class UnitsSpikeTimes(VectorData): description: str = Field(..., description="""Description of what these vectors represent.""") +class UnitsWaveformMean(VectorData): + """ + Spike waveform mean for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_mean"] = Field( + "waveform_mean", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_mean", "ifabsent": "string(waveform_mean)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + + +class UnitsWaveformSd(VectorData): + """ + Spike waveform standard deviation for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_sd"] = Field( + "waveform_sd", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_sd", "ifabsent": "string(waveform_sd)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model AbstractFeatureSeries.model_rebuild() AbstractFeatureSeriesData.model_rebuild() AnnotationSeries.model_rebuild() +AnnotationSeriesData.model_rebuild() IntervalSeries.model_rebuild() +IntervalSeriesData.model_rebuild() DecompositionSeries.model_rebuild() DecompositionSeriesData.model_rebuild() DecompositionSeriesBands.model_rebuild() Units.model_rebuild() UnitsSpikeTimes.model_rebuild() +UnitsWaveformMean.model_rebuild() +UnitsWaveformSd.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py index 44f7e6a..240ec82 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py @@ -158,10 +158,8 @@ class OptogeneticSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], float] = Field( - ..., - description="""Applied power for optogenetic stimulus, in watts.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: OptogeneticSeriesData = Field( + ..., description="""Applied power for optogenetic stimulus, in watts.""" ) site: Union[OptogeneticStimulusSite, str] = Field( ..., @@ -209,6 +207,37 @@ class OptogeneticSeries(TimeSeries): ) +class OptogeneticSeriesData(ConfiguredBaseModel): + """ + Applied power for optogenetic stimulus, in watts. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ogen"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["watts"] = Field( + "watts", + description="""Unit of measurement for data, which is fixed to 'watts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "watts", "ifabsent": "string(watts)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class OptogeneticStimulusSite(NWBContainer): """ A site of optogenetic stimulation. @@ -239,4 +268,5 @@ class OptogeneticStimulusSite(NWBContainer): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model OptogeneticSeries.model_rebuild() +OptogeneticSeriesData.model_rebuild() OptogeneticStimulusSite.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py index eda0cf9..82374d7 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py @@ -28,7 +28,7 @@ from ...core.v2_2_0.core_nwb_base import ( TimeSeriesSync, ) from ...core.v2_2_0.core_nwb_device import Device -from ...core.v2_2_0.core_nwb_image import ImageSeries, ImageSeriesExternalFile +from ...core.v2_2_0.core_nwb_image import ImageSeries, ImageSeriesData, ImageSeriesExternalFile from ...hdmf_common.v1_1_0.hdmf_common_table import DynamicTable, DynamicTableRegion @@ -209,12 +209,9 @@ class TwoPhotonSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -225,8 +222,9 @@ class TwoPhotonSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -275,9 +273,7 @@ class RoiResponseSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], NDArray[Shape["* num_times, * num_rois"], float] - ] = Field(..., description="""Signals from ROIs.""") + data: RoiResponseSeriesData = Field(..., description="""Signals from ROIs.""") rois: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.""", @@ -327,6 +323,39 @@ class RoiResponseSeries(TimeSeries): ) +class RoiResponseSeriesData(ConfiguredBaseModel): + """ + Signals from ROIs. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ophys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_rois"], float | int], + ] + ] = Field(None) + + class DfOverF(NWBDataInterface): """ dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes). @@ -336,10 +365,10 @@ class DfOverF(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field("DfOverF", json_schema_extra={"linkml_meta": {"ifabsent": "string(DfOverF)"}}) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class Fluorescence(NWBDataInterface): @@ -351,10 +380,12 @@ class Fluorescence(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field( + "Fluorescence", json_schema_extra={"linkml_meta": {"ifabsent": "string(Fluorescence)"}} + ) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class ImageSegmentation(NWBDataInterface): @@ -366,10 +397,13 @@ class ImageSegmentation(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[DynamicTable]] = Field( + name: str = Field( + "ImageSegmentation", + json_schema_extra={"linkml_meta": {"ifabsent": "string(ImageSegmentation)"}}, + ) + value: Optional[Dict[str, DynamicTable]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "DynamicTable"}]}} ) - name: str = Field(...) class ImagingPlane(NWBContainer): @@ -538,16 +572,20 @@ class MotionCorrection(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[NWBDataInterface]] = Field( + name: str = Field( + "MotionCorrection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(MotionCorrection)"}}, + ) + value: Optional[Dict[str, NWBDataInterface]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "NWBDataInterface"}]}} ) - name: str = Field(...) # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model TwoPhotonSeries.model_rebuild() RoiResponseSeries.model_rebuild() +RoiResponseSeriesData.model_rebuild() DfOverF.model_rebuild() Fluorescence.model_rebuild() ImageSegmentation.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py index 3031e3c..e290ee6 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py @@ -235,7 +235,7 @@ class RetinotopyImage(GrayscaleImage): ) field_of_view: List[float] = Field(..., description="""Size of viewing area, in meters.""") format: str = Field(..., description="""Format of image. Right now only 'raw' is supported.""") - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} @@ -374,7 +374,7 @@ class ImagingRetinotopyFocalDepthImage(RetinotopyImage): ) field_of_view: List[float] = Field(..., description="""Size of viewing area, in meters.""") format: str = Field(..., description="""Format of image. Right now only 'raw' is supported.""") - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py index 805e58c..486ae90 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py @@ -38,6 +38,7 @@ from ...core.v2_2_0.core_nwb_ecephys import ( ClusterWaveforms, Clustering, ElectricalSeries, + ElectricalSeriesData, ElectrodeGroup, ElectrodeGroupPosition, EventDetection, @@ -46,6 +47,7 @@ from ...core.v2_2_0.core_nwb_ecephys import ( FilteredEphys, LFP, SpikeEventSeries, + SpikeEventSeriesData, ) from ...core.v2_2_0.core_nwb_epoch import TimeIntervals, TimeIntervalsTimeseries from ...core.v2_2_0.core_nwb_file import ( @@ -85,8 +87,10 @@ from ...core.v2_2_0.core_nwb_image import ( GrayscaleImage, ImageMaskSeries, ImageSeries, + ImageSeriesData, ImageSeriesExternalFile, IndexSeries, + IndexSeriesData, OpticalSeries, RGBAImage, RGBImage, @@ -95,14 +99,22 @@ from ...core.v2_2_0.core_nwb_misc import ( AbstractFeatureSeries, AbstractFeatureSeriesData, AnnotationSeries, + AnnotationSeriesData, DecompositionSeries, DecompositionSeriesBands, DecompositionSeriesData, IntervalSeries, + IntervalSeriesData, Units, UnitsSpikeTimes, + UnitsWaveformMean, + UnitsWaveformSd, +) +from ...core.v2_2_0.core_nwb_ogen import ( + OptogeneticSeries, + OptogeneticSeriesData, + OptogeneticStimulusSite, ) -from ...core.v2_2_0.core_nwb_ogen import OptogeneticSeries, OptogeneticStimulusSite from ...core.v2_2_0.core_nwb_ophys import ( DfOverF, Fluorescence, @@ -114,6 +126,7 @@ from ...core.v2_2_0.core_nwb_ophys import ( MotionCorrection, OpticalChannel, RoiResponseSeries, + RoiResponseSeriesData, TwoPhotonSeries, ) from ...core.v2_2_0.core_nwb_retinotopy import ( diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py index 044db0d..2d99237 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py @@ -170,9 +170,9 @@ class Image(NWBData): description: Optional[str] = Field(None, description="""Description of the image.""") value: Optional[ Union[ - NDArray[Shape["* x, * y"], float], - NDArray[Shape["* x, * y, 3 r_g_b"], float], - NDArray[Shape["* x, * y, 4 r_g_b_a"], float], + NDArray[Shape["* x, * y"], float | int], + NDArray[Shape["* x, * y, 3 r_g_b"], float | int], + NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int], ] ] = Field(None) @@ -333,13 +333,16 @@ class ProcessingModule(NWBContainer): {"from_schema": "core.nwb.base", "tree_root": True} ) - value: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + name: str = Field(...) + description: str = Field( + ..., description="""Description of this collection of processed data.""" + ) + value: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - name: str = Field(...) class Images(NWBDataInterface): @@ -353,7 +356,7 @@ class Images(NWBDataInterface): name: str = Field("Images", json_schema_extra={"linkml_meta": {"ifabsent": "string(Images)"}}) description: str = Field(..., description="""Description of this collection of images.""") - image: List[Image] = Field(..., description="""Images stored in this collection.""") + image: List[str] = Field(..., description="""Images stored in this collection.""") # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py index aaf0f41..15a2147 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py @@ -213,6 +213,16 @@ class SpatialSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "meters", description="""Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -220,8 +230,8 @@ class SpatialSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -235,10 +245,13 @@ class BehavioralEpochs(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[IntervalSeries]] = Field( + name: str = Field( + "BehavioralEpochs", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEpochs)"}}, + ) + value: Optional[Dict[str, IntervalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "IntervalSeries"}]}} ) - name: str = Field(...) class BehavioralEvents(NWBDataInterface): @@ -250,10 +263,13 @@ class BehavioralEvents(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralEvents", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEvents)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class BehavioralTimeSeries(NWBDataInterface): @@ -265,10 +281,13 @@ class BehavioralTimeSeries(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralTimeSeries", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralTimeSeries)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class PupilTracking(NWBDataInterface): @@ -280,10 +299,12 @@ class PupilTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "PupilTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(PupilTracking)"}} + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class EyeTracking(NWBDataInterface): @@ -295,10 +316,12 @@ class EyeTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "EyeTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(EyeTracking)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class CompassDirection(NWBDataInterface): @@ -310,10 +333,13 @@ class CompassDirection(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "CompassDirection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(CompassDirection)"}}, + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class Position(NWBDataInterface): @@ -325,10 +351,12 @@ class Position(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "Position", json_schema_extra={"linkml_meta": {"ifabsent": "string(Position)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py index 4d16d36..6fe5bc3 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py @@ -190,11 +190,12 @@ class ElectricalSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_channels"], float], - NDArray[Shape["* num_times, * num_channels, * num_samples"], float], - ] = Field(..., description="""Recorded voltage data.""") + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) + data: ElectricalSeriesData = Field(..., description="""Recorded voltage data.""") electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -207,11 +208,6 @@ class ElectricalSeries(TimeSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -249,6 +245,41 @@ class ElectricalSeries(TimeSeries): ) +class ElectricalSeriesData(ConfiguredBaseModel): + """ + Recorded voltage data. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_channels"], float | int], + NDArray[Shape["* num_times, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class SpikeEventSeries(ElectricalSeries): """ Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode). @@ -259,15 +290,17 @@ class SpikeEventSeries(ElectricalSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_events, * num_samples"], float], - NDArray[Shape["* num_events, * num_channels, * num_samples"], float], - ] = Field(..., description="""Spike waveforms.""") + data: SpikeEventSeriesData = Field(..., description="""Spike waveforms.""") timestamps: NDArray[Shape["* num_times"], float] = Field( ..., description="""Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, ) + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -280,11 +313,6 @@ class SpikeEventSeries(ElectricalSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -317,6 +345,40 @@ class SpikeEventSeries(ElectricalSeries): ) +class SpikeEventSeriesData(ConfiguredBaseModel): + """ + Spike waveforms. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Unit of measurement for waveforms, which is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_events, * num_samples"], float | int], + NDArray[Shape["* num_events, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class FeatureExtraction(NWBDataInterface): """ Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source. @@ -415,10 +477,12 @@ class EventWaveform(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[SpikeEventSeries]] = Field( + name: str = Field( + "EventWaveform", json_schema_extra={"linkml_meta": {"ifabsent": "string(EventWaveform)"}} + ) + value: Optional[Dict[str, SpikeEventSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpikeEventSeries"}]}} ) - name: str = Field(...) class FilteredEphys(NWBDataInterface): @@ -430,10 +494,12 @@ class FilteredEphys(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field( + "FilteredEphys", json_schema_extra={"linkml_meta": {"ifabsent": "string(FilteredEphys)"}} + ) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class LFP(NWBDataInterface): @@ -445,10 +511,10 @@ class LFP(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field("LFP", json_schema_extra={"linkml_meta": {"ifabsent": "string(LFP)"}}) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class ElectrodeGroup(NWBContainer): @@ -591,7 +657,9 @@ class Clustering(NWBDataInterface): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model ElectricalSeries.model_rebuild() +ElectricalSeriesData.model_rebuild() SpikeEventSeries.model_rebuild() +SpikeEventSeriesData.model_rebuild() FeatureExtraction.model_rebuild() EventDetection.model_rebuild() EventWaveform.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py index ce0dbfd..a9c4c0c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py @@ -247,9 +247,6 @@ class TimeIntervals(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class TimeIntervalsTimeseries(VectorData): diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py index 49a1846..feeffa8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py @@ -211,28 +211,28 @@ class NWBFile(NWBContainer): ..., description="""Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).""", ) - acquisition: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + acquisition: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, description="""Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - analysis: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + analysis: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - scratch: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + scratch: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - processing: Optional[List[ProcessingModule]] = Field( + processing: Optional[Dict[str, ProcessingModule]] = Field( None, description="""The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ProcessingModule"}]}}, @@ -250,6 +250,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -265,12 +268,12 @@ class NWBFileStimulus(ConfiguredBaseModel): "linkml_meta": {"equals_string": "stimulus", "ifabsent": "string(stimulus)"} }, ) - presentation: Optional[List[TimeSeries]] = Field( + presentation: Optional[Dict[str, TimeSeries]] = Field( None, description="""Stimuli presented during the experiment.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, ) - templates: Optional[List[TimeSeries]] = Field( + templates: Optional[Dict[str, TimeSeries]] = Field( None, description="""Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, @@ -348,11 +351,11 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - nwb_container: Optional[List[NWBContainer]] = Field( + nwb_container: Optional[Dict[str, NWBContainer]] = Field( None, description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", ) - devices: Optional[List[Device]] = Field( + devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "Device"}]}}, @@ -367,12 +370,12 @@ class NWBFileGeneral(ConfiguredBaseModel): intracellular_ephys: Optional[GeneralIntracellularEphys] = Field( None, description="""Metadata related to intracellular electrophysiology.""" ) - optogenetics: Optional[List[OptogeneticStimulusSite]] = Field( + optogenetics: Optional[Dict[str, OptogeneticStimulusSite]] = Field( None, description="""Metadata describing optogenetic stimuluation.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "OptogeneticStimulusSite"}]}}, ) - optophysiology: Optional[List[ImagingPlane]] = Field( + optophysiology: Optional[Dict[str, ImagingPlane]] = Field( None, description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, @@ -450,12 +453,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -525,8 +528,14 @@ class ExtracellularEphysElectrodes(DynamicTable): } }, ) - group: List[ElectrodeGroup] = Field( - ..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" + group: VectorData[NDArray[Any, ElectrodeGroup]] = Field( + ..., + description="""Reference to the ElectrodeGroup this electrode is a part of.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, ) group_name: VectorData[NDArray[Any, str]] = Field( ..., @@ -583,9 +592,6 @@ class ExtracellularEphysElectrodes(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class GeneralIntracellularEphys(ConfiguredBaseModel): @@ -608,12 +614,12 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[List[IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""The table which groups different PatchClampSeries together.""" ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -639,7 +645,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[List[TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py index 19b2f81..54355a8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py @@ -262,11 +262,21 @@ class PatchClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( ..., description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", ) - value: Optional[NDArray[Shape["* num_times"], float]] = Field( + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} ) @@ -281,12 +291,12 @@ class CurrentClampSeries(PatchClampSeries): ) name: str = Field(...) - data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") bias_current: Optional[float] = Field(None, description="""Bias current, in amps.""") bridge_balance: Optional[float] = Field(None, description="""Bridge balance, in ohms.""") capacitance_compensation: Optional[float] = Field( None, description="""Capacitance compensation, in farads.""" ) + data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") stimulus_description: str = Field( ..., description="""Protocol/stimulus name for this patch-clamp dataset.""" ) @@ -354,12 +364,24 @@ class CurrentClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IZeroClampSeries(CurrentClampSeries): @@ -512,6 +534,16 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["amperes"] = Field( "amperes", description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -519,7 +551,9 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} }, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class VoltageClampSeries(PatchClampSeries): @@ -532,13 +566,13 @@ class VoltageClampSeries(PatchClampSeries): ) name: str = Field(...) - data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") capacitance_fast: Optional[VoltageClampSeriesCapacitanceFast] = Field( None, description="""Fast capacitance, in farads.""" ) capacitance_slow: Optional[VoltageClampSeriesCapacitanceSlow] = Field( None, description="""Slow capacitance, in farads.""" ) + data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") resistance_comp_bandwidth: Optional[VoltageClampSeriesResistanceCompBandwidth] = Field( None, description="""Resistance compensation bandwidth, in hertz.""" ) @@ -610,27 +644,6 @@ class VoltageClampSeries(PatchClampSeries): ) -class VoltageClampSeriesData(ConfiguredBaseModel): - """ - Recorded current. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) - - name: Literal["data"] = Field( - "data", - json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, - ) - unit: Literal["amperes"] = Field( - "amperes", - description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", - json_schema_extra={ - "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} - }, - ) - value: Any = Field(...) - - class VoltageClampSeriesCapacitanceFast(ConfiguredBaseModel): """ Fast capacitance, in farads. @@ -683,6 +696,39 @@ class VoltageClampSeriesCapacitanceSlow(ConfiguredBaseModel): value: float = Field(...) +class VoltageClampSeriesData(ConfiguredBaseModel): + """ + Recorded current. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["amperes"] = Field( + "amperes", + description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + json_schema_extra={ + "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} + }, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class VoltageClampSeriesResistanceCompBandwidth(ConfiguredBaseModel): """ Resistance compensation bandwidth, in hertz. @@ -887,12 +933,24 @@ class VoltageClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IntracellularElectrode(NWBContainer): @@ -942,18 +1000,15 @@ class SweepTable(DynamicTable): ) name: str = Field(...) - sweep_number: VectorData[NDArray[Any, int]] = Field( + series: VectorData[NDArray[Any, PatchClampSeries]] = Field( ..., - description="""Sweep number of the PatchClampSeries in that row.""", + description="""The PatchClampSeries with the sweep number in that row.""", json_schema_extra={ "linkml_meta": { "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} } }, ) - series: List[PatchClampSeries] = Field( - ..., description="""The PatchClampSeries with the sweep number in that row.""" - ) series_index: Named[VectorIndex] = Field( ..., description="""Index for series.""", @@ -966,6 +1021,15 @@ class SweepTable(DynamicTable): } }, ) + sweep_number: VectorData[NDArray[Any, int]] = Field( + ..., + description="""Sweep number of the PatchClampSeries in that row.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -976,9 +1040,6 @@ class SweepTable(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild @@ -991,9 +1052,9 @@ IZeroClampSeries.model_rebuild() CurrentClampStimulusSeries.model_rebuild() CurrentClampStimulusSeriesData.model_rebuild() VoltageClampSeries.model_rebuild() -VoltageClampSeriesData.model_rebuild() VoltageClampSeriesCapacitanceFast.model_rebuild() VoltageClampSeriesCapacitanceSlow.model_rebuild() +VoltageClampSeriesData.model_rebuild() VoltageClampSeriesResistanceCompBandwidth.model_rebuild() VoltageClampSeriesResistanceCompCorrection.model_rebuild() VoltageClampSeriesResistanceCompPrediction.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py index 990cc6a..3cb3726 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py @@ -152,7 +152,7 @@ class GrayscaleImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} @@ -174,7 +174,7 @@ class RGBImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -204,7 +204,7 @@ class RGBAImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -234,12 +234,9 @@ class ImageSeries(TimeSeries): ) name: str = Field(...) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -250,8 +247,9 @@ class ImageSeries(TimeSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -290,6 +288,39 @@ class ImageSeries(TimeSeries): ) +class ImageSeriesData(ConfiguredBaseModel): + """ + Binary data representing images across frames. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, * z"], float | int], + ] + ] = Field(None) + + class ImageSeriesExternalFile(ConfiguredBaseModel): """ Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file. @@ -331,12 +362,9 @@ class ImageMaskSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -347,8 +375,9 @@ class ImageMaskSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -409,12 +438,9 @@ class OpticalSeries(ImageSeries): None, description="""Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.""", ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -425,8 +451,9 @@ class OpticalSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -475,10 +502,8 @@ class IndexSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Index of the frame in the referenced ImageSeries.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IndexSeriesData = Field( + ..., description="""Index of the frame in the referenced ImageSeries.""" ) indexed_timeseries: Union[ImageSeries, str] = Field( ..., @@ -526,13 +551,45 @@ class IndexSeries(TimeSeries): ) +class IndexSeriesData(ConfiguredBaseModel): + """ + Index of the frame in the referenced ImageSeries. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model GrayscaleImage.model_rebuild() RGBImage.model_rebuild() RGBAImage.model_rebuild() ImageSeries.model_rebuild() +ImageSeriesData.model_rebuild() ImageSeriesExternalFile.model_rebuild() ImageMaskSeries.model_rebuild() OpticalSeries.model_rebuild() IndexSeries.model_rebuild() +IndexSeriesData.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py index 2249720..4854da4 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py @@ -251,6 +251,16 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "see ", description="""Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".""", @@ -258,8 +268,8 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -274,10 +284,8 @@ class AnnotationSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], str] = Field( - ..., - description="""Annotations made during an experiment.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: AnnotationSeriesData = Field( + ..., description="""Annotations made during an experiment.""" ) description: Optional[str] = Field( "no description", @@ -316,6 +324,39 @@ class AnnotationSeries(TimeSeries): ) +class AnnotationSeriesData(ConfiguredBaseModel): + """ + Annotations made during an experiment. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], str]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class IntervalSeries(TimeSeries): """ Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. @@ -326,10 +367,8 @@ class IntervalSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Use values >0 if interval started, <0 if interval ended.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IntervalSeriesData = Field( + ..., description="""Use values >0 if interval started, <0 if interval ended.""" ) description: Optional[str] = Field( "no description", @@ -368,6 +407,39 @@ class IntervalSeries(TimeSeries): ) +class IntervalSeriesData(ConfiguredBaseModel): + """ + Use values >0 if interval started, <0 if interval ended. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class DecompositionSeries(TimeSeries): """ Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -443,24 +515,36 @@ class DecompositionSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( "no unit", description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"ifabsent": "string(no unit)"}}, ) - value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float]] = Field( - None, - json_schema_extra={ - "linkml_meta": { - "array": { - "dimensions": [ - {"alias": "num_times"}, - {"alias": "num_channels"}, - {"alias": "num_bands"}, - ] + value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float | int]] = ( + Field( + None, + json_schema_extra={ + "linkml_meta": { + "array": { + "dimensions": [ + {"alias": "num_times"}, + {"alias": "num_channels"}, + {"alias": "num_bands"}, + ] + } } - } - }, + }, + ) ) @@ -518,9 +602,6 @@ class DecompositionSeriesBands(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class Units(DynamicTable): @@ -533,9 +614,18 @@ class Units(DynamicTable): ) name: str = Field("Units", json_schema_extra={"linkml_meta": {"ifabsent": "string(Units)"}}) - spike_times_index: Optional[Named[VectorIndex]] = Field( + electrode_group: Optional[VectorData[NDArray[Any, ElectrodeGroup]]] = Field( None, - description="""Index into the spike_times dataset.""", + description="""Electrode group that each spike unit came from.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) + electrodes: Optional[Named[DynamicTableRegion]] = Field( + None, + description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -545,12 +635,9 @@ class Units(DynamicTable): } }, ) - spike_times: Optional[UnitsSpikeTimes] = Field( - None, description="""Spike times for each unit.""" - ) - obs_intervals_index: Optional[Named[VectorIndex]] = Field( + electrodes_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into the obs_intervals dataset.""", + description="""Index into electrodes.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -576,9 +663,9 @@ class Units(DynamicTable): }, ) ) - electrodes_index: Optional[Named[VectorIndex]] = Field( + obs_intervals_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into electrodes.""", + description="""Index into the obs_intervals dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -588,9 +675,12 @@ class Units(DynamicTable): } }, ) - electrodes: Optional[Named[DynamicTableRegion]] = Field( + spike_times: Optional[UnitsSpikeTimes] = Field( + None, description="""Spike times for each unit.""" + ) + spike_times_index: Optional[Named[VectorIndex]] = Field( None, - description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", + description="""Index into the spike_times dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -600,25 +690,12 @@ class Units(DynamicTable): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Electrode group that each spike unit came from.""" + waveform_mean: Optional[UnitsWaveformMean] = Field( + None, description="""Spike waveform mean for each spike unit.""" + ) + waveform_sd: Optional[UnitsWaveformSd] = Field( + None, description="""Spike waveform standard deviation for each spike unit.""" ) - waveform_mean: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform mean for each spike unit.""") - waveform_sd: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""") colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -629,9 +706,6 @@ class Units(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class UnitsSpikeTimes(VectorData): @@ -654,14 +728,62 @@ class UnitsSpikeTimes(VectorData): description: str = Field(..., description="""Description of what these vectors represent.""") +class UnitsWaveformMean(VectorData): + """ + Spike waveform mean for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_mean"] = Field( + "waveform_mean", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_mean", "ifabsent": "string(waveform_mean)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + + +class UnitsWaveformSd(VectorData): + """ + Spike waveform standard deviation for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_sd"] = Field( + "waveform_sd", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_sd", "ifabsent": "string(waveform_sd)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model AbstractFeatureSeries.model_rebuild() AbstractFeatureSeriesData.model_rebuild() AnnotationSeries.model_rebuild() +AnnotationSeriesData.model_rebuild() IntervalSeries.model_rebuild() +IntervalSeriesData.model_rebuild() DecompositionSeries.model_rebuild() DecompositionSeriesData.model_rebuild() DecompositionSeriesBands.model_rebuild() Units.model_rebuild() UnitsSpikeTimes.model_rebuild() +UnitsWaveformMean.model_rebuild() +UnitsWaveformSd.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py index 64649f4..8091c95 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py @@ -158,10 +158,8 @@ class OptogeneticSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], float] = Field( - ..., - description="""Applied power for optogenetic stimulus, in watts.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: OptogeneticSeriesData = Field( + ..., description="""Applied power for optogenetic stimulus, in watts.""" ) site: Union[OptogeneticStimulusSite, str] = Field( ..., @@ -209,6 +207,37 @@ class OptogeneticSeries(TimeSeries): ) +class OptogeneticSeriesData(ConfiguredBaseModel): + """ + Applied power for optogenetic stimulus, in watts. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ogen"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["watts"] = Field( + "watts", + description="""Unit of measurement for data, which is fixed to 'watts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "watts", "ifabsent": "string(watts)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class OptogeneticStimulusSite(NWBContainer): """ A site of optogenetic stimulation. @@ -239,4 +268,5 @@ class OptogeneticStimulusSite(NWBContainer): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model OptogeneticSeries.model_rebuild() +OptogeneticSeriesData.model_rebuild() OptogeneticStimulusSite.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py index deecf64..fc21826 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py @@ -28,7 +28,7 @@ from ...core.v2_2_1.core_nwb_base import ( TimeSeriesSync, ) from ...core.v2_2_1.core_nwb_device import Device -from ...core.v2_2_1.core_nwb_image import ImageSeries, ImageSeriesExternalFile +from ...core.v2_2_1.core_nwb_image import ImageSeries, ImageSeriesData, ImageSeriesExternalFile from ...hdmf_common.v1_1_2.hdmf_common_table import DynamicTable, DynamicTableRegion @@ -209,12 +209,9 @@ class TwoPhotonSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -225,8 +222,9 @@ class TwoPhotonSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -275,9 +273,7 @@ class RoiResponseSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], NDArray[Shape["* num_times, * num_rois"], float] - ] = Field(..., description="""Signals from ROIs.""") + data: RoiResponseSeriesData = Field(..., description="""Signals from ROIs.""") rois: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.""", @@ -327,6 +323,39 @@ class RoiResponseSeries(TimeSeries): ) +class RoiResponseSeriesData(ConfiguredBaseModel): + """ + Signals from ROIs. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ophys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_rois"], float | int], + ] + ] = Field(None) + + class DfOverF(NWBDataInterface): """ dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes). @@ -336,10 +365,10 @@ class DfOverF(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field("DfOverF", json_schema_extra={"linkml_meta": {"ifabsent": "string(DfOverF)"}}) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class Fluorescence(NWBDataInterface): @@ -351,10 +380,12 @@ class Fluorescence(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field( + "Fluorescence", json_schema_extra={"linkml_meta": {"ifabsent": "string(Fluorescence)"}} + ) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class ImageSegmentation(NWBDataInterface): @@ -366,10 +397,13 @@ class ImageSegmentation(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[DynamicTable]] = Field( + name: str = Field( + "ImageSegmentation", + json_schema_extra={"linkml_meta": {"ifabsent": "string(ImageSegmentation)"}}, + ) + value: Optional[Dict[str, DynamicTable]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "DynamicTable"}]}} ) - name: str = Field(...) class ImagingPlane(NWBContainer): @@ -538,16 +572,20 @@ class MotionCorrection(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[NWBDataInterface]] = Field( + name: str = Field( + "MotionCorrection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(MotionCorrection)"}}, + ) + value: Optional[Dict[str, NWBDataInterface]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "NWBDataInterface"}]}} ) - name: str = Field(...) # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model TwoPhotonSeries.model_rebuild() RoiResponseSeries.model_rebuild() +RoiResponseSeriesData.model_rebuild() DfOverF.model_rebuild() Fluorescence.model_rebuild() ImageSegmentation.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py index dd8a84e..3a1d8de 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py @@ -235,7 +235,7 @@ class RetinotopyImage(GrayscaleImage): ) field_of_view: List[float] = Field(..., description="""Size of viewing area, in meters.""") format: str = Field(..., description="""Format of image. Right now only 'raw' is supported.""") - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} @@ -374,7 +374,7 @@ class ImagingRetinotopyFocalDepthImage(RetinotopyImage): ) field_of_view: List[float] = Field(..., description="""Size of viewing area, in meters.""") format: str = Field(..., description="""Format of image. Right now only 'raw' is supported.""") - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py index cbab2e1..2f99d8f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py @@ -38,6 +38,7 @@ from ...core.v2_2_1.core_nwb_ecephys import ( ClusterWaveforms, Clustering, ElectricalSeries, + ElectricalSeriesData, ElectrodeGroup, ElectrodeGroupPosition, EventDetection, @@ -46,6 +47,7 @@ from ...core.v2_2_1.core_nwb_ecephys import ( FilteredEphys, LFP, SpikeEventSeries, + SpikeEventSeriesData, ) from ...core.v2_2_1.core_nwb_epoch import TimeIntervals, TimeIntervalsTimeseries from ...core.v2_2_1.core_nwb_file import ( @@ -85,8 +87,10 @@ from ...core.v2_2_1.core_nwb_image import ( GrayscaleImage, ImageMaskSeries, ImageSeries, + ImageSeriesData, ImageSeriesExternalFile, IndexSeries, + IndexSeriesData, OpticalSeries, RGBAImage, RGBImage, @@ -95,14 +99,22 @@ from ...core.v2_2_1.core_nwb_misc import ( AbstractFeatureSeries, AbstractFeatureSeriesData, AnnotationSeries, + AnnotationSeriesData, DecompositionSeries, DecompositionSeriesBands, DecompositionSeriesData, IntervalSeries, + IntervalSeriesData, Units, UnitsSpikeTimes, + UnitsWaveformMean, + UnitsWaveformSd, +) +from ...core.v2_2_1.core_nwb_ogen import ( + OptogeneticSeries, + OptogeneticSeriesData, + OptogeneticStimulusSite, ) -from ...core.v2_2_1.core_nwb_ogen import OptogeneticSeries, OptogeneticStimulusSite from ...core.v2_2_1.core_nwb_ophys import ( DfOverF, Fluorescence, @@ -114,6 +126,7 @@ from ...core.v2_2_1.core_nwb_ophys import ( MotionCorrection, OpticalChannel, RoiResponseSeries, + RoiResponseSeriesData, TwoPhotonSeries, ) from ...core.v2_2_1.core_nwb_retinotopy import ( diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py index bce6112..868c0a0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py @@ -170,9 +170,9 @@ class Image(NWBData): description: Optional[str] = Field(None, description="""Description of the image.""") value: Optional[ Union[ - NDArray[Shape["* x, * y"], float], - NDArray[Shape["* x, * y, 3 r_g_b"], float], - NDArray[Shape["* x, * y, 4 r_g_b_a"], float], + NDArray[Shape["* x, * y"], float | int], + NDArray[Shape["* x, * y, 3 r_g_b"], float | int], + NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int], ] ] = Field(None) @@ -333,13 +333,16 @@ class ProcessingModule(NWBContainer): {"from_schema": "core.nwb.base", "tree_root": True} ) - value: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + name: str = Field(...) + description: str = Field( + ..., description="""Description of this collection of processed data.""" + ) + value: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - name: str = Field(...) class Images(NWBDataInterface): @@ -353,7 +356,7 @@ class Images(NWBDataInterface): name: str = Field("Images", json_schema_extra={"linkml_meta": {"ifabsent": "string(Images)"}}) description: str = Field(..., description="""Description of this collection of images.""") - image: List[Image] = Field(..., description="""Images stored in this collection.""") + image: List[str] = Field(..., description="""Images stored in this collection.""") # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py index 1536adb..c5cf858 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py @@ -213,6 +213,16 @@ class SpatialSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "meters", description="""Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -220,8 +230,8 @@ class SpatialSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -235,10 +245,13 @@ class BehavioralEpochs(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[IntervalSeries]] = Field( + name: str = Field( + "BehavioralEpochs", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEpochs)"}}, + ) + value: Optional[Dict[str, IntervalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "IntervalSeries"}]}} ) - name: str = Field(...) class BehavioralEvents(NWBDataInterface): @@ -250,10 +263,13 @@ class BehavioralEvents(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralEvents", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEvents)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class BehavioralTimeSeries(NWBDataInterface): @@ -265,10 +281,13 @@ class BehavioralTimeSeries(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralTimeSeries", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralTimeSeries)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class PupilTracking(NWBDataInterface): @@ -280,10 +299,12 @@ class PupilTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "PupilTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(PupilTracking)"}} + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class EyeTracking(NWBDataInterface): @@ -295,10 +316,12 @@ class EyeTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "EyeTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(EyeTracking)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class CompassDirection(NWBDataInterface): @@ -310,10 +333,13 @@ class CompassDirection(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "CompassDirection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(CompassDirection)"}}, + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class Position(NWBDataInterface): @@ -325,10 +351,12 @@ class Position(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "Position", json_schema_extra={"linkml_meta": {"ifabsent": "string(Position)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py index 22e0ff7..8d95787 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py @@ -190,11 +190,12 @@ class ElectricalSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_channels"], float], - NDArray[Shape["* num_times, * num_channels, * num_samples"], float], - ] = Field(..., description="""Recorded voltage data.""") + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) + data: ElectricalSeriesData = Field(..., description="""Recorded voltage data.""") electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -207,11 +208,6 @@ class ElectricalSeries(TimeSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -249,6 +245,41 @@ class ElectricalSeries(TimeSeries): ) +class ElectricalSeriesData(ConfiguredBaseModel): + """ + Recorded voltage data. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_channels"], float | int], + NDArray[Shape["* num_times, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class SpikeEventSeries(ElectricalSeries): """ Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode). @@ -259,15 +290,17 @@ class SpikeEventSeries(ElectricalSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_events, * num_samples"], float], - NDArray[Shape["* num_events, * num_channels, * num_samples"], float], - ] = Field(..., description="""Spike waveforms.""") + data: SpikeEventSeriesData = Field(..., description="""Spike waveforms.""") timestamps: NDArray[Shape["* num_times"], float] = Field( ..., description="""Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, ) + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -280,11 +313,6 @@ class SpikeEventSeries(ElectricalSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -317,6 +345,40 @@ class SpikeEventSeries(ElectricalSeries): ) +class SpikeEventSeriesData(ConfiguredBaseModel): + """ + Spike waveforms. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Unit of measurement for waveforms, which is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_events, * num_samples"], float | int], + NDArray[Shape["* num_events, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class FeatureExtraction(NWBDataInterface): """ Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source. @@ -415,10 +477,12 @@ class EventWaveform(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[SpikeEventSeries]] = Field( + name: str = Field( + "EventWaveform", json_schema_extra={"linkml_meta": {"ifabsent": "string(EventWaveform)"}} + ) + value: Optional[Dict[str, SpikeEventSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpikeEventSeries"}]}} ) - name: str = Field(...) class FilteredEphys(NWBDataInterface): @@ -430,10 +494,12 @@ class FilteredEphys(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field( + "FilteredEphys", json_schema_extra={"linkml_meta": {"ifabsent": "string(FilteredEphys)"}} + ) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class LFP(NWBDataInterface): @@ -445,10 +511,10 @@ class LFP(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field("LFP", json_schema_extra={"linkml_meta": {"ifabsent": "string(LFP)"}}) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class ElectrodeGroup(NWBContainer): @@ -591,7 +657,9 @@ class Clustering(NWBDataInterface): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model ElectricalSeries.model_rebuild() +ElectricalSeriesData.model_rebuild() SpikeEventSeries.model_rebuild() +SpikeEventSeriesData.model_rebuild() FeatureExtraction.model_rebuild() EventDetection.model_rebuild() EventWaveform.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py index d599a8c..e374b7d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py @@ -247,9 +247,6 @@ class TimeIntervals(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class TimeIntervalsTimeseries(VectorData): diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py index 8b5d38b..3f9a448 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py @@ -211,28 +211,28 @@ class NWBFile(NWBContainer): ..., description="""Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).""", ) - acquisition: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + acquisition: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, description="""Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - analysis: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + analysis: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - scratch: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + scratch: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - processing: Optional[List[ProcessingModule]] = Field( + processing: Optional[Dict[str, ProcessingModule]] = Field( None, description="""The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ProcessingModule"}]}}, @@ -250,6 +250,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -265,12 +268,12 @@ class NWBFileStimulus(ConfiguredBaseModel): "linkml_meta": {"equals_string": "stimulus", "ifabsent": "string(stimulus)"} }, ) - presentation: Optional[List[TimeSeries]] = Field( + presentation: Optional[Dict[str, TimeSeries]] = Field( None, description="""Stimuli presented during the experiment.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, ) - templates: Optional[List[TimeSeries]] = Field( + templates: Optional[Dict[str, TimeSeries]] = Field( None, description="""Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, @@ -348,11 +351,11 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - nwb_container: Optional[List[NWBContainer]] = Field( + nwb_container: Optional[Dict[str, NWBContainer]] = Field( None, description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", ) - devices: Optional[List[Device]] = Field( + devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "Device"}]}}, @@ -367,12 +370,12 @@ class NWBFileGeneral(ConfiguredBaseModel): intracellular_ephys: Optional[GeneralIntracellularEphys] = Field( None, description="""Metadata related to intracellular electrophysiology.""" ) - optogenetics: Optional[List[OptogeneticStimulusSite]] = Field( + optogenetics: Optional[Dict[str, OptogeneticStimulusSite]] = Field( None, description="""Metadata describing optogenetic stimuluation.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "OptogeneticStimulusSite"}]}}, ) - optophysiology: Optional[List[ImagingPlane]] = Field( + optophysiology: Optional[Dict[str, ImagingPlane]] = Field( None, description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, @@ -450,12 +453,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -525,8 +528,14 @@ class ExtracellularEphysElectrodes(DynamicTable): } }, ) - group: List[ElectrodeGroup] = Field( - ..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" + group: VectorData[NDArray[Any, ElectrodeGroup]] = Field( + ..., + description="""Reference to the ElectrodeGroup this electrode is a part of.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, ) group_name: VectorData[NDArray[Any, str]] = Field( ..., @@ -583,9 +592,6 @@ class ExtracellularEphysElectrodes(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class GeneralIntracellularEphys(ConfiguredBaseModel): @@ -608,12 +614,12 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[List[IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""The table which groups different PatchClampSeries together.""" ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -639,7 +645,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[List[TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py index 464dcc8..4ec6c40 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py @@ -262,11 +262,21 @@ class PatchClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( ..., description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", ) - value: Optional[NDArray[Shape["* num_times"], float]] = Field( + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} ) @@ -281,12 +291,12 @@ class CurrentClampSeries(PatchClampSeries): ) name: str = Field(...) - data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") bias_current: Optional[float] = Field(None, description="""Bias current, in amps.""") bridge_balance: Optional[float] = Field(None, description="""Bridge balance, in ohms.""") capacitance_compensation: Optional[float] = Field( None, description="""Capacitance compensation, in farads.""" ) + data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") stimulus_description: str = Field( ..., description="""Protocol/stimulus name for this patch-clamp dataset.""" ) @@ -354,12 +364,24 @@ class CurrentClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IZeroClampSeries(CurrentClampSeries): @@ -512,6 +534,16 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["amperes"] = Field( "amperes", description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -519,7 +551,9 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} }, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class VoltageClampSeries(PatchClampSeries): @@ -532,13 +566,13 @@ class VoltageClampSeries(PatchClampSeries): ) name: str = Field(...) - data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") capacitance_fast: Optional[VoltageClampSeriesCapacitanceFast] = Field( None, description="""Fast capacitance, in farads.""" ) capacitance_slow: Optional[VoltageClampSeriesCapacitanceSlow] = Field( None, description="""Slow capacitance, in farads.""" ) + data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") resistance_comp_bandwidth: Optional[VoltageClampSeriesResistanceCompBandwidth] = Field( None, description="""Resistance compensation bandwidth, in hertz.""" ) @@ -610,27 +644,6 @@ class VoltageClampSeries(PatchClampSeries): ) -class VoltageClampSeriesData(ConfiguredBaseModel): - """ - Recorded current. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) - - name: Literal["data"] = Field( - "data", - json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, - ) - unit: Literal["amperes"] = Field( - "amperes", - description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", - json_schema_extra={ - "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} - }, - ) - value: Any = Field(...) - - class VoltageClampSeriesCapacitanceFast(ConfiguredBaseModel): """ Fast capacitance, in farads. @@ -683,6 +696,39 @@ class VoltageClampSeriesCapacitanceSlow(ConfiguredBaseModel): value: float = Field(...) +class VoltageClampSeriesData(ConfiguredBaseModel): + """ + Recorded current. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["amperes"] = Field( + "amperes", + description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + json_schema_extra={ + "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} + }, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class VoltageClampSeriesResistanceCompBandwidth(ConfiguredBaseModel): """ Resistance compensation bandwidth, in hertz. @@ -887,12 +933,24 @@ class VoltageClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IntracellularElectrode(NWBContainer): @@ -942,18 +1000,15 @@ class SweepTable(DynamicTable): ) name: str = Field(...) - sweep_number: VectorData[NDArray[Any, int]] = Field( + series: VectorData[NDArray[Any, PatchClampSeries]] = Field( ..., - description="""Sweep number of the PatchClampSeries in that row.""", + description="""The PatchClampSeries with the sweep number in that row.""", json_schema_extra={ "linkml_meta": { "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} } }, ) - series: List[PatchClampSeries] = Field( - ..., description="""The PatchClampSeries with the sweep number in that row.""" - ) series_index: Named[VectorIndex] = Field( ..., description="""Index for series.""", @@ -966,6 +1021,15 @@ class SweepTable(DynamicTable): } }, ) + sweep_number: VectorData[NDArray[Any, int]] = Field( + ..., + description="""Sweep number of the PatchClampSeries in that row.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -976,9 +1040,6 @@ class SweepTable(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild @@ -991,9 +1052,9 @@ IZeroClampSeries.model_rebuild() CurrentClampStimulusSeries.model_rebuild() CurrentClampStimulusSeriesData.model_rebuild() VoltageClampSeries.model_rebuild() -VoltageClampSeriesData.model_rebuild() VoltageClampSeriesCapacitanceFast.model_rebuild() VoltageClampSeriesCapacitanceSlow.model_rebuild() +VoltageClampSeriesData.model_rebuild() VoltageClampSeriesResistanceCompBandwidth.model_rebuild() VoltageClampSeriesResistanceCompCorrection.model_rebuild() VoltageClampSeriesResistanceCompPrediction.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py index b88c1b1..1de22fc 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py @@ -152,7 +152,7 @@ class GrayscaleImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} @@ -174,7 +174,7 @@ class RGBImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -204,7 +204,7 @@ class RGBAImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -234,12 +234,9 @@ class ImageSeries(TimeSeries): ) name: str = Field(...) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -250,8 +247,9 @@ class ImageSeries(TimeSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -290,6 +288,39 @@ class ImageSeries(TimeSeries): ) +class ImageSeriesData(ConfiguredBaseModel): + """ + Binary data representing images across frames. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, * z"], float | int], + ] + ] = Field(None) + + class ImageSeriesExternalFile(ConfiguredBaseModel): """ Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file. @@ -331,12 +362,9 @@ class ImageMaskSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -347,8 +375,9 @@ class ImageMaskSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -397,6 +426,9 @@ class OpticalSeries(ImageSeries): ) name: str = Field(...) + data: OpticalSeriesData = Field( + ..., description="""Images presented to subject, either grayscale or RGB""" + ) distance: Optional[float] = Field( None, description="""Distance from camera/monitor to target/eye.""" ) @@ -405,10 +437,6 @@ class OpticalSeries(ImageSeries): NDArray[Shape["2 width_height"], float], NDArray[Shape["3 width_height_depth"], float] ] ] = Field(None, description="""Width, height and depth of image, or imaged area, in meters.""") - data: Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, 3 r_g_b"], float], - ] = Field(..., description="""Images presented to subject, either grayscale or RGB""") orientation: Optional[str] = Field( None, description="""Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.""", @@ -423,8 +451,9 @@ class OpticalSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -463,6 +492,39 @@ class OpticalSeries(ImageSeries): ) +class OpticalSeriesData(ConfiguredBaseModel): + """ + Images presented to subject, either grayscale or RGB + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, 3 r_g_b"], float | int], + ] + ] = Field(None) + + class IndexSeries(TimeSeries): """ Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed. @@ -473,10 +535,8 @@ class IndexSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Index of the frame in the referenced ImageSeries.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IndexSeriesData = Field( + ..., description="""Index of the frame in the referenced ImageSeries.""" ) indexed_timeseries: Union[ImageSeries, str] = Field( ..., @@ -524,13 +584,46 @@ class IndexSeries(TimeSeries): ) +class IndexSeriesData(ConfiguredBaseModel): + """ + Index of the frame in the referenced ImageSeries. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model GrayscaleImage.model_rebuild() RGBImage.model_rebuild() RGBAImage.model_rebuild() ImageSeries.model_rebuild() +ImageSeriesData.model_rebuild() ImageSeriesExternalFile.model_rebuild() ImageMaskSeries.model_rebuild() OpticalSeries.model_rebuild() +OpticalSeriesData.model_rebuild() IndexSeries.model_rebuild() +IndexSeriesData.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py index e12bfb2..2de3b20 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py @@ -251,6 +251,16 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "see ", description="""Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".""", @@ -258,8 +268,8 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -274,10 +284,8 @@ class AnnotationSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], str] = Field( - ..., - description="""Annotations made during an experiment.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: AnnotationSeriesData = Field( + ..., description="""Annotations made during an experiment.""" ) description: Optional[str] = Field( "no description", @@ -316,6 +324,39 @@ class AnnotationSeries(TimeSeries): ) +class AnnotationSeriesData(ConfiguredBaseModel): + """ + Annotations made during an experiment. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], str]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class IntervalSeries(TimeSeries): """ Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. @@ -326,10 +367,8 @@ class IntervalSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Use values >0 if interval started, <0 if interval ended.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IntervalSeriesData = Field( + ..., description="""Use values >0 if interval started, <0 if interval ended.""" ) description: Optional[str] = Field( "no description", @@ -368,6 +407,39 @@ class IntervalSeries(TimeSeries): ) +class IntervalSeriesData(ConfiguredBaseModel): + """ + Use values >0 if interval started, <0 if interval ended. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class DecompositionSeries(TimeSeries): """ Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -443,24 +515,36 @@ class DecompositionSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( "no unit", description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"ifabsent": "string(no unit)"}}, ) - value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float]] = Field( - None, - json_schema_extra={ - "linkml_meta": { - "array": { - "dimensions": [ - {"alias": "num_times"}, - {"alias": "num_channels"}, - {"alias": "num_bands"}, - ] + value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float | int]] = ( + Field( + None, + json_schema_extra={ + "linkml_meta": { + "array": { + "dimensions": [ + {"alias": "num_times"}, + {"alias": "num_channels"}, + {"alias": "num_bands"}, + ] + } } - } - }, + }, + ) ) @@ -518,9 +602,6 @@ class DecompositionSeriesBands(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class Units(DynamicTable): @@ -533,9 +614,18 @@ class Units(DynamicTable): ) name: str = Field("Units", json_schema_extra={"linkml_meta": {"ifabsent": "string(Units)"}}) - spike_times_index: Optional[Named[VectorIndex]] = Field( + electrode_group: Optional[VectorData[NDArray[Any, ElectrodeGroup]]] = Field( None, - description="""Index into the spike_times dataset.""", + description="""Electrode group that each spike unit came from.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) + electrodes: Optional[Named[DynamicTableRegion]] = Field( + None, + description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -545,12 +635,9 @@ class Units(DynamicTable): } }, ) - spike_times: Optional[UnitsSpikeTimes] = Field( - None, description="""Spike times for each unit.""" - ) - obs_intervals_index: Optional[Named[VectorIndex]] = Field( + electrodes_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into the obs_intervals dataset.""", + description="""Index into electrodes.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -576,9 +663,9 @@ class Units(DynamicTable): }, ) ) - electrodes_index: Optional[Named[VectorIndex]] = Field( + obs_intervals_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into electrodes.""", + description="""Index into the obs_intervals dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -588,9 +675,12 @@ class Units(DynamicTable): } }, ) - electrodes: Optional[Named[DynamicTableRegion]] = Field( + spike_times: Optional[UnitsSpikeTimes] = Field( + None, description="""Spike times for each unit.""" + ) + spike_times_index: Optional[Named[VectorIndex]] = Field( None, - description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", + description="""Index into the spike_times dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -600,25 +690,12 @@ class Units(DynamicTable): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Electrode group that each spike unit came from.""" + waveform_mean: Optional[UnitsWaveformMean] = Field( + None, description="""Spike waveform mean for each spike unit.""" + ) + waveform_sd: Optional[UnitsWaveformSd] = Field( + None, description="""Spike waveform standard deviation for each spike unit.""" ) - waveform_mean: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform mean for each spike unit.""") - waveform_sd: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""") colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -629,9 +706,6 @@ class Units(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class UnitsSpikeTimes(VectorData): @@ -662,14 +736,78 @@ class UnitsSpikeTimes(VectorData): ] = Field(None) +class UnitsWaveformMean(VectorData): + """ + Spike waveform mean for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_mean"] = Field( + "waveform_mean", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_mean", "ifabsent": "string(waveform_mean)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + value: Optional[ + Union[ + NDArray[Shape["* dim0"], Any], + NDArray[Shape["* dim0, * dim1"], Any], + NDArray[Shape["* dim0, * dim1, * dim2"], Any], + NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], + ] + ] = Field(None) + + +class UnitsWaveformSd(VectorData): + """ + Spike waveform standard deviation for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_sd"] = Field( + "waveform_sd", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_sd", "ifabsent": "string(waveform_sd)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + value: Optional[ + Union[ + NDArray[Shape["* dim0"], Any], + NDArray[Shape["* dim0, * dim1"], Any], + NDArray[Shape["* dim0, * dim1, * dim2"], Any], + NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], + ] + ] = Field(None) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model AbstractFeatureSeries.model_rebuild() AbstractFeatureSeriesData.model_rebuild() AnnotationSeries.model_rebuild() +AnnotationSeriesData.model_rebuild() IntervalSeries.model_rebuild() +IntervalSeriesData.model_rebuild() DecompositionSeries.model_rebuild() DecompositionSeriesData.model_rebuild() DecompositionSeriesBands.model_rebuild() Units.model_rebuild() UnitsSpikeTimes.model_rebuild() +UnitsWaveformMean.model_rebuild() +UnitsWaveformSd.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py index 7bdc063..0c8d4eb 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py @@ -158,10 +158,8 @@ class OptogeneticSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], float] = Field( - ..., - description="""Applied power for optogenetic stimulus, in watts.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: OptogeneticSeriesData = Field( + ..., description="""Applied power for optogenetic stimulus, in watts.""" ) site: Union[OptogeneticStimulusSite, str] = Field( ..., @@ -209,6 +207,37 @@ class OptogeneticSeries(TimeSeries): ) +class OptogeneticSeriesData(ConfiguredBaseModel): + """ + Applied power for optogenetic stimulus, in watts. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ogen"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["watts"] = Field( + "watts", + description="""Unit of measurement for data, which is fixed to 'watts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "watts", "ifabsent": "string(watts)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class OptogeneticStimulusSite(NWBContainer): """ A site of optogenetic stimulation. @@ -239,4 +268,5 @@ class OptogeneticStimulusSite(NWBContainer): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model OptogeneticSeries.model_rebuild() +OptogeneticSeriesData.model_rebuild() OptogeneticStimulusSite.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py index 2ac1358..2bc26d9 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py @@ -28,7 +28,7 @@ from ...core.v2_2_2.core_nwb_base import ( TimeSeriesSync, ) from ...core.v2_2_2.core_nwb_device import Device -from ...core.v2_2_2.core_nwb_image import ImageSeries, ImageSeriesExternalFile +from ...core.v2_2_2.core_nwb_image import ImageSeries, ImageSeriesData, ImageSeriesExternalFile from ...hdmf_common.v1_1_3.hdmf_common_table import DynamicTable, DynamicTableRegion @@ -209,12 +209,9 @@ class TwoPhotonSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -225,8 +222,9 @@ class TwoPhotonSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -275,9 +273,7 @@ class RoiResponseSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], NDArray[Shape["* num_times, * num_rois"], float] - ] = Field(..., description="""Signals from ROIs.""") + data: RoiResponseSeriesData = Field(..., description="""Signals from ROIs.""") rois: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.""", @@ -327,6 +323,39 @@ class RoiResponseSeries(TimeSeries): ) +class RoiResponseSeriesData(ConfiguredBaseModel): + """ + Signals from ROIs. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ophys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_rois"], float | int], + ] + ] = Field(None) + + class DfOverF(NWBDataInterface): """ dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes). @@ -336,10 +365,10 @@ class DfOverF(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field("DfOverF", json_schema_extra={"linkml_meta": {"ifabsent": "string(DfOverF)"}}) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class Fluorescence(NWBDataInterface): @@ -351,10 +380,12 @@ class Fluorescence(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field( + "Fluorescence", json_schema_extra={"linkml_meta": {"ifabsent": "string(Fluorescence)"}} + ) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class ImageSegmentation(NWBDataInterface): @@ -366,10 +397,13 @@ class ImageSegmentation(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[DynamicTable]] = Field( + name: str = Field( + "ImageSegmentation", + json_schema_extra={"linkml_meta": {"ifabsent": "string(ImageSegmentation)"}}, + ) + value: Optional[Dict[str, DynamicTable]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "DynamicTable"}]}} ) - name: str = Field(...) class ImagingPlane(NWBContainer): @@ -538,16 +572,20 @@ class MotionCorrection(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[NWBDataInterface]] = Field( + name: str = Field( + "MotionCorrection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(MotionCorrection)"}}, + ) + value: Optional[Dict[str, NWBDataInterface]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "NWBDataInterface"}]}} ) - name: str = Field(...) # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model TwoPhotonSeries.model_rebuild() RoiResponseSeries.model_rebuild() +RoiResponseSeriesData.model_rebuild() DfOverF.model_rebuild() Fluorescence.model_rebuild() ImageSegmentation.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py index 9dbeca9..900c006 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py @@ -38,6 +38,7 @@ from ...core.v2_2_2.core_nwb_ecephys import ( ClusterWaveforms, Clustering, ElectricalSeries, + ElectricalSeriesData, ElectrodeGroup, ElectrodeGroupPosition, EventDetection, @@ -46,6 +47,7 @@ from ...core.v2_2_2.core_nwb_ecephys import ( FilteredEphys, LFP, SpikeEventSeries, + SpikeEventSeriesData, ) from ...core.v2_2_2.core_nwb_epoch import TimeIntervals, TimeIntervalsTimeseries from ...core.v2_2_2.core_nwb_file import ( @@ -85,9 +87,12 @@ from ...core.v2_2_2.core_nwb_image import ( GrayscaleImage, ImageMaskSeries, ImageSeries, + ImageSeriesData, ImageSeriesExternalFile, IndexSeries, + IndexSeriesData, OpticalSeries, + OpticalSeriesData, RGBAImage, RGBImage, ) @@ -95,14 +100,22 @@ from ...core.v2_2_2.core_nwb_misc import ( AbstractFeatureSeries, AbstractFeatureSeriesData, AnnotationSeries, + AnnotationSeriesData, DecompositionSeries, DecompositionSeriesBands, DecompositionSeriesData, IntervalSeries, + IntervalSeriesData, Units, UnitsSpikeTimes, + UnitsWaveformMean, + UnitsWaveformSd, +) +from ...core.v2_2_2.core_nwb_ogen import ( + OptogeneticSeries, + OptogeneticSeriesData, + OptogeneticStimulusSite, ) -from ...core.v2_2_2.core_nwb_ogen import OptogeneticSeries, OptogeneticStimulusSite from ...core.v2_2_2.core_nwb_ophys import ( DfOverF, Fluorescence, @@ -114,6 +127,7 @@ from ...core.v2_2_2.core_nwb_ophys import ( MotionCorrection, OpticalChannel, RoiResponseSeries, + RoiResponseSeriesData, TwoPhotonSeries, ) from ...core.v2_2_2.core_nwb_retinotopy import ( diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py index 8c5293b..cdc7d72 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py @@ -170,9 +170,9 @@ class Image(NWBData): description: Optional[str] = Field(None, description="""Description of the image.""") value: Optional[ Union[ - NDArray[Shape["* x, * y"], float], - NDArray[Shape["* x, * y, 3 r_g_b"], float], - NDArray[Shape["* x, * y, 4 r_g_b_a"], float], + NDArray[Shape["* x, * y"], float | int], + NDArray[Shape["* x, * y, 3 r_g_b"], float | int], + NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int], ] ] = Field(None) @@ -333,13 +333,16 @@ class ProcessingModule(NWBContainer): {"from_schema": "core.nwb.base", "tree_root": True} ) - value: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + name: str = Field(...) + description: str = Field( + ..., description="""Description of this collection of processed data.""" + ) + value: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - name: str = Field(...) class Images(NWBDataInterface): @@ -353,7 +356,7 @@ class Images(NWBDataInterface): name: str = Field("Images", json_schema_extra={"linkml_meta": {"ifabsent": "string(Images)"}}) description: str = Field(..., description="""Description of this collection of images.""") - image: List[Image] = Field(..., description="""Images stored in this collection.""") + image: List[str] = Field(..., description="""Images stored in this collection.""") # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py index 0775e8f..ce6b0b2 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py @@ -213,6 +213,16 @@ class SpatialSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "meters", description="""Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -220,8 +230,8 @@ class SpatialSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -235,10 +245,13 @@ class BehavioralEpochs(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[IntervalSeries]] = Field( + name: str = Field( + "BehavioralEpochs", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEpochs)"}}, + ) + value: Optional[Dict[str, IntervalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "IntervalSeries"}]}} ) - name: str = Field(...) class BehavioralEvents(NWBDataInterface): @@ -250,10 +263,13 @@ class BehavioralEvents(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralEvents", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEvents)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class BehavioralTimeSeries(NWBDataInterface): @@ -265,10 +281,13 @@ class BehavioralTimeSeries(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralTimeSeries", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralTimeSeries)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class PupilTracking(NWBDataInterface): @@ -280,10 +299,12 @@ class PupilTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "PupilTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(PupilTracking)"}} + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class EyeTracking(NWBDataInterface): @@ -295,10 +316,12 @@ class EyeTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "EyeTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(EyeTracking)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class CompassDirection(NWBDataInterface): @@ -310,10 +333,13 @@ class CompassDirection(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "CompassDirection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(CompassDirection)"}}, + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class Position(NWBDataInterface): @@ -325,10 +351,12 @@ class Position(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "Position", json_schema_extra={"linkml_meta": {"ifabsent": "string(Position)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py index 0db2758..4c4e77a 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py @@ -190,11 +190,12 @@ class ElectricalSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_channels"], float], - NDArray[Shape["* num_times, * num_channels, * num_samples"], float], - ] = Field(..., description="""Recorded voltage data.""") + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) + data: ElectricalSeriesData = Field(..., description="""Recorded voltage data.""") electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -207,11 +208,6 @@ class ElectricalSeries(TimeSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -249,6 +245,41 @@ class ElectricalSeries(TimeSeries): ) +class ElectricalSeriesData(ConfiguredBaseModel): + """ + Recorded voltage data. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_channels"], float | int], + NDArray[Shape["* num_times, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class SpikeEventSeries(ElectricalSeries): """ Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode). @@ -259,15 +290,17 @@ class SpikeEventSeries(ElectricalSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_events, * num_samples"], float], - NDArray[Shape["* num_events, * num_channels, * num_samples"], float], - ] = Field(..., description="""Spike waveforms.""") + data: SpikeEventSeriesData = Field(..., description="""Spike waveforms.""") timestamps: NDArray[Shape["* num_times"], float] = Field( ..., description="""Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, ) + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -280,11 +313,6 @@ class SpikeEventSeries(ElectricalSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -317,6 +345,40 @@ class SpikeEventSeries(ElectricalSeries): ) +class SpikeEventSeriesData(ConfiguredBaseModel): + """ + Spike waveforms. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Unit of measurement for waveforms, which is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_events, * num_samples"], float | int], + NDArray[Shape["* num_events, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class FeatureExtraction(NWBDataInterface): """ Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source. @@ -415,10 +477,12 @@ class EventWaveform(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[SpikeEventSeries]] = Field( + name: str = Field( + "EventWaveform", json_schema_extra={"linkml_meta": {"ifabsent": "string(EventWaveform)"}} + ) + value: Optional[Dict[str, SpikeEventSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpikeEventSeries"}]}} ) - name: str = Field(...) class FilteredEphys(NWBDataInterface): @@ -430,10 +494,12 @@ class FilteredEphys(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field( + "FilteredEphys", json_schema_extra={"linkml_meta": {"ifabsent": "string(FilteredEphys)"}} + ) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class LFP(NWBDataInterface): @@ -445,10 +511,10 @@ class LFP(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field("LFP", json_schema_extra={"linkml_meta": {"ifabsent": "string(LFP)"}}) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class ElectrodeGroup(NWBContainer): @@ -591,7 +657,9 @@ class Clustering(NWBDataInterface): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model ElectricalSeries.model_rebuild() +ElectricalSeriesData.model_rebuild() SpikeEventSeries.model_rebuild() +SpikeEventSeriesData.model_rebuild() FeatureExtraction.model_rebuild() EventDetection.model_rebuild() EventWaveform.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py index 7ed9c06..3fcfe9b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py @@ -247,9 +247,6 @@ class TimeIntervals(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class TimeIntervalsTimeseries(VectorData): diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py index 32f00ff..6217a0e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py @@ -225,28 +225,28 @@ class NWBFile(NWBContainer): ..., description="""Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).""", ) - acquisition: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + acquisition: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, description="""Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - analysis: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + analysis: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - scratch: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + scratch: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - processing: Optional[List[ProcessingModule]] = Field( + processing: Optional[Dict[str, ProcessingModule]] = Field( None, description="""The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ProcessingModule"}]}}, @@ -264,6 +264,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -279,12 +282,12 @@ class NWBFileStimulus(ConfiguredBaseModel): "linkml_meta": {"equals_string": "stimulus", "ifabsent": "string(stimulus)"} }, ) - presentation: Optional[List[TimeSeries]] = Field( + presentation: Optional[Dict[str, TimeSeries]] = Field( None, description="""Stimuli presented during the experiment.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, ) - templates: Optional[List[TimeSeries]] = Field( + templates: Optional[Dict[str, TimeSeries]] = Field( None, description="""Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, @@ -362,11 +365,7 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - lab_meta_data: Optional[List[LabMetaData]] = Field( - None, - description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", - ) - devices: Optional[List[Device]] = Field( + devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "Device"}]}}, @@ -381,16 +380,20 @@ class NWBFileGeneral(ConfiguredBaseModel): intracellular_ephys: Optional[GeneralIntracellularEphys] = Field( None, description="""Metadata related to intracellular electrophysiology.""" ) - optogenetics: Optional[List[OptogeneticStimulusSite]] = Field( + optogenetics: Optional[Dict[str, OptogeneticStimulusSite]] = Field( None, description="""Metadata describing optogenetic stimuluation.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "OptogeneticStimulusSite"}]}}, ) - optophysiology: Optional[List[ImagingPlane]] = Field( + optophysiology: Optional[Dict[str, ImagingPlane]] = Field( None, description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, ) + value: Optional[Dict[str, LabMetaData]] = Field( + None, + description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", + ) class GeneralSourceScript(ConfiguredBaseModel): @@ -426,12 +429,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -501,8 +504,14 @@ class ExtracellularEphysElectrodes(DynamicTable): } }, ) - group: List[ElectrodeGroup] = Field( - ..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" + group: VectorData[NDArray[Any, ElectrodeGroup]] = Field( + ..., + description="""Reference to the ElectrodeGroup this electrode is a part of.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, ) group_name: VectorData[NDArray[Any, str]] = Field( ..., @@ -559,9 +568,6 @@ class ExtracellularEphysElectrodes(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class GeneralIntracellularEphys(ConfiguredBaseModel): @@ -584,12 +590,12 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[List[IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""The table which groups different PatchClampSeries together.""" ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -615,7 +621,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[List[TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py index 0a4bf27..a4433e6 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py @@ -262,11 +262,21 @@ class PatchClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( ..., description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", ) - value: Optional[NDArray[Shape["* num_times"], float]] = Field( + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} ) @@ -281,12 +291,12 @@ class CurrentClampSeries(PatchClampSeries): ) name: str = Field(...) - data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") bias_current: Optional[float] = Field(None, description="""Bias current, in amps.""") bridge_balance: Optional[float] = Field(None, description="""Bridge balance, in ohms.""") capacitance_compensation: Optional[float] = Field( None, description="""Capacitance compensation, in farads.""" ) + data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") stimulus_description: str = Field( ..., description="""Protocol/stimulus name for this patch-clamp dataset.""" ) @@ -354,12 +364,24 @@ class CurrentClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IZeroClampSeries(CurrentClampSeries): @@ -512,6 +534,16 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["amperes"] = Field( "amperes", description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -519,7 +551,9 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} }, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class VoltageClampSeries(PatchClampSeries): @@ -532,13 +566,13 @@ class VoltageClampSeries(PatchClampSeries): ) name: str = Field(...) - data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") capacitance_fast: Optional[VoltageClampSeriesCapacitanceFast] = Field( None, description="""Fast capacitance, in farads.""" ) capacitance_slow: Optional[VoltageClampSeriesCapacitanceSlow] = Field( None, description="""Slow capacitance, in farads.""" ) + data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") resistance_comp_bandwidth: Optional[VoltageClampSeriesResistanceCompBandwidth] = Field( None, description="""Resistance compensation bandwidth, in hertz.""" ) @@ -610,27 +644,6 @@ class VoltageClampSeries(PatchClampSeries): ) -class VoltageClampSeriesData(ConfiguredBaseModel): - """ - Recorded current. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) - - name: Literal["data"] = Field( - "data", - json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, - ) - unit: Literal["amperes"] = Field( - "amperes", - description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", - json_schema_extra={ - "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} - }, - ) - value: Any = Field(...) - - class VoltageClampSeriesCapacitanceFast(ConfiguredBaseModel): """ Fast capacitance, in farads. @@ -683,6 +696,39 @@ class VoltageClampSeriesCapacitanceSlow(ConfiguredBaseModel): value: float = Field(...) +class VoltageClampSeriesData(ConfiguredBaseModel): + """ + Recorded current. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["amperes"] = Field( + "amperes", + description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + json_schema_extra={ + "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} + }, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class VoltageClampSeriesResistanceCompBandwidth(ConfiguredBaseModel): """ Resistance compensation bandwidth, in hertz. @@ -887,12 +933,24 @@ class VoltageClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IntracellularElectrode(NWBContainer): @@ -942,18 +1000,15 @@ class SweepTable(DynamicTable): ) name: str = Field(...) - sweep_number: VectorData[NDArray[Any, int]] = Field( + series: VectorData[NDArray[Any, PatchClampSeries]] = Field( ..., - description="""Sweep number of the PatchClampSeries in that row.""", + description="""The PatchClampSeries with the sweep number in that row.""", json_schema_extra={ "linkml_meta": { "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} } }, ) - series: List[PatchClampSeries] = Field( - ..., description="""The PatchClampSeries with the sweep number in that row.""" - ) series_index: Named[VectorIndex] = Field( ..., description="""Index for series.""", @@ -966,6 +1021,15 @@ class SweepTable(DynamicTable): } }, ) + sweep_number: VectorData[NDArray[Any, int]] = Field( + ..., + description="""Sweep number of the PatchClampSeries in that row.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -976,9 +1040,6 @@ class SweepTable(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild @@ -991,9 +1052,9 @@ IZeroClampSeries.model_rebuild() CurrentClampStimulusSeries.model_rebuild() CurrentClampStimulusSeriesData.model_rebuild() VoltageClampSeries.model_rebuild() -VoltageClampSeriesData.model_rebuild() VoltageClampSeriesCapacitanceFast.model_rebuild() VoltageClampSeriesCapacitanceSlow.model_rebuild() +VoltageClampSeriesData.model_rebuild() VoltageClampSeriesResistanceCompBandwidth.model_rebuild() VoltageClampSeriesResistanceCompCorrection.model_rebuild() VoltageClampSeriesResistanceCompPrediction.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py index f0fb808..21d475a 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py @@ -152,7 +152,7 @@ class GrayscaleImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} @@ -174,7 +174,7 @@ class RGBImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -204,7 +204,7 @@ class RGBAImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -234,12 +234,9 @@ class ImageSeries(TimeSeries): ) name: str = Field(...) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -250,8 +247,9 @@ class ImageSeries(TimeSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -290,6 +288,39 @@ class ImageSeries(TimeSeries): ) +class ImageSeriesData(ConfiguredBaseModel): + """ + Binary data representing images across frames. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, * z"], float | int], + ] + ] = Field(None) + + class ImageSeriesExternalFile(ConfiguredBaseModel): """ Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file. @@ -331,12 +362,9 @@ class ImageMaskSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -347,8 +375,9 @@ class ImageMaskSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -397,6 +426,9 @@ class OpticalSeries(ImageSeries): ) name: str = Field(...) + data: OpticalSeriesData = Field( + ..., description="""Images presented to subject, either grayscale or RGB""" + ) distance: Optional[float] = Field( None, description="""Distance from camera/monitor to target/eye.""" ) @@ -405,10 +437,6 @@ class OpticalSeries(ImageSeries): NDArray[Shape["2 width_height"], float], NDArray[Shape["3 width_height_depth"], float] ] ] = Field(None, description="""Width, height and depth of image, or imaged area, in meters.""") - data: Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, 3 r_g_b"], float], - ] = Field(..., description="""Images presented to subject, either grayscale or RGB""") orientation: Optional[str] = Field( None, description="""Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.""", @@ -423,8 +451,9 @@ class OpticalSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -463,6 +492,39 @@ class OpticalSeries(ImageSeries): ) +class OpticalSeriesData(ConfiguredBaseModel): + """ + Images presented to subject, either grayscale or RGB + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, 3 r_g_b"], float | int], + ] + ] = Field(None) + + class IndexSeries(TimeSeries): """ Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed. @@ -473,10 +535,8 @@ class IndexSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Index of the frame in the referenced ImageSeries.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IndexSeriesData = Field( + ..., description="""Index of the frame in the referenced ImageSeries.""" ) indexed_timeseries: Union[ImageSeries, str] = Field( ..., @@ -524,13 +584,46 @@ class IndexSeries(TimeSeries): ) +class IndexSeriesData(ConfiguredBaseModel): + """ + Index of the frame in the referenced ImageSeries. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model GrayscaleImage.model_rebuild() RGBImage.model_rebuild() RGBAImage.model_rebuild() ImageSeries.model_rebuild() +ImageSeriesData.model_rebuild() ImageSeriesExternalFile.model_rebuild() ImageMaskSeries.model_rebuild() OpticalSeries.model_rebuild() +OpticalSeriesData.model_rebuild() IndexSeries.model_rebuild() +IndexSeriesData.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py index 65b6dc0..28308e1 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py @@ -251,6 +251,16 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "see ", description="""Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".""", @@ -258,8 +268,8 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -274,10 +284,8 @@ class AnnotationSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], str] = Field( - ..., - description="""Annotations made during an experiment.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: AnnotationSeriesData = Field( + ..., description="""Annotations made during an experiment.""" ) description: Optional[str] = Field( "no description", @@ -316,6 +324,39 @@ class AnnotationSeries(TimeSeries): ) +class AnnotationSeriesData(ConfiguredBaseModel): + """ + Annotations made during an experiment. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], str]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class IntervalSeries(TimeSeries): """ Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. @@ -326,10 +367,8 @@ class IntervalSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Use values >0 if interval started, <0 if interval ended.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IntervalSeriesData = Field( + ..., description="""Use values >0 if interval started, <0 if interval ended.""" ) description: Optional[str] = Field( "no description", @@ -368,6 +407,39 @@ class IntervalSeries(TimeSeries): ) +class IntervalSeriesData(ConfiguredBaseModel): + """ + Use values >0 if interval started, <0 if interval ended. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class DecompositionSeries(TimeSeries): """ Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -443,24 +515,36 @@ class DecompositionSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( "no unit", description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"ifabsent": "string(no unit)"}}, ) - value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float]] = Field( - None, - json_schema_extra={ - "linkml_meta": { - "array": { - "dimensions": [ - {"alias": "num_times"}, - {"alias": "num_channels"}, - {"alias": "num_bands"}, - ] + value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float | int]] = ( + Field( + None, + json_schema_extra={ + "linkml_meta": { + "array": { + "dimensions": [ + {"alias": "num_times"}, + {"alias": "num_channels"}, + {"alias": "num_bands"}, + ] + } } - } - }, + }, + ) ) @@ -518,9 +602,6 @@ class DecompositionSeriesBands(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class Units(DynamicTable): @@ -533,9 +614,18 @@ class Units(DynamicTable): ) name: str = Field("Units", json_schema_extra={"linkml_meta": {"ifabsent": "string(Units)"}}) - spike_times_index: Optional[Named[VectorIndex]] = Field( + electrode_group: Optional[VectorData[NDArray[Any, ElectrodeGroup]]] = Field( None, - description="""Index into the spike_times dataset.""", + description="""Electrode group that each spike unit came from.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) + electrodes: Optional[Named[DynamicTableRegion]] = Field( + None, + description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -545,12 +635,9 @@ class Units(DynamicTable): } }, ) - spike_times: Optional[UnitsSpikeTimes] = Field( - None, description="""Spike times for each unit.""" - ) - obs_intervals_index: Optional[Named[VectorIndex]] = Field( + electrodes_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into the obs_intervals dataset.""", + description="""Index into electrodes.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -576,9 +663,9 @@ class Units(DynamicTable): }, ) ) - electrodes_index: Optional[Named[VectorIndex]] = Field( + obs_intervals_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into electrodes.""", + description="""Index into the obs_intervals dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -588,9 +675,12 @@ class Units(DynamicTable): } }, ) - electrodes: Optional[Named[DynamicTableRegion]] = Field( + spike_times: Optional[UnitsSpikeTimes] = Field( + None, description="""Spike times for each unit.""" + ) + spike_times_index: Optional[Named[VectorIndex]] = Field( None, - description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", + description="""Index into the spike_times dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -600,25 +690,12 @@ class Units(DynamicTable): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Electrode group that each spike unit came from.""" + waveform_mean: Optional[UnitsWaveformMean] = Field( + None, description="""Spike waveform mean for each spike unit.""" + ) + waveform_sd: Optional[UnitsWaveformSd] = Field( + None, description="""Spike waveform standard deviation for each spike unit.""" ) - waveform_mean: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform mean for each spike unit.""") - waveform_sd: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""") colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -629,9 +706,6 @@ class Units(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class UnitsSpikeTimes(VectorData): @@ -662,14 +736,78 @@ class UnitsSpikeTimes(VectorData): ] = Field(None) +class UnitsWaveformMean(VectorData): + """ + Spike waveform mean for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_mean"] = Field( + "waveform_mean", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_mean", "ifabsent": "string(waveform_mean)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + value: Optional[ + Union[ + NDArray[Shape["* dim0"], Any], + NDArray[Shape["* dim0, * dim1"], Any], + NDArray[Shape["* dim0, * dim1, * dim2"], Any], + NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], + ] + ] = Field(None) + + +class UnitsWaveformSd(VectorData): + """ + Spike waveform standard deviation for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_sd"] = Field( + "waveform_sd", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_sd", "ifabsent": "string(waveform_sd)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + value: Optional[ + Union[ + NDArray[Shape["* dim0"], Any], + NDArray[Shape["* dim0, * dim1"], Any], + NDArray[Shape["* dim0, * dim1, * dim2"], Any], + NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], + ] + ] = Field(None) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model AbstractFeatureSeries.model_rebuild() AbstractFeatureSeriesData.model_rebuild() AnnotationSeries.model_rebuild() +AnnotationSeriesData.model_rebuild() IntervalSeries.model_rebuild() +IntervalSeriesData.model_rebuild() DecompositionSeries.model_rebuild() DecompositionSeriesData.model_rebuild() DecompositionSeriesBands.model_rebuild() Units.model_rebuild() UnitsSpikeTimes.model_rebuild() +UnitsWaveformMean.model_rebuild() +UnitsWaveformSd.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py index af170bd..7651c68 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py @@ -158,10 +158,8 @@ class OptogeneticSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], float] = Field( - ..., - description="""Applied power for optogenetic stimulus, in watts.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: OptogeneticSeriesData = Field( + ..., description="""Applied power for optogenetic stimulus, in watts.""" ) site: Union[OptogeneticStimulusSite, str] = Field( ..., @@ -209,6 +207,37 @@ class OptogeneticSeries(TimeSeries): ) +class OptogeneticSeriesData(ConfiguredBaseModel): + """ + Applied power for optogenetic stimulus, in watts. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ogen"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["watts"] = Field( + "watts", + description="""Unit of measurement for data, which is fixed to 'watts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "watts", "ifabsent": "string(watts)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class OptogeneticStimulusSite(NWBContainer): """ A site of optogenetic stimulation. @@ -239,4 +268,5 @@ class OptogeneticStimulusSite(NWBContainer): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model OptogeneticSeries.model_rebuild() +OptogeneticSeriesData.model_rebuild() OptogeneticStimulusSite.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py index 91a59a0..9bb24e6 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py @@ -28,7 +28,7 @@ from ...core.v2_2_4.core_nwb_base import ( TimeSeriesSync, ) from ...core.v2_2_4.core_nwb_device import Device -from ...core.v2_2_4.core_nwb_image import ImageSeries, ImageSeriesExternalFile +from ...core.v2_2_4.core_nwb_image import ImageSeries, ImageSeriesData, ImageSeriesExternalFile from ...hdmf_common.v1_1_3.hdmf_common_table import ( DynamicTable, DynamicTableRegion, @@ -215,12 +215,9 @@ class TwoPhotonSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -231,8 +228,9 @@ class TwoPhotonSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -281,9 +279,7 @@ class RoiResponseSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], NDArray[Shape["* num_times, * num_rois"], float] - ] = Field(..., description="""Signals from ROIs.""") + data: RoiResponseSeriesData = Field(..., description="""Signals from ROIs.""") rois: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.""", @@ -333,6 +329,39 @@ class RoiResponseSeries(TimeSeries): ) +class RoiResponseSeriesData(ConfiguredBaseModel): + """ + Signals from ROIs. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ophys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_rois"], float | int], + ] + ] = Field(None) + + class DfOverF(NWBDataInterface): """ dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes). @@ -342,10 +371,10 @@ class DfOverF(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field("DfOverF", json_schema_extra={"linkml_meta": {"ifabsent": "string(DfOverF)"}}) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class Fluorescence(NWBDataInterface): @@ -357,10 +386,12 @@ class Fluorescence(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field( + "Fluorescence", json_schema_extra={"linkml_meta": {"ifabsent": "string(Fluorescence)"}} + ) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class ImageSegmentation(NWBDataInterface): @@ -372,10 +403,13 @@ class ImageSegmentation(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[PlaneSegmentation]] = Field( + name: str = Field( + "ImageSegmentation", + json_schema_extra={"linkml_meta": {"ifabsent": "string(ImageSegmentation)"}}, + ) + value: Optional[Dict[str, PlaneSegmentation]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "PlaneSegmentation"}]}} ) - name: str = Field(...) class PlaneSegmentation(DynamicTable): @@ -388,10 +422,21 @@ class PlaneSegmentation(DynamicTable): ) name: str = Field(...) - image_mask: Optional[PlaneSegmentationImageMask] = Field( + image_mask: Optional[ + VectorData[ + Union[ + NDArray[Shape["* num_roi, * num_x, * num_y"], Any], + NDArray[Shape["* num_roi, * num_x, * num_y, * num_z"], Any], + ] + ] + ] = Field( None, description="""ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.""", ) + pixel_mask: Optional[PlaneSegmentationPixelMask] = Field( + None, + description="""Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", + ) pixel_mask_index: Optional[Named[VectorIndex]] = Field( None, description="""Index into pixel_mask.""", @@ -404,9 +449,9 @@ class PlaneSegmentation(DynamicTable): } }, ) - pixel_mask: Optional[PlaneSegmentationPixelMask] = Field( + voxel_mask: Optional[PlaneSegmentationVoxelMask] = Field( None, - description="""Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", + description="""Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", ) voxel_mask_index: Optional[Named[VectorIndex]] = Field( None, @@ -420,11 +465,7 @@ class PlaneSegmentation(DynamicTable): } }, ) - voxel_mask: Optional[PlaneSegmentationVoxelMask] = Field( - None, - description="""Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", - ) - reference_images: Optional[List[ImageSeries]] = Field( + reference_images: Optional[Dict[str, ImageSeries]] = Field( None, description="""Image stacks that the segmentation masks apply to.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImageSeries"}]}}, @@ -448,33 +489,6 @@ class PlaneSegmentation(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) - - -class PlaneSegmentationImageMask(VectorData): - """ - ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ophys"}) - - name: Literal["image_mask"] = Field( - "image_mask", - json_schema_extra={ - "linkml_meta": {"equals_string": "image_mask", "ifabsent": "string(image_mask)"} - }, - ) - description: str = Field(..., description="""Description of what these vectors represent.""") - value: Optional[ - Union[ - NDArray[Shape["* dim0"], Any], - NDArray[Shape["* dim0, * dim1"], Any], - NDArray[Shape["* dim0, * dim1, * dim2"], Any], - NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], - ] - ] = Field(None) class PlaneSegmentationPixelMask(VectorData): @@ -597,7 +611,7 @@ class ImagingPlane(NWBContainer): None, description="""Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"""", ) - optical_channel: List[OpticalChannel] = Field( + optical_channel: Dict[str, OpticalChannel] = Field( ..., description="""An optical channel used to record from an imaging plane.""" ) device: Union[Device, str] = Field( @@ -731,10 +745,13 @@ class MotionCorrection(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[CorrectedImageStack]] = Field( + name: str = Field( + "MotionCorrection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(MotionCorrection)"}}, + ) + value: Optional[Dict[str, CorrectedImageStack]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "CorrectedImageStack"}]}} ) - name: str = Field(...) class CorrectedImageStack(NWBDataInterface): @@ -769,11 +786,11 @@ class CorrectedImageStack(NWBDataInterface): # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model TwoPhotonSeries.model_rebuild() RoiResponseSeries.model_rebuild() +RoiResponseSeriesData.model_rebuild() DfOverF.model_rebuild() Fluorescence.model_rebuild() ImageSegmentation.model_rebuild() PlaneSegmentation.model_rebuild() -PlaneSegmentationImageMask.model_rebuild() PlaneSegmentationPixelMask.model_rebuild() PlaneSegmentationVoxelMask.model_rebuild() ImagingPlane.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py index 0950468..6ff6e5a 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py @@ -38,6 +38,7 @@ from ...core.v2_2_4.core_nwb_ecephys import ( ClusterWaveforms, Clustering, ElectricalSeries, + ElectricalSeriesData, ElectrodeGroup, ElectrodeGroupPosition, EventDetection, @@ -46,6 +47,7 @@ from ...core.v2_2_4.core_nwb_ecephys import ( FilteredEphys, LFP, SpikeEventSeries, + SpikeEventSeriesData, ) from ...core.v2_2_4.core_nwb_epoch import TimeIntervals, TimeIntervalsTimeseries from ...core.v2_2_4.core_nwb_file import ( @@ -87,9 +89,12 @@ from ...core.v2_2_4.core_nwb_image import ( GrayscaleImage, ImageMaskSeries, ImageSeries, + ImageSeriesData, ImageSeriesExternalFile, IndexSeries, + IndexSeriesData, OpticalSeries, + OpticalSeriesData, RGBAImage, RGBImage, ) @@ -97,14 +102,22 @@ from ...core.v2_2_4.core_nwb_misc import ( AbstractFeatureSeries, AbstractFeatureSeriesData, AnnotationSeries, + AnnotationSeriesData, DecompositionSeries, DecompositionSeriesBands, DecompositionSeriesData, IntervalSeries, + IntervalSeriesData, Units, UnitsSpikeTimes, + UnitsWaveformMean, + UnitsWaveformSd, +) +from ...core.v2_2_4.core_nwb_ogen import ( + OptogeneticSeries, + OptogeneticSeriesData, + OptogeneticStimulusSite, ) -from ...core.v2_2_4.core_nwb_ogen import OptogeneticSeries, OptogeneticStimulusSite from ...core.v2_2_4.core_nwb_ophys import ( CorrectedImageStack, DfOverF, @@ -117,10 +130,10 @@ from ...core.v2_2_4.core_nwb_ophys import ( MotionCorrection, OpticalChannel, PlaneSegmentation, - PlaneSegmentationImageMask, PlaneSegmentationPixelMask, PlaneSegmentationVoxelMask, RoiResponseSeries, + RoiResponseSeriesData, TwoPhotonSeries, ) from ...core.v2_2_4.core_nwb_retinotopy import ( diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py index 36e9a95..8adaa07 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py @@ -170,9 +170,9 @@ class Image(NWBData): description: Optional[str] = Field(None, description="""Description of the image.""") value: Optional[ Union[ - NDArray[Shape["* x, * y"], float], - NDArray[Shape["* x, * y, 3 r_g_b"], float], - NDArray[Shape["* x, * y, 4 r_g_b_a"], float], + NDArray[Shape["* x, * y"], float | int], + NDArray[Shape["* x, * y, 3 r_g_b"], float | int], + NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int], ] ] = Field(None) @@ -333,13 +333,16 @@ class ProcessingModule(NWBContainer): {"from_schema": "core.nwb.base", "tree_root": True} ) - value: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + name: str = Field(...) + description: str = Field( + ..., description="""Description of this collection of processed data.""" + ) + value: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - name: str = Field(...) class Images(NWBDataInterface): @@ -353,7 +356,7 @@ class Images(NWBDataInterface): name: str = Field("Images", json_schema_extra={"linkml_meta": {"ifabsent": "string(Images)"}}) description: str = Field(..., description="""Description of this collection of images.""") - image: List[Image] = Field(..., description="""Images stored in this collection.""") + image: List[str] = Field(..., description="""Images stored in this collection.""") # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py index f15481e..707d902 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py @@ -213,6 +213,16 @@ class SpatialSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "meters", description="""Base unit of measurement for working with the data. The default value is 'meters'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -220,8 +230,8 @@ class SpatialSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -235,10 +245,13 @@ class BehavioralEpochs(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[IntervalSeries]] = Field( + name: str = Field( + "BehavioralEpochs", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEpochs)"}}, + ) + value: Optional[Dict[str, IntervalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "IntervalSeries"}]}} ) - name: str = Field(...) class BehavioralEvents(NWBDataInterface): @@ -250,10 +263,13 @@ class BehavioralEvents(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralEvents", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralEvents)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class BehavioralTimeSeries(NWBDataInterface): @@ -265,10 +281,13 @@ class BehavioralTimeSeries(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "BehavioralTimeSeries", + json_schema_extra={"linkml_meta": {"ifabsent": "string(BehavioralTimeSeries)"}}, + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class PupilTracking(NWBDataInterface): @@ -280,10 +299,12 @@ class PupilTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[TimeSeries]] = Field( + name: str = Field( + "PupilTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(PupilTracking)"}} + ) + value: Optional[Dict[str, TimeSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}} ) - name: str = Field(...) class EyeTracking(NWBDataInterface): @@ -295,10 +316,12 @@ class EyeTracking(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "EyeTracking", json_schema_extra={"linkml_meta": {"ifabsent": "string(EyeTracking)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class CompassDirection(NWBDataInterface): @@ -310,10 +333,13 @@ class CompassDirection(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "CompassDirection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(CompassDirection)"}}, + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) class Position(NWBDataInterface): @@ -325,10 +351,12 @@ class Position(NWBDataInterface): {"from_schema": "core.nwb.behavior", "tree_root": True} ) - value: Optional[List[SpatialSeries]] = Field( + name: str = Field( + "Position", json_schema_extra={"linkml_meta": {"ifabsent": "string(Position)"}} + ) + value: Optional[Dict[str, SpatialSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpatialSeries"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py index 39d0aad..3fa33b8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py @@ -190,11 +190,12 @@ class ElectricalSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_channels"], float], - NDArray[Shape["* num_times, * num_channels, * num_samples"], float], - ] = Field(..., description="""Recorded voltage data.""") + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) + data: ElectricalSeriesData = Field(..., description="""Recorded voltage data.""") electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -207,11 +208,6 @@ class ElectricalSeries(TimeSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -249,6 +245,41 @@ class ElectricalSeries(TimeSeries): ) +class ElectricalSeriesData(ConfiguredBaseModel): + """ + Recorded voltage data. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Base unit of measurement for working with the data. This value is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion' and 'channel_conversion' (if present).""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_channels"], float | int], + NDArray[Shape["* num_times, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class SpikeEventSeries(ElectricalSeries): """ Stores snapshots/snippets of recorded spike events (i.e., threshold crossings). This may also be raw data, as reported by ephys hardware. If so, the TimeSeries::description field should describe how events were detected. All SpikeEventSeries should reside in a module (under EventWaveform interface) even if the spikes were reported and stored by hardware. All events span the same recording channels and store snapshots of equal duration. TimeSeries::data array structure: [num events] [num channels] [num samples] (or [num events] [num samples] for single electrode). @@ -259,15 +290,17 @@ class SpikeEventSeries(ElectricalSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_events, * num_samples"], float], - NDArray[Shape["* num_events, * num_channels, * num_samples"], float], - ] = Field(..., description="""Spike waveforms.""") + data: SpikeEventSeriesData = Field(..., description="""Spike waveforms.""") timestamps: NDArray[Shape["* num_times"], float] = Field( ..., description="""Timestamps for samples stored in data, in seconds, relative to the common experiment master-clock stored in NWBFile.timestamps_reference_time. Timestamps are required for the events. Unlike for TimeSeries, timestamps are required for SpikeEventSeries and are thus re-specified here.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, ) + channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( + None, + description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", + json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, + ) electrodes: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion pointer to the electrodes that this time series was generated from.""", @@ -280,11 +313,6 @@ class SpikeEventSeries(ElectricalSeries): } }, ) - channel_conversion: Optional[NDArray[Shape["* num_channels"], float]] = Field( - None, - description="""Channel-specific conversion factor. Multiply the data in the 'data' dataset by these values along the channel axis (as indicated by axis attribute) AND by the global conversion factor in the 'conversion' attribute of 'data' to get the data values in Volts, i.e, data in Volts = data * data.conversion * channel_conversion. This approach allows for both global and per-channel data conversion factors needed to support the storage of electrical recordings as native values generated by data acquisition systems. If this dataset is not present, then there is no channel-specific conversion factor, i.e. it is 1 for all channels.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_channels"}]}}}, - ) description: Optional[str] = Field( "no description", description="""Description of the time series.""", @@ -317,6 +345,40 @@ class SpikeEventSeries(ElectricalSeries): ) +class SpikeEventSeriesData(ConfiguredBaseModel): + """ + Spike waveforms. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ecephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["volts"] = Field( + "volts", + description="""Unit of measurement for waveforms, which is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + value: Optional[ + Union[ + NDArray[Shape["* num_events, * num_samples"], float | int], + NDArray[Shape["* num_events, * num_channels, * num_samples"], float | int], + ] + ] = Field(None) + + class FeatureExtraction(NWBDataInterface): """ Features, such as PC1 and PC2, that are extracted from signals stored in a SpikeEventSeries or other source. @@ -415,10 +477,12 @@ class EventWaveform(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[SpikeEventSeries]] = Field( + name: str = Field( + "EventWaveform", json_schema_extra={"linkml_meta": {"ifabsent": "string(EventWaveform)"}} + ) + value: Optional[Dict[str, SpikeEventSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "SpikeEventSeries"}]}} ) - name: str = Field(...) class FilteredEphys(NWBDataInterface): @@ -430,10 +494,12 @@ class FilteredEphys(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field( + "FilteredEphys", json_schema_extra={"linkml_meta": {"ifabsent": "string(FilteredEphys)"}} + ) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class LFP(NWBDataInterface): @@ -445,10 +511,10 @@ class LFP(NWBDataInterface): {"from_schema": "core.nwb.ecephys", "tree_root": True} ) - value: Optional[List[ElectricalSeries]] = Field( + name: str = Field("LFP", json_schema_extra={"linkml_meta": {"ifabsent": "string(LFP)"}}) + value: Optional[Dict[str, ElectricalSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "ElectricalSeries"}]}} ) - name: str = Field(...) class ElectrodeGroup(NWBContainer): @@ -591,7 +657,9 @@ class Clustering(NWBDataInterface): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model ElectricalSeries.model_rebuild() +ElectricalSeriesData.model_rebuild() SpikeEventSeries.model_rebuild() +SpikeEventSeriesData.model_rebuild() FeatureExtraction.model_rebuild() EventDetection.model_rebuild() EventWaveform.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py index d610d4a..712b3de 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py @@ -247,9 +247,6 @@ class TimeIntervals(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class TimeIntervalsTimeseries(VectorData): diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py index fdcd4c9..c7b34cf 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py @@ -225,28 +225,28 @@ class NWBFile(NWBContainer): ..., description="""Date and time corresponding to time zero of all timestamps. The date is stored in UTC with local timezone offset as ISO 8601 extended formatted string: 2018-09-28T14:43:54.123+02:00. Dates stored in UTC end in \"Z\" with no timezone offset. Date accuracy is up to milliseconds. All times stored in the file use this time as reference (i.e., time zero).""", ) - acquisition: Optional[List[Union[DynamicTable, NWBDataInterface]]] = Field( + acquisition: Optional[Dict[str, Union[DynamicTable, NWBDataInterface]]] = Field( None, description="""Data streams recorded from the system, including ephys, ophys, tracking, etc. This group should be read-only after the experiment is completed and timestamps are corrected to a common timebase. The data stored here may be links to raw data stored in external NWB files. This will allow keeping bulky raw data out of the file while preserving the option of keeping some/all in the file. Acquired data includes tracking and experimental data streams (i.e., everything measured from the system). If bulky data is stored in the /acquisition group, the data can exist in a separate NWB file that is linked to by the file being used for processing and analysis.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBDataInterface"}, {"range": "DynamicTable"}]} }, ) - analysis: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + analysis: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""Lab-specific and custom scientific analysis of data. There is no defined format for the content of this group - the format is up to the individual user/lab. To facilitate sharing analysis data between labs, the contents here should be stored in standard types (e.g., neurodata_types) and appropriately documented. The file can store lab-specific and custom data analysis without restriction on its form or schema, reducing data formatting restrictions on end users. Such data should be placed in the analysis group. The analysis data should be documented so that it could be shared with other labs.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - scratch: Optional[List[Union[DynamicTable, NWBContainer]]] = Field( + scratch: Optional[Dict[str, Union[DynamicTable, NWBContainer]]] = Field( None, description="""A place to store one-off analysis results. Data placed here is not intended for sharing. By placing data here, users acknowledge that there is no guarantee that their data meets any standard.""", json_schema_extra={ "linkml_meta": {"any_of": [{"range": "NWBContainer"}, {"range": "DynamicTable"}]} }, ) - processing: Optional[List[ProcessingModule]] = Field( + processing: Optional[Dict[str, ProcessingModule]] = Field( None, description="""The home for ProcessingModules. These modules perform intermediate analysis of data that is necessary to perform before scientific analysis. Examples include spike clustering, extracting position from tracking data, stitching together image slices. ProcessingModules can be large and express many data sets from relatively complex analysis (e.g., spike detection and clustering) or small, representing extraction of position information from tracking video, or even binary lick/no-lick decisions. Common software tools (e.g., klustakwik, MClust) are expected to read/write data here. 'Processing' refers to intermediate analysis of the acquired data to make it more amenable to scientific analysis.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ProcessingModule"}]}}, @@ -264,6 +264,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -279,12 +282,12 @@ class NWBFileStimulus(ConfiguredBaseModel): "linkml_meta": {"equals_string": "stimulus", "ifabsent": "string(stimulus)"} }, ) - presentation: Optional[List[TimeSeries]] = Field( + presentation: Optional[Dict[str, TimeSeries]] = Field( None, description="""Stimuli presented during the experiment.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, ) - templates: Optional[List[TimeSeries]] = Field( + templates: Optional[Dict[str, TimeSeries]] = Field( None, description="""Template stimuli. Timestamps in templates are based on stimulus design and are relative to the beginning of the stimulus. When templates are used, the stimulus instances must convert presentation times to the experiment`s time reference frame.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "TimeSeries"}]}}, @@ -362,11 +365,7 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - lab_meta_data: Optional[List[LabMetaData]] = Field( - None, - description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", - ) - devices: Optional[List[Device]] = Field( + devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "Device"}]}}, @@ -381,16 +380,20 @@ class NWBFileGeneral(ConfiguredBaseModel): intracellular_ephys: Optional[GeneralIntracellularEphys] = Field( None, description="""Metadata related to intracellular electrophysiology.""" ) - optogenetics: Optional[List[OptogeneticStimulusSite]] = Field( + optogenetics: Optional[Dict[str, OptogeneticStimulusSite]] = Field( None, description="""Metadata describing optogenetic stimuluation.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "OptogeneticStimulusSite"}]}}, ) - optophysiology: Optional[List[ImagingPlane]] = Field( + optophysiology: Optional[Dict[str, ImagingPlane]] = Field( None, description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, ) + value: Optional[Dict[str, LabMetaData]] = Field( + None, + description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", + ) class GeneralSourceScript(ConfiguredBaseModel): @@ -426,12 +429,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -501,8 +504,14 @@ class ExtracellularEphysElectrodes(DynamicTable): } }, ) - group: List[ElectrodeGroup] = Field( - ..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" + group: VectorData[NDArray[Any, ElectrodeGroup]] = Field( + ..., + description="""Reference to the ElectrodeGroup this electrode is a part of.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, ) group_name: VectorData[NDArray[Any, str]] = Field( ..., @@ -559,9 +568,6 @@ class ExtracellularEphysElectrodes(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class GeneralIntracellularEphys(ConfiguredBaseModel): @@ -584,12 +590,12 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[List[IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""The table which groups different PatchClampSeries together.""" ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -615,7 +621,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[List[TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py index 3c878c5..019ca96 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py @@ -262,11 +262,21 @@ class PatchClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( ..., description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", ) - value: Optional[NDArray[Shape["* num_times"], float]] = Field( + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} ) @@ -281,12 +291,12 @@ class CurrentClampSeries(PatchClampSeries): ) name: str = Field(...) - data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") bias_current: Optional[float] = Field(None, description="""Bias current, in amps.""") bridge_balance: Optional[float] = Field(None, description="""Bridge balance, in ohms.""") capacitance_compensation: Optional[float] = Field( None, description="""Capacitance compensation, in farads.""" ) + data: CurrentClampSeriesData = Field(..., description="""Recorded voltage.""") stimulus_description: str = Field( ..., description="""Protocol/stimulus name for this patch-clamp dataset.""" ) @@ -354,12 +364,24 @@ class CurrentClampSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IZeroClampSeries(CurrentClampSeries): @@ -512,6 +534,16 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["amperes"] = Field( "amperes", description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", @@ -519,7 +551,9 @@ class CurrentClampStimulusSeriesData(ConfiguredBaseModel): "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} }, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class VoltageClampSeries(PatchClampSeries): @@ -532,13 +566,13 @@ class VoltageClampSeries(PatchClampSeries): ) name: str = Field(...) - data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") capacitance_fast: Optional[VoltageClampSeriesCapacitanceFast] = Field( None, description="""Fast capacitance, in farads.""" ) capacitance_slow: Optional[VoltageClampSeriesCapacitanceSlow] = Field( None, description="""Slow capacitance, in farads.""" ) + data: VoltageClampSeriesData = Field(..., description="""Recorded current.""") resistance_comp_bandwidth: Optional[VoltageClampSeriesResistanceCompBandwidth] = Field( None, description="""Resistance compensation bandwidth, in hertz.""" ) @@ -610,27 +644,6 @@ class VoltageClampSeries(PatchClampSeries): ) -class VoltageClampSeriesData(ConfiguredBaseModel): - """ - Recorded current. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) - - name: Literal["data"] = Field( - "data", - json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, - ) - unit: Literal["amperes"] = Field( - "amperes", - description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", - json_schema_extra={ - "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} - }, - ) - value: Any = Field(...) - - class VoltageClampSeriesCapacitanceFast(ConfiguredBaseModel): """ Fast capacitance, in farads. @@ -683,6 +696,39 @@ class VoltageClampSeriesCapacitanceSlow(ConfiguredBaseModel): value: float = Field(...) +class VoltageClampSeriesData(ConfiguredBaseModel): + """ + Recorded current. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.icephys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["amperes"] = Field( + "amperes", + description="""Base unit of measurement for working with the data. which is fixed to 'amperes'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + json_schema_extra={ + "linkml_meta": {"equals_string": "amperes", "ifabsent": "string(amperes)"} + }, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class VoltageClampSeriesResistanceCompBandwidth(ConfiguredBaseModel): """ Resistance compensation bandwidth, in hertz. @@ -887,12 +933,24 @@ class VoltageClampStimulusSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Literal["volts"] = Field( "volts", description="""Base unit of measurement for working with the data. which is fixed to 'volts'. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, ) - value: Any = Field(...) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) class IntracellularElectrode(NWBContainer): @@ -942,18 +1000,15 @@ class SweepTable(DynamicTable): ) name: str = Field(...) - sweep_number: VectorData[NDArray[Any, int]] = Field( + series: VectorData[NDArray[Any, PatchClampSeries]] = Field( ..., - description="""Sweep number of the PatchClampSeries in that row.""", + description="""The PatchClampSeries with the sweep number in that row.""", json_schema_extra={ "linkml_meta": { "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} } }, ) - series: List[PatchClampSeries] = Field( - ..., description="""The PatchClampSeries with the sweep number in that row.""" - ) series_index: Named[VectorIndex] = Field( ..., description="""Index for series.""", @@ -966,6 +1021,15 @@ class SweepTable(DynamicTable): } }, ) + sweep_number: VectorData[NDArray[Any, int]] = Field( + ..., + description="""Sweep number of the PatchClampSeries in that row.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -976,9 +1040,6 @@ class SweepTable(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild @@ -991,9 +1052,9 @@ IZeroClampSeries.model_rebuild() CurrentClampStimulusSeries.model_rebuild() CurrentClampStimulusSeriesData.model_rebuild() VoltageClampSeries.model_rebuild() -VoltageClampSeriesData.model_rebuild() VoltageClampSeriesCapacitanceFast.model_rebuild() VoltageClampSeriesCapacitanceSlow.model_rebuild() +VoltageClampSeriesData.model_rebuild() VoltageClampSeriesResistanceCompBandwidth.model_rebuild() VoltageClampSeriesResistanceCompCorrection.model_rebuild() VoltageClampSeriesResistanceCompPrediction.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py index 79f339a..9816ed1 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py @@ -152,7 +152,7 @@ class GrayscaleImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": {"array": {"dimensions": [{"alias": "x"}, {"alias": "y"}]}} @@ -174,7 +174,7 @@ class RGBImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 3 r_g_b"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -204,7 +204,7 @@ class RGBAImage(Image): ) name: str = Field(...) - value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float]] = Field( + value: Optional[NDArray[Shape["* x, * y, 4 r_g_b_a"], float | int]] = Field( None, json_schema_extra={ "linkml_meta": { @@ -234,12 +234,9 @@ class ImageSeries(TimeSeries): ) name: str = Field(...) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -250,8 +247,9 @@ class ImageSeries(TimeSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -290,6 +288,39 @@ class ImageSeries(TimeSeries): ) +class ImageSeriesData(ConfiguredBaseModel): + """ + Binary data representing images across frames. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, * z"], float | int], + ] + ] = Field(None) + + class ImageSeriesExternalFile(ConfiguredBaseModel): """ Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file. @@ -331,12 +362,9 @@ class ImageMaskSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -347,8 +375,9 @@ class ImageMaskSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -397,6 +426,9 @@ class OpticalSeries(ImageSeries): ) name: str = Field(...) + data: OpticalSeriesData = Field( + ..., description="""Images presented to subject, either grayscale or RGB""" + ) distance: Optional[float] = Field( None, description="""Distance from camera/monitor to target/eye.""" ) @@ -405,10 +437,6 @@ class OpticalSeries(ImageSeries): NDArray[Shape["2 width_height"], float], NDArray[Shape["3 width_height_depth"], float] ] ] = Field(None, description="""Width, height and depth of image, or imaged area, in meters.""") - data: Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, 3 r_g_b"], float], - ] = Field(..., description="""Images presented to subject, either grayscale or RGB""") orientation: Optional[str] = Field( None, description="""Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference.""", @@ -423,8 +451,9 @@ class OpticalSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -463,6 +492,39 @@ class OpticalSeries(ImageSeries): ) +class OpticalSeriesData(ConfiguredBaseModel): + """ + Images presented to subject, either grayscale or RGB + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* frame, * x, * y"], float | int], + NDArray[Shape["* frame, * x, * y, 3 r_g_b"], float | int], + ] + ] = Field(None) + + class IndexSeries(TimeSeries): """ Stores indices to image frames stored in an ImageSeries. The purpose of the ImageIndexSeries is to allow a static image stack to be stored somewhere, and the images in the stack to be referenced out-of-order. This can be for the display of individual images, or of movie segments (as a movie is simply a series of images). The data field stores the index of the frame in the referenced ImageSeries, and the timestamps array indicates when that image was displayed. @@ -473,10 +535,8 @@ class IndexSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Index of the frame in the referenced ImageSeries.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IndexSeriesData = Field( + ..., description="""Index of the frame in the referenced ImageSeries.""" ) indexed_timeseries: Union[ImageSeries, str] = Field( ..., @@ -524,13 +584,46 @@ class IndexSeries(TimeSeries): ) +class IndexSeriesData(ConfiguredBaseModel): + """ + Index of the frame in the referenced ImageSeries. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.image"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model GrayscaleImage.model_rebuild() RGBImage.model_rebuild() RGBAImage.model_rebuild() ImageSeries.model_rebuild() +ImageSeriesData.model_rebuild() ImageSeriesExternalFile.model_rebuild() ImageMaskSeries.model_rebuild() OpticalSeries.model_rebuild() +OpticalSeriesData.model_rebuild() IndexSeries.model_rebuild() +IndexSeriesData.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py index 969c646..4ed1cb2 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py @@ -251,6 +251,16 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: Optional[str] = Field( "see ", description="""Since there can be different units for different features, store the units in 'feature_units'. The default value for this attribute is \"see 'feature_units'\".""", @@ -258,8 +268,8 @@ class AbstractFeatureSeriesData(ConfiguredBaseModel): ) value: Optional[ Union[ - NDArray[Shape["* num_times"], float], - NDArray[Shape["* num_times, * num_features"], float], + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_features"], float | int], ] ] = Field(None) @@ -274,10 +284,8 @@ class AnnotationSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], str] = Field( - ..., - description="""Annotations made during an experiment.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: AnnotationSeriesData = Field( + ..., description="""Annotations made during an experiment.""" ) description: Optional[str] = Field( "no description", @@ -316,6 +324,39 @@ class AnnotationSeries(TimeSeries): ) +class AnnotationSeriesData(ConfiguredBaseModel): + """ + Annotations made during an experiment. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], str]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class IntervalSeries(TimeSeries): """ Stores intervals of data. The timestamps field stores the beginning and end of intervals. The data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. @@ -326,10 +367,8 @@ class IntervalSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], int] = Field( - ..., - description="""Use values >0 if interval started, <0 if interval ended.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: IntervalSeriesData = Field( + ..., description="""Use values >0 if interval started, <0 if interval ended.""" ) description: Optional[str] = Field( "no description", @@ -368,6 +407,39 @@ class IntervalSeries(TimeSeries): ) +class IntervalSeriesData(ConfiguredBaseModel): + """ + Use values >0 if interval started, <0 if interval ended. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: float = Field( + -1.0, + description="""Smallest meaningful difference between values in data. Annotations have no units, so the value is fixed to -1.0.""", + le=-1, + ge=-1, + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["n/a"] = Field( + "n/a", + description="""Base unit of measurement for working with the data. Annotations have no units, so the value is fixed to 'n/a'.""", + json_schema_extra={"linkml_meta": {"equals_string": "n/a", "ifabsent": "string(n/a)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class DecompositionSeries(TimeSeries): """ Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -443,24 +515,36 @@ class DecompositionSeriesData(ConfiguredBaseModel): "data", json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) unit: str = Field( "no unit", description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", json_schema_extra={"linkml_meta": {"ifabsent": "string(no unit)"}}, ) - value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float]] = Field( - None, - json_schema_extra={ - "linkml_meta": { - "array": { - "dimensions": [ - {"alias": "num_times"}, - {"alias": "num_channels"}, - {"alias": "num_bands"}, - ] + value: Optional[NDArray[Shape["* num_times, * num_channels, * num_bands"], float | int]] = ( + Field( + None, + json_schema_extra={ + "linkml_meta": { + "array": { + "dimensions": [ + {"alias": "num_times"}, + {"alias": "num_channels"}, + {"alias": "num_bands"}, + ] + } } - } - }, + }, + ) ) @@ -518,9 +602,6 @@ class DecompositionSeriesBands(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class Units(DynamicTable): @@ -533,9 +614,18 @@ class Units(DynamicTable): ) name: str = Field("Units", json_schema_extra={"linkml_meta": {"ifabsent": "string(Units)"}}) - spike_times_index: Optional[Named[VectorIndex]] = Field( + electrode_group: Optional[VectorData[NDArray[Any, ElectrodeGroup]]] = Field( None, - description="""Index into the spike_times dataset.""", + description="""Electrode group that each spike unit came from.""", + json_schema_extra={ + "linkml_meta": { + "array": {"maximum_number_dimensions": False, "minimum_number_dimensions": 1} + } + }, + ) + electrodes: Optional[Named[DynamicTableRegion]] = Field( + None, + description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -545,12 +635,9 @@ class Units(DynamicTable): } }, ) - spike_times: Optional[UnitsSpikeTimes] = Field( - None, description="""Spike times for each unit.""" - ) - obs_intervals_index: Optional[Named[VectorIndex]] = Field( + electrodes_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into the obs_intervals dataset.""", + description="""Index into electrodes.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -576,9 +663,9 @@ class Units(DynamicTable): }, ) ) - electrodes_index: Optional[Named[VectorIndex]] = Field( + obs_intervals_index: Optional[Named[VectorIndex]] = Field( None, - description="""Index into electrodes.""", + description="""Index into the obs_intervals dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -588,9 +675,12 @@ class Units(DynamicTable): } }, ) - electrodes: Optional[Named[DynamicTableRegion]] = Field( + spike_times: Optional[UnitsSpikeTimes] = Field( + None, description="""Spike times for each unit.""" + ) + spike_times_index: Optional[Named[VectorIndex]] = Field( None, - description="""Electrode that each spike unit came from, specified using a DynamicTableRegion.""", + description="""Index into the spike_times dataset.""", json_schema_extra={ "linkml_meta": { "annotations": { @@ -600,25 +690,12 @@ class Units(DynamicTable): } }, ) - electrode_group: Optional[List[ElectrodeGroup]] = Field( - None, description="""Electrode group that each spike unit came from.""" + waveform_mean: Optional[UnitsWaveformMean] = Field( + None, description="""Spike waveform mean for each spike unit.""" + ) + waveform_sd: Optional[UnitsWaveformSd] = Field( + None, description="""Spike waveform standard deviation for each spike unit.""" ) - waveform_mean: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform mean for each spike unit.""") - waveform_sd: Optional[ - VectorData[ - Union[ - NDArray[Shape["* num_units, * num_samples"], float], - NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], - ] - ] - ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""") colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", @@ -629,9 +706,6 @@ class Units(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) class UnitsSpikeTimes(VectorData): @@ -662,14 +736,78 @@ class UnitsSpikeTimes(VectorData): ] = Field(None) +class UnitsWaveformMean(VectorData): + """ + Spike waveform mean for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_mean"] = Field( + "waveform_mean", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_mean", "ifabsent": "string(waveform_mean)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + value: Optional[ + Union[ + NDArray[Shape["* dim0"], Any], + NDArray[Shape["* dim0, * dim1"], Any], + NDArray[Shape["* dim0, * dim1, * dim2"], Any], + NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], + ] + ] = Field(None) + + +class UnitsWaveformSd(VectorData): + """ + Spike waveform standard deviation for each spike unit. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.misc"}) + + name: Literal["waveform_sd"] = Field( + "waveform_sd", + json_schema_extra={ + "linkml_meta": {"equals_string": "waveform_sd", "ifabsent": "string(waveform_sd)"} + }, + ) + sampling_rate: Optional[float] = Field(None, description="""Sampling rate, in hertz.""") + unit: Optional[Literal["volts"]] = Field( + "volts", + description="""Unit of measurement. This value is fixed to 'volts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "volts", "ifabsent": "string(volts)"}}, + ) + description: str = Field(..., description="""Description of what these vectors represent.""") + value: Optional[ + Union[ + NDArray[Shape["* dim0"], Any], + NDArray[Shape["* dim0, * dim1"], Any], + NDArray[Shape["* dim0, * dim1, * dim2"], Any], + NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], + ] + ] = Field(None) + + # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model AbstractFeatureSeries.model_rebuild() AbstractFeatureSeriesData.model_rebuild() AnnotationSeries.model_rebuild() +AnnotationSeriesData.model_rebuild() IntervalSeries.model_rebuild() +IntervalSeriesData.model_rebuild() DecompositionSeries.model_rebuild() DecompositionSeriesData.model_rebuild() DecompositionSeriesBands.model_rebuild() Units.model_rebuild() UnitsSpikeTimes.model_rebuild() +UnitsWaveformMean.model_rebuild() +UnitsWaveformSd.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py index 763c7f3..3ce8f2a 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py @@ -158,10 +158,8 @@ class OptogeneticSeries(TimeSeries): ) name: str = Field(...) - data: NDArray[Shape["* num_times"], float] = Field( - ..., - description="""Applied power for optogenetic stimulus, in watts.""", - json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}}, + data: OptogeneticSeriesData = Field( + ..., description="""Applied power for optogenetic stimulus, in watts.""" ) site: Union[OptogeneticStimulusSite, str] = Field( ..., @@ -209,6 +207,37 @@ class OptogeneticSeries(TimeSeries): ) +class OptogeneticSeriesData(ConfiguredBaseModel): + """ + Applied power for optogenetic stimulus, in watts. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ogen"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: Literal["watts"] = Field( + "watts", + description="""Unit of measurement for data, which is fixed to 'watts'.""", + json_schema_extra={"linkml_meta": {"equals_string": "watts", "ifabsent": "string(watts)"}}, + ) + value: Optional[NDArray[Shape["* num_times"], float | int]] = Field( + None, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_times"}]}}} + ) + + class OptogeneticStimulusSite(NWBContainer): """ A site of optogenetic stimulation. @@ -239,4 +268,5 @@ class OptogeneticStimulusSite(NWBContainer): # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model OptogeneticSeries.model_rebuild() +OptogeneticSeriesData.model_rebuild() OptogeneticStimulusSite.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py index b106054..4787f8c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py @@ -28,7 +28,7 @@ from ...core.v2_2_5.core_nwb_base import ( TimeSeriesSync, ) from ...core.v2_2_5.core_nwb_device import Device -from ...core.v2_2_5.core_nwb_image import ImageSeries, ImageSeriesExternalFile +from ...core.v2_2_5.core_nwb_image import ImageSeries, ImageSeriesData, ImageSeriesExternalFile from ...hdmf_common.v1_1_3.hdmf_common_table import ( DynamicTable, DynamicTableRegion, @@ -217,12 +217,9 @@ class TwoPhotonSeries(ImageSeries): } }, ) - data: Optional[ - Union[ - NDArray[Shape["* frame, * x, * y"], float], - NDArray[Shape["* frame, * x, * y, * z"], float], - ] - ] = Field(None, description="""Binary data representing images across frames.""") + data: Optional[ImageSeriesData] = Field( + None, description="""Binary data representing images across frames.""" + ) dimension: Optional[NDArray[Shape["* rank"], int]] = Field( None, description="""Number of pixels on x, y, (and z) axes.""", @@ -233,8 +230,9 @@ class TwoPhotonSeries(ImageSeries): description="""Paths to one or more external file(s). The field is only present if format='external'. This is only relevant if the image series is stored in the file system as one or more image file(s). This field should NOT be used if the image is stored in another NWB file and that file is linked to this file.""", ) format: Optional[str] = Field( - None, + "raw", description="""Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed.""", + json_schema_extra={"linkml_meta": {"ifabsent": "string(raw)"}}, ) description: Optional[str] = Field( "no description", @@ -283,9 +281,7 @@ class RoiResponseSeries(TimeSeries): ) name: str = Field(...) - data: Union[ - NDArray[Shape["* num_times"], float], NDArray[Shape["* num_times, * num_rois"], float] - ] = Field(..., description="""Signals from ROIs.""") + data: RoiResponseSeriesData = Field(..., description="""Signals from ROIs.""") rois: Named[DynamicTableRegion] = Field( ..., description="""DynamicTableRegion referencing into an ROITable containing information on the ROIs stored in this timeseries.""", @@ -335,6 +331,39 @@ class RoiResponseSeries(TimeSeries): ) +class RoiResponseSeriesData(ConfiguredBaseModel): + """ + Signals from ROIs. + """ + + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ophys"}) + + name: Literal["data"] = Field( + "data", + json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + ) + conversion: Optional[float] = Field( + 1.0, + description="""Scalar to multiply each element in data to convert it to the specified 'unit'. If the data are stored in acquisition system units or other units that require a conversion to be interpretable, multiply the data by 'conversion' to convert the data to the specified 'unit'. e.g. if the data acquisition system stores values in this object as signed 16-bit integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' multiplier to get from raw data acquisition values to recorded volts is 2.5/32768/8000 = 9.5367e-9.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(1.0)"}}, + ) + resolution: Optional[float] = Field( + -1.0, + description="""Smallest meaningful difference between values in data, stored in the specified by unit, e.g., the change in value of the least significant bit, or a larger number if signal noise is known to be present. If unknown, use -1.0.""", + json_schema_extra={"linkml_meta": {"ifabsent": "float(-1.0)"}}, + ) + unit: str = Field( + ..., + description="""Base unit of measurement for working with the data. Actual stored values are not necessarily stored in these units. To access the data in these units, multiply 'data' by 'conversion'.""", + ) + value: Optional[ + Union[ + NDArray[Shape["* num_times"], float | int], + NDArray[Shape["* num_times, * num_rois"], float | int], + ] + ] = Field(None) + + class DfOverF(NWBDataInterface): """ dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes). @@ -344,10 +373,10 @@ class DfOverF(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field("DfOverF", json_schema_extra={"linkml_meta": {"ifabsent": "string(DfOverF)"}}) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class Fluorescence(NWBDataInterface): @@ -359,10 +388,12 @@ class Fluorescence(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[RoiResponseSeries]] = Field( + name: str = Field( + "Fluorescence", json_schema_extra={"linkml_meta": {"ifabsent": "string(Fluorescence)"}} + ) + value: Optional[Dict[str, RoiResponseSeries]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "RoiResponseSeries"}]}} ) - name: str = Field(...) class ImageSegmentation(NWBDataInterface): @@ -374,10 +405,13 @@ class ImageSegmentation(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[PlaneSegmentation]] = Field( + name: str = Field( + "ImageSegmentation", + json_schema_extra={"linkml_meta": {"ifabsent": "string(ImageSegmentation)"}}, + ) + value: Optional[Dict[str, PlaneSegmentation]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "PlaneSegmentation"}]}} ) - name: str = Field(...) class PlaneSegmentation(DynamicTable): @@ -390,10 +424,21 @@ class PlaneSegmentation(DynamicTable): ) name: str = Field(...) - image_mask: Optional[PlaneSegmentationImageMask] = Field( + image_mask: Optional[ + VectorData[ + Union[ + NDArray[Shape["* num_roi, * num_x, * num_y"], Any], + NDArray[Shape["* num_roi, * num_x, * num_y, * num_z"], Any], + ] + ] + ] = Field( None, description="""ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero.""", ) + pixel_mask: Optional[PlaneSegmentationPixelMask] = Field( + None, + description="""Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", + ) pixel_mask_index: Optional[Named[VectorIndex]] = Field( None, description="""Index into pixel_mask.""", @@ -406,9 +451,9 @@ class PlaneSegmentation(DynamicTable): } }, ) - pixel_mask: Optional[PlaneSegmentationPixelMask] = Field( + voxel_mask: Optional[PlaneSegmentationVoxelMask] = Field( None, - description="""Pixel masks for each ROI: a list of indices and weights for the ROI. Pixel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", + description="""Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", ) voxel_mask_index: Optional[Named[VectorIndex]] = Field( None, @@ -422,11 +467,7 @@ class PlaneSegmentation(DynamicTable): } }, ) - voxel_mask: Optional[PlaneSegmentationVoxelMask] = Field( - None, - description="""Voxel masks for each ROI: a list of indices and weights for the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation""", - ) - reference_images: Optional[List[ImageSeries]] = Field( + reference_images: Optional[Dict[str, ImageSeries]] = Field( None, description="""Image stacks that the segmentation masks apply to.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImageSeries"}]}}, @@ -450,33 +491,6 @@ class PlaneSegmentation(DynamicTable): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) - - -class PlaneSegmentationImageMask(VectorData): - """ - ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "core.nwb.ophys"}) - - name: Literal["image_mask"] = Field( - "image_mask", - json_schema_extra={ - "linkml_meta": {"equals_string": "image_mask", "ifabsent": "string(image_mask)"} - }, - ) - description: str = Field(..., description="""Description of what these vectors represent.""") - value: Optional[ - Union[ - NDArray[Shape["* dim0"], Any], - NDArray[Shape["* dim0, * dim1"], Any], - NDArray[Shape["* dim0, * dim1, * dim2"], Any], - NDArray[Shape["* dim0, * dim1, * dim2, * dim3"], Any], - ] - ] = Field(None) class PlaneSegmentationPixelMask(VectorData): @@ -599,7 +613,7 @@ class ImagingPlane(NWBContainer): None, description="""Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = \"Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral).\"""", ) - optical_channel: List[OpticalChannel] = Field( + optical_channel: Dict[str, OpticalChannel] = Field( ..., description="""An optical channel used to record from an imaging plane.""" ) device: Union[Device, str] = Field( @@ -713,10 +727,13 @@ class MotionCorrection(NWBDataInterface): {"from_schema": "core.nwb.ophys", "tree_root": True} ) - value: Optional[List[CorrectedImageStack]] = Field( + name: str = Field( + "MotionCorrection", + json_schema_extra={"linkml_meta": {"ifabsent": "string(MotionCorrection)"}}, + ) + value: Optional[Dict[str, CorrectedImageStack]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "CorrectedImageStack"}]}} ) - name: str = Field(...) class CorrectedImageStack(NWBDataInterface): @@ -751,11 +768,11 @@ class CorrectedImageStack(NWBDataInterface): # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model TwoPhotonSeries.model_rebuild() RoiResponseSeries.model_rebuild() +RoiResponseSeriesData.model_rebuild() DfOverF.model_rebuild() Fluorescence.model_rebuild() ImageSegmentation.model_rebuild() PlaneSegmentation.model_rebuild() -PlaneSegmentationImageMask.model_rebuild() PlaneSegmentationPixelMask.model_rebuild() PlaneSegmentationVoxelMask.model_rebuild() ImagingPlane.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py index 849cf0b..cbc208f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py @@ -38,6 +38,7 @@ from ...core.v2_2_5.core_nwb_ecephys import ( ClusterWaveforms, Clustering, ElectricalSeries, + ElectricalSeriesData, ElectrodeGroup, ElectrodeGroupPosition, EventDetection, @@ -46,6 +47,7 @@ from ...core.v2_2_5.core_nwb_ecephys import ( FilteredEphys, LFP, SpikeEventSeries, + SpikeEventSeriesData, ) from ...core.v2_2_5.core_nwb_epoch import TimeIntervals, TimeIntervalsTimeseries from ...core.v2_2_5.core_nwb_file import ( @@ -87,9 +89,12 @@ from ...core.v2_2_5.core_nwb_image import ( GrayscaleImage, ImageMaskSeries, ImageSeries, + ImageSeriesData, ImageSeriesExternalFile, IndexSeries, + IndexSeriesData, OpticalSeries, + OpticalSeriesData, RGBAImage, RGBImage, ) @@ -97,14 +102,22 @@ from ...core.v2_2_5.core_nwb_misc import ( AbstractFeatureSeries, AbstractFeatureSeriesData, AnnotationSeries, + AnnotationSeriesData, DecompositionSeries, DecompositionSeriesBands, DecompositionSeriesData, IntervalSeries, + IntervalSeriesData, Units, UnitsSpikeTimes, + UnitsWaveformMean, + UnitsWaveformSd, +) +from ...core.v2_2_5.core_nwb_ogen import ( + OptogeneticSeries, + OptogeneticSeriesData, + OptogeneticStimulusSite, ) -from ...core.v2_2_5.core_nwb_ogen import OptogeneticSeries, OptogeneticStimulusSite from ...core.v2_2_5.core_nwb_ophys import ( CorrectedImageStack, DfOverF, @@ -117,10 +130,10 @@ from ...core.v2_2_5.core_nwb_ophys import ( MotionCorrection, OpticalChannel, PlaneSegmentation, - PlaneSegmentationImageMask, PlaneSegmentationPixelMask, PlaneSegmentationVoxelMask, RoiResponseSeries, + RoiResponseSeriesData, TwoPhotonSeries, ) from ...core.v2_2_5.core_nwb_retinotopy import ( diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py index 4b7bebf..db25fc0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py @@ -989,12 +989,12 @@ class DynamicTableRegion(DynamicTableRegionMixin, VectorData): ) name: str = Field(...) - table: DynamicTable = Field( - ..., description="""Reference to the DynamicTable object that this region applies to.""" - ) description: str = Field( ..., description="""Description of what this table region points to.""" ) + table: DynamicTable = Field( + ..., description="""Reference to the DynamicTable object that this region applies to.""" + ) class Container(ConfiguredBaseModel): @@ -1029,9 +1029,6 @@ class DynamicTable(DynamicTableMixin): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py index df885a6..17d747c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py @@ -989,12 +989,12 @@ class DynamicTableRegion(DynamicTableRegionMixin, VectorData): ) name: str = Field(...) - table: DynamicTable = Field( - ..., description="""Reference to the DynamicTable object that this region applies to.""" - ) description: str = Field( ..., description="""Description of what this table region points to.""" ) + table: DynamicTable = Field( + ..., description="""Reference to the DynamicTable object that this region applies to.""" + ) class Container(ConfiguredBaseModel): @@ -1029,9 +1029,6 @@ class DynamicTable(DynamicTableMixin): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py index 454e1eb..5cab7d5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py @@ -993,12 +993,12 @@ class DynamicTableRegion(DynamicTableRegionMixin, VectorData): ) name: str = Field(...) - table: DynamicTable = Field( - ..., description="""Reference to the DynamicTable object that this region applies to.""" - ) description: str = Field( ..., description="""Description of what this table region points to.""" ) + table: DynamicTable = Field( + ..., description="""Reference to the DynamicTable object that this region applies to.""" + ) value: Optional[ Union[ NDArray[Shape["* dim0"], Any], @@ -1041,9 +1041,6 @@ class DynamicTable(DynamicTableMixin): description="""Array of unique identifiers for the rows of this dynamic table.""", json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, ) - vector_index: Optional[List[VectorIndex]] = Field( - None, description="""Indices for the vector columns of this dynamic table.""" - ) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py index e7458c5..c6e8011 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py @@ -974,12 +974,12 @@ class DynamicTableRegion(DynamicTableRegionMixin, VectorData): ) name: str = Field(...) - table: DynamicTable = Field( - ..., description="""Reference to the DynamicTable object that this region applies to.""" - ) description: str = Field( ..., description="""Description of what this table region points to.""" ) + table: DynamicTable = Field( + ..., description="""Reference to the DynamicTable object that this region applies to.""" + ) value: Optional[ Union[ NDArray[Shape["* dim0"], Any], diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py index 1900b5a..5a6ee99 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py @@ -171,10 +171,10 @@ class SimpleMultiContainer(Container): {"from_schema": "hdmf-common.base", "tree_root": True} ) - value: Optional[List[Container]] = Field( + name: str = Field(...) + value: Optional[Dict[str, Container]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "Container"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py index 129bd39..b386e25 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py @@ -974,12 +974,12 @@ class DynamicTableRegion(DynamicTableRegionMixin, VectorData): ) name: str = Field(...) - table: DynamicTable = Field( - ..., description="""Reference to the DynamicTable object that this region applies to.""" - ) description: str = Field( ..., description="""Description of what this table region points to.""" ) + table: DynamicTable = Field( + ..., description="""Reference to the DynamicTable object that this region applies to.""" + ) value: Optional[ Union[ NDArray[Shape["* dim0"], Any], diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py index 73dfb25..38ef8bd 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py @@ -171,10 +171,10 @@ class SimpleMultiContainer(Container): {"from_schema": "hdmf-common.base", "tree_root": True} ) - value: Optional[List[Container]] = Field( + name: str = Field(...) + value: Optional[Dict[str, Container]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "Container"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py index 718593e..c424360 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py @@ -169,23 +169,15 @@ class CSRMatrix(Container): "linkml_meta": {"array": {"dimensions": [{"alias": "number_of_rows_in_the_matrix_1"}]}} }, ) - data: CSRMatrixData = Field(..., description="""The non-zero values in the matrix.""") - - -class CSRMatrixData(ConfiguredBaseModel): - """ - The non-zero values in the matrix. - """ - - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({"from_schema": "hdmf-common.sparse"}) - - name: Literal["data"] = Field( - "data", - json_schema_extra={"linkml_meta": {"equals_string": "data", "ifabsent": "string(data)"}}, + data: NDArray[Shape["* number_of_non_zero_values"], Any] = Field( + ..., + description="""The non-zero values in the matrix.""", + json_schema_extra={ + "linkml_meta": {"array": {"dimensions": [{"alias": "number_of_non_zero_values"}]}} + }, ) # Model rebuild # see https://pydantic-docs.helpmanual.io/usage/models/#rebuilding-a-model CSRMatrix.model_rebuild() -CSRMatrixData.model_rebuild() diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py index 1fe61d6..c192750 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py @@ -974,12 +974,12 @@ class DynamicTableRegion(DynamicTableRegionMixin, VectorData): ) name: str = Field(...) - table: DynamicTable = Field( - ..., description="""Reference to the DynamicTable object that this region applies to.""" - ) description: str = Field( ..., description="""Description of what this table region points to.""" ) + table: DynamicTable = Field( + ..., description="""Reference to the DynamicTable object that this region applies to.""" + ) value: Optional[ Union[ NDArray[Shape["* dim0"], Any], diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py index 7988815..32fdddf 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py @@ -18,7 +18,7 @@ from ...hdmf_common.v1_3_0.hdmf_common_resources import ( ExternalResourcesObjects, ExternalResourcesResources, ) -from ...hdmf_common.v1_3_0.hdmf_common_sparse import CSRMatrix, CSRMatrixData +from ...hdmf_common.v1_3_0.hdmf_common_sparse import CSRMatrix from ...hdmf_common.v1_3_0.hdmf_common_table import ( DynamicTable, DynamicTableRegion, diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py index 0eab9b0..d9c64fa 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py @@ -11,7 +11,7 @@ import numpy as np from numpydantic import NDArray, Shape from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator -from ...hdmf_common.v1_4_0.hdmf_common_table import VectorData +from ...hdmf_common.v1_5_0.hdmf_common_table import VectorData metamodel_version = "None" @@ -136,7 +136,7 @@ linkml_meta = LinkMLMeta( }, "default_prefix": "hdmf-experimental.experimental/", "id": "hdmf-experimental.experimental", - "imports": ["../../hdmf_common/v1_4_0/namespace", "hdmf-experimental.nwb.language"], + "imports": ["../../hdmf_common/v1_5_0/namespace", "hdmf-experimental.nwb.language"], "name": "hdmf-experimental.experimental", } ) diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py index a4e00af..0e505bd 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py @@ -11,7 +11,7 @@ import numpy as np from numpydantic import NDArray, Shape from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator -from ...hdmf_common.v1_4_0.hdmf_common_base import Container, Data +from ...hdmf_common.v1_5_0.hdmf_common_base import Container, Data metamodel_version = "None" @@ -136,7 +136,7 @@ linkml_meta = LinkMLMeta( }, "default_prefix": "hdmf-experimental.resources/", "id": "hdmf-experimental.resources", - "imports": ["../../hdmf_common/v1_4_0/namespace", "hdmf-experimental.nwb.language"], + "imports": ["../../hdmf_common/v1_5_0/namespace", "hdmf-experimental.nwb.language"], "name": "hdmf-experimental.resources", } ) diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py index 5e1eaba..e546c20 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py @@ -10,9 +10,10 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator -from ...hdmf_common.v1_4_0.hdmf_common_base import Container, Data, SimpleMultiContainer -from ...hdmf_common.v1_4_0.hdmf_common_sparse import CSRMatrix -from ...hdmf_common.v1_4_0.hdmf_common_table import ( +from ...hdmf_common.v1_5_0.hdmf_common_base import Container, Data, SimpleMultiContainer +from ...hdmf_common.v1_5_0.hdmf_common_sparse import CSRMatrix +from ...hdmf_common.v1_5_0.hdmf_common_table import ( + AlignedDynamicTable, DynamicTable, DynamicTableRegion, ElementIdentifiers, diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.base.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.base.yaml index e66d53c..09884f8 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.base.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -32,6 +33,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true resolution: @@ -73,6 +75,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -84,6 +87,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -94,6 +98,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -118,15 +123,14 @@ classes: external file. range: TimeSeries__data required: true - multivalued: false + inlined: true starting_time: name: starting_time description: Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute. range: TimeSeries__starting_time - required: false - multivalued: false + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -168,8 +172,8 @@ classes: external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes. range: TimeSeries__sync - required: false - multivalued: false + inlined: true + inlined_as_list: true tree_root: true TimeSeries__data: name: TimeSeries__data @@ -180,6 +184,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data @@ -244,6 +249,7 @@ classes: name: name: name ifabsent: string(starting_time) + identifier: true range: string required: true equals_string: starting_time @@ -275,6 +281,7 @@ classes: name: name: name ifabsent: string(sync) + identifier: true range: string required: true equals_string: sync @@ -283,13 +290,24 @@ classes: description: A collection of processed data. is_a: NWBContainer attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + description: + name: description + description: Description of this collection of processed data. + range: text + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface + - range: DynamicTable tree_root: true Images: name: Images @@ -299,6 +317,7 @@ classes: name: name: name ifabsent: string(Images) + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.behavior.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.behavior.yaml index 5cff1a7..e7ce7db 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.behavior.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.behavior.yaml @@ -29,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,13 +38,11 @@ classes: reference frame. range: SpatialSeries__data required: true - multivalued: false + inlined: true reference_frame: name: reference_frame description: Description defining what exactly 'straight-ahead' means. range: text - required: false - multivalued: false tree_root: true SpatialSeries__data: name: SpatialSeries__data @@ -53,9 +52,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. The default @@ -91,12 +114,19 @@ classes: events. BehavioralTimeSeries is for continuous data. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: IntervalSeries + name: + name: name + ifabsent: string(BehavioralEpochs) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: IntervalSeries tree_root: true BehavioralEvents: name: BehavioralEvents @@ -104,12 +134,19 @@ classes: for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralEvents) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true BehavioralTimeSeries: name: BehavioralTimeSeries @@ -117,36 +154,57 @@ classes: of BehavioralEpochs for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralTimeSeries) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true PupilTracking: name: PupilTracking description: Eye-tracking data, representing pupil size. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(PupilTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true EyeTracking: name: EyeTracking description: Eye-tracking data, representing direction of gaze. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(EyeTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true CompassDirection: name: CompassDirection @@ -157,22 +215,36 @@ classes: be radians or degrees. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(CompassDirection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true Position: name: Position description: Position data, whether along the x, x/y or x/y/z axis. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(Position) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.device.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.device.yaml index 1b7492f..f525ac6 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.device.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.device.yaml @@ -21,6 +21,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ecephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ecephys.yaml index e476e7c..a0e976b 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ecephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ecephys.yaml @@ -25,41 +25,9 @@ classes: attributes: name: name: name + identifier: true range: string required: true - data: - name: data - description: Recorded voltage data. - range: numeric - required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_channels - - array: - dimensions: - - alias: num_times - - alias: num_channels - - alias: num_samples - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: DynamicTableRegion pointer to the electrodes that this time series - was generated from. - range: DynamicTableRegion - required: true - multivalued: false channel_conversion: name: channel_conversion description: Channel-specific conversion factor. Multiply the data in the @@ -77,7 +45,87 @@ classes: range: float32 required: false multivalued: false + data: + name: data + description: Recorded voltage data. + range: ElectricalSeries__data + required: true + inlined: true + electrodes: + name: electrodes + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: DynamicTableRegion pointer to the electrodes that this time series + was generated from. + range: DynamicTableRegion + required: true + inlined: true tree_root: true + ElectricalSeries__data: + name: ElectricalSeries__data + description: Recorded voltage data. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. This value + is fixed to 'volts'. Actual stored values are not necessarily stored in + these units. To access the data in these units, multiply 'data' by 'conversion' + and 'channel_conversion' (if present). + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_channels + - array: + dimensions: + - alias: num_times + - alias: num_channels + - alias: num_samples SpikeEventSeries: name: SpikeEventSeries description: 'Stores snapshots/snippets of recorded spike events (i.e., threshold @@ -92,24 +140,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Spike waveforms. - range: numeric + range: SpikeEventSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_events - - alias: num_samples - - array: - dimensions: - - alias: num_events - - alias: num_channels - - alias: num_samples + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -123,6 +162,60 @@ classes: required: true multivalued: false tree_root: true + SpikeEventSeries__data: + name: SpikeEventSeries__data + description: Spike waveforms. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for waveforms, which is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_events + - alias: num_samples + - array: + dimensions: + - alias: num_events + - alias: num_channels + - alias: num_samples FeatureExtraction: name: FeatureExtraction description: Features, such as PC1 and PC2, that are extracted from signals stored @@ -132,6 +225,7 @@ classes: name: name: name ifabsent: string(FeatureExtraction) + identifier: true range: string required: true description: @@ -177,7 +271,7 @@ classes: was generated from. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true EventDetection: name: EventDetection @@ -187,6 +281,7 @@ classes: name: name: name ifabsent: string(EventDetection) + identifier: true range: string required: true detection_method: @@ -195,7 +290,6 @@ classes: or dV/dT threshold, as well as relevant values. range: text required: true - multivalued: false source_idx: name: source_idx description: Indices (zero-based) into source ElectricalSeries::data array @@ -224,7 +318,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ElectricalSeries - range: string @@ -236,12 +330,19 @@ classes: during experiment acquisition. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpikeEventSeries + name: + name: name + ifabsent: string(EventWaveform) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpikeEventSeries tree_root: true FilteredEphys: name: FilteredEphys @@ -258,12 +359,19 @@ classes: the ElectricalSeries. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(FilteredEphys) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true LFP: name: LFP @@ -272,12 +380,19 @@ classes: properties should be noted in the ElectricalSeries description or comments field. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(LFP) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true ElectrodeGroup: name: ElectrodeGroup @@ -286,6 +401,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -304,8 +420,7 @@ classes: name: position description: stereotaxic or common framework coordinates range: ElectrodeGroup__position - required: false - multivalued: false + inlined: true device: name: device annotations: @@ -313,7 +428,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -325,6 +440,7 @@ classes: name: name: name ifabsent: string(position) + identifier: true range: string required: true equals_string: position @@ -334,24 +450,18 @@ classes: array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false y: name: y description: y coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false z: name: z description: z coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false ClusterWaveforms: name: ClusterWaveforms description: DEPRECATED The mean waveform shape, including standard deviation, @@ -365,6 +475,7 @@ classes: name: name: name ifabsent: string(ClusterWaveforms) + identifier: true range: string required: true waveform_filtering: @@ -372,7 +483,6 @@ classes: description: Filtering applied to data before generating mean/sd range: text required: true - multivalued: false waveform_mean: name: waveform_mean description: The mean waveform for each cluster, using the same indices for @@ -404,7 +514,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Clustering - range: string @@ -418,6 +528,7 @@ classes: name: name: name ifabsent: string(Clustering) + identifier: true range: string required: true description: @@ -426,7 +537,6 @@ classes: clusters curated using Klusters, etc) range: text required: true - multivalued: false num: name: num description: Cluster number of each event diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.epoch.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.epoch.yaml index 2e5ca8e..b0c30b3 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.epoch.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.epoch.yaml @@ -22,6 +22,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true start_time: @@ -62,14 +63,12 @@ classes: value: neurodata_type_inc description: Index for tags. range: VectorIndex - required: false - multivalued: false + inlined: true timeseries: name: timeseries description: An index into a TimeSeries object. range: TimeIntervals__timeseries - required: false - multivalued: false + inlined: true timeseries_index: name: timeseries_index annotations: @@ -81,8 +80,7 @@ classes: value: neurodata_type_inc description: Index for timeseries. range: VectorIndex - required: false - multivalued: false + inlined: true tree_root: true TimeIntervals__timeseries: name: TimeIntervals__timeseries @@ -92,6 +90,7 @@ classes: name: name: name ifabsent: string(timeseries) + identifier: true range: string required: true equals_string: timeseries @@ -103,8 +102,6 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false count: name: count description: Number of data samples available in this time series, during @@ -112,13 +109,10 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false timeseries: name: timeseries description: the TimeSeries that this index applies to. array: exact_number_dimensions: 1 range: TimeSeries - required: false - multivalued: false + inlined: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.file.yaml index 6550555..edd73a9 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.file.yaml @@ -30,6 +30,7 @@ classes: name: name: name ifabsent: string(root) + identifier: true range: string required: true equals_string: root @@ -64,13 +65,11 @@ classes: other files. range: text required: true - multivalued: false session_description: name: session_description description: A description of the experimental session and data in the file. range: text required: true - multivalued: false session_start_time: name: session_start_time description: 'Date and time of the experiment/session start. The date is stored @@ -79,7 +78,6 @@ classes: offset. Date accuracy is up to milliseconds.' range: isodatetime required: true - multivalued: false timestamps_reference_time: name: timestamps_reference_time description: 'Date and time corresponding to time zero of all timestamps. @@ -89,7 +87,6 @@ classes: times stored in the file use this time as reference (i.e., time zero).' range: isodatetime required: true - multivalued: false acquisition: name: acquisition description: Data streams recorded from the system, including ephys, ophys, @@ -168,7 +165,8 @@ classes: can exist in the present file or can be linked to a remote library file. range: NWBFile__stimulus required: true - multivalued: false + inlined: true + inlined_as_list: true general: name: general description: Experimental metadata, including protocol, notes and description @@ -188,7 +186,8 @@ classes: should not be created unless there is data to store within them. range: NWBFile__general required: true - multivalued: false + inlined: true + inlined_as_list: true intervals: name: intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -196,14 +195,18 @@ classes: an experiment, or epochs (see epochs subgroup) deriving from analysis of data. range: NWBFile__intervals - required: false - multivalued: false + inlined: true + inlined_as_list: true units: name: units description: Data about sorted spike units. range: Units - required: false - multivalued: false + inlined: true + inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -223,6 +226,7 @@ classes: name: name: name ifabsent: string(stimulus) + identifier: true range: string required: true equals_string: stimulus @@ -265,6 +269,7 @@ classes: name: name: name ifabsent: string(general) + identifier: true range: string required: true equals_string: general @@ -272,14 +277,10 @@ classes: name: data_collection description: Notes about data collection and analysis. range: text - required: false - multivalued: false experiment_description: name: experiment_description description: General description of the experiment. range: text - required: false - multivalued: false experimenter: name: experimenter description: Name of person(s) who performed the experiment. Can also specify @@ -294,8 +295,6 @@ classes: name: institution description: Institution(s) where experiment was performed. range: text - required: false - multivalued: false keywords: name: keywords description: Terms to search over. @@ -309,28 +308,20 @@ classes: name: lab description: Laboratory where experiment was performed. range: text - required: false - multivalued: false notes: name: notes description: Notes about the experiment. range: text - required: false - multivalued: false pharmacology: name: pharmacology description: Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc. range: text - required: false - multivalued: false protocol: name: protocol description: Experimental protocol, if applicable. e.g., include IACUC protocol number. range: text - required: false - multivalued: false related_publications: name: related_publications description: Publication information. PMID, DOI, URL, etc. @@ -344,49 +335,39 @@ classes: name: session_id description: Lab-specific ID for the session. range: text - required: false - multivalued: false slices: name: slices description: Description of slices, including information about preparation thickness, orientation, temperature, and bath solution. range: text - required: false - multivalued: false source_script: name: source_script description: Script file or link to public source code used to create this NWB file. range: general__source_script - required: false - multivalued: false + inlined: true stimulus: name: stimulus description: Notes about stimuli, such as how and where they were presented. range: text - required: false - multivalued: false surgery: name: surgery description: Narrative description about surgery/surgeries, including date(s) and who performed surgery. range: text - required: false - multivalued: false virus: name: virus description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - required: false - multivalued: false nwb_container: name: nwb_container description: Place-holder than can be extended so that lab-specific meta-data can be placed in /general. range: NWBContainer - required: false multivalued: true + inlined: true + inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -401,20 +382,20 @@ classes: description: Information about the animal or person from which the data was measured. range: Subject - required: false - multivalued: false + inlined: true + inlined_as_list: true extracellular_ephys: name: extracellular_ephys description: Metadata related to extracellular electrophysiology. range: general__extracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true intracellular_ephys: name: intracellular_ephys description: Metadata related to intracellular electrophysiology. range: general__intracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true optogenetics: name: optogenetics description: Metadata describing optogenetic stimuluation. @@ -439,6 +420,7 @@ classes: name: name: name ifabsent: string(source_script) + identifier: true range: string required: true equals_string: source_script @@ -459,6 +441,7 @@ classes: name: name: name ifabsent: string(subject) + identifier: true range: string required: true equals_string: subject @@ -466,52 +449,36 @@ classes: name: age description: Age of subject. Can be supplied instead of 'date_of_birth'. range: text - required: false - multivalued: false date_of_birth: name: date_of_birth description: Date of birth of subject. Can be supplied instead of 'age'. range: isodatetime - required: false - multivalued: false description: name: description description: Description of subject and where subject came from (e.g., breeder, if animal). range: text - required: false - multivalued: false genotype: name: genotype description: Genetic strain. If absent, assume Wild Type (WT). range: text - required: false - multivalued: false sex: name: sex description: Gender of subject. range: text - required: false - multivalued: false species: name: species description: Species of subject. range: text - required: false - multivalued: false subject_id: name: subject_id description: ID of animal/person used/participating in experiment (lab convention). range: text - required: false - multivalued: false weight: name: weight description: Weight at time of experiment, at time of surgery and at other important times. range: text - required: false - multivalued: false general__extracellular_ephys: name: general__extracellular_ephys description: Metadata related to extracellular electrophysiology. @@ -519,21 +486,23 @@ classes: name: name: name ifabsent: string(extracellular_ephys) + identifier: true range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - required: false - multivalued: true electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes - required: false - multivalued: false + inlined: true + inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -542,6 +511,7 @@ classes: name: name: name ifabsent: string(electrodes) + identifier: true range: string required: true equals_string: electrodes @@ -604,9 +574,13 @@ classes: group: name: group description: Reference to the ElectrodeGroup this electrode is a part of. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: ElectrodeGroup required: true - multivalued: true + multivalued: false + inlined: true group_name: name: group_name description: Name of the ElectrodeGroup this electrode is a part of. @@ -659,6 +633,7 @@ classes: name: name: name ifabsent: string(intracellular_ephys) + identifier: true range: string required: true equals_string: intracellular_ephys @@ -668,20 +643,19 @@ classes: frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries. range: text - required: false - multivalued: false - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - required: false - multivalued: true sweep_table: name: sweep_table description: The table which groups different PatchClampSeries together. range: SweepTable - required: false - multivalued: false + inlined: true + inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -691,6 +665,7 @@ classes: name: name: name ifabsent: string(intervals) + identifier: true range: string required: true equals_string: intervals @@ -699,24 +674,25 @@ classes: description: Divisions in time marking experimental stages or sub-divisions of a single recording session. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false trials: name: trials description: Repeated experimental events that have a logical grouping. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false invalid_times: name: invalid_times description: Time intervals that should be removed from analysis. range: TimeIntervals - required: false - multivalued: false - time_intervals: - name: time_intervals + inlined: true + inlined_as_list: false + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals - required: false multivalued: true + inlined: true + inlined_as_list: false diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.icephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.icephys.yaml index dc70464..2b251ac 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.icephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.icephys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true stimulus_description: @@ -40,14 +41,12 @@ classes: description: Recorded voltage or current. range: PatchClampSeries__data required: true - multivalued: false + inlined: true gain: name: gain description: Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp). range: float32 - required: false - multivalued: false electrode: name: electrode annotations: @@ -55,7 +54,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: IntracellularElectrode - range: string @@ -67,9 +66,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -92,32 +115,27 @@ classes: attributes: name: name: name + identifier: true range: string required: true + bias_current: + name: bias_current + description: Bias current, in amps. + range: float32 + bridge_balance: + name: bridge_balance + description: Bridge balance, in ohms. + range: float32 + capacitance_compensation: + name: capacitance_compensation + description: Capacitance compensation, in farads. + range: float32 data: name: data description: Recorded voltage. range: CurrentClampSeries__data required: true - multivalued: false - bias_current: - name: bias_current - description: Bias current, in amps. - range: float32 - required: false - multivalued: false - bridge_balance: - name: bridge_balance - description: Bridge balance, in ohms. - range: float32 - required: false - multivalued: false - capacitance_compensation: - name: capacitance_compensation - description: Capacitance compensation, in farads. - range: float32 - required: false - multivalued: false + inlined: true tree_root: true CurrentClampSeries__data: name: CurrentClampSeries__data @@ -126,9 +144,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -140,8 +182,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IZeroClampSeries: name: IZeroClampSeries description: Voltage data from an intracellular recording when all current and @@ -152,6 +196,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true bias_current: @@ -159,19 +204,16 @@ classes: description: Bias current, in amps, fixed to 0.0. range: float32 required: true - multivalued: false bridge_balance: name: bridge_balance description: Bridge balance, in ohms, fixed to 0.0. range: float32 required: true - multivalued: false capacitance_compensation: name: capacitance_compensation description: Capacitance compensation, in farads, fixed to 0.0. range: float32 required: true - multivalued: false tree_root: true CurrentClampStimulusSeries: name: CurrentClampStimulusSeries @@ -180,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -187,7 +230,7 @@ classes: description: Stimulus current applied. range: CurrentClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true CurrentClampStimulusSeries__data: name: CurrentClampStimulusSeries__data @@ -196,9 +239,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -210,8 +277,10 @@ classes: equals_string: amperes value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries: name: VoltageClampSeries description: Current data from an intracellular voltage-clamp recording. A corresponding @@ -221,80 +290,51 @@ classes: attributes: name: name: name + identifier: true range: string required: true + capacitance_fast: + name: capacitance_fast + description: Fast capacitance, in farads. + range: VoltageClampSeries__capacitance_fast + inlined: true + capacitance_slow: + name: capacitance_slow + description: Slow capacitance, in farads. + range: VoltageClampSeries__capacitance_slow + inlined: true data: name: data description: Recorded current. range: VoltageClampSeries__data required: true - multivalued: false - capacitance_fast: - name: capacitance_fast - description: Fast capacitance, in farads. - range: VoltageClampSeries__capacitance_fast - required: false - multivalued: false - capacitance_slow: - name: capacitance_slow - description: Slow capacitance, in farads. - range: VoltageClampSeries__capacitance_slow - required: false - multivalued: false + inlined: true resistance_comp_bandwidth: name: resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. range: VoltageClampSeries__resistance_comp_bandwidth - required: false - multivalued: false + inlined: true resistance_comp_correction: name: resistance_comp_correction description: Resistance compensation correction, in percent. range: VoltageClampSeries__resistance_comp_correction - required: false - multivalued: false + inlined: true resistance_comp_prediction: name: resistance_comp_prediction description: Resistance compensation prediction, in percent. range: VoltageClampSeries__resistance_comp_prediction - required: false - multivalued: false + inlined: true whole_cell_capacitance_comp: name: whole_cell_capacitance_comp description: Whole cell capacitance compensation, in farads. range: VoltageClampSeries__whole_cell_capacitance_comp - required: false - multivalued: false + inlined: true whole_cell_series_resistance_comp: name: whole_cell_series_resistance_comp description: Whole cell series resistance compensation, in ohms. range: VoltageClampSeries__whole_cell_series_resistance_comp - required: false - multivalued: false + inlined: true tree_root: true - VoltageClampSeries__data: - name: VoltageClampSeries__data - description: Recorded current. - attributes: - name: - name: name - ifabsent: string(data) - range: string - required: true - equals_string: data - unit: - name: unit - description: Base unit of measurement for working with the data. which is - fixed to 'amperes'. Actual stored values are not necessarily stored in these - units. To access the data in these units, multiply 'data' by 'conversion'. - ifabsent: string(amperes) - range: text - required: true - equals_string: amperes - value: - name: value - range: AnyType - required: true VoltageClampSeries__capacitance_fast: name: VoltageClampSeries__capacitance_fast description: Fast capacitance, in farads. @@ -302,6 +342,7 @@ classes: name: name: name ifabsent: string(capacitance_fast) + identifier: true range: string required: true equals_string: capacitance_fast @@ -323,6 +364,7 @@ classes: name: name: name ifabsent: string(capacitance_slow) + identifier: true range: string required: true equals_string: capacitance_slow @@ -337,6 +379,55 @@ classes: name: value range: float32 required: true + VoltageClampSeries__data: + name: VoltageClampSeries__data + description: Recorded current. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. which is + fixed to 'amperes'. Actual stored values are not necessarily stored in these + units. To access the data in these units, multiply 'data' by 'conversion'. + ifabsent: string(amperes) + range: text + required: true + equals_string: amperes + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries__resistance_comp_bandwidth: name: VoltageClampSeries__resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. @@ -344,6 +435,7 @@ classes: name: name: name ifabsent: string(resistance_comp_bandwidth) + identifier: true range: string required: true equals_string: resistance_comp_bandwidth @@ -366,6 +458,7 @@ classes: name: name: name ifabsent: string(resistance_comp_correction) + identifier: true range: string required: true equals_string: resistance_comp_correction @@ -388,6 +481,7 @@ classes: name: name: name ifabsent: string(resistance_comp_prediction) + identifier: true range: string required: true equals_string: resistance_comp_prediction @@ -410,6 +504,7 @@ classes: name: name: name ifabsent: string(whole_cell_capacitance_comp) + identifier: true range: string required: true equals_string: whole_cell_capacitance_comp @@ -432,6 +527,7 @@ classes: name: name: name ifabsent: string(whole_cell_series_resistance_comp) + identifier: true range: string required: true equals_string: whole_cell_series_resistance_comp @@ -454,6 +550,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -461,7 +558,7 @@ classes: description: Stimulus voltage applied. range: VoltageClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true VoltageClampStimulusSeries__data: name: VoltageClampStimulusSeries__data @@ -470,9 +567,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -484,8 +605,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IntracellularElectrode: name: IntracellularElectrode description: An intracellular electrode and its metadata. @@ -493,6 +616,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -500,45 +624,32 @@ classes: description: Description of electrode (e.g., whole-cell, sharp, etc.). range: text required: true - multivalued: false filtering: name: filtering description: Electrode specific filtering. range: text - required: false - multivalued: false initial_access_resistance: name: initial_access_resistance description: Initial access resistance. range: text - required: false - multivalued: false location: name: location description: Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. range: text - required: false - multivalued: false resistance: name: resistance description: Electrode resistance, in ohms. range: text - required: false - multivalued: false seal: name: seal description: Information about seal used for recording. range: text - required: false - multivalued: false slice: name: slice description: Information about slice used for recording. range: text - required: false - multivalued: false device: name: device annotations: @@ -546,7 +657,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -558,23 +669,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true - sweep_number: - name: sweep_number - description: Sweep number of the PatchClampSeries in that row. - array: - minimum_number_dimensions: 1 - maximum_number_dimensions: false - range: uint32 - required: true - multivalued: false series: name: series description: The PatchClampSeries with the sweep number in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: PatchClampSeries required: true - multivalued: true + multivalued: false + inlined: true series_index: name: series_index annotations: @@ -587,5 +694,14 @@ classes: description: Index for series. range: VectorIndex required: true + inlined: true + sweep_number: + name: sweep_number + description: Sweep number of the PatchClampSeries in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: uint32 + required: true multivalued: false tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.image.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.image.yaml index 9019ee0..51c969f 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.image.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.image.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -37,6 +38,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -56,6 +58,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -80,26 +83,14 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Binary data representing images across frames. - range: numeric - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - alias: z + range: ImageSeries__data + inlined: true dimension: name: dimension description: Number of pixels on x, y, (and z) axes. @@ -117,18 +108,72 @@ classes: used if the image is stored in another NWB file and that file is linked to this file. range: ImageSeries__external_file - required: false - multivalued: false + inlined: true format: name: format description: Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed. + ifabsent: string(raw) range: text - required: false - multivalued: false tree_root: true + ImageSeries__data: + name: ImageSeries__data + description: Binary data representing images across frames. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - alias: z ImageSeries__external_file: name: ImageSeries__external_file description: Paths to one or more external file(s). The field is only present @@ -139,6 +184,7 @@ classes: name: name: name ifabsent: string(external_file) + identifier: true range: string required: true equals_string: external_file @@ -176,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true masked_imageseries: @@ -185,7 +232,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string @@ -201,14 +248,13 @@ classes: attributes: name: name: name + identifier: true range: string required: true distance: name: distance description: Distance from camera/monitor to target/eye. range: float32 - required: false - multivalued: false field_of_view: name: field_of_view description: Width, height and depth of image, or imaged area, in meters. @@ -229,8 +275,6 @@ classes: description: Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference. range: text - required: false - multivalued: false tree_root: true IndexSeries: name: IndexSeries @@ -244,17 +288,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Index of the frame in the referenced ImageSeries. - array: - dimensions: - - alias: num_times - range: int32 + range: IndexSeries__data required: true - multivalued: false + inlined: true indexed_timeseries: name: indexed_timeseries annotations: @@ -262,8 +304,55 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string tree_root: true + IndexSeries__data: + name: IndexSeries__data + description: Index of the frame in the referenced ImageSeries. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + array: + dimensions: + - alias: num_times + range: int32 diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.language.yaml index e42c742..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.misc.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.misc.yaml index 4337a4e..ffc6f56 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.misc.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.misc.yaml @@ -30,6 +30,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,7 +38,7 @@ classes: description: Values of each feature at each time. range: AbstractFeatureSeries__data required: true - multivalued: false + inlined: true feature_units: name: feature_units description: Units of each feature. @@ -64,9 +65,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Since there can be different units for different features, store @@ -96,18 +121,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Annotations made during an experiment. + range: AnnotationSeries__data + required: true + inlined: true + tree_root: true + AnnotationSeries__data: + name: AnnotationSeries__data + description: Annotations made during an experiment. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: text - required: true - multivalued: false - tree_root: true IntervalSeries: name: IntervalSeries description: Stores intervals of data. The timestamps field stores the beginning @@ -121,18 +191,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Use values >0 if interval started, <0 if interval ended. + range: IntervalSeries__data + required: true + inlined: true + tree_root: true + IntervalSeries__data: + name: IntervalSeries__data + description: Use values >0 if interval started, <0 if interval ended. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: int8 - required: true - multivalued: false - tree_root: true DecompositionSeries: name: DecompositionSeries description: Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -140,6 +255,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -147,28 +263,27 @@ classes: description: Data decomposed into frequency bands. range: DecompositionSeries__data required: true - multivalued: false + inlined: true metric: name: metric description: The metric used, e.g. phase, amplitude, power. range: text required: true - multivalued: false bands: name: bands description: Table for describing the bands that this series was generated from. There should be one row in this table for each band. range: DecompositionSeries__bands required: true - multivalued: false + inlined: true + inlined_as_list: true source_timeseries: name: source_timeseries annotations: source_type: tag: source_type value: link - required: false - multivalued: false + inlined: true any_of: - range: TimeSeries - range: string @@ -180,9 +295,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -208,6 +347,7 @@ classes: name: name: name ifabsent: string(bands) + identifier: true range: string required: true equals_string: bands @@ -259,10 +399,21 @@ classes: name: name: name ifabsent: string(Units) + identifier: true range: string required: true - spike_times_index: - name: spike_times_index + electrode_group: + name: electrode_group + description: Electrode group that each spike unit came from. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: ElectrodeGroup + required: false + multivalued: false + inlined: true + electrodes: + name: electrodes annotations: named: tag: named @@ -270,14 +421,30 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into the spike_times dataset. + description: Electrode that each spike unit came from, specified using a DynamicTableRegion. + range: DynamicTableRegion + inlined: true + electrodes_index: + name: electrodes_index + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: Index into electrodes. range: VectorIndex - required: false - multivalued: false - spike_times: - name: spike_times - description: Spike times for each unit. - range: Units__spike_times + inlined: true + obs_intervals: + name: obs_intervals + description: Observation intervals for each unit. + array: + dimensions: + - alias: num_intervals + - alias: start_end + exact_cardinality: 2 + range: float64 required: false multivalued: false obs_intervals_index: @@ -291,21 +458,14 @@ classes: value: neurodata_type_inc description: Index into the obs_intervals dataset. range: VectorIndex - required: false - multivalued: false - obs_intervals: - name: obs_intervals - description: Observation intervals for each unit. - array: - dimensions: - - alias: num_intervals - - alias: start_end - exact_cardinality: 2 - range: float64 - required: false - multivalued: false - electrodes_index: - name: electrodes_index + inlined: true + spike_times: + name: spike_times + description: Spike times for each unit. + range: Units__spike_times + inlined: true + spike_times_index: + name: spike_times_index annotations: named: tag: named @@ -313,61 +473,19 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into electrodes. + description: Index into the spike_times dataset. range: VectorIndex - required: false - multivalued: false - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: Electrode that each spike unit came from, specified using a DynamicTableRegion. - range: DynamicTableRegion - required: false - multivalued: false - electrode_group: - name: electrode_group - description: Electrode group that each spike unit came from. - range: ElectrodeGroup - required: false - multivalued: true + inlined: true waveform_mean: name: waveform_mean description: Spike waveform mean for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_mean + inlined: true waveform_sd: name: waveform_sd description: Spike waveform standard deviation for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_sd + inlined: true tree_root: true Units__spike_times: name: Units__spike_times @@ -377,6 +495,7 @@ classes: name: name: name ifabsent: string(spike_times) + identifier: true range: string required: true equals_string: spike_times @@ -389,3 +508,51 @@ classes: for the spike time to be between samples. range: float64 required: false + Units__waveform_mean: + name: Units__waveform_mean + description: Spike waveform mean for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_mean) + identifier: true + range: string + required: true + equals_string: waveform_mean + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts + Units__waveform_sd: + name: Units__waveform_sd + description: Spike waveform standard deviation for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_sd) + identifier: true + range: string + required: true + equals_string: waveform_sd + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ogen.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ogen.yaml index 4f62a54..d903613 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ogen.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ogen.yaml @@ -21,17 +21,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Applied power for optogenetic stimulus, in watts. - array: - dimensions: - - alias: num_times - range: numeric + range: OptogeneticSeries__data required: true - multivalued: false + inlined: true site: name: site annotations: @@ -39,11 +37,58 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: OptogeneticStimulusSite - range: string tree_root: true + OptogeneticSeries__data: + name: OptogeneticSeries__data + description: Applied power for optogenetic stimulus, in watts. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for data, which is fixed to 'watts'. + ifabsent: string(watts) + range: text + required: true + equals_string: watts + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric OptogeneticStimulusSite: name: OptogeneticStimulusSite description: A site of optogenetic stimulation. @@ -51,6 +96,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -58,13 +104,11 @@ classes: description: Description of stimulation site. range: text required: true - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false location: name: location description: Location of the stimulation site. Specify the area, layer, comments @@ -72,7 +116,6 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false device: name: device annotations: @@ -80,7 +123,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ophys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ophys.yaml index 5f792da..e2b57d7 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ophys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.ophys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true pmt_gain: @@ -59,7 +60,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImagingPlane - range: string @@ -72,22 +73,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Signals from ROIs. - range: numeric + range: RoiResponseSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_rois + inlined: true rois: name: rois annotations: @@ -101,8 +95,60 @@ classes: on the ROIs stored in this timeseries. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true + RoiResponseSeries__data: + name: RoiResponseSeries__data + description: Signals from ROIs. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_rois DfOverF: name: DfOverF description: dF/F information about a region of interest (ROI). Storage hierarchy @@ -110,12 +156,19 @@ classes: for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(DfOverF) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true Fluorescence: name: Fluorescence @@ -124,12 +177,19 @@ classes: for ROIs and for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(Fluorescence) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true ImageSegmentation: name: ImageSegmentation @@ -142,12 +202,19 @@ classes: is required and ROI names should remain consistent between them. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: DynamicTable + name: + name: name + ifabsent: string(ImageSegmentation) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: DynamicTable tree_root: true ImagingPlane: name: ImagingPlane @@ -156,32 +223,28 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: name: description description: Description of the imaging plane. range: text - required: false - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false imaging_rate: name: imaging_rate description: Rate that images are acquired, in Hz. range: float32 required: true - multivalued: false indicator: name: indicator description: Calcium indicator. range: text required: true - multivalued: false location: name: location description: Location of the imaging plane. Specify the area, layer, comments @@ -189,31 +252,27 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false manifold: name: manifold description: DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing. range: ImagingPlane__manifold - required: false - multivalued: false + inlined: true origin_coords: name: origin_coords description: Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma). range: ImagingPlane__origin_coords - required: false - multivalued: false + inlined: true grid_spacing: name: grid_spacing description: Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid. range: ImagingPlane__grid_spacing - required: false - multivalued: false + inlined: true reference_frame: name: reference_frame description: Describes reference frame of origin_coords and grid_spacing. @@ -234,14 +293,13 @@ classes: axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral)." range: text - required: false - multivalued: false optical_channel: name: optical_channel description: An optical channel used to record from an imaging plane. range: OpticalChannel required: true - multivalued: false + inlined: true + inlined_as_list: true device: name: device annotations: @@ -249,7 +307,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -263,6 +321,7 @@ classes: name: name: name ifabsent: string(manifold) + identifier: true range: string required: true equals_string: manifold @@ -312,6 +371,7 @@ classes: name: name: name ifabsent: string(origin_coords) + identifier: true range: string required: true equals_string: origin_coords @@ -339,6 +399,7 @@ classes: name: name: name ifabsent: string(grid_spacing) + identifier: true range: string required: true equals_string: grid_spacing @@ -364,6 +425,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -371,13 +433,11 @@ classes: description: Description or other notes about the channel. range: text required: true - multivalued: false emission_lambda: name: emission_lambda description: Emission wavelength for channel, in nm. range: float32 required: true - multivalued: false MotionCorrection: name: MotionCorrection description: 'An image stack where all frames are shifted (registered) to a common @@ -385,10 +445,17 @@ classes: frame at each point in time is assumed to be 2-D (has only x & y dimensions).' is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface + name: + name: name + ifabsent: string(MotionCorrection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.retinotopy.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.retinotopy.yaml index 3150687..204d282 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.retinotopy.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_0/core.nwb.retinotopy.yaml @@ -21,6 +21,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true dimension: @@ -52,6 +53,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true unit: @@ -75,6 +77,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true bits_per_pixel: @@ -115,6 +118,7 @@ classes: name: name: name ifabsent: string(ImagingRetinotopy) + identifier: true range: string required: true axis_1_phase_map: @@ -129,7 +133,7 @@ classes: description: Phase response to stimulus on the first measured axis. range: AxisMap required: true - multivalued: false + inlined: true axis_1_power_map: name: axis_1_power_map annotations: @@ -142,8 +146,7 @@ classes: description: Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: AxisMap - required: false - multivalued: false + inlined: true axis_2_phase_map: name: axis_2_phase_map annotations: @@ -156,7 +159,7 @@ classes: description: Phase response to stimulus on the second measured axis. range: AxisMap required: true - multivalued: false + inlined: true axis_2_power_map: name: axis_2_power_map annotations: @@ -168,8 +171,7 @@ classes: value: neurodata_type_inc description: Power response to stimulus on the second measured axis. range: AxisMap - required: false - multivalued: false + inlined: true sign_map: name: sign_map annotations: @@ -183,7 +185,7 @@ classes: and axis_2. range: RetinotopyMap required: true - multivalued: false + inlined: true axis_descriptions: name: axis_descriptions description: Two-element array describing the contents of the two response @@ -202,7 +204,7 @@ classes: focal depth, wavelength) as data collection. Array format: [rows][columns].' range: ImagingRetinotopy__focal_depth_image required: true - multivalued: false + inlined: true vasculature_image: name: vasculature_image annotations: @@ -216,7 +218,7 @@ classes: [rows][columns]' range: RetinotopyImage required: true - multivalued: false + inlined: true tree_root: true ImagingRetinotopy__focal_depth_image: name: ImagingRetinotopy__focal_depth_image @@ -227,6 +229,7 @@ classes: name: name: name ifabsent: string(focal_depth_image) + identifier: true range: string required: true equals_string: focal_depth_image diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.base.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.base.yaml index 687baf5..079a779 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.base.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -32,6 +33,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true resolution: @@ -73,6 +75,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -84,6 +87,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -94,6 +98,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -118,15 +123,14 @@ classes: external file. range: TimeSeries__data required: true - multivalued: false + inlined: true starting_time: name: starting_time description: Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute. range: TimeSeries__starting_time - required: false - multivalued: false + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -168,8 +172,8 @@ classes: external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes. range: TimeSeries__sync - required: false - multivalued: false + inlined: true + inlined_as_list: true tree_root: true TimeSeries__data: name: TimeSeries__data @@ -180,6 +184,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data @@ -244,6 +249,7 @@ classes: name: name: name ifabsent: string(starting_time) + identifier: true range: string required: true equals_string: starting_time @@ -275,6 +281,7 @@ classes: name: name: name ifabsent: string(sync) + identifier: true range: string required: true equals_string: sync @@ -283,13 +290,24 @@ classes: description: A collection of processed data. is_a: NWBContainer attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + description: + name: description + description: Description of this collection of processed data. + range: text + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface + - range: DynamicTable tree_root: true Images: name: Images @@ -299,6 +317,7 @@ classes: name: name: name ifabsent: string(Images) + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.behavior.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.behavior.yaml index 275d786..d08990a 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.behavior.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.behavior.yaml @@ -29,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,13 +38,11 @@ classes: reference frame. range: SpatialSeries__data required: true - multivalued: false + inlined: true reference_frame: name: reference_frame description: Description defining what exactly 'straight-ahead' means. range: text - required: false - multivalued: false tree_root: true SpatialSeries__data: name: SpatialSeries__data @@ -53,9 +52,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. The default @@ -91,12 +114,19 @@ classes: events. BehavioralTimeSeries is for continuous data. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: IntervalSeries + name: + name: name + ifabsent: string(BehavioralEpochs) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: IntervalSeries tree_root: true BehavioralEvents: name: BehavioralEvents @@ -104,12 +134,19 @@ classes: for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralEvents) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true BehavioralTimeSeries: name: BehavioralTimeSeries @@ -117,36 +154,57 @@ classes: of BehavioralEpochs for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralTimeSeries) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true PupilTracking: name: PupilTracking description: Eye-tracking data, representing pupil size. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(PupilTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true EyeTracking: name: EyeTracking description: Eye-tracking data, representing direction of gaze. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(EyeTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true CompassDirection: name: CompassDirection @@ -157,22 +215,36 @@ classes: be radians or degrees. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(CompassDirection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true Position: name: Position description: Position data, whether along the x, x/y or x/y/z axis. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(Position) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.device.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.device.yaml index e0969c8..c9f3f86 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.device.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.device.yaml @@ -21,6 +21,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ecephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ecephys.yaml index ac39533..bc09762 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ecephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ecephys.yaml @@ -25,41 +25,9 @@ classes: attributes: name: name: name + identifier: true range: string required: true - data: - name: data - description: Recorded voltage data. - range: numeric - required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_channels - - array: - dimensions: - - alias: num_times - - alias: num_channels - - alias: num_samples - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: DynamicTableRegion pointer to the electrodes that this time series - was generated from. - range: DynamicTableRegion - required: true - multivalued: false channel_conversion: name: channel_conversion description: Channel-specific conversion factor. Multiply the data in the @@ -77,7 +45,87 @@ classes: range: float32 required: false multivalued: false + data: + name: data + description: Recorded voltage data. + range: ElectricalSeries__data + required: true + inlined: true + electrodes: + name: electrodes + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: DynamicTableRegion pointer to the electrodes that this time series + was generated from. + range: DynamicTableRegion + required: true + inlined: true tree_root: true + ElectricalSeries__data: + name: ElectricalSeries__data + description: Recorded voltage data. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. This value + is fixed to 'volts'. Actual stored values are not necessarily stored in + these units. To access the data in these units, multiply 'data' by 'conversion' + and 'channel_conversion' (if present). + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_channels + - array: + dimensions: + - alias: num_times + - alias: num_channels + - alias: num_samples SpikeEventSeries: name: SpikeEventSeries description: 'Stores snapshots/snippets of recorded spike events (i.e., threshold @@ -92,24 +140,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Spike waveforms. - range: numeric + range: SpikeEventSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_events - - alias: num_samples - - array: - dimensions: - - alias: num_events - - alias: num_channels - - alias: num_samples + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -123,6 +162,60 @@ classes: required: true multivalued: false tree_root: true + SpikeEventSeries__data: + name: SpikeEventSeries__data + description: Spike waveforms. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for waveforms, which is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_events + - alias: num_samples + - array: + dimensions: + - alias: num_events + - alias: num_channels + - alias: num_samples FeatureExtraction: name: FeatureExtraction description: Features, such as PC1 and PC2, that are extracted from signals stored @@ -132,6 +225,7 @@ classes: name: name: name ifabsent: string(FeatureExtraction) + identifier: true range: string required: true description: @@ -177,7 +271,7 @@ classes: was generated from. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true EventDetection: name: EventDetection @@ -187,6 +281,7 @@ classes: name: name: name ifabsent: string(EventDetection) + identifier: true range: string required: true detection_method: @@ -195,7 +290,6 @@ classes: or dV/dT threshold, as well as relevant values. range: text required: true - multivalued: false source_idx: name: source_idx description: Indices (zero-based) into source ElectricalSeries::data array @@ -224,7 +318,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ElectricalSeries - range: string @@ -236,12 +330,19 @@ classes: during experiment acquisition. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpikeEventSeries + name: + name: name + ifabsent: string(EventWaveform) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpikeEventSeries tree_root: true FilteredEphys: name: FilteredEphys @@ -258,12 +359,19 @@ classes: the ElectricalSeries. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(FilteredEphys) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true LFP: name: LFP @@ -272,12 +380,19 @@ classes: properties should be noted in the ElectricalSeries description or comments field. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(LFP) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true ElectrodeGroup: name: ElectrodeGroup @@ -286,6 +401,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -304,8 +420,7 @@ classes: name: position description: stereotaxic or common framework coordinates range: ElectrodeGroup__position - required: false - multivalued: false + inlined: true device: name: device annotations: @@ -313,7 +428,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -325,6 +440,7 @@ classes: name: name: name ifabsent: string(position) + identifier: true range: string required: true equals_string: position @@ -334,24 +450,18 @@ classes: array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false y: name: y description: y coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false z: name: z description: z coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false ClusterWaveforms: name: ClusterWaveforms description: DEPRECATED The mean waveform shape, including standard deviation, @@ -365,6 +475,7 @@ classes: name: name: name ifabsent: string(ClusterWaveforms) + identifier: true range: string required: true waveform_filtering: @@ -372,7 +483,6 @@ classes: description: Filtering applied to data before generating mean/sd range: text required: true - multivalued: false waveform_mean: name: waveform_mean description: The mean waveform for each cluster, using the same indices for @@ -404,7 +514,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Clustering - range: string @@ -418,6 +528,7 @@ classes: name: name: name ifabsent: string(Clustering) + identifier: true range: string required: true description: @@ -426,7 +537,6 @@ classes: clusters curated using Klusters, etc) range: text required: true - multivalued: false num: name: num description: Cluster number of each event diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.epoch.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.epoch.yaml index e7e66c5..a35bbd9 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.epoch.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.epoch.yaml @@ -22,6 +22,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true start_time: @@ -62,14 +63,12 @@ classes: value: neurodata_type_inc description: Index for tags. range: VectorIndex - required: false - multivalued: false + inlined: true timeseries: name: timeseries description: An index into a TimeSeries object. range: TimeIntervals__timeseries - required: false - multivalued: false + inlined: true timeseries_index: name: timeseries_index annotations: @@ -81,8 +80,7 @@ classes: value: neurodata_type_inc description: Index for timeseries. range: VectorIndex - required: false - multivalued: false + inlined: true tree_root: true TimeIntervals__timeseries: name: TimeIntervals__timeseries @@ -92,6 +90,7 @@ classes: name: name: name ifabsent: string(timeseries) + identifier: true range: string required: true equals_string: timeseries @@ -103,8 +102,6 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false count: name: count description: Number of data samples available in this time series, during @@ -112,13 +109,10 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false timeseries: name: timeseries description: the TimeSeries that this index applies to. array: exact_number_dimensions: 1 range: TimeSeries - required: false - multivalued: false + inlined: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.file.yaml index 2b01096..9d303fd 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.file.yaml @@ -30,6 +30,7 @@ classes: name: name: name ifabsent: string(root) + identifier: true range: string required: true equals_string: root @@ -64,13 +65,11 @@ classes: other files. range: text required: true - multivalued: false session_description: name: session_description description: A description of the experimental session and data in the file. range: text required: true - multivalued: false session_start_time: name: session_start_time description: 'Date and time of the experiment/session start. The date is stored @@ -79,7 +78,6 @@ classes: offset. Date accuracy is up to milliseconds.' range: isodatetime required: true - multivalued: false timestamps_reference_time: name: timestamps_reference_time description: 'Date and time corresponding to time zero of all timestamps. @@ -89,7 +87,6 @@ classes: times stored in the file use this time as reference (i.e., time zero).' range: isodatetime required: true - multivalued: false acquisition: name: acquisition description: Data streams recorded from the system, including ephys, ophys, @@ -168,7 +165,8 @@ classes: can exist in the present file or can be linked to a remote library file. range: NWBFile__stimulus required: true - multivalued: false + inlined: true + inlined_as_list: true general: name: general description: Experimental metadata, including protocol, notes and description @@ -188,7 +186,8 @@ classes: should not be created unless there is data to store within them. range: NWBFile__general required: true - multivalued: false + inlined: true + inlined_as_list: true intervals: name: intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -196,14 +195,18 @@ classes: an experiment, or epochs (see epochs subgroup) deriving from analysis of data. range: NWBFile__intervals - required: false - multivalued: false + inlined: true + inlined_as_list: true units: name: units description: Data about sorted spike units. range: Units - required: false - multivalued: false + inlined: true + inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -223,6 +226,7 @@ classes: name: name: name ifabsent: string(stimulus) + identifier: true range: string required: true equals_string: stimulus @@ -265,6 +269,7 @@ classes: name: name: name ifabsent: string(general) + identifier: true range: string required: true equals_string: general @@ -272,14 +277,10 @@ classes: name: data_collection description: Notes about data collection and analysis. range: text - required: false - multivalued: false experiment_description: name: experiment_description description: General description of the experiment. range: text - required: false - multivalued: false experimenter: name: experimenter description: Name of person(s) who performed the experiment. Can also specify @@ -294,8 +295,6 @@ classes: name: institution description: Institution(s) where experiment was performed. range: text - required: false - multivalued: false keywords: name: keywords description: Terms to search over. @@ -309,28 +308,20 @@ classes: name: lab description: Laboratory where experiment was performed. range: text - required: false - multivalued: false notes: name: notes description: Notes about the experiment. range: text - required: false - multivalued: false pharmacology: name: pharmacology description: Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc. range: text - required: false - multivalued: false protocol: name: protocol description: Experimental protocol, if applicable. e.g., include IACUC protocol number. range: text - required: false - multivalued: false related_publications: name: related_publications description: Publication information. PMID, DOI, URL, etc. @@ -344,49 +335,39 @@ classes: name: session_id description: Lab-specific ID for the session. range: text - required: false - multivalued: false slices: name: slices description: Description of slices, including information about preparation thickness, orientation, temperature, and bath solution. range: text - required: false - multivalued: false source_script: name: source_script description: Script file or link to public source code used to create this NWB file. range: general__source_script - required: false - multivalued: false + inlined: true stimulus: name: stimulus description: Notes about stimuli, such as how and where they were presented. range: text - required: false - multivalued: false surgery: name: surgery description: Narrative description about surgery/surgeries, including date(s) and who performed surgery. range: text - required: false - multivalued: false virus: name: virus description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - required: false - multivalued: false nwb_container: name: nwb_container description: Place-holder than can be extended so that lab-specific meta-data can be placed in /general. range: NWBContainer - required: false multivalued: true + inlined: true + inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -401,20 +382,20 @@ classes: description: Information about the animal or person from which the data was measured. range: Subject - required: false - multivalued: false + inlined: true + inlined_as_list: true extracellular_ephys: name: extracellular_ephys description: Metadata related to extracellular electrophysiology. range: general__extracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true intracellular_ephys: name: intracellular_ephys description: Metadata related to intracellular electrophysiology. range: general__intracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true optogenetics: name: optogenetics description: Metadata describing optogenetic stimuluation. @@ -439,6 +420,7 @@ classes: name: name: name ifabsent: string(source_script) + identifier: true range: string required: true equals_string: source_script @@ -459,6 +441,7 @@ classes: name: name: name ifabsent: string(subject) + identifier: true range: string required: true equals_string: subject @@ -466,52 +449,36 @@ classes: name: age description: Age of subject. Can be supplied instead of 'date_of_birth'. range: text - required: false - multivalued: false date_of_birth: name: date_of_birth description: Date of birth of subject. Can be supplied instead of 'age'. range: isodatetime - required: false - multivalued: false description: name: description description: Description of subject and where subject came from (e.g., breeder, if animal). range: text - required: false - multivalued: false genotype: name: genotype description: Genetic strain. If absent, assume Wild Type (WT). range: text - required: false - multivalued: false sex: name: sex description: Gender of subject. range: text - required: false - multivalued: false species: name: species description: Species of subject. range: text - required: false - multivalued: false subject_id: name: subject_id description: ID of animal/person used/participating in experiment (lab convention). range: text - required: false - multivalued: false weight: name: weight description: Weight at time of experiment, at time of surgery and at other important times. range: text - required: false - multivalued: false general__extracellular_ephys: name: general__extracellular_ephys description: Metadata related to extracellular electrophysiology. @@ -519,21 +486,23 @@ classes: name: name: name ifabsent: string(extracellular_ephys) + identifier: true range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - required: false - multivalued: true electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes - required: false - multivalued: false + inlined: true + inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -542,6 +511,7 @@ classes: name: name: name ifabsent: string(electrodes) + identifier: true range: string required: true equals_string: electrodes @@ -604,9 +574,13 @@ classes: group: name: group description: Reference to the ElectrodeGroup this electrode is a part of. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: ElectrodeGroup required: true - multivalued: true + multivalued: false + inlined: true group_name: name: group_name description: Name of the ElectrodeGroup this electrode is a part of. @@ -659,6 +633,7 @@ classes: name: name: name ifabsent: string(intracellular_ephys) + identifier: true range: string required: true equals_string: intracellular_ephys @@ -668,20 +643,19 @@ classes: frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries. range: text - required: false - multivalued: false - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - required: false - multivalued: true sweep_table: name: sweep_table description: The table which groups different PatchClampSeries together. range: SweepTable - required: false - multivalued: false + inlined: true + inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -691,6 +665,7 @@ classes: name: name: name ifabsent: string(intervals) + identifier: true range: string required: true equals_string: intervals @@ -699,24 +674,25 @@ classes: description: Divisions in time marking experimental stages or sub-divisions of a single recording session. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false trials: name: trials description: Repeated experimental events that have a logical grouping. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false invalid_times: name: invalid_times description: Time intervals that should be removed from analysis. range: TimeIntervals - required: false - multivalued: false - time_intervals: - name: time_intervals + inlined: true + inlined_as_list: false + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals - required: false multivalued: true + inlined: true + inlined_as_list: false diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.icephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.icephys.yaml index 11c4893..1f8696c 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.icephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.icephys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true stimulus_description: @@ -40,14 +41,12 @@ classes: description: Recorded voltage or current. range: PatchClampSeries__data required: true - multivalued: false + inlined: true gain: name: gain description: Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp). range: float32 - required: false - multivalued: false electrode: name: electrode annotations: @@ -55,7 +54,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: IntracellularElectrode - range: string @@ -67,9 +66,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -92,32 +115,27 @@ classes: attributes: name: name: name + identifier: true range: string required: true + bias_current: + name: bias_current + description: Bias current, in amps. + range: float32 + bridge_balance: + name: bridge_balance + description: Bridge balance, in ohms. + range: float32 + capacitance_compensation: + name: capacitance_compensation + description: Capacitance compensation, in farads. + range: float32 data: name: data description: Recorded voltage. range: CurrentClampSeries__data required: true - multivalued: false - bias_current: - name: bias_current - description: Bias current, in amps. - range: float32 - required: false - multivalued: false - bridge_balance: - name: bridge_balance - description: Bridge balance, in ohms. - range: float32 - required: false - multivalued: false - capacitance_compensation: - name: capacitance_compensation - description: Capacitance compensation, in farads. - range: float32 - required: false - multivalued: false + inlined: true tree_root: true CurrentClampSeries__data: name: CurrentClampSeries__data @@ -126,9 +144,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -140,8 +182,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IZeroClampSeries: name: IZeroClampSeries description: Voltage data from an intracellular recording when all current and @@ -152,6 +196,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true bias_current: @@ -159,19 +204,16 @@ classes: description: Bias current, in amps, fixed to 0.0. range: float32 required: true - multivalued: false bridge_balance: name: bridge_balance description: Bridge balance, in ohms, fixed to 0.0. range: float32 required: true - multivalued: false capacitance_compensation: name: capacitance_compensation description: Capacitance compensation, in farads, fixed to 0.0. range: float32 required: true - multivalued: false tree_root: true CurrentClampStimulusSeries: name: CurrentClampStimulusSeries @@ -180,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -187,7 +230,7 @@ classes: description: Stimulus current applied. range: CurrentClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true CurrentClampStimulusSeries__data: name: CurrentClampStimulusSeries__data @@ -196,9 +239,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -210,8 +277,10 @@ classes: equals_string: amperes value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries: name: VoltageClampSeries description: Current data from an intracellular voltage-clamp recording. A corresponding @@ -221,80 +290,51 @@ classes: attributes: name: name: name + identifier: true range: string required: true + capacitance_fast: + name: capacitance_fast + description: Fast capacitance, in farads. + range: VoltageClampSeries__capacitance_fast + inlined: true + capacitance_slow: + name: capacitance_slow + description: Slow capacitance, in farads. + range: VoltageClampSeries__capacitance_slow + inlined: true data: name: data description: Recorded current. range: VoltageClampSeries__data required: true - multivalued: false - capacitance_fast: - name: capacitance_fast - description: Fast capacitance, in farads. - range: VoltageClampSeries__capacitance_fast - required: false - multivalued: false - capacitance_slow: - name: capacitance_slow - description: Slow capacitance, in farads. - range: VoltageClampSeries__capacitance_slow - required: false - multivalued: false + inlined: true resistance_comp_bandwidth: name: resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. range: VoltageClampSeries__resistance_comp_bandwidth - required: false - multivalued: false + inlined: true resistance_comp_correction: name: resistance_comp_correction description: Resistance compensation correction, in percent. range: VoltageClampSeries__resistance_comp_correction - required: false - multivalued: false + inlined: true resistance_comp_prediction: name: resistance_comp_prediction description: Resistance compensation prediction, in percent. range: VoltageClampSeries__resistance_comp_prediction - required: false - multivalued: false + inlined: true whole_cell_capacitance_comp: name: whole_cell_capacitance_comp description: Whole cell capacitance compensation, in farads. range: VoltageClampSeries__whole_cell_capacitance_comp - required: false - multivalued: false + inlined: true whole_cell_series_resistance_comp: name: whole_cell_series_resistance_comp description: Whole cell series resistance compensation, in ohms. range: VoltageClampSeries__whole_cell_series_resistance_comp - required: false - multivalued: false + inlined: true tree_root: true - VoltageClampSeries__data: - name: VoltageClampSeries__data - description: Recorded current. - attributes: - name: - name: name - ifabsent: string(data) - range: string - required: true - equals_string: data - unit: - name: unit - description: Base unit of measurement for working with the data. which is - fixed to 'amperes'. Actual stored values are not necessarily stored in these - units. To access the data in these units, multiply 'data' by 'conversion'. - ifabsent: string(amperes) - range: text - required: true - equals_string: amperes - value: - name: value - range: AnyType - required: true VoltageClampSeries__capacitance_fast: name: VoltageClampSeries__capacitance_fast description: Fast capacitance, in farads. @@ -302,6 +342,7 @@ classes: name: name: name ifabsent: string(capacitance_fast) + identifier: true range: string required: true equals_string: capacitance_fast @@ -323,6 +364,7 @@ classes: name: name: name ifabsent: string(capacitance_slow) + identifier: true range: string required: true equals_string: capacitance_slow @@ -337,6 +379,55 @@ classes: name: value range: float32 required: true + VoltageClampSeries__data: + name: VoltageClampSeries__data + description: Recorded current. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. which is + fixed to 'amperes'. Actual stored values are not necessarily stored in these + units. To access the data in these units, multiply 'data' by 'conversion'. + ifabsent: string(amperes) + range: text + required: true + equals_string: amperes + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries__resistance_comp_bandwidth: name: VoltageClampSeries__resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. @@ -344,6 +435,7 @@ classes: name: name: name ifabsent: string(resistance_comp_bandwidth) + identifier: true range: string required: true equals_string: resistance_comp_bandwidth @@ -366,6 +458,7 @@ classes: name: name: name ifabsent: string(resistance_comp_correction) + identifier: true range: string required: true equals_string: resistance_comp_correction @@ -388,6 +481,7 @@ classes: name: name: name ifabsent: string(resistance_comp_prediction) + identifier: true range: string required: true equals_string: resistance_comp_prediction @@ -410,6 +504,7 @@ classes: name: name: name ifabsent: string(whole_cell_capacitance_comp) + identifier: true range: string required: true equals_string: whole_cell_capacitance_comp @@ -432,6 +527,7 @@ classes: name: name: name ifabsent: string(whole_cell_series_resistance_comp) + identifier: true range: string required: true equals_string: whole_cell_series_resistance_comp @@ -454,6 +550,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -461,7 +558,7 @@ classes: description: Stimulus voltage applied. range: VoltageClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true VoltageClampStimulusSeries__data: name: VoltageClampStimulusSeries__data @@ -470,9 +567,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -484,8 +605,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IntracellularElectrode: name: IntracellularElectrode description: An intracellular electrode and its metadata. @@ -493,6 +616,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -500,45 +624,32 @@ classes: description: Description of electrode (e.g., whole-cell, sharp, etc.). range: text required: true - multivalued: false filtering: name: filtering description: Electrode specific filtering. range: text - required: false - multivalued: false initial_access_resistance: name: initial_access_resistance description: Initial access resistance. range: text - required: false - multivalued: false location: name: location description: Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. range: text - required: false - multivalued: false resistance: name: resistance description: Electrode resistance, in ohms. range: text - required: false - multivalued: false seal: name: seal description: Information about seal used for recording. range: text - required: false - multivalued: false slice: name: slice description: Information about slice used for recording. range: text - required: false - multivalued: false device: name: device annotations: @@ -546,7 +657,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -558,23 +669,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true - sweep_number: - name: sweep_number - description: Sweep number of the PatchClampSeries in that row. - array: - minimum_number_dimensions: 1 - maximum_number_dimensions: false - range: uint32 - required: true - multivalued: false series: name: series description: The PatchClampSeries with the sweep number in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: PatchClampSeries required: true - multivalued: true + multivalued: false + inlined: true series_index: name: series_index annotations: @@ -587,5 +694,14 @@ classes: description: Index for series. range: VectorIndex required: true + inlined: true + sweep_number: + name: sweep_number + description: Sweep number of the PatchClampSeries in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: uint32 + required: true multivalued: false tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.image.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.image.yaml index 785ebbb..587b8d9 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.image.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.image.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -37,6 +38,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -56,6 +58,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -80,26 +83,14 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Binary data representing images across frames. - range: numeric - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - alias: z + range: ImageSeries__data + inlined: true dimension: name: dimension description: Number of pixels on x, y, (and z) axes. @@ -117,18 +108,72 @@ classes: used if the image is stored in another NWB file and that file is linked to this file. range: ImageSeries__external_file - required: false - multivalued: false + inlined: true format: name: format description: Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed. + ifabsent: string(raw) range: text - required: false - multivalued: false tree_root: true + ImageSeries__data: + name: ImageSeries__data + description: Binary data representing images across frames. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - alias: z ImageSeries__external_file: name: ImageSeries__external_file description: Paths to one or more external file(s). The field is only present @@ -139,6 +184,7 @@ classes: name: name: name ifabsent: string(external_file) + identifier: true range: string required: true equals_string: external_file @@ -176,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true masked_imageseries: @@ -185,7 +232,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string @@ -201,14 +248,13 @@ classes: attributes: name: name: name + identifier: true range: string required: true distance: name: distance description: Distance from camera/monitor to target/eye. range: float32 - required: false - multivalued: false field_of_view: name: field_of_view description: Width, height and depth of image, or imaged area, in meters. @@ -229,8 +275,6 @@ classes: description: Description of image relative to some reference frame (e.g., which way is up). Must also specify frame of reference. range: text - required: false - multivalued: false tree_root: true IndexSeries: name: IndexSeries @@ -244,17 +288,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Index of the frame in the referenced ImageSeries. - array: - dimensions: - - alias: num_times - range: int32 + range: IndexSeries__data required: true - multivalued: false + inlined: true indexed_timeseries: name: indexed_timeseries annotations: @@ -262,8 +304,55 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string tree_root: true + IndexSeries__data: + name: IndexSeries__data + description: Index of the frame in the referenced ImageSeries. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + array: + dimensions: + - alias: num_times + range: int32 diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.language.yaml index e42c742..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.misc.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.misc.yaml index 59ff81b..b567eec 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.misc.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.misc.yaml @@ -30,6 +30,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,7 +38,7 @@ classes: description: Values of each feature at each time. range: AbstractFeatureSeries__data required: true - multivalued: false + inlined: true feature_units: name: feature_units description: Units of each feature. @@ -64,9 +65,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Since there can be different units for different features, store @@ -96,18 +121,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Annotations made during an experiment. + range: AnnotationSeries__data + required: true + inlined: true + tree_root: true + AnnotationSeries__data: + name: AnnotationSeries__data + description: Annotations made during an experiment. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: text - required: true - multivalued: false - tree_root: true IntervalSeries: name: IntervalSeries description: Stores intervals of data. The timestamps field stores the beginning @@ -121,18 +191,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Use values >0 if interval started, <0 if interval ended. + range: IntervalSeries__data + required: true + inlined: true + tree_root: true + IntervalSeries__data: + name: IntervalSeries__data + description: Use values >0 if interval started, <0 if interval ended. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: int8 - required: true - multivalued: false - tree_root: true DecompositionSeries: name: DecompositionSeries description: Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -140,6 +255,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -147,28 +263,27 @@ classes: description: Data decomposed into frequency bands. range: DecompositionSeries__data required: true - multivalued: false + inlined: true metric: name: metric description: The metric used, e.g. phase, amplitude, power. range: text required: true - multivalued: false bands: name: bands description: Table for describing the bands that this series was generated from. There should be one row in this table for each band. range: DecompositionSeries__bands required: true - multivalued: false + inlined: true + inlined_as_list: true source_timeseries: name: source_timeseries annotations: source_type: tag: source_type value: link - required: false - multivalued: false + inlined: true any_of: - range: TimeSeries - range: string @@ -180,9 +295,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -208,6 +347,7 @@ classes: name: name: name ifabsent: string(bands) + identifier: true range: string required: true equals_string: bands @@ -259,10 +399,21 @@ classes: name: name: name ifabsent: string(Units) + identifier: true range: string required: true - spike_times_index: - name: spike_times_index + electrode_group: + name: electrode_group + description: Electrode group that each spike unit came from. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: ElectrodeGroup + required: false + multivalued: false + inlined: true + electrodes: + name: electrodes annotations: named: tag: named @@ -270,14 +421,30 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into the spike_times dataset. + description: Electrode that each spike unit came from, specified using a DynamicTableRegion. + range: DynamicTableRegion + inlined: true + electrodes_index: + name: electrodes_index + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: Index into electrodes. range: VectorIndex - required: false - multivalued: false - spike_times: - name: spike_times - description: Spike times for each unit. - range: Units__spike_times + inlined: true + obs_intervals: + name: obs_intervals + description: Observation intervals for each unit. + array: + dimensions: + - alias: num_intervals + - alias: start_end + exact_cardinality: 2 + range: float64 required: false multivalued: false obs_intervals_index: @@ -291,21 +458,14 @@ classes: value: neurodata_type_inc description: Index into the obs_intervals dataset. range: VectorIndex - required: false - multivalued: false - obs_intervals: - name: obs_intervals - description: Observation intervals for each unit. - array: - dimensions: - - alias: num_intervals - - alias: start_end - exact_cardinality: 2 - range: float64 - required: false - multivalued: false - electrodes_index: - name: electrodes_index + inlined: true + spike_times: + name: spike_times + description: Spike times for each unit. + range: Units__spike_times + inlined: true + spike_times_index: + name: spike_times_index annotations: named: tag: named @@ -313,61 +473,19 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into electrodes. + description: Index into the spike_times dataset. range: VectorIndex - required: false - multivalued: false - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: Electrode that each spike unit came from, specified using a DynamicTableRegion. - range: DynamicTableRegion - required: false - multivalued: false - electrode_group: - name: electrode_group - description: Electrode group that each spike unit came from. - range: ElectrodeGroup - required: false - multivalued: true + inlined: true waveform_mean: name: waveform_mean description: Spike waveform mean for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_mean + inlined: true waveform_sd: name: waveform_sd description: Spike waveform standard deviation for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_sd + inlined: true tree_root: true Units__spike_times: name: Units__spike_times @@ -377,6 +495,7 @@ classes: name: name: name ifabsent: string(spike_times) + identifier: true range: string required: true equals_string: spike_times @@ -389,3 +508,51 @@ classes: for the spike time to be between samples. range: float64 required: false + Units__waveform_mean: + name: Units__waveform_mean + description: Spike waveform mean for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_mean) + identifier: true + range: string + required: true + equals_string: waveform_mean + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts + Units__waveform_sd: + name: Units__waveform_sd + description: Spike waveform standard deviation for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_sd) + identifier: true + range: string + required: true + equals_string: waveform_sd + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ogen.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ogen.yaml index 61e640c..430c11c 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ogen.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ogen.yaml @@ -21,17 +21,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Applied power for optogenetic stimulus, in watts. - array: - dimensions: - - alias: num_times - range: numeric + range: OptogeneticSeries__data required: true - multivalued: false + inlined: true site: name: site annotations: @@ -39,11 +37,58 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: OptogeneticStimulusSite - range: string tree_root: true + OptogeneticSeries__data: + name: OptogeneticSeries__data + description: Applied power for optogenetic stimulus, in watts. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for data, which is fixed to 'watts'. + ifabsent: string(watts) + range: text + required: true + equals_string: watts + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric OptogeneticStimulusSite: name: OptogeneticStimulusSite description: A site of optogenetic stimulation. @@ -51,6 +96,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -58,13 +104,11 @@ classes: description: Description of stimulation site. range: text required: true - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false location: name: location description: Location of the stimulation site. Specify the area, layer, comments @@ -72,7 +116,6 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false device: name: device annotations: @@ -80,7 +123,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ophys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ophys.yaml index 0744a1f..e454bf4 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ophys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.ophys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true pmt_gain: @@ -59,7 +60,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImagingPlane - range: string @@ -72,22 +73,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Signals from ROIs. - range: numeric + range: RoiResponseSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_rois + inlined: true rois: name: rois annotations: @@ -101,8 +95,60 @@ classes: on the ROIs stored in this timeseries. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true + RoiResponseSeries__data: + name: RoiResponseSeries__data + description: Signals from ROIs. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_rois DfOverF: name: DfOverF description: dF/F information about a region of interest (ROI). Storage hierarchy @@ -110,12 +156,19 @@ classes: for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(DfOverF) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true Fluorescence: name: Fluorescence @@ -124,12 +177,19 @@ classes: for ROIs and for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(Fluorescence) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true ImageSegmentation: name: ImageSegmentation @@ -142,12 +202,19 @@ classes: is required and ROI names should remain consistent between them. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: DynamicTable + name: + name: name + ifabsent: string(ImageSegmentation) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: DynamicTable tree_root: true ImagingPlane: name: ImagingPlane @@ -156,32 +223,28 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: name: description description: Description of the imaging plane. range: text - required: false - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false imaging_rate: name: imaging_rate description: Rate that images are acquired, in Hz. range: float32 required: true - multivalued: false indicator: name: indicator description: Calcium indicator. range: text required: true - multivalued: false location: name: location description: Location of the imaging plane. Specify the area, layer, comments @@ -189,31 +252,27 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false manifold: name: manifold description: DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing. range: ImagingPlane__manifold - required: false - multivalued: false + inlined: true origin_coords: name: origin_coords description: Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma). range: ImagingPlane__origin_coords - required: false - multivalued: false + inlined: true grid_spacing: name: grid_spacing description: Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid. range: ImagingPlane__grid_spacing - required: false - multivalued: false + inlined: true reference_frame: name: reference_frame description: Describes reference frame of origin_coords and grid_spacing. @@ -234,14 +293,13 @@ classes: axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral)." range: text - required: false - multivalued: false optical_channel: name: optical_channel description: An optical channel used to record from an imaging plane. range: OpticalChannel required: true - multivalued: false + inlined: true + inlined_as_list: true device: name: device annotations: @@ -249,7 +307,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -263,6 +321,7 @@ classes: name: name: name ifabsent: string(manifold) + identifier: true range: string required: true equals_string: manifold @@ -312,6 +371,7 @@ classes: name: name: name ifabsent: string(origin_coords) + identifier: true range: string required: true equals_string: origin_coords @@ -339,6 +399,7 @@ classes: name: name: name ifabsent: string(grid_spacing) + identifier: true range: string required: true equals_string: grid_spacing @@ -364,6 +425,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -371,13 +433,11 @@ classes: description: Description or other notes about the channel. range: text required: true - multivalued: false emission_lambda: name: emission_lambda description: Emission wavelength for channel, in nm. range: float32 required: true - multivalued: false MotionCorrection: name: MotionCorrection description: 'An image stack where all frames are shifted (registered) to a common @@ -385,10 +445,17 @@ classes: frame at each point in time is assumed to be 2-D (has only x & y dimensions).' is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface + name: + name: name + ifabsent: string(MotionCorrection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.retinotopy.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.retinotopy.yaml index 8543f50..b2dea56 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.retinotopy.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_1/core.nwb.retinotopy.yaml @@ -21,6 +21,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true dimension: @@ -52,6 +53,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true unit: @@ -75,6 +77,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true bits_per_pixel: @@ -115,6 +118,7 @@ classes: name: name: name ifabsent: string(ImagingRetinotopy) + identifier: true range: string required: true axis_1_phase_map: @@ -129,7 +133,7 @@ classes: description: Phase response to stimulus on the first measured axis. range: AxisMap required: true - multivalued: false + inlined: true axis_1_power_map: name: axis_1_power_map annotations: @@ -142,8 +146,7 @@ classes: description: Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: AxisMap - required: false - multivalued: false + inlined: true axis_2_phase_map: name: axis_2_phase_map annotations: @@ -156,7 +159,7 @@ classes: description: Phase response to stimulus on the second measured axis. range: AxisMap required: true - multivalued: false + inlined: true axis_2_power_map: name: axis_2_power_map annotations: @@ -168,8 +171,7 @@ classes: value: neurodata_type_inc description: Power response to stimulus on the second measured axis. range: AxisMap - required: false - multivalued: false + inlined: true sign_map: name: sign_map annotations: @@ -183,7 +185,7 @@ classes: and axis_2. range: RetinotopyMap required: true - multivalued: false + inlined: true axis_descriptions: name: axis_descriptions description: Two-element array describing the contents of the two response @@ -202,7 +204,7 @@ classes: focal depth, wavelength) as data collection. Array format: [rows][columns].' range: ImagingRetinotopy__focal_depth_image required: true - multivalued: false + inlined: true vasculature_image: name: vasculature_image annotations: @@ -216,7 +218,7 @@ classes: [rows][columns]' range: RetinotopyImage required: true - multivalued: false + inlined: true tree_root: true ImagingRetinotopy__focal_depth_image: name: ImagingRetinotopy__focal_depth_image @@ -227,6 +229,7 @@ classes: name: name: name ifabsent: string(focal_depth_image) + identifier: true range: string required: true equals_string: focal_depth_image diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.base.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.base.yaml index 01c72b7..cf2d21c 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.base.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -32,6 +33,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true resolution: @@ -73,6 +75,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -84,6 +87,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -94,6 +98,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -118,15 +123,14 @@ classes: external file. range: TimeSeries__data required: true - multivalued: false + inlined: true starting_time: name: starting_time description: Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute. range: TimeSeries__starting_time - required: false - multivalued: false + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -168,8 +172,8 @@ classes: external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes. range: TimeSeries__sync - required: false - multivalued: false + inlined: true + inlined_as_list: true tree_root: true TimeSeries__data: name: TimeSeries__data @@ -180,6 +184,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data @@ -244,6 +249,7 @@ classes: name: name: name ifabsent: string(starting_time) + identifier: true range: string required: true equals_string: starting_time @@ -275,6 +281,7 @@ classes: name: name: name ifabsent: string(sync) + identifier: true range: string required: true equals_string: sync @@ -283,13 +290,24 @@ classes: description: A collection of processed data. is_a: NWBContainer attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + description: + name: description + description: Description of this collection of processed data. + range: text + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface + - range: DynamicTable tree_root: true Images: name: Images @@ -299,6 +317,7 @@ classes: name: name: name ifabsent: string(Images) + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.behavior.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.behavior.yaml index 9bd385a..0b67766 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.behavior.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.behavior.yaml @@ -29,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,13 +38,11 @@ classes: reference frame. range: SpatialSeries__data required: true - multivalued: false + inlined: true reference_frame: name: reference_frame description: Description defining what exactly 'straight-ahead' means. range: text - required: false - multivalued: false tree_root: true SpatialSeries__data: name: SpatialSeries__data @@ -53,9 +52,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. The default @@ -91,12 +114,19 @@ classes: events. BehavioralTimeSeries is for continuous data. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: IntervalSeries + name: + name: name + ifabsent: string(BehavioralEpochs) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: IntervalSeries tree_root: true BehavioralEvents: name: BehavioralEvents @@ -104,12 +134,19 @@ classes: for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralEvents) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true BehavioralTimeSeries: name: BehavioralTimeSeries @@ -117,36 +154,57 @@ classes: of BehavioralEpochs for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralTimeSeries) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true PupilTracking: name: PupilTracking description: Eye-tracking data, representing pupil size. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(PupilTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true EyeTracking: name: EyeTracking description: Eye-tracking data, representing direction of gaze. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(EyeTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true CompassDirection: name: CompassDirection @@ -157,22 +215,36 @@ classes: be radians or degrees. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(CompassDirection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true Position: name: Position description: Position data, whether along the x, x/y or x/y/z axis. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(Position) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.device.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.device.yaml index 2f26c6a..961b6ae 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.device.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.device.yaml @@ -21,6 +21,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ecephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ecephys.yaml index 89484e3..f0592f8 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ecephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ecephys.yaml @@ -25,41 +25,9 @@ classes: attributes: name: name: name + identifier: true range: string required: true - data: - name: data - description: Recorded voltage data. - range: numeric - required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_channels - - array: - dimensions: - - alias: num_times - - alias: num_channels - - alias: num_samples - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: DynamicTableRegion pointer to the electrodes that this time series - was generated from. - range: DynamicTableRegion - required: true - multivalued: false channel_conversion: name: channel_conversion description: Channel-specific conversion factor. Multiply the data in the @@ -77,7 +45,87 @@ classes: range: float32 required: false multivalued: false + data: + name: data + description: Recorded voltage data. + range: ElectricalSeries__data + required: true + inlined: true + electrodes: + name: electrodes + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: DynamicTableRegion pointer to the electrodes that this time series + was generated from. + range: DynamicTableRegion + required: true + inlined: true tree_root: true + ElectricalSeries__data: + name: ElectricalSeries__data + description: Recorded voltage data. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. This value + is fixed to 'volts'. Actual stored values are not necessarily stored in + these units. To access the data in these units, multiply 'data' by 'conversion' + and 'channel_conversion' (if present). + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_channels + - array: + dimensions: + - alias: num_times + - alias: num_channels + - alias: num_samples SpikeEventSeries: name: SpikeEventSeries description: 'Stores snapshots/snippets of recorded spike events (i.e., threshold @@ -92,24 +140,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Spike waveforms. - range: numeric + range: SpikeEventSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_events - - alias: num_samples - - array: - dimensions: - - alias: num_events - - alias: num_channels - - alias: num_samples + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -123,6 +162,60 @@ classes: required: true multivalued: false tree_root: true + SpikeEventSeries__data: + name: SpikeEventSeries__data + description: Spike waveforms. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for waveforms, which is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_events + - alias: num_samples + - array: + dimensions: + - alias: num_events + - alias: num_channels + - alias: num_samples FeatureExtraction: name: FeatureExtraction description: Features, such as PC1 and PC2, that are extracted from signals stored @@ -132,6 +225,7 @@ classes: name: name: name ifabsent: string(FeatureExtraction) + identifier: true range: string required: true description: @@ -177,7 +271,7 @@ classes: was generated from. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true EventDetection: name: EventDetection @@ -187,6 +281,7 @@ classes: name: name: name ifabsent: string(EventDetection) + identifier: true range: string required: true detection_method: @@ -195,7 +290,6 @@ classes: or dV/dT threshold, as well as relevant values. range: text required: true - multivalued: false source_idx: name: source_idx description: Indices (zero-based) into source ElectricalSeries::data array @@ -224,7 +318,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ElectricalSeries - range: string @@ -236,12 +330,19 @@ classes: during experiment acquisition. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpikeEventSeries + name: + name: name + ifabsent: string(EventWaveform) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpikeEventSeries tree_root: true FilteredEphys: name: FilteredEphys @@ -258,12 +359,19 @@ classes: the ElectricalSeries. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(FilteredEphys) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true LFP: name: LFP @@ -272,12 +380,19 @@ classes: properties should be noted in the ElectricalSeries description or comments field. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(LFP) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true ElectrodeGroup: name: ElectrodeGroup @@ -286,6 +401,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -304,8 +420,7 @@ classes: name: position description: stereotaxic or common framework coordinates range: ElectrodeGroup__position - required: false - multivalued: false + inlined: true device: name: device annotations: @@ -313,7 +428,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -325,6 +440,7 @@ classes: name: name: name ifabsent: string(position) + identifier: true range: string required: true equals_string: position @@ -334,24 +450,18 @@ classes: array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false y: name: y description: y coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false z: name: z description: z coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false ClusterWaveforms: name: ClusterWaveforms description: DEPRECATED The mean waveform shape, including standard deviation, @@ -365,6 +475,7 @@ classes: name: name: name ifabsent: string(ClusterWaveforms) + identifier: true range: string required: true waveform_filtering: @@ -372,7 +483,6 @@ classes: description: Filtering applied to data before generating mean/sd range: text required: true - multivalued: false waveform_mean: name: waveform_mean description: The mean waveform for each cluster, using the same indices for @@ -404,7 +514,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Clustering - range: string @@ -418,6 +528,7 @@ classes: name: name: name ifabsent: string(Clustering) + identifier: true range: string required: true description: @@ -426,7 +537,6 @@ classes: clusters curated using Klusters, etc) range: text required: true - multivalued: false num: name: num description: Cluster number of each event diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.epoch.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.epoch.yaml index 6121bb5..08511a6 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.epoch.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.epoch.yaml @@ -22,6 +22,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true start_time: @@ -62,14 +63,12 @@ classes: value: neurodata_type_inc description: Index for tags. range: VectorIndex - required: false - multivalued: false + inlined: true timeseries: name: timeseries description: An index into a TimeSeries object. range: TimeIntervals__timeseries - required: false - multivalued: false + inlined: true timeseries_index: name: timeseries_index annotations: @@ -81,8 +80,7 @@ classes: value: neurodata_type_inc description: Index for timeseries. range: VectorIndex - required: false - multivalued: false + inlined: true tree_root: true TimeIntervals__timeseries: name: TimeIntervals__timeseries @@ -92,6 +90,7 @@ classes: name: name: name ifabsent: string(timeseries) + identifier: true range: string required: true equals_string: timeseries @@ -103,8 +102,6 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false count: name: count description: Number of data samples available in this time series, during @@ -112,13 +109,10 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false timeseries: name: timeseries description: the TimeSeries that this index applies to. array: exact_number_dimensions: 1 range: TimeSeries - required: false - multivalued: false + inlined: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.file.yaml index 1186898..7df4315 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.file.yaml @@ -30,6 +30,7 @@ classes: name: name: name ifabsent: string(root) + identifier: true range: string required: true equals_string: root @@ -64,13 +65,11 @@ classes: other files. range: text required: true - multivalued: false session_description: name: session_description description: A description of the experimental session and data in the file. range: text required: true - multivalued: false session_start_time: name: session_start_time description: 'Date and time of the experiment/session start. The date is stored @@ -79,7 +78,6 @@ classes: offset. Date accuracy is up to milliseconds.' range: isodatetime required: true - multivalued: false timestamps_reference_time: name: timestamps_reference_time description: 'Date and time corresponding to time zero of all timestamps. @@ -89,7 +87,6 @@ classes: times stored in the file use this time as reference (i.e., time zero).' range: isodatetime required: true - multivalued: false acquisition: name: acquisition description: Data streams recorded from the system, including ephys, ophys, @@ -168,7 +165,8 @@ classes: can exist in the present file or can be linked to a remote library file. range: NWBFile__stimulus required: true - multivalued: false + inlined: true + inlined_as_list: true general: name: general description: Experimental metadata, including protocol, notes and description @@ -188,7 +186,8 @@ classes: should not be created unless there is data to store within them. range: NWBFile__general required: true - multivalued: false + inlined: true + inlined_as_list: true intervals: name: intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -196,14 +195,18 @@ classes: an experiment, or epochs (see epochs subgroup) deriving from analysis of data. range: NWBFile__intervals - required: false - multivalued: false + inlined: true + inlined_as_list: true units: name: units description: Data about sorted spike units. range: Units - required: false - multivalued: false + inlined: true + inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -223,6 +226,7 @@ classes: name: name: name ifabsent: string(stimulus) + identifier: true range: string required: true equals_string: stimulus @@ -265,6 +269,7 @@ classes: name: name: name ifabsent: string(general) + identifier: true range: string required: true equals_string: general @@ -272,14 +277,10 @@ classes: name: data_collection description: Notes about data collection and analysis. range: text - required: false - multivalued: false experiment_description: name: experiment_description description: General description of the experiment. range: text - required: false - multivalued: false experimenter: name: experimenter description: Name of person(s) who performed the experiment. Can also specify @@ -294,8 +295,6 @@ classes: name: institution description: Institution(s) where experiment was performed. range: text - required: false - multivalued: false keywords: name: keywords description: Terms to search over. @@ -309,28 +308,20 @@ classes: name: lab description: Laboratory where experiment was performed. range: text - required: false - multivalued: false notes: name: notes description: Notes about the experiment. range: text - required: false - multivalued: false pharmacology: name: pharmacology description: Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc. range: text - required: false - multivalued: false protocol: name: protocol description: Experimental protocol, if applicable. e.g., include IACUC protocol number. range: text - required: false - multivalued: false related_publications: name: related_publications description: Publication information. PMID, DOI, URL, etc. @@ -344,49 +335,39 @@ classes: name: session_id description: Lab-specific ID for the session. range: text - required: false - multivalued: false slices: name: slices description: Description of slices, including information about preparation thickness, orientation, temperature, and bath solution. range: text - required: false - multivalued: false source_script: name: source_script description: Script file or link to public source code used to create this NWB file. range: general__source_script - required: false - multivalued: false + inlined: true stimulus: name: stimulus description: Notes about stimuli, such as how and where they were presented. range: text - required: false - multivalued: false surgery: name: surgery description: Narrative description about surgery/surgeries, including date(s) and who performed surgery. range: text - required: false - multivalued: false virus: name: virus description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - required: false - multivalued: false nwb_container: name: nwb_container description: Place-holder than can be extended so that lab-specific meta-data can be placed in /general. range: NWBContainer - required: false multivalued: true + inlined: true + inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -401,20 +382,20 @@ classes: description: Information about the animal or person from which the data was measured. range: Subject - required: false - multivalued: false + inlined: true + inlined_as_list: true extracellular_ephys: name: extracellular_ephys description: Metadata related to extracellular electrophysiology. range: general__extracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true intracellular_ephys: name: intracellular_ephys description: Metadata related to intracellular electrophysiology. range: general__intracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true optogenetics: name: optogenetics description: Metadata describing optogenetic stimuluation. @@ -439,6 +420,7 @@ classes: name: name: name ifabsent: string(source_script) + identifier: true range: string required: true equals_string: source_script @@ -459,6 +441,7 @@ classes: name: name: name ifabsent: string(subject) + identifier: true range: string required: true equals_string: subject @@ -466,52 +449,36 @@ classes: name: age description: Age of subject. Can be supplied instead of 'date_of_birth'. range: text - required: false - multivalued: false date_of_birth: name: date_of_birth description: Date of birth of subject. Can be supplied instead of 'age'. range: isodatetime - required: false - multivalued: false description: name: description description: Description of subject and where subject came from (e.g., breeder, if animal). range: text - required: false - multivalued: false genotype: name: genotype description: Genetic strain. If absent, assume Wild Type (WT). range: text - required: false - multivalued: false sex: name: sex description: Gender of subject. range: text - required: false - multivalued: false species: name: species description: Species of subject. range: text - required: false - multivalued: false subject_id: name: subject_id description: ID of animal/person used/participating in experiment (lab convention). range: text - required: false - multivalued: false weight: name: weight description: Weight at time of experiment, at time of surgery and at other important times. range: text - required: false - multivalued: false general__extracellular_ephys: name: general__extracellular_ephys description: Metadata related to extracellular electrophysiology. @@ -519,21 +486,23 @@ classes: name: name: name ifabsent: string(extracellular_ephys) + identifier: true range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - required: false - multivalued: true electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes - required: false - multivalued: false + inlined: true + inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -542,6 +511,7 @@ classes: name: name: name ifabsent: string(electrodes) + identifier: true range: string required: true equals_string: electrodes @@ -604,9 +574,13 @@ classes: group: name: group description: Reference to the ElectrodeGroup this electrode is a part of. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: ElectrodeGroup required: true - multivalued: true + multivalued: false + inlined: true group_name: name: group_name description: Name of the ElectrodeGroup this electrode is a part of. @@ -659,6 +633,7 @@ classes: name: name: name ifabsent: string(intracellular_ephys) + identifier: true range: string required: true equals_string: intracellular_ephys @@ -668,20 +643,19 @@ classes: frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries. range: text - required: false - multivalued: false - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - required: false - multivalued: true sweep_table: name: sweep_table description: The table which groups different PatchClampSeries together. range: SweepTable - required: false - multivalued: false + inlined: true + inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -691,6 +665,7 @@ classes: name: name: name ifabsent: string(intervals) + identifier: true range: string required: true equals_string: intervals @@ -699,24 +674,25 @@ classes: description: Divisions in time marking experimental stages or sub-divisions of a single recording session. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false trials: name: trials description: Repeated experimental events that have a logical grouping. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false invalid_times: name: invalid_times description: Time intervals that should be removed from analysis. range: TimeIntervals - required: false - multivalued: false - time_intervals: - name: time_intervals + inlined: true + inlined_as_list: false + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals - required: false multivalued: true + inlined: true + inlined_as_list: false diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.icephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.icephys.yaml index a9c82e9..b5b828c 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.icephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.icephys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true stimulus_description: @@ -40,14 +41,12 @@ classes: description: Recorded voltage or current. range: PatchClampSeries__data required: true - multivalued: false + inlined: true gain: name: gain description: Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp). range: float32 - required: false - multivalued: false electrode: name: electrode annotations: @@ -55,7 +54,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: IntracellularElectrode - range: string @@ -67,9 +66,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -92,32 +115,27 @@ classes: attributes: name: name: name + identifier: true range: string required: true + bias_current: + name: bias_current + description: Bias current, in amps. + range: float32 + bridge_balance: + name: bridge_balance + description: Bridge balance, in ohms. + range: float32 + capacitance_compensation: + name: capacitance_compensation + description: Capacitance compensation, in farads. + range: float32 data: name: data description: Recorded voltage. range: CurrentClampSeries__data required: true - multivalued: false - bias_current: - name: bias_current - description: Bias current, in amps. - range: float32 - required: false - multivalued: false - bridge_balance: - name: bridge_balance - description: Bridge balance, in ohms. - range: float32 - required: false - multivalued: false - capacitance_compensation: - name: capacitance_compensation - description: Capacitance compensation, in farads. - range: float32 - required: false - multivalued: false + inlined: true tree_root: true CurrentClampSeries__data: name: CurrentClampSeries__data @@ -126,9 +144,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -140,8 +182,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IZeroClampSeries: name: IZeroClampSeries description: Voltage data from an intracellular recording when all current and @@ -152,6 +196,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true bias_current: @@ -159,19 +204,16 @@ classes: description: Bias current, in amps, fixed to 0.0. range: float32 required: true - multivalued: false bridge_balance: name: bridge_balance description: Bridge balance, in ohms, fixed to 0.0. range: float32 required: true - multivalued: false capacitance_compensation: name: capacitance_compensation description: Capacitance compensation, in farads, fixed to 0.0. range: float32 required: true - multivalued: false tree_root: true CurrentClampStimulusSeries: name: CurrentClampStimulusSeries @@ -180,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -187,7 +230,7 @@ classes: description: Stimulus current applied. range: CurrentClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true CurrentClampStimulusSeries__data: name: CurrentClampStimulusSeries__data @@ -196,9 +239,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -210,8 +277,10 @@ classes: equals_string: amperes value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries: name: VoltageClampSeries description: Current data from an intracellular voltage-clamp recording. A corresponding @@ -221,80 +290,51 @@ classes: attributes: name: name: name + identifier: true range: string required: true + capacitance_fast: + name: capacitance_fast + description: Fast capacitance, in farads. + range: VoltageClampSeries__capacitance_fast + inlined: true + capacitance_slow: + name: capacitance_slow + description: Slow capacitance, in farads. + range: VoltageClampSeries__capacitance_slow + inlined: true data: name: data description: Recorded current. range: VoltageClampSeries__data required: true - multivalued: false - capacitance_fast: - name: capacitance_fast - description: Fast capacitance, in farads. - range: VoltageClampSeries__capacitance_fast - required: false - multivalued: false - capacitance_slow: - name: capacitance_slow - description: Slow capacitance, in farads. - range: VoltageClampSeries__capacitance_slow - required: false - multivalued: false + inlined: true resistance_comp_bandwidth: name: resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. range: VoltageClampSeries__resistance_comp_bandwidth - required: false - multivalued: false + inlined: true resistance_comp_correction: name: resistance_comp_correction description: Resistance compensation correction, in percent. range: VoltageClampSeries__resistance_comp_correction - required: false - multivalued: false + inlined: true resistance_comp_prediction: name: resistance_comp_prediction description: Resistance compensation prediction, in percent. range: VoltageClampSeries__resistance_comp_prediction - required: false - multivalued: false + inlined: true whole_cell_capacitance_comp: name: whole_cell_capacitance_comp description: Whole cell capacitance compensation, in farads. range: VoltageClampSeries__whole_cell_capacitance_comp - required: false - multivalued: false + inlined: true whole_cell_series_resistance_comp: name: whole_cell_series_resistance_comp description: Whole cell series resistance compensation, in ohms. range: VoltageClampSeries__whole_cell_series_resistance_comp - required: false - multivalued: false + inlined: true tree_root: true - VoltageClampSeries__data: - name: VoltageClampSeries__data - description: Recorded current. - attributes: - name: - name: name - ifabsent: string(data) - range: string - required: true - equals_string: data - unit: - name: unit - description: Base unit of measurement for working with the data. which is - fixed to 'amperes'. Actual stored values are not necessarily stored in these - units. To access the data in these units, multiply 'data' by 'conversion'. - ifabsent: string(amperes) - range: text - required: true - equals_string: amperes - value: - name: value - range: AnyType - required: true VoltageClampSeries__capacitance_fast: name: VoltageClampSeries__capacitance_fast description: Fast capacitance, in farads. @@ -302,6 +342,7 @@ classes: name: name: name ifabsent: string(capacitance_fast) + identifier: true range: string required: true equals_string: capacitance_fast @@ -323,6 +364,7 @@ classes: name: name: name ifabsent: string(capacitance_slow) + identifier: true range: string required: true equals_string: capacitance_slow @@ -337,6 +379,55 @@ classes: name: value range: float32 required: true + VoltageClampSeries__data: + name: VoltageClampSeries__data + description: Recorded current. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. which is + fixed to 'amperes'. Actual stored values are not necessarily stored in these + units. To access the data in these units, multiply 'data' by 'conversion'. + ifabsent: string(amperes) + range: text + required: true + equals_string: amperes + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries__resistance_comp_bandwidth: name: VoltageClampSeries__resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. @@ -344,6 +435,7 @@ classes: name: name: name ifabsent: string(resistance_comp_bandwidth) + identifier: true range: string required: true equals_string: resistance_comp_bandwidth @@ -366,6 +458,7 @@ classes: name: name: name ifabsent: string(resistance_comp_correction) + identifier: true range: string required: true equals_string: resistance_comp_correction @@ -388,6 +481,7 @@ classes: name: name: name ifabsent: string(resistance_comp_prediction) + identifier: true range: string required: true equals_string: resistance_comp_prediction @@ -410,6 +504,7 @@ classes: name: name: name ifabsent: string(whole_cell_capacitance_comp) + identifier: true range: string required: true equals_string: whole_cell_capacitance_comp @@ -432,6 +527,7 @@ classes: name: name: name ifabsent: string(whole_cell_series_resistance_comp) + identifier: true range: string required: true equals_string: whole_cell_series_resistance_comp @@ -454,6 +550,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -461,7 +558,7 @@ classes: description: Stimulus voltage applied. range: VoltageClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true VoltageClampStimulusSeries__data: name: VoltageClampStimulusSeries__data @@ -470,9 +567,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -484,8 +605,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IntracellularElectrode: name: IntracellularElectrode description: An intracellular electrode and its metadata. @@ -493,6 +616,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -500,45 +624,32 @@ classes: description: Description of electrode (e.g., whole-cell, sharp, etc.). range: text required: true - multivalued: false filtering: name: filtering description: Electrode specific filtering. range: text - required: false - multivalued: false initial_access_resistance: name: initial_access_resistance description: Initial access resistance. range: text - required: false - multivalued: false location: name: location description: Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. range: text - required: false - multivalued: false resistance: name: resistance description: Electrode resistance, in ohms. range: text - required: false - multivalued: false seal: name: seal description: Information about seal used for recording. range: text - required: false - multivalued: false slice: name: slice description: Information about slice used for recording. range: text - required: false - multivalued: false device: name: device annotations: @@ -546,7 +657,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -558,23 +669,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true - sweep_number: - name: sweep_number - description: Sweep number of the PatchClampSeries in that row. - array: - minimum_number_dimensions: 1 - maximum_number_dimensions: false - range: uint32 - required: true - multivalued: false series: name: series description: The PatchClampSeries with the sweep number in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: PatchClampSeries required: true - multivalued: true + multivalued: false + inlined: true series_index: name: series_index annotations: @@ -587,5 +694,14 @@ classes: description: Index for series. range: VectorIndex required: true + inlined: true + sweep_number: + name: sweep_number + description: Sweep number of the PatchClampSeries in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: uint32 + required: true multivalued: false tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.image.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.image.yaml index 9b619e3..979eddc 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.image.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.image.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -37,6 +38,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -56,6 +58,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -80,26 +83,14 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Binary data representing images across frames. - range: numeric - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - alias: z + range: ImageSeries__data + inlined: true dimension: name: dimension description: Number of pixels on x, y, (and z) axes. @@ -117,18 +108,72 @@ classes: used if the image is stored in another NWB file and that file is linked to this file. range: ImageSeries__external_file - required: false - multivalued: false + inlined: true format: name: format description: Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed. + ifabsent: string(raw) range: text - required: false - multivalued: false tree_root: true + ImageSeries__data: + name: ImageSeries__data + description: Binary data representing images across frames. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - alias: z ImageSeries__external_file: name: ImageSeries__external_file description: Paths to one or more external file(s). The field is only present @@ -139,6 +184,7 @@ classes: name: name: name ifabsent: string(external_file) + identifier: true range: string required: true equals_string: external_file @@ -176,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true masked_imageseries: @@ -185,7 +232,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string @@ -201,14 +248,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true + data: + name: data + description: Images presented to subject, either grayscale or RGB + range: OpticalSeries__data + required: true + inlined: true distance: name: distance description: Distance from camera/monitor to target/eye. range: float32 - required: false - multivalued: false field_of_view: name: field_of_view description: Width, height and depth of image, or imaged area, in meters. @@ -224,12 +276,56 @@ classes: dimensions: - alias: width_height_depth exact_cardinality: 3 - data: - name: data - description: Images presented to subject, either grayscale or RGB - range: numeric + orientation: + name: orientation + description: Description of image relative to some reference frame (e.g., + which way is up). Must also specify frame of reference. + range: text + tree_root: true + OpticalSeries__data: + name: OpticalSeries__data + description: Images presented to subject, either grayscale or RGB + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string required: true - multivalued: false + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric any_of: - array: dimensions: @@ -243,14 +339,6 @@ classes: - alias: y - alias: r_g_b exact_cardinality: 3 - orientation: - name: orientation - description: Description of image relative to some reference frame (e.g., - which way is up). Must also specify frame of reference. - range: text - required: false - multivalued: false - tree_root: true IndexSeries: name: IndexSeries description: Stores indices to image frames stored in an ImageSeries. The purpose @@ -263,17 +351,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Index of the frame in the referenced ImageSeries. - array: - dimensions: - - alias: num_times - range: int32 + range: IndexSeries__data required: true - multivalued: false + inlined: true indexed_timeseries: name: indexed_timeseries annotations: @@ -281,8 +367,55 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string tree_root: true + IndexSeries__data: + name: IndexSeries__data + description: Index of the frame in the referenced ImageSeries. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + array: + dimensions: + - alias: num_times + range: int32 diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.language.yaml index e42c742..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.misc.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.misc.yaml index de3d137..03307b6 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.misc.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.misc.yaml @@ -30,6 +30,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,7 +38,7 @@ classes: description: Values of each feature at each time. range: AbstractFeatureSeries__data required: true - multivalued: false + inlined: true feature_units: name: feature_units description: Units of each feature. @@ -64,9 +65,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Since there can be different units for different features, store @@ -96,18 +121,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Annotations made during an experiment. + range: AnnotationSeries__data + required: true + inlined: true + tree_root: true + AnnotationSeries__data: + name: AnnotationSeries__data + description: Annotations made during an experiment. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: text - required: true - multivalued: false - tree_root: true IntervalSeries: name: IntervalSeries description: Stores intervals of data. The timestamps field stores the beginning @@ -121,18 +191,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Use values >0 if interval started, <0 if interval ended. + range: IntervalSeries__data + required: true + inlined: true + tree_root: true + IntervalSeries__data: + name: IntervalSeries__data + description: Use values >0 if interval started, <0 if interval ended. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: int8 - required: true - multivalued: false - tree_root: true DecompositionSeries: name: DecompositionSeries description: Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -140,6 +255,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -147,28 +263,27 @@ classes: description: Data decomposed into frequency bands. range: DecompositionSeries__data required: true - multivalued: false + inlined: true metric: name: metric description: The metric used, e.g. phase, amplitude, power. range: text required: true - multivalued: false bands: name: bands description: Table for describing the bands that this series was generated from. There should be one row in this table for each band. range: DecompositionSeries__bands required: true - multivalued: false + inlined: true + inlined_as_list: true source_timeseries: name: source_timeseries annotations: source_type: tag: source_type value: link - required: false - multivalued: false + inlined: true any_of: - range: TimeSeries - range: string @@ -180,9 +295,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -208,6 +347,7 @@ classes: name: name: name ifabsent: string(bands) + identifier: true range: string required: true equals_string: bands @@ -259,10 +399,21 @@ classes: name: name: name ifabsent: string(Units) + identifier: true range: string required: true - spike_times_index: - name: spike_times_index + electrode_group: + name: electrode_group + description: Electrode group that each spike unit came from. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: ElectrodeGroup + required: false + multivalued: false + inlined: true + electrodes: + name: electrodes annotations: named: tag: named @@ -270,14 +421,30 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into the spike_times dataset. + description: Electrode that each spike unit came from, specified using a DynamicTableRegion. + range: DynamicTableRegion + inlined: true + electrodes_index: + name: electrodes_index + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: Index into electrodes. range: VectorIndex - required: false - multivalued: false - spike_times: - name: spike_times - description: Spike times for each unit. - range: Units__spike_times + inlined: true + obs_intervals: + name: obs_intervals + description: Observation intervals for each unit. + array: + dimensions: + - alias: num_intervals + - alias: start_end + exact_cardinality: 2 + range: float64 required: false multivalued: false obs_intervals_index: @@ -291,21 +458,14 @@ classes: value: neurodata_type_inc description: Index into the obs_intervals dataset. range: VectorIndex - required: false - multivalued: false - obs_intervals: - name: obs_intervals - description: Observation intervals for each unit. - array: - dimensions: - - alias: num_intervals - - alias: start_end - exact_cardinality: 2 - range: float64 - required: false - multivalued: false - electrodes_index: - name: electrodes_index + inlined: true + spike_times: + name: spike_times + description: Spike times for each unit. + range: Units__spike_times + inlined: true + spike_times_index: + name: spike_times_index annotations: named: tag: named @@ -313,61 +473,19 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into electrodes. + description: Index into the spike_times dataset. range: VectorIndex - required: false - multivalued: false - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: Electrode that each spike unit came from, specified using a DynamicTableRegion. - range: DynamicTableRegion - required: false - multivalued: false - electrode_group: - name: electrode_group - description: Electrode group that each spike unit came from. - range: ElectrodeGroup - required: false - multivalued: true + inlined: true waveform_mean: name: waveform_mean description: Spike waveform mean for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_mean + inlined: true waveform_sd: name: waveform_sd description: Spike waveform standard deviation for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_sd + inlined: true tree_root: true Units__spike_times: name: Units__spike_times @@ -377,6 +495,7 @@ classes: name: name: name ifabsent: string(spike_times) + identifier: true range: string required: true equals_string: spike_times @@ -389,3 +508,51 @@ classes: for the spike time to be between samples. range: float64 required: false + Units__waveform_mean: + name: Units__waveform_mean + description: Spike waveform mean for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_mean) + identifier: true + range: string + required: true + equals_string: waveform_mean + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts + Units__waveform_sd: + name: Units__waveform_sd + description: Spike waveform standard deviation for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_sd) + identifier: true + range: string + required: true + equals_string: waveform_sd + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ogen.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ogen.yaml index f281783..a402837 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ogen.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ogen.yaml @@ -21,17 +21,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Applied power for optogenetic stimulus, in watts. - array: - dimensions: - - alias: num_times - range: numeric + range: OptogeneticSeries__data required: true - multivalued: false + inlined: true site: name: site annotations: @@ -39,11 +37,58 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: OptogeneticStimulusSite - range: string tree_root: true + OptogeneticSeries__data: + name: OptogeneticSeries__data + description: Applied power for optogenetic stimulus, in watts. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for data, which is fixed to 'watts'. + ifabsent: string(watts) + range: text + required: true + equals_string: watts + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric OptogeneticStimulusSite: name: OptogeneticStimulusSite description: A site of optogenetic stimulation. @@ -51,6 +96,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -58,13 +104,11 @@ classes: description: Description of stimulation site. range: text required: true - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false location: name: location description: Location of the stimulation site. Specify the area, layer, comments @@ -72,7 +116,6 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false device: name: device annotations: @@ -80,7 +123,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ophys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ophys.yaml index 34915f6..ddf2017 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ophys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.ophys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true pmt_gain: @@ -59,7 +60,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImagingPlane - range: string @@ -72,22 +73,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Signals from ROIs. - range: numeric + range: RoiResponseSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_rois + inlined: true rois: name: rois annotations: @@ -101,8 +95,60 @@ classes: on the ROIs stored in this timeseries. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true + RoiResponseSeries__data: + name: RoiResponseSeries__data + description: Signals from ROIs. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_rois DfOverF: name: DfOverF description: dF/F information about a region of interest (ROI). Storage hierarchy @@ -110,12 +156,19 @@ classes: for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(DfOverF) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true Fluorescence: name: Fluorescence @@ -124,12 +177,19 @@ classes: for ROIs and for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(Fluorescence) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true ImageSegmentation: name: ImageSegmentation @@ -142,12 +202,19 @@ classes: is required and ROI names should remain consistent between them. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: DynamicTable + name: + name: name + ifabsent: string(ImageSegmentation) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: DynamicTable tree_root: true ImagingPlane: name: ImagingPlane @@ -156,32 +223,28 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: name: description description: Description of the imaging plane. range: text - required: false - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false imaging_rate: name: imaging_rate description: Rate that images are acquired, in Hz. range: float32 required: true - multivalued: false indicator: name: indicator description: Calcium indicator. range: text required: true - multivalued: false location: name: location description: Location of the imaging plane. Specify the area, layer, comments @@ -189,31 +252,27 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false manifold: name: manifold description: DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing. range: ImagingPlane__manifold - required: false - multivalued: false + inlined: true origin_coords: name: origin_coords description: Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma). range: ImagingPlane__origin_coords - required: false - multivalued: false + inlined: true grid_spacing: name: grid_spacing description: Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid. range: ImagingPlane__grid_spacing - required: false - multivalued: false + inlined: true reference_frame: name: reference_frame description: Describes reference frame of origin_coords and grid_spacing. @@ -234,14 +293,14 @@ classes: axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral)." range: text - required: false - multivalued: false optical_channel: name: optical_channel description: An optical channel used to record from an imaging plane. range: OpticalChannel required: true multivalued: true + inlined: true + inlined_as_list: true device: name: device annotations: @@ -249,7 +308,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -263,6 +322,7 @@ classes: name: name: name ifabsent: string(manifold) + identifier: true range: string required: true equals_string: manifold @@ -312,6 +372,7 @@ classes: name: name: name ifabsent: string(origin_coords) + identifier: true range: string required: true equals_string: origin_coords @@ -339,6 +400,7 @@ classes: name: name: name ifabsent: string(grid_spacing) + identifier: true range: string required: true equals_string: grid_spacing @@ -364,6 +426,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -371,13 +434,11 @@ classes: description: Description or other notes about the channel. range: text required: true - multivalued: false emission_lambda: name: emission_lambda description: Emission wavelength for channel, in nm. range: float32 required: true - multivalued: false MotionCorrection: name: MotionCorrection description: 'An image stack where all frames are shifted (registered) to a common @@ -385,10 +446,17 @@ classes: frame at each point in time is assumed to be 2-D (has only x & y dimensions).' is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface + name: + name: name + ifabsent: string(MotionCorrection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.retinotopy.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.retinotopy.yaml index 5248fa1..f708f10 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.retinotopy.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_2/core.nwb.retinotopy.yaml @@ -29,6 +29,7 @@ classes: name: name: name ifabsent: string(ImagingRetinotopy) + identifier: true range: string required: true axis_1_phase_map: @@ -36,27 +37,25 @@ classes: description: Phase response to stimulus on the first measured axis. range: ImagingRetinotopy__axis_1_phase_map required: true - multivalued: false + inlined: true axis_1_power_map: name: axis_1_power_map description: Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: ImagingRetinotopy__axis_1_power_map - required: false - multivalued: false + inlined: true axis_2_phase_map: name: axis_2_phase_map description: Phase response to stimulus on the second measured axis. range: ImagingRetinotopy__axis_2_phase_map required: true - multivalued: false + inlined: true axis_2_power_map: name: axis_2_power_map description: Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: ImagingRetinotopy__axis_2_power_map - required: false - multivalued: false + inlined: true axis_descriptions: name: axis_descriptions description: Two-element array describing the contents of the two response @@ -74,22 +73,20 @@ classes: description: 'Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].' range: ImagingRetinotopy__focal_depth_image - required: false - multivalued: false + inlined: true sign_map: name: sign_map description: Sine of the angle between the direction of the gradient in axis_1 and axis_2. range: ImagingRetinotopy__sign_map - required: false - multivalued: false + inlined: true vasculature_image: name: vasculature_image description: 'Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]' range: ImagingRetinotopy__vasculature_image required: true - multivalued: false + inlined: true tree_root: true ImagingRetinotopy__axis_1_phase_map: name: ImagingRetinotopy__axis_1_phase_map @@ -98,6 +95,7 @@ classes: name: name: name ifabsent: string(axis_1_phase_map) + identifier: true range: string required: true equals_string: axis_1_phase_map @@ -134,6 +132,7 @@ classes: name: name: name ifabsent: string(axis_1_power_map) + identifier: true range: string required: true equals_string: axis_1_power_map @@ -169,6 +168,7 @@ classes: name: name: name ifabsent: string(axis_2_phase_map) + identifier: true range: string required: true equals_string: axis_2_phase_map @@ -205,6 +205,7 @@ classes: name: name: name ifabsent: string(axis_2_power_map) + identifier: true range: string required: true equals_string: axis_2_power_map @@ -241,6 +242,7 @@ classes: name: name: name ifabsent: string(focal_depth_image) + identifier: true range: string required: true equals_string: focal_depth_image @@ -288,6 +290,7 @@ classes: name: name: name ifabsent: string(sign_map) + identifier: true range: string required: true equals_string: sign_map @@ -319,6 +322,7 @@ classes: name: name: name ifabsent: string(vasculature_image) + identifier: true range: string required: true equals_string: vasculature_image diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.base.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.base.yaml index 9d2e112..d4e4fa0 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.base.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -32,6 +33,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true resolution: @@ -73,6 +75,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -84,6 +87,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -94,6 +98,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -118,15 +123,14 @@ classes: external file. range: TimeSeries__data required: true - multivalued: false + inlined: true starting_time: name: starting_time description: Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute. range: TimeSeries__starting_time - required: false - multivalued: false + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -168,8 +172,8 @@ classes: external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes. range: TimeSeries__sync - required: false - multivalued: false + inlined: true + inlined_as_list: true tree_root: true TimeSeries__data: name: TimeSeries__data @@ -180,6 +184,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data @@ -244,6 +249,7 @@ classes: name: name: name ifabsent: string(starting_time) + identifier: true range: string required: true equals_string: starting_time @@ -275,6 +281,7 @@ classes: name: name: name ifabsent: string(sync) + identifier: true range: string required: true equals_string: sync @@ -283,13 +290,24 @@ classes: description: A collection of processed data. is_a: NWBContainer attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + description: + name: description + description: Description of this collection of processed data. + range: text + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface + - range: DynamicTable tree_root: true Images: name: Images @@ -299,6 +317,7 @@ classes: name: name: name ifabsent: string(Images) + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.behavior.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.behavior.yaml index 8bd048c..d586a66 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.behavior.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.behavior.yaml @@ -29,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,13 +38,11 @@ classes: reference frame. range: SpatialSeries__data required: true - multivalued: false + inlined: true reference_frame: name: reference_frame description: Description defining what exactly 'straight-ahead' means. range: text - required: false - multivalued: false tree_root: true SpatialSeries__data: name: SpatialSeries__data @@ -53,9 +52,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. The default @@ -91,12 +114,19 @@ classes: events. BehavioralTimeSeries is for continuous data. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: IntervalSeries + name: + name: name + ifabsent: string(BehavioralEpochs) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: IntervalSeries tree_root: true BehavioralEvents: name: BehavioralEvents @@ -104,12 +134,19 @@ classes: for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralEvents) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true BehavioralTimeSeries: name: BehavioralTimeSeries @@ -117,36 +154,57 @@ classes: of BehavioralEpochs for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralTimeSeries) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true PupilTracking: name: PupilTracking description: Eye-tracking data, representing pupil size. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(PupilTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true EyeTracking: name: EyeTracking description: Eye-tracking data, representing direction of gaze. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(EyeTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true CompassDirection: name: CompassDirection @@ -157,22 +215,36 @@ classes: be radians or degrees. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(CompassDirection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true Position: name: Position description: Position data, whether along the x, x/y or x/y/z axis. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(Position) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.device.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.device.yaml index 62fc686..bb0cd21 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.device.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.device.yaml @@ -21,6 +21,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ecephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ecephys.yaml index 67fc278..a5d7bc2 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ecephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ecephys.yaml @@ -25,41 +25,9 @@ classes: attributes: name: name: name + identifier: true range: string required: true - data: - name: data - description: Recorded voltage data. - range: numeric - required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_channels - - array: - dimensions: - - alias: num_times - - alias: num_channels - - alias: num_samples - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: DynamicTableRegion pointer to the electrodes that this time series - was generated from. - range: DynamicTableRegion - required: true - multivalued: false channel_conversion: name: channel_conversion description: Channel-specific conversion factor. Multiply the data in the @@ -77,7 +45,87 @@ classes: range: float32 required: false multivalued: false + data: + name: data + description: Recorded voltage data. + range: ElectricalSeries__data + required: true + inlined: true + electrodes: + name: electrodes + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: DynamicTableRegion pointer to the electrodes that this time series + was generated from. + range: DynamicTableRegion + required: true + inlined: true tree_root: true + ElectricalSeries__data: + name: ElectricalSeries__data + description: Recorded voltage data. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. This value + is fixed to 'volts'. Actual stored values are not necessarily stored in + these units. To access the data in these units, multiply 'data' by 'conversion' + and 'channel_conversion' (if present). + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_channels + - array: + dimensions: + - alias: num_times + - alias: num_channels + - alias: num_samples SpikeEventSeries: name: SpikeEventSeries description: 'Stores snapshots/snippets of recorded spike events (i.e., threshold @@ -92,24 +140,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Spike waveforms. - range: numeric + range: SpikeEventSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_events - - alias: num_samples - - array: - dimensions: - - alias: num_events - - alias: num_channels - - alias: num_samples + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -123,6 +162,60 @@ classes: required: true multivalued: false tree_root: true + SpikeEventSeries__data: + name: SpikeEventSeries__data + description: Spike waveforms. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for waveforms, which is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_events + - alias: num_samples + - array: + dimensions: + - alias: num_events + - alias: num_channels + - alias: num_samples FeatureExtraction: name: FeatureExtraction description: Features, such as PC1 and PC2, that are extracted from signals stored @@ -132,6 +225,7 @@ classes: name: name: name ifabsent: string(FeatureExtraction) + identifier: true range: string required: true description: @@ -177,7 +271,7 @@ classes: was generated from. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true EventDetection: name: EventDetection @@ -187,6 +281,7 @@ classes: name: name: name ifabsent: string(EventDetection) + identifier: true range: string required: true detection_method: @@ -195,7 +290,6 @@ classes: or dV/dT threshold, as well as relevant values. range: text required: true - multivalued: false source_idx: name: source_idx description: Indices (zero-based) into source ElectricalSeries::data array @@ -224,7 +318,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ElectricalSeries - range: string @@ -236,12 +330,19 @@ classes: during experiment acquisition. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpikeEventSeries + name: + name: name + ifabsent: string(EventWaveform) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpikeEventSeries tree_root: true FilteredEphys: name: FilteredEphys @@ -258,12 +359,19 @@ classes: the ElectricalSeries. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(FilteredEphys) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true LFP: name: LFP @@ -272,12 +380,19 @@ classes: properties should be noted in the ElectricalSeries description or comments field. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(LFP) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true ElectrodeGroup: name: ElectrodeGroup @@ -286,6 +401,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -304,8 +420,7 @@ classes: name: position description: stereotaxic or common framework coordinates range: ElectrodeGroup__position - required: false - multivalued: false + inlined: true device: name: device annotations: @@ -313,7 +428,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -325,6 +440,7 @@ classes: name: name: name ifabsent: string(position) + identifier: true range: string required: true equals_string: position @@ -334,24 +450,18 @@ classes: array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false y: name: y description: y coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false z: name: z description: z coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false ClusterWaveforms: name: ClusterWaveforms description: DEPRECATED The mean waveform shape, including standard deviation, @@ -365,6 +475,7 @@ classes: name: name: name ifabsent: string(ClusterWaveforms) + identifier: true range: string required: true waveform_filtering: @@ -372,7 +483,6 @@ classes: description: Filtering applied to data before generating mean/sd range: text required: true - multivalued: false waveform_mean: name: waveform_mean description: The mean waveform for each cluster, using the same indices for @@ -404,7 +514,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Clustering - range: string @@ -418,6 +528,7 @@ classes: name: name: name ifabsent: string(Clustering) + identifier: true range: string required: true description: @@ -426,7 +537,6 @@ classes: clusters curated using Klusters, etc) range: text required: true - multivalued: false num: name: num description: Cluster number of each event diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.epoch.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.epoch.yaml index 68a7004..b128f43 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.epoch.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.epoch.yaml @@ -22,6 +22,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true start_time: @@ -62,14 +63,12 @@ classes: value: neurodata_type_inc description: Index for tags. range: VectorIndex - required: false - multivalued: false + inlined: true timeseries: name: timeseries description: An index into a TimeSeries object. range: TimeIntervals__timeseries - required: false - multivalued: false + inlined: true timeseries_index: name: timeseries_index annotations: @@ -81,8 +80,7 @@ classes: value: neurodata_type_inc description: Index for timeseries. range: VectorIndex - required: false - multivalued: false + inlined: true tree_root: true TimeIntervals__timeseries: name: TimeIntervals__timeseries @@ -92,6 +90,7 @@ classes: name: name: name ifabsent: string(timeseries) + identifier: true range: string required: true equals_string: timeseries @@ -103,8 +102,6 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false count: name: count description: Number of data samples available in this time series, during @@ -112,13 +109,10 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false timeseries: name: timeseries description: the TimeSeries that this index applies to. array: exact_number_dimensions: 1 range: TimeSeries - required: false - multivalued: false + inlined: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.file.yaml index 45add51..cca1d5e 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.file.yaml @@ -28,6 +28,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true notes: @@ -45,6 +46,7 @@ classes: name: name: name ifabsent: string(root) + identifier: true range: string required: true equals_string: root @@ -79,13 +81,11 @@ classes: other files. range: text required: true - multivalued: false session_description: name: session_description description: A description of the experimental session and data in the file. range: text required: true - multivalued: false session_start_time: name: session_start_time description: 'Date and time of the experiment/session start. The date is stored @@ -94,7 +94,6 @@ classes: offset. Date accuracy is up to milliseconds.' range: isodatetime required: true - multivalued: false timestamps_reference_time: name: timestamps_reference_time description: 'Date and time corresponding to time zero of all timestamps. @@ -104,7 +103,6 @@ classes: times stored in the file use this time as reference (i.e., time zero).' range: isodatetime required: true - multivalued: false acquisition: name: acquisition description: Data streams recorded from the system, including ephys, ophys, @@ -183,7 +181,8 @@ classes: can exist in the present file or can be linked to a remote library file. range: NWBFile__stimulus required: true - multivalued: false + inlined: true + inlined_as_list: true general: name: general description: Experimental metadata, including protocol, notes and description @@ -203,7 +202,8 @@ classes: should not be created unless there is data to store within them. range: NWBFile__general required: true - multivalued: false + inlined: true + inlined_as_list: true intervals: name: intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -211,14 +211,18 @@ classes: an experiment, or epochs (see epochs subgroup) deriving from analysis of data. range: NWBFile__intervals - required: false - multivalued: false + inlined: true + inlined_as_list: true units: name: units description: Data about sorted spike units. range: Units - required: false - multivalued: false + inlined: true + inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -238,6 +242,7 @@ classes: name: name: name ifabsent: string(stimulus) + identifier: true range: string required: true equals_string: stimulus @@ -280,6 +285,7 @@ classes: name: name: name ifabsent: string(general) + identifier: true range: string required: true equals_string: general @@ -287,14 +293,10 @@ classes: name: data_collection description: Notes about data collection and analysis. range: text - required: false - multivalued: false experiment_description: name: experiment_description description: General description of the experiment. range: text - required: false - multivalued: false experimenter: name: experimenter description: Name of person(s) who performed the experiment. Can also specify @@ -309,8 +311,6 @@ classes: name: institution description: Institution(s) where experiment was performed. range: text - required: false - multivalued: false keywords: name: keywords description: Terms to search over. @@ -324,28 +324,20 @@ classes: name: lab description: Laboratory where experiment was performed. range: text - required: false - multivalued: false notes: name: notes description: Notes about the experiment. range: text - required: false - multivalued: false pharmacology: name: pharmacology description: Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc. range: text - required: false - multivalued: false protocol: name: protocol description: Experimental protocol, if applicable. e.g., include IACUC protocol number. range: text - required: false - multivalued: false related_publications: name: related_publications description: Publication information. PMID, DOI, URL, etc. @@ -359,49 +351,31 @@ classes: name: session_id description: Lab-specific ID for the session. range: text - required: false - multivalued: false slices: name: slices description: Description of slices, including information about preparation thickness, orientation, temperature, and bath solution. range: text - required: false - multivalued: false source_script: name: source_script description: Script file or link to public source code used to create this NWB file. range: general__source_script - required: false - multivalued: false + inlined: true stimulus: name: stimulus description: Notes about stimuli, such as how and where they were presented. range: text - required: false - multivalued: false surgery: name: surgery description: Narrative description about surgery/surgeries, including date(s) and who performed surgery. range: text - required: false - multivalued: false virus: name: virus description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - required: false - multivalued: false - lab_meta_data: - name: lab_meta_data - description: Place-holder than can be extended so that lab-specific meta-data - can be placed in /general. - range: LabMetaData - required: false - multivalued: true devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -416,20 +390,20 @@ classes: description: Information about the animal or person from which the data was measured. range: Subject - required: false - multivalued: false + inlined: true + inlined_as_list: false extracellular_ephys: name: extracellular_ephys description: Metadata related to extracellular electrophysiology. range: general__extracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true intracellular_ephys: name: intracellular_ephys description: Metadata related to intracellular electrophysiology. range: general__intracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true optogenetics: name: optogenetics description: Metadata describing optogenetic stimuluation. @@ -446,6 +420,14 @@ classes: inlined_as_list: false any_of: - range: ImagingPlane + value: + name: value + description: Place-holder than can be extended so that lab-specific meta-data + can be placed in /general. + range: LabMetaData + multivalued: true + inlined: true + inlined_as_list: false general__source_script: name: general__source_script description: Script file or link to public source code used to create this NWB @@ -454,6 +436,7 @@ classes: name: name: name ifabsent: string(source_script) + identifier: true range: string required: true equals_string: source_script @@ -473,21 +456,23 @@ classes: name: name: name ifabsent: string(extracellular_ephys) + identifier: true range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - required: false - multivalued: true electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes - required: false - multivalued: false + inlined: true + inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -496,6 +481,7 @@ classes: name: name: name ifabsent: string(electrodes) + identifier: true range: string required: true equals_string: electrodes @@ -558,9 +544,13 @@ classes: group: name: group description: Reference to the ElectrodeGroup this electrode is a part of. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: ElectrodeGroup required: true - multivalued: true + multivalued: false + inlined: true group_name: name: group_name description: Name of the ElectrodeGroup this electrode is a part of. @@ -613,6 +603,7 @@ classes: name: name: name ifabsent: string(intracellular_ephys) + identifier: true range: string required: true equals_string: intracellular_ephys @@ -622,20 +613,19 @@ classes: frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries. range: text - required: false - multivalued: false - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - required: false - multivalued: true sweep_table: name: sweep_table description: The table which groups different PatchClampSeries together. range: SweepTable - required: false - multivalued: false + inlined: true + inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -645,6 +635,7 @@ classes: name: name: name ifabsent: string(intervals) + identifier: true range: string required: true equals_string: intervals @@ -653,27 +644,28 @@ classes: description: Divisions in time marking experimental stages or sub-divisions of a single recording session. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false trials: name: trials description: Repeated experimental events that have a logical grouping. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false invalid_times: name: invalid_times description: Time intervals that should be removed from analysis. range: TimeIntervals - required: false - multivalued: false - time_intervals: - name: time_intervals + inlined: true + inlined_as_list: false + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals - required: false multivalued: true + inlined: true + inlined_as_list: false LabMetaData: name: LabMetaData description: Lab-specific meta-data. @@ -681,6 +673,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -691,56 +684,41 @@ classes: attributes: name: name: name + identifier: true range: string required: true age: name: age description: Age of subject. Can be supplied instead of 'date_of_birth'. range: text - required: false - multivalued: false date_of_birth: name: date_of_birth description: Date of birth of subject. Can be supplied instead of 'age'. range: isodatetime - required: false - multivalued: false description: name: description description: Description of subject and where subject came from (e.g., breeder, if animal). range: text - required: false - multivalued: false genotype: name: genotype description: Genetic strain. If absent, assume Wild Type (WT). range: text - required: false - multivalued: false sex: name: sex description: Gender of subject. range: text - required: false - multivalued: false species: name: species description: Species of subject. range: text - required: false - multivalued: false subject_id: name: subject_id description: ID of animal/person used/participating in experiment (lab convention). range: text - required: false - multivalued: false weight: name: weight description: Weight at time of experiment, at time of surgery and at other important times. range: text - required: false - multivalued: false tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.icephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.icephys.yaml index 200456d..2d8db0f 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.icephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.icephys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true stimulus_description: @@ -40,14 +41,12 @@ classes: description: Recorded voltage or current. range: PatchClampSeries__data required: true - multivalued: false + inlined: true gain: name: gain description: Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp). range: float32 - required: false - multivalued: false electrode: name: electrode annotations: @@ -55,7 +54,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: IntracellularElectrode - range: string @@ -67,9 +66,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -92,32 +115,27 @@ classes: attributes: name: name: name + identifier: true range: string required: true + bias_current: + name: bias_current + description: Bias current, in amps. + range: float32 + bridge_balance: + name: bridge_balance + description: Bridge balance, in ohms. + range: float32 + capacitance_compensation: + name: capacitance_compensation + description: Capacitance compensation, in farads. + range: float32 data: name: data description: Recorded voltage. range: CurrentClampSeries__data required: true - multivalued: false - bias_current: - name: bias_current - description: Bias current, in amps. - range: float32 - required: false - multivalued: false - bridge_balance: - name: bridge_balance - description: Bridge balance, in ohms. - range: float32 - required: false - multivalued: false - capacitance_compensation: - name: capacitance_compensation - description: Capacitance compensation, in farads. - range: float32 - required: false - multivalued: false + inlined: true tree_root: true CurrentClampSeries__data: name: CurrentClampSeries__data @@ -126,9 +144,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -140,8 +182,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IZeroClampSeries: name: IZeroClampSeries description: Voltage data from an intracellular recording when all current and @@ -152,6 +196,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true bias_current: @@ -159,19 +204,16 @@ classes: description: Bias current, in amps, fixed to 0.0. range: float32 required: true - multivalued: false bridge_balance: name: bridge_balance description: Bridge balance, in ohms, fixed to 0.0. range: float32 required: true - multivalued: false capacitance_compensation: name: capacitance_compensation description: Capacitance compensation, in farads, fixed to 0.0. range: float32 required: true - multivalued: false tree_root: true CurrentClampStimulusSeries: name: CurrentClampStimulusSeries @@ -180,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -187,7 +230,7 @@ classes: description: Stimulus current applied. range: CurrentClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true CurrentClampStimulusSeries__data: name: CurrentClampStimulusSeries__data @@ -196,9 +239,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -210,8 +277,10 @@ classes: equals_string: amperes value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries: name: VoltageClampSeries description: Current data from an intracellular voltage-clamp recording. A corresponding @@ -221,80 +290,51 @@ classes: attributes: name: name: name + identifier: true range: string required: true + capacitance_fast: + name: capacitance_fast + description: Fast capacitance, in farads. + range: VoltageClampSeries__capacitance_fast + inlined: true + capacitance_slow: + name: capacitance_slow + description: Slow capacitance, in farads. + range: VoltageClampSeries__capacitance_slow + inlined: true data: name: data description: Recorded current. range: VoltageClampSeries__data required: true - multivalued: false - capacitance_fast: - name: capacitance_fast - description: Fast capacitance, in farads. - range: VoltageClampSeries__capacitance_fast - required: false - multivalued: false - capacitance_slow: - name: capacitance_slow - description: Slow capacitance, in farads. - range: VoltageClampSeries__capacitance_slow - required: false - multivalued: false + inlined: true resistance_comp_bandwidth: name: resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. range: VoltageClampSeries__resistance_comp_bandwidth - required: false - multivalued: false + inlined: true resistance_comp_correction: name: resistance_comp_correction description: Resistance compensation correction, in percent. range: VoltageClampSeries__resistance_comp_correction - required: false - multivalued: false + inlined: true resistance_comp_prediction: name: resistance_comp_prediction description: Resistance compensation prediction, in percent. range: VoltageClampSeries__resistance_comp_prediction - required: false - multivalued: false + inlined: true whole_cell_capacitance_comp: name: whole_cell_capacitance_comp description: Whole cell capacitance compensation, in farads. range: VoltageClampSeries__whole_cell_capacitance_comp - required: false - multivalued: false + inlined: true whole_cell_series_resistance_comp: name: whole_cell_series_resistance_comp description: Whole cell series resistance compensation, in ohms. range: VoltageClampSeries__whole_cell_series_resistance_comp - required: false - multivalued: false + inlined: true tree_root: true - VoltageClampSeries__data: - name: VoltageClampSeries__data - description: Recorded current. - attributes: - name: - name: name - ifabsent: string(data) - range: string - required: true - equals_string: data - unit: - name: unit - description: Base unit of measurement for working with the data. which is - fixed to 'amperes'. Actual stored values are not necessarily stored in these - units. To access the data in these units, multiply 'data' by 'conversion'. - ifabsent: string(amperes) - range: text - required: true - equals_string: amperes - value: - name: value - range: AnyType - required: true VoltageClampSeries__capacitance_fast: name: VoltageClampSeries__capacitance_fast description: Fast capacitance, in farads. @@ -302,6 +342,7 @@ classes: name: name: name ifabsent: string(capacitance_fast) + identifier: true range: string required: true equals_string: capacitance_fast @@ -323,6 +364,7 @@ classes: name: name: name ifabsent: string(capacitance_slow) + identifier: true range: string required: true equals_string: capacitance_slow @@ -337,6 +379,55 @@ classes: name: value range: float32 required: true + VoltageClampSeries__data: + name: VoltageClampSeries__data + description: Recorded current. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. which is + fixed to 'amperes'. Actual stored values are not necessarily stored in these + units. To access the data in these units, multiply 'data' by 'conversion'. + ifabsent: string(amperes) + range: text + required: true + equals_string: amperes + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries__resistance_comp_bandwidth: name: VoltageClampSeries__resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. @@ -344,6 +435,7 @@ classes: name: name: name ifabsent: string(resistance_comp_bandwidth) + identifier: true range: string required: true equals_string: resistance_comp_bandwidth @@ -366,6 +458,7 @@ classes: name: name: name ifabsent: string(resistance_comp_correction) + identifier: true range: string required: true equals_string: resistance_comp_correction @@ -388,6 +481,7 @@ classes: name: name: name ifabsent: string(resistance_comp_prediction) + identifier: true range: string required: true equals_string: resistance_comp_prediction @@ -410,6 +504,7 @@ classes: name: name: name ifabsent: string(whole_cell_capacitance_comp) + identifier: true range: string required: true equals_string: whole_cell_capacitance_comp @@ -432,6 +527,7 @@ classes: name: name: name ifabsent: string(whole_cell_series_resistance_comp) + identifier: true range: string required: true equals_string: whole_cell_series_resistance_comp @@ -454,6 +550,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -461,7 +558,7 @@ classes: description: Stimulus voltage applied. range: VoltageClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true VoltageClampStimulusSeries__data: name: VoltageClampStimulusSeries__data @@ -470,9 +567,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -484,8 +605,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IntracellularElectrode: name: IntracellularElectrode description: An intracellular electrode and its metadata. @@ -493,6 +616,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -500,45 +624,32 @@ classes: description: Description of electrode (e.g., whole-cell, sharp, etc.). range: text required: true - multivalued: false filtering: name: filtering description: Electrode specific filtering. range: text - required: false - multivalued: false initial_access_resistance: name: initial_access_resistance description: Initial access resistance. range: text - required: false - multivalued: false location: name: location description: Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. range: text - required: false - multivalued: false resistance: name: resistance description: Electrode resistance, in ohms. range: text - required: false - multivalued: false seal: name: seal description: Information about seal used for recording. range: text - required: false - multivalued: false slice: name: slice description: Information about slice used for recording. range: text - required: false - multivalued: false device: name: device annotations: @@ -546,7 +657,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -558,23 +669,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true - sweep_number: - name: sweep_number - description: Sweep number of the PatchClampSeries in that row. - array: - minimum_number_dimensions: 1 - maximum_number_dimensions: false - range: uint32 - required: true - multivalued: false series: name: series description: The PatchClampSeries with the sweep number in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: PatchClampSeries required: true - multivalued: true + multivalued: false + inlined: true series_index: name: series_index annotations: @@ -587,5 +694,14 @@ classes: description: Index for series. range: VectorIndex required: true + inlined: true + sweep_number: + name: sweep_number + description: Sweep number of the PatchClampSeries in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: uint32 + required: true multivalued: false tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.image.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.image.yaml index 1db1fba..626e39f 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.image.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.image.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -37,6 +38,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -56,6 +58,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -80,26 +83,14 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Binary data representing images across frames. - range: numeric - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - alias: z + range: ImageSeries__data + inlined: true dimension: name: dimension description: Number of pixels on x, y, (and z) axes. @@ -117,18 +108,72 @@ classes: used if the image is stored in another NWB file and that file is linked to this file. range: ImageSeries__external_file - required: false - multivalued: false + inlined: true format: name: format description: Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed. + ifabsent: string(raw) range: text - required: false - multivalued: false tree_root: true + ImageSeries__data: + name: ImageSeries__data + description: Binary data representing images across frames. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - alias: z ImageSeries__external_file: name: ImageSeries__external_file description: Paths to one or more external file(s). The field is only present @@ -139,6 +184,7 @@ classes: name: name: name ifabsent: string(external_file) + identifier: true range: string required: true equals_string: external_file @@ -176,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true masked_imageseries: @@ -185,7 +232,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string @@ -201,14 +248,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true + data: + name: data + description: Images presented to subject, either grayscale or RGB + range: OpticalSeries__data + required: true + inlined: true distance: name: distance description: Distance from camera/monitor to target/eye. range: float32 - required: false - multivalued: false field_of_view: name: field_of_view description: Width, height and depth of image, or imaged area, in meters. @@ -224,12 +276,56 @@ classes: dimensions: - alias: width_height_depth exact_cardinality: 3 - data: - name: data - description: Images presented to subject, either grayscale or RGB - range: numeric + orientation: + name: orientation + description: Description of image relative to some reference frame (e.g., + which way is up). Must also specify frame of reference. + range: text + tree_root: true + OpticalSeries__data: + name: OpticalSeries__data + description: Images presented to subject, either grayscale or RGB + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string required: true - multivalued: false + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric any_of: - array: dimensions: @@ -243,14 +339,6 @@ classes: - alias: y - alias: r_g_b exact_cardinality: 3 - orientation: - name: orientation - description: Description of image relative to some reference frame (e.g., - which way is up). Must also specify frame of reference. - range: text - required: false - multivalued: false - tree_root: true IndexSeries: name: IndexSeries description: Stores indices to image frames stored in an ImageSeries. The purpose @@ -263,17 +351,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Index of the frame in the referenced ImageSeries. - array: - dimensions: - - alias: num_times - range: int32 + range: IndexSeries__data required: true - multivalued: false + inlined: true indexed_timeseries: name: indexed_timeseries annotations: @@ -281,8 +367,55 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string tree_root: true + IndexSeries__data: + name: IndexSeries__data + description: Index of the frame in the referenced ImageSeries. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + array: + dimensions: + - alias: num_times + range: int32 diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.language.yaml index e42c742..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.misc.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.misc.yaml index 82d4a9f..6ab2cd6 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.misc.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.misc.yaml @@ -30,6 +30,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,7 +38,7 @@ classes: description: Values of each feature at each time. range: AbstractFeatureSeries__data required: true - multivalued: false + inlined: true feature_units: name: feature_units description: Units of each feature. @@ -64,9 +65,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Since there can be different units for different features, store @@ -96,18 +121,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Annotations made during an experiment. + range: AnnotationSeries__data + required: true + inlined: true + tree_root: true + AnnotationSeries__data: + name: AnnotationSeries__data + description: Annotations made during an experiment. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: text - required: true - multivalued: false - tree_root: true IntervalSeries: name: IntervalSeries description: Stores intervals of data. The timestamps field stores the beginning @@ -121,18 +191,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Use values >0 if interval started, <0 if interval ended. + range: IntervalSeries__data + required: true + inlined: true + tree_root: true + IntervalSeries__data: + name: IntervalSeries__data + description: Use values >0 if interval started, <0 if interval ended. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: int8 - required: true - multivalued: false - tree_root: true DecompositionSeries: name: DecompositionSeries description: Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -140,6 +255,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -147,28 +263,27 @@ classes: description: Data decomposed into frequency bands. range: DecompositionSeries__data required: true - multivalued: false + inlined: true metric: name: metric description: The metric used, e.g. phase, amplitude, power. range: text required: true - multivalued: false bands: name: bands description: Table for describing the bands that this series was generated from. There should be one row in this table for each band. range: DecompositionSeries__bands required: true - multivalued: false + inlined: true + inlined_as_list: true source_timeseries: name: source_timeseries annotations: source_type: tag: source_type value: link - required: false - multivalued: false + inlined: true any_of: - range: TimeSeries - range: string @@ -180,9 +295,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -208,6 +347,7 @@ classes: name: name: name ifabsent: string(bands) + identifier: true range: string required: true equals_string: bands @@ -259,10 +399,21 @@ classes: name: name: name ifabsent: string(Units) + identifier: true range: string required: true - spike_times_index: - name: spike_times_index + electrode_group: + name: electrode_group + description: Electrode group that each spike unit came from. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: ElectrodeGroup + required: false + multivalued: false + inlined: true + electrodes: + name: electrodes annotations: named: tag: named @@ -270,14 +421,30 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into the spike_times dataset. + description: Electrode that each spike unit came from, specified using a DynamicTableRegion. + range: DynamicTableRegion + inlined: true + electrodes_index: + name: electrodes_index + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: Index into electrodes. range: VectorIndex - required: false - multivalued: false - spike_times: - name: spike_times - description: Spike times for each unit. - range: Units__spike_times + inlined: true + obs_intervals: + name: obs_intervals + description: Observation intervals for each unit. + array: + dimensions: + - alias: num_intervals + - alias: start_end + exact_cardinality: 2 + range: float64 required: false multivalued: false obs_intervals_index: @@ -291,21 +458,14 @@ classes: value: neurodata_type_inc description: Index into the obs_intervals dataset. range: VectorIndex - required: false - multivalued: false - obs_intervals: - name: obs_intervals - description: Observation intervals for each unit. - array: - dimensions: - - alias: num_intervals - - alias: start_end - exact_cardinality: 2 - range: float64 - required: false - multivalued: false - electrodes_index: - name: electrodes_index + inlined: true + spike_times: + name: spike_times + description: Spike times for each unit. + range: Units__spike_times + inlined: true + spike_times_index: + name: spike_times_index annotations: named: tag: named @@ -313,61 +473,19 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into electrodes. + description: Index into the spike_times dataset. range: VectorIndex - required: false - multivalued: false - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: Electrode that each spike unit came from, specified using a DynamicTableRegion. - range: DynamicTableRegion - required: false - multivalued: false - electrode_group: - name: electrode_group - description: Electrode group that each spike unit came from. - range: ElectrodeGroup - required: false - multivalued: true + inlined: true waveform_mean: name: waveform_mean description: Spike waveform mean for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_mean + inlined: true waveform_sd: name: waveform_sd description: Spike waveform standard deviation for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_sd + inlined: true tree_root: true Units__spike_times: name: Units__spike_times @@ -377,6 +495,7 @@ classes: name: name: name ifabsent: string(spike_times) + identifier: true range: string required: true equals_string: spike_times @@ -389,3 +508,51 @@ classes: for the spike time to be between samples. range: float64 required: false + Units__waveform_mean: + name: Units__waveform_mean + description: Spike waveform mean for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_mean) + identifier: true + range: string + required: true + equals_string: waveform_mean + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts + Units__waveform_sd: + name: Units__waveform_sd + description: Spike waveform standard deviation for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_sd) + identifier: true + range: string + required: true + equals_string: waveform_sd + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ogen.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ogen.yaml index ec81c05..78fe244 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ogen.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ogen.yaml @@ -21,17 +21,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Applied power for optogenetic stimulus, in watts. - array: - dimensions: - - alias: num_times - range: numeric + range: OptogeneticSeries__data required: true - multivalued: false + inlined: true site: name: site annotations: @@ -39,11 +37,58 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: OptogeneticStimulusSite - range: string tree_root: true + OptogeneticSeries__data: + name: OptogeneticSeries__data + description: Applied power for optogenetic stimulus, in watts. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for data, which is fixed to 'watts'. + ifabsent: string(watts) + range: text + required: true + equals_string: watts + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric OptogeneticStimulusSite: name: OptogeneticStimulusSite description: A site of optogenetic stimulation. @@ -51,6 +96,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -58,13 +104,11 @@ classes: description: Description of stimulation site. range: text required: true - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false location: name: location description: Location of the stimulation site. Specify the area, layer, comments @@ -72,7 +116,6 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false device: name: device annotations: @@ -80,7 +123,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ophys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ophys.yaml index 1dc5b4e..a637f40 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ophys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.ophys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true pmt_gain: @@ -59,7 +60,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImagingPlane - range: string @@ -72,22 +73,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Signals from ROIs. - range: numeric + range: RoiResponseSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_rois + inlined: true rois: name: rois annotations: @@ -101,8 +95,60 @@ classes: on the ROIs stored in this timeseries. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true + RoiResponseSeries__data: + name: RoiResponseSeries__data + description: Signals from ROIs. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_rois DfOverF: name: DfOverF description: dF/F information about a region of interest (ROI). Storage hierarchy @@ -110,12 +156,19 @@ classes: for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(DfOverF) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true Fluorescence: name: Fluorescence @@ -124,12 +177,19 @@ classes: for ROIs and for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(Fluorescence) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true ImageSegmentation: name: ImageSegmentation @@ -142,12 +202,19 @@ classes: is required and ROI names should remain consistent between them. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: PlaneSegmentation + name: + name: name + ifabsent: string(ImageSegmentation) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: PlaneSegmentation tree_root: true PlaneSegmentation: name: PlaneSegmentation @@ -156,15 +223,35 @@ classes: attributes: name: name: name + identifier: true range: string required: true image_mask: name: image_mask description: ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero. - range: PlaneSegmentation__image_mask + range: AnyType required: false multivalued: false + any_of: + - array: + dimensions: + - alias: num_roi + - alias: num_x + - alias: num_y + - array: + dimensions: + - alias: num_roi + - alias: num_x + - alias: num_y + - alias: num_z + pixel_mask: + name: pixel_mask + description: 'Pixel masks for each ROI: a list of indices and weights for + the ROI. Pixel masks are concatenated and parsing of this dataset is maintained + by the PlaneSegmentation' + range: PlaneSegmentation__pixel_mask + inlined: true pixel_mask_index: name: pixel_mask_index annotations: @@ -176,16 +263,14 @@ classes: value: neurodata_type_inc description: Index into pixel_mask. range: VectorIndex - required: false - multivalued: false - pixel_mask: - name: pixel_mask - description: 'Pixel masks for each ROI: a list of indices and weights for - the ROI. Pixel masks are concatenated and parsing of this dataset is maintained + inlined: true + voxel_mask: + name: voxel_mask + description: 'Voxel masks for each ROI: a list of indices and weights for + the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation' - range: PlaneSegmentation__pixel_mask - required: false - multivalued: false + range: PlaneSegmentation__voxel_mask + inlined: true voxel_mask_index: name: voxel_mask_index annotations: @@ -197,16 +282,7 @@ classes: value: neurodata_type_inc description: Index into voxel_mask. range: VectorIndex - required: false - multivalued: false - voxel_mask: - name: voxel_mask - description: 'Voxel masks for each ROI: a list of indices and weights for - the ROI. Voxel masks are concatenated and parsing of this dataset is maintained - by the PlaneSegmentation' - range: PlaneSegmentation__voxel_mask - required: false - multivalued: false + inlined: true reference_images: name: reference_images description: Image stacks that the segmentation masks apply to. @@ -222,23 +298,11 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImagingPlane - range: string tree_root: true - PlaneSegmentation__image_mask: - name: PlaneSegmentation__image_mask - description: ROI masks for each ROI. Each image mask is the size of the original - imaging plane (or volume) and members of the ROI are finite non-zero. - is_a: VectorData - attributes: - name: - name: name - ifabsent: string(image_mask) - range: string - required: true - equals_string: image_mask PlaneSegmentation__pixel_mask: name: PlaneSegmentation__pixel_mask description: 'Pixel masks for each ROI: a list of indices and weights for the @@ -249,6 +313,7 @@ classes: name: name: name ifabsent: string(pixel_mask) + identifier: true range: string required: true equals_string: pixel_mask @@ -258,24 +323,18 @@ classes: array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false y: name: y description: Pixel y-coordinate. array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false weight: name: weight description: Weight of the pixel. array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false PlaneSegmentation__voxel_mask: name: PlaneSegmentation__voxel_mask description: 'Voxel masks for each ROI: a list of indices and weights for the @@ -286,6 +345,7 @@ classes: name: name: name ifabsent: string(voxel_mask) + identifier: true range: string required: true equals_string: voxel_mask @@ -295,32 +355,24 @@ classes: array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false y: name: y description: Voxel y-coordinate. array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false z: name: z description: Voxel z-coordinate. array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false weight: name: weight description: Weight of the voxel. array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false ImagingPlane: name: ImagingPlane description: An imaging plane and its metadata. @@ -328,33 +380,28 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: name: description description: Description of the imaging plane. range: text - required: false - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false imaging_rate: name: imaging_rate description: Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead. range: float32 - required: false - multivalued: false indicator: name: indicator description: Calcium indicator. range: text required: true - multivalued: false location: name: location description: Location of the imaging plane. Specify the area, layer, comments @@ -362,31 +409,27 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false manifold: name: manifold description: DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing. range: ImagingPlane__manifold - required: false - multivalued: false + inlined: true origin_coords: name: origin_coords description: Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma). range: ImagingPlane__origin_coords - required: false - multivalued: false + inlined: true grid_spacing: name: grid_spacing description: Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid. range: ImagingPlane__grid_spacing - required: false - multivalued: false + inlined: true reference_frame: name: reference_frame description: Describes reference frame of origin_coords and grid_spacing. @@ -407,14 +450,14 @@ classes: axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral)." range: text - required: false - multivalued: false optical_channel: name: optical_channel description: An optical channel used to record from an imaging plane. range: OpticalChannel required: true multivalued: true + inlined: true + inlined_as_list: false device: name: device annotations: @@ -422,7 +465,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -436,6 +479,7 @@ classes: name: name: name ifabsent: string(manifold) + identifier: true range: string required: true equals_string: manifold @@ -485,6 +529,7 @@ classes: name: name: name ifabsent: string(origin_coords) + identifier: true range: string required: true equals_string: origin_coords @@ -512,6 +557,7 @@ classes: name: name: name ifabsent: string(grid_spacing) + identifier: true range: string required: true equals_string: grid_spacing @@ -537,6 +583,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -544,13 +591,11 @@ classes: description: Description or other notes about the channel. range: text required: true - multivalued: false emission_lambda: name: emission_lambda description: Emission wavelength for channel, in nm. range: float32 required: true - multivalued: false tree_root: true MotionCorrection: name: MotionCorrection @@ -559,12 +604,19 @@ classes: frame at each point in time is assumed to be 2-D (has only x & y dimensions).' is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: CorrectedImageStack + name: + name: name + ifabsent: string(MotionCorrection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: CorrectedImageStack tree_root: true CorrectedImageStack: name: CorrectedImageStack @@ -573,6 +625,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true corrected: @@ -580,14 +633,16 @@ classes: description: Image stack with frames shifted to the common coordinates. range: ImageSeries required: true - multivalued: false + inlined: true + inlined_as_list: false xy_translation: name: xy_translation description: Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image. range: TimeSeries required: true - multivalued: false + inlined: true + inlined_as_list: false original: name: original annotations: @@ -595,7 +650,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.retinotopy.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.retinotopy.yaml index 5869564..1ab12db 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.retinotopy.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_4/core.nwb.retinotopy.yaml @@ -29,6 +29,7 @@ classes: name: name: name ifabsent: string(ImagingRetinotopy) + identifier: true range: string required: true axis_1_phase_map: @@ -36,27 +37,25 @@ classes: description: Phase response to stimulus on the first measured axis. range: ImagingRetinotopy__axis_1_phase_map required: true - multivalued: false + inlined: true axis_1_power_map: name: axis_1_power_map description: Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: ImagingRetinotopy__axis_1_power_map - required: false - multivalued: false + inlined: true axis_2_phase_map: name: axis_2_phase_map description: Phase response to stimulus on the second measured axis. range: ImagingRetinotopy__axis_2_phase_map required: true - multivalued: false + inlined: true axis_2_power_map: name: axis_2_power_map description: Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: ImagingRetinotopy__axis_2_power_map - required: false - multivalued: false + inlined: true axis_descriptions: name: axis_descriptions description: Two-element array describing the contents of the two response @@ -74,22 +73,20 @@ classes: description: 'Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].' range: ImagingRetinotopy__focal_depth_image - required: false - multivalued: false + inlined: true sign_map: name: sign_map description: Sine of the angle between the direction of the gradient in axis_1 and axis_2. range: ImagingRetinotopy__sign_map - required: false - multivalued: false + inlined: true vasculature_image: name: vasculature_image description: 'Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]' range: ImagingRetinotopy__vasculature_image required: true - multivalued: false + inlined: true tree_root: true ImagingRetinotopy__axis_1_phase_map: name: ImagingRetinotopy__axis_1_phase_map @@ -98,6 +95,7 @@ classes: name: name: name ifabsent: string(axis_1_phase_map) + identifier: true range: string required: true equals_string: axis_1_phase_map @@ -134,6 +132,7 @@ classes: name: name: name ifabsent: string(axis_1_power_map) + identifier: true range: string required: true equals_string: axis_1_power_map @@ -169,6 +168,7 @@ classes: name: name: name ifabsent: string(axis_2_phase_map) + identifier: true range: string required: true equals_string: axis_2_phase_map @@ -205,6 +205,7 @@ classes: name: name: name ifabsent: string(axis_2_power_map) + identifier: true range: string required: true equals_string: axis_2_power_map @@ -241,6 +242,7 @@ classes: name: name: name ifabsent: string(focal_depth_image) + identifier: true range: string required: true equals_string: focal_depth_image @@ -288,6 +290,7 @@ classes: name: name: name ifabsent: string(sign_map) + identifier: true range: string required: true equals_string: sign_map @@ -319,6 +322,7 @@ classes: name: name: name ifabsent: string(vasculature_image) + identifier: true range: string required: true equals_string: vasculature_image diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.base.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.base.yaml index ba25032..0662185 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.base.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -32,6 +33,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true resolution: @@ -73,6 +75,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -84,6 +87,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -94,6 +98,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -118,15 +123,14 @@ classes: external file. range: TimeSeries__data required: true - multivalued: false + inlined: true starting_time: name: starting_time description: Timestamp of the first sample in seconds. When timestamps are uniformly spaced, the timestamp of the first sample can be specified and all subsequent ones calculated from the sampling rate attribute. range: TimeSeries__starting_time - required: false - multivalued: false + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -168,8 +172,8 @@ classes: external to the NWB file, in files storing raw data. Once timestamp data is calculated, the contents of 'sync' are mostly for archival purposes. range: TimeSeries__sync - required: false - multivalued: false + inlined: true + inlined_as_list: true tree_root: true TimeSeries__data: name: TimeSeries__data @@ -180,6 +184,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data @@ -244,6 +249,7 @@ classes: name: name: name ifabsent: string(starting_time) + identifier: true range: string required: true equals_string: starting_time @@ -275,6 +281,7 @@ classes: name: name: name ifabsent: string(sync) + identifier: true range: string required: true equals_string: sync @@ -283,13 +290,24 @@ classes: description: A collection of processed data. is_a: NWBContainer attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: NWBDataInterface - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + description: + name: description + description: Description of this collection of processed data. + range: text + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: NWBDataInterface + - range: DynamicTable tree_root: true Images: name: Images @@ -299,6 +317,7 @@ classes: name: name: name ifabsent: string(Images) + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.behavior.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.behavior.yaml index 242fe70..387933c 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.behavior.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.behavior.yaml @@ -29,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,13 +38,11 @@ classes: reference frame. range: SpatialSeries__data required: true - multivalued: false + inlined: true reference_frame: name: reference_frame description: Description defining what exactly 'straight-ahead' means. range: text - required: false - multivalued: false tree_root: true SpatialSeries__data: name: SpatialSeries__data @@ -53,9 +52,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. The default @@ -91,12 +114,19 @@ classes: events. BehavioralTimeSeries is for continuous data. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: IntervalSeries + name: + name: name + ifabsent: string(BehavioralEpochs) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: IntervalSeries tree_root: true BehavioralEvents: name: BehavioralEvents @@ -104,12 +134,19 @@ classes: for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralEvents) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true BehavioralTimeSeries: name: BehavioralTimeSeries @@ -117,36 +154,57 @@ classes: of BehavioralEpochs for more details. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(BehavioralTimeSeries) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true PupilTracking: name: PupilTracking description: Eye-tracking data, representing pupil size. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: TimeSeries + name: + name: name + ifabsent: string(PupilTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: TimeSeries tree_root: true EyeTracking: name: EyeTracking description: Eye-tracking data, representing direction of gaze. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(EyeTracking) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true CompassDirection: name: CompassDirection @@ -157,22 +215,36 @@ classes: be radians or degrees. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(CompassDirection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true Position: name: Position description: Position data, whether along the x, x/y or x/y/z axis. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpatialSeries + name: + name: name + ifabsent: string(Position) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpatialSeries tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.device.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.device.yaml index 9572c3b..d2fb572 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.device.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.device.yaml @@ -21,6 +21,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ecephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ecephys.yaml index bb3f4fd..2e332c8 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ecephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ecephys.yaml @@ -25,41 +25,9 @@ classes: attributes: name: name: name + identifier: true range: string required: true - data: - name: data - description: Recorded voltage data. - range: numeric - required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_channels - - array: - dimensions: - - alias: num_times - - alias: num_channels - - alias: num_samples - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: DynamicTableRegion pointer to the electrodes that this time series - was generated from. - range: DynamicTableRegion - required: true - multivalued: false channel_conversion: name: channel_conversion description: Channel-specific conversion factor. Multiply the data in the @@ -77,7 +45,87 @@ classes: range: float32 required: false multivalued: false + data: + name: data + description: Recorded voltage data. + range: ElectricalSeries__data + required: true + inlined: true + electrodes: + name: electrodes + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: DynamicTableRegion pointer to the electrodes that this time series + was generated from. + range: DynamicTableRegion + required: true + inlined: true tree_root: true + ElectricalSeries__data: + name: ElectricalSeries__data + description: Recorded voltage data. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. This value + is fixed to 'volts'. Actual stored values are not necessarily stored in + these units. To access the data in these units, multiply 'data' by 'conversion' + and 'channel_conversion' (if present). + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_channels + - array: + dimensions: + - alias: num_times + - alias: num_channels + - alias: num_samples SpikeEventSeries: name: SpikeEventSeries description: 'Stores snapshots/snippets of recorded spike events (i.e., threshold @@ -92,24 +140,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Spike waveforms. - range: numeric + range: SpikeEventSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_events - - alias: num_samples - - array: - dimensions: - - alias: num_events - - alias: num_channels - - alias: num_samples + inlined: true timestamps: name: timestamps description: Timestamps for samples stored in data, in seconds, relative to @@ -123,6 +162,60 @@ classes: required: true multivalued: false tree_root: true + SpikeEventSeries__data: + name: SpikeEventSeries__data + description: Spike waveforms. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for waveforms, which is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: true + equals_string: volts + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_events + - alias: num_samples + - array: + dimensions: + - alias: num_events + - alias: num_channels + - alias: num_samples FeatureExtraction: name: FeatureExtraction description: Features, such as PC1 and PC2, that are extracted from signals stored @@ -132,6 +225,7 @@ classes: name: name: name ifabsent: string(FeatureExtraction) + identifier: true range: string required: true description: @@ -177,7 +271,7 @@ classes: was generated from. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true EventDetection: name: EventDetection @@ -187,6 +281,7 @@ classes: name: name: name ifabsent: string(EventDetection) + identifier: true range: string required: true detection_method: @@ -195,7 +290,6 @@ classes: or dV/dT threshold, as well as relevant values. range: text required: true - multivalued: false source_idx: name: source_idx description: Indices (zero-based) into source ElectricalSeries::data array @@ -224,7 +318,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ElectricalSeries - range: string @@ -236,12 +330,19 @@ classes: during experiment acquisition. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: SpikeEventSeries + name: + name: name + ifabsent: string(EventWaveform) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: SpikeEventSeries tree_root: true FilteredEphys: name: FilteredEphys @@ -258,12 +359,19 @@ classes: the ElectricalSeries. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(FilteredEphys) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true LFP: name: LFP @@ -272,12 +380,19 @@ classes: properties should be noted in the ElectricalSeries description or comments field. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: ElectricalSeries + name: + name: name + ifabsent: string(LFP) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: ElectricalSeries tree_root: true ElectrodeGroup: name: ElectrodeGroup @@ -286,6 +401,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -304,8 +420,7 @@ classes: name: position description: stereotaxic or common framework coordinates range: ElectrodeGroup__position - required: false - multivalued: false + inlined: true device: name: device annotations: @@ -313,7 +428,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -325,6 +440,7 @@ classes: name: name: name ifabsent: string(position) + identifier: true range: string required: true equals_string: position @@ -334,24 +450,18 @@ classes: array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false y: name: y description: y coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false z: name: z description: z coordinate array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false ClusterWaveforms: name: ClusterWaveforms description: DEPRECATED The mean waveform shape, including standard deviation, @@ -365,6 +475,7 @@ classes: name: name: name ifabsent: string(ClusterWaveforms) + identifier: true range: string required: true waveform_filtering: @@ -372,7 +483,6 @@ classes: description: Filtering applied to data before generating mean/sd range: text required: true - multivalued: false waveform_mean: name: waveform_mean description: The mean waveform for each cluster, using the same indices for @@ -404,7 +514,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Clustering - range: string @@ -418,6 +528,7 @@ classes: name: name: name ifabsent: string(Clustering) + identifier: true range: string required: true description: @@ -426,7 +537,6 @@ classes: clusters curated using Klusters, etc) range: text required: true - multivalued: false num: name: num description: Cluster number of each event diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.epoch.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.epoch.yaml index 2b4fbde..afb55f9 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.epoch.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.epoch.yaml @@ -22,6 +22,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true start_time: @@ -62,14 +63,12 @@ classes: value: neurodata_type_inc description: Index for tags. range: VectorIndex - required: false - multivalued: false + inlined: true timeseries: name: timeseries description: An index into a TimeSeries object. range: TimeIntervals__timeseries - required: false - multivalued: false + inlined: true timeseries_index: name: timeseries_index annotations: @@ -81,8 +80,7 @@ classes: value: neurodata_type_inc description: Index for timeseries. range: VectorIndex - required: false - multivalued: false + inlined: true tree_root: true TimeIntervals__timeseries: name: TimeIntervals__timeseries @@ -92,6 +90,7 @@ classes: name: name: name ifabsent: string(timeseries) + identifier: true range: string required: true equals_string: timeseries @@ -103,8 +102,6 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false count: name: count description: Number of data samples available in this time series, during @@ -112,13 +109,10 @@ classes: array: exact_number_dimensions: 1 range: int32 - required: false - multivalued: false timeseries: name: timeseries description: the TimeSeries that this index applies to. array: exact_number_dimensions: 1 range: TimeSeries - required: false - multivalued: false + inlined: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.file.yaml index f52421b..601f158 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.file.yaml @@ -28,6 +28,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true notes: @@ -45,6 +46,7 @@ classes: name: name: name ifabsent: string(root) + identifier: true range: string required: true equals_string: root @@ -79,13 +81,11 @@ classes: other files. range: text required: true - multivalued: false session_description: name: session_description description: A description of the experimental session and data in the file. range: text required: true - multivalued: false session_start_time: name: session_start_time description: 'Date and time of the experiment/session start. The date is stored @@ -94,7 +94,6 @@ classes: offset. Date accuracy is up to milliseconds.' range: isodatetime required: true - multivalued: false timestamps_reference_time: name: timestamps_reference_time description: 'Date and time corresponding to time zero of all timestamps. @@ -104,7 +103,6 @@ classes: times stored in the file use this time as reference (i.e., time zero).' range: isodatetime required: true - multivalued: false acquisition: name: acquisition description: Data streams recorded from the system, including ephys, ophys, @@ -183,7 +181,8 @@ classes: can exist in the present file or can be linked to a remote library file. range: NWBFile__stimulus required: true - multivalued: false + inlined: true + inlined_as_list: true general: name: general description: Experimental metadata, including protocol, notes and description @@ -203,7 +202,8 @@ classes: should not be created unless there is data to store within them. range: NWBFile__general required: true - multivalued: false + inlined: true + inlined_as_list: true intervals: name: intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -211,14 +211,18 @@ classes: an experiment, or epochs (see epochs subgroup) deriving from analysis of data. range: NWBFile__intervals - required: false - multivalued: false + inlined: true + inlined_as_list: true units: name: units description: Data about sorted spike units. range: Units - required: false - multivalued: false + inlined: true + inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -238,6 +242,7 @@ classes: name: name: name ifabsent: string(stimulus) + identifier: true range: string required: true equals_string: stimulus @@ -280,6 +285,7 @@ classes: name: name: name ifabsent: string(general) + identifier: true range: string required: true equals_string: general @@ -287,14 +293,10 @@ classes: name: data_collection description: Notes about data collection and analysis. range: text - required: false - multivalued: false experiment_description: name: experiment_description description: General description of the experiment. range: text - required: false - multivalued: false experimenter: name: experimenter description: Name of person(s) who performed the experiment. Can also specify @@ -309,8 +311,6 @@ classes: name: institution description: Institution(s) where experiment was performed. range: text - required: false - multivalued: false keywords: name: keywords description: Terms to search over. @@ -324,28 +324,20 @@ classes: name: lab description: Laboratory where experiment was performed. range: text - required: false - multivalued: false notes: name: notes description: Notes about the experiment. range: text - required: false - multivalued: false pharmacology: name: pharmacology description: Description of drugs used, including how and when they were administered. Anesthesia(s), painkiller(s), etc., plus dosage, concentration, etc. range: text - required: false - multivalued: false protocol: name: protocol description: Experimental protocol, if applicable. e.g., include IACUC protocol number. range: text - required: false - multivalued: false related_publications: name: related_publications description: Publication information. PMID, DOI, URL, etc. @@ -359,49 +351,31 @@ classes: name: session_id description: Lab-specific ID for the session. range: text - required: false - multivalued: false slices: name: slices description: Description of slices, including information about preparation thickness, orientation, temperature, and bath solution. range: text - required: false - multivalued: false source_script: name: source_script description: Script file or link to public source code used to create this NWB file. range: general__source_script - required: false - multivalued: false + inlined: true stimulus: name: stimulus description: Notes about stimuli, such as how and where they were presented. range: text - required: false - multivalued: false surgery: name: surgery description: Narrative description about surgery/surgeries, including date(s) and who performed surgery. range: text - required: false - multivalued: false virus: name: virus description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - required: false - multivalued: false - lab_meta_data: - name: lab_meta_data - description: Place-holder than can be extended so that lab-specific meta-data - can be placed in /general. - range: LabMetaData - required: false - multivalued: true devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -416,20 +390,20 @@ classes: description: Information about the animal or person from which the data was measured. range: Subject - required: false - multivalued: false + inlined: true + inlined_as_list: false extracellular_ephys: name: extracellular_ephys description: Metadata related to extracellular electrophysiology. range: general__extracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true intracellular_ephys: name: intracellular_ephys description: Metadata related to intracellular electrophysiology. range: general__intracellular_ephys - required: false - multivalued: false + inlined: true + inlined_as_list: true optogenetics: name: optogenetics description: Metadata describing optogenetic stimuluation. @@ -446,6 +420,14 @@ classes: inlined_as_list: false any_of: - range: ImagingPlane + value: + name: value + description: Place-holder than can be extended so that lab-specific meta-data + can be placed in /general. + range: LabMetaData + multivalued: true + inlined: true + inlined_as_list: false general__source_script: name: general__source_script description: Script file or link to public source code used to create this NWB @@ -454,6 +436,7 @@ classes: name: name: name ifabsent: string(source_script) + identifier: true range: string required: true equals_string: source_script @@ -473,21 +456,23 @@ classes: name: name: name ifabsent: string(extracellular_ephys) + identifier: true range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - required: false - multivalued: true electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes - required: false - multivalued: false + inlined: true + inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -496,6 +481,7 @@ classes: name: name: name ifabsent: string(electrodes) + identifier: true range: string required: true equals_string: electrodes @@ -558,9 +544,13 @@ classes: group: name: group description: Reference to the ElectrodeGroup this electrode is a part of. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: ElectrodeGroup required: true - multivalued: true + multivalued: false + inlined: true group_name: name: group_name description: Name of the ElectrodeGroup this electrode is a part of. @@ -613,6 +603,7 @@ classes: name: name: name ifabsent: string(intracellular_ephys) + identifier: true range: string required: true equals_string: intracellular_ephys @@ -622,20 +613,19 @@ classes: frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries. range: text - required: false - multivalued: false - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - required: false - multivalued: true sweep_table: name: sweep_table description: The table which groups different PatchClampSeries together. range: SweepTable - required: false - multivalued: false + inlined: true + inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -645,6 +635,7 @@ classes: name: name: name ifabsent: string(intervals) + identifier: true range: string required: true equals_string: intervals @@ -653,27 +644,28 @@ classes: description: Divisions in time marking experimental stages or sub-divisions of a single recording session. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false trials: name: trials description: Repeated experimental events that have a logical grouping. range: TimeIntervals - required: false - multivalued: false + inlined: true + inlined_as_list: false invalid_times: name: invalid_times description: Time intervals that should be removed from analysis. range: TimeIntervals - required: false - multivalued: false - time_intervals: - name: time_intervals + inlined: true + inlined_as_list: false + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals - required: false multivalued: true + inlined: true + inlined_as_list: false LabMetaData: name: LabMetaData description: Lab-specific meta-data. @@ -681,6 +673,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -691,56 +684,41 @@ classes: attributes: name: name: name + identifier: true range: string required: true age: name: age description: Age of subject. Can be supplied instead of 'date_of_birth'. range: text - required: false - multivalued: false date_of_birth: name: date_of_birth description: Date of birth of subject. Can be supplied instead of 'age'. range: isodatetime - required: false - multivalued: false description: name: description description: Description of subject and where subject came from (e.g., breeder, if animal). range: text - required: false - multivalued: false genotype: name: genotype description: Genetic strain. If absent, assume Wild Type (WT). range: text - required: false - multivalued: false sex: name: sex description: Gender of subject. range: text - required: false - multivalued: false species: name: species description: Species of subject. range: text - required: false - multivalued: false subject_id: name: subject_id description: ID of animal/person used/participating in experiment (lab convention). range: text - required: false - multivalued: false weight: name: weight description: Weight at time of experiment, at time of surgery and at other important times. range: text - required: false - multivalued: false tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.icephys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.icephys.yaml index 9eb505a..9962426 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.icephys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.icephys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true stimulus_description: @@ -40,14 +41,12 @@ classes: description: Recorded voltage or current. range: PatchClampSeries__data required: true - multivalued: false + inlined: true gain: name: gain description: Gain of the recording, in units Volt/Amp (v-clamp) or Volt/Volt (c-clamp). range: float32 - required: false - multivalued: false electrode: name: electrode annotations: @@ -55,7 +54,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: IntracellularElectrode - range: string @@ -67,9 +66,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -92,32 +115,27 @@ classes: attributes: name: name: name + identifier: true range: string required: true + bias_current: + name: bias_current + description: Bias current, in amps. + range: float32 + bridge_balance: + name: bridge_balance + description: Bridge balance, in ohms. + range: float32 + capacitance_compensation: + name: capacitance_compensation + description: Capacitance compensation, in farads. + range: float32 data: name: data description: Recorded voltage. range: CurrentClampSeries__data required: true - multivalued: false - bias_current: - name: bias_current - description: Bias current, in amps. - range: float32 - required: false - multivalued: false - bridge_balance: - name: bridge_balance - description: Bridge balance, in ohms. - range: float32 - required: false - multivalued: false - capacitance_compensation: - name: capacitance_compensation - description: Capacitance compensation, in farads. - range: float32 - required: false - multivalued: false + inlined: true tree_root: true CurrentClampSeries__data: name: CurrentClampSeries__data @@ -126,9 +144,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -140,8 +182,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IZeroClampSeries: name: IZeroClampSeries description: Voltage data from an intracellular recording when all current and @@ -152,6 +196,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true bias_current: @@ -159,19 +204,16 @@ classes: description: Bias current, in amps, fixed to 0.0. range: float32 required: true - multivalued: false bridge_balance: name: bridge_balance description: Bridge balance, in ohms, fixed to 0.0. range: float32 required: true - multivalued: false capacitance_compensation: name: capacitance_compensation description: Capacitance compensation, in farads, fixed to 0.0. range: float32 required: true - multivalued: false tree_root: true CurrentClampStimulusSeries: name: CurrentClampStimulusSeries @@ -180,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -187,7 +230,7 @@ classes: description: Stimulus current applied. range: CurrentClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true CurrentClampStimulusSeries__data: name: CurrentClampStimulusSeries__data @@ -196,9 +239,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -210,8 +277,10 @@ classes: equals_string: amperes value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries: name: VoltageClampSeries description: Current data from an intracellular voltage-clamp recording. A corresponding @@ -221,80 +290,51 @@ classes: attributes: name: name: name + identifier: true range: string required: true + capacitance_fast: + name: capacitance_fast + description: Fast capacitance, in farads. + range: VoltageClampSeries__capacitance_fast + inlined: true + capacitance_slow: + name: capacitance_slow + description: Slow capacitance, in farads. + range: VoltageClampSeries__capacitance_slow + inlined: true data: name: data description: Recorded current. range: VoltageClampSeries__data required: true - multivalued: false - capacitance_fast: - name: capacitance_fast - description: Fast capacitance, in farads. - range: VoltageClampSeries__capacitance_fast - required: false - multivalued: false - capacitance_slow: - name: capacitance_slow - description: Slow capacitance, in farads. - range: VoltageClampSeries__capacitance_slow - required: false - multivalued: false + inlined: true resistance_comp_bandwidth: name: resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. range: VoltageClampSeries__resistance_comp_bandwidth - required: false - multivalued: false + inlined: true resistance_comp_correction: name: resistance_comp_correction description: Resistance compensation correction, in percent. range: VoltageClampSeries__resistance_comp_correction - required: false - multivalued: false + inlined: true resistance_comp_prediction: name: resistance_comp_prediction description: Resistance compensation prediction, in percent. range: VoltageClampSeries__resistance_comp_prediction - required: false - multivalued: false + inlined: true whole_cell_capacitance_comp: name: whole_cell_capacitance_comp description: Whole cell capacitance compensation, in farads. range: VoltageClampSeries__whole_cell_capacitance_comp - required: false - multivalued: false + inlined: true whole_cell_series_resistance_comp: name: whole_cell_series_resistance_comp description: Whole cell series resistance compensation, in ohms. range: VoltageClampSeries__whole_cell_series_resistance_comp - required: false - multivalued: false + inlined: true tree_root: true - VoltageClampSeries__data: - name: VoltageClampSeries__data - description: Recorded current. - attributes: - name: - name: name - ifabsent: string(data) - range: string - required: true - equals_string: data - unit: - name: unit - description: Base unit of measurement for working with the data. which is - fixed to 'amperes'. Actual stored values are not necessarily stored in these - units. To access the data in these units, multiply 'data' by 'conversion'. - ifabsent: string(amperes) - range: text - required: true - equals_string: amperes - value: - name: value - range: AnyType - required: true VoltageClampSeries__capacitance_fast: name: VoltageClampSeries__capacitance_fast description: Fast capacitance, in farads. @@ -302,6 +342,7 @@ classes: name: name: name ifabsent: string(capacitance_fast) + identifier: true range: string required: true equals_string: capacitance_fast @@ -323,6 +364,7 @@ classes: name: name: name ifabsent: string(capacitance_slow) + identifier: true range: string required: true equals_string: capacitance_slow @@ -337,6 +379,55 @@ classes: name: value range: float32 required: true + VoltageClampSeries__data: + name: VoltageClampSeries__data + description: Recorded current. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. which is + fixed to 'amperes'. Actual stored values are not necessarily stored in these + units. To access the data in these units, multiply 'data' by 'conversion'. + ifabsent: string(amperes) + range: text + required: true + equals_string: amperes + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric VoltageClampSeries__resistance_comp_bandwidth: name: VoltageClampSeries__resistance_comp_bandwidth description: Resistance compensation bandwidth, in hertz. @@ -344,6 +435,7 @@ classes: name: name: name ifabsent: string(resistance_comp_bandwidth) + identifier: true range: string required: true equals_string: resistance_comp_bandwidth @@ -366,6 +458,7 @@ classes: name: name: name ifabsent: string(resistance_comp_correction) + identifier: true range: string required: true equals_string: resistance_comp_correction @@ -388,6 +481,7 @@ classes: name: name: name ifabsent: string(resistance_comp_prediction) + identifier: true range: string required: true equals_string: resistance_comp_prediction @@ -410,6 +504,7 @@ classes: name: name: name ifabsent: string(whole_cell_capacitance_comp) + identifier: true range: string required: true equals_string: whole_cell_capacitance_comp @@ -432,6 +527,7 @@ classes: name: name: name ifabsent: string(whole_cell_series_resistance_comp) + identifier: true range: string required: true equals_string: whole_cell_series_resistance_comp @@ -454,6 +550,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -461,7 +558,7 @@ classes: description: Stimulus voltage applied. range: VoltageClampStimulusSeries__data required: true - multivalued: false + inlined: true tree_root: true VoltageClampStimulusSeries__data: name: VoltageClampStimulusSeries__data @@ -470,9 +567,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. which is @@ -484,8 +605,10 @@ classes: equals_string: volts value: name: value - range: AnyType - required: true + array: + dimensions: + - alias: num_times + range: numeric IntracellularElectrode: name: IntracellularElectrode description: An intracellular electrode and its metadata. @@ -493,6 +616,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -500,45 +624,32 @@ classes: description: Description of electrode (e.g., whole-cell, sharp, etc.). range: text required: true - multivalued: false filtering: name: filtering description: Electrode specific filtering. range: text - required: false - multivalued: false initial_access_resistance: name: initial_access_resistance description: Initial access resistance. range: text - required: false - multivalued: false location: name: location description: Location of the electrode. Specify the area, layer, comments on estimation of area/layer, stereotaxic coordinates if in vivo, etc. Use standard atlas names for anatomical regions when possible. range: text - required: false - multivalued: false resistance: name: resistance description: Electrode resistance, in ohms. range: text - required: false - multivalued: false seal: name: seal description: Information about seal used for recording. range: text - required: false - multivalued: false slice: name: slice description: Information about slice used for recording. range: text - required: false - multivalued: false device: name: device annotations: @@ -546,7 +657,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -558,23 +669,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true - sweep_number: - name: sweep_number - description: Sweep number of the PatchClampSeries in that row. - array: - minimum_number_dimensions: 1 - maximum_number_dimensions: false - range: uint32 - required: true - multivalued: false series: name: series description: The PatchClampSeries with the sweep number in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false range: PatchClampSeries required: true - multivalued: true + multivalued: false + inlined: true series_index: name: series_index annotations: @@ -587,5 +694,14 @@ classes: description: Index for series. range: VectorIndex required: true + inlined: true + sweep_number: + name: sweep_number + description: Sweep number of the PatchClampSeries in that row. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: uint32 + required: true multivalued: false tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.image.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.image.yaml index 3a7025a..606ea0a 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.image.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.image.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -37,6 +38,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -56,6 +58,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true value: @@ -80,26 +83,14 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Binary data representing images across frames. - range: numeric - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - array: - dimensions: - - alias: frame - - alias: x - - alias: y - - alias: z + range: ImageSeries__data + inlined: true dimension: name: dimension description: Number of pixels on x, y, (and z) axes. @@ -117,18 +108,72 @@ classes: used if the image is stored in another NWB file and that file is linked to this file. range: ImageSeries__external_file - required: false - multivalued: false + inlined: true format: name: format description: Format of image. If this is 'external', then the attribute 'external_file' contains the path information to the image files. If this is 'raw', then the raw (single-channel) binary data is stored in the 'data' dataset. If this attribute is not present, then the default format='raw' case is assumed. + ifabsent: string(raw) range: text - required: false - multivalued: false tree_root: true + ImageSeries__data: + name: ImageSeries__data + description: Binary data representing images across frames. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - array: + dimensions: + - alias: frame + - alias: x + - alias: y + - alias: z ImageSeries__external_file: name: ImageSeries__external_file description: Paths to one or more external file(s). The field is only present @@ -139,6 +184,7 @@ classes: name: name: name ifabsent: string(external_file) + identifier: true range: string required: true equals_string: external_file @@ -176,6 +222,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true masked_imageseries: @@ -185,7 +232,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string @@ -201,14 +248,19 @@ classes: attributes: name: name: name + identifier: true range: string required: true + data: + name: data + description: Images presented to subject, either grayscale or RGB + range: OpticalSeries__data + required: true + inlined: true distance: name: distance description: Distance from camera/monitor to target/eye. range: float32 - required: false - multivalued: false field_of_view: name: field_of_view description: Width, height and depth of image, or imaged area, in meters. @@ -224,12 +276,56 @@ classes: dimensions: - alias: width_height_depth exact_cardinality: 3 - data: - name: data - description: Images presented to subject, either grayscale or RGB - range: numeric + orientation: + name: orientation + description: Description of image relative to some reference frame (e.g., + which way is up). Must also specify frame of reference. + range: text + tree_root: true + OpticalSeries__data: + name: OpticalSeries__data + description: Images presented to subject, either grayscale or RGB + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string required: true - multivalued: false + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric any_of: - array: dimensions: @@ -243,14 +339,6 @@ classes: - alias: y - alias: r_g_b exact_cardinality: 3 - orientation: - name: orientation - description: Description of image relative to some reference frame (e.g., - which way is up). Must also specify frame of reference. - range: text - required: false - multivalued: false - tree_root: true IndexSeries: name: IndexSeries description: Stores indices to image frames stored in an ImageSeries. The purpose @@ -263,17 +351,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Index of the frame in the referenced ImageSeries. - array: - dimensions: - - alias: num_times - range: int32 + range: IndexSeries__data required: true - multivalued: false + inlined: true indexed_timeseries: name: indexed_timeseries annotations: @@ -281,8 +367,55 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string tree_root: true + IndexSeries__data: + name: IndexSeries__data + description: Index of the frame in the referenced ImageSeries. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + array: + dimensions: + - alias: num_times + range: int32 diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.language.yaml index e42c742..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.misc.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.misc.yaml index f163348..f87b7dc 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.misc.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.misc.yaml @@ -30,6 +30,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -37,7 +38,7 @@ classes: description: Values of each feature at each time. range: AbstractFeatureSeries__data required: true - multivalued: false + inlined: true feature_units: name: feature_units description: Units of each feature. @@ -64,9 +65,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Since there can be different units for different features, store @@ -96,18 +121,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Annotations made during an experiment. + range: AnnotationSeries__data + required: true + inlined: true + tree_root: true + AnnotationSeries__data: + name: AnnotationSeries__data + description: Annotations made during an experiment. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: text - required: true - multivalued: false - tree_root: true IntervalSeries: name: IntervalSeries description: Stores intervals of data. The timestamps field stores the beginning @@ -121,18 +191,63 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Use values >0 if interval started, <0 if interval ended. + range: IntervalSeries__data + required: true + inlined: true + tree_root: true + IntervalSeries__data: + name: IntervalSeries__data + description: Use values >0 if interval started, <0 if interval ended. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data. Annotations + have no units, so the value is fixed to -1.0. + ifabsent: float(-1.0) + range: float32 + required: true + equals_number: -1 + unit: + name: unit + description: Base unit of measurement for working with the data. Annotations + have no units, so the value is fixed to 'n/a'. + ifabsent: string(n/a) + range: text + required: true + equals_string: n/a + value: + name: value array: dimensions: - alias: num_times range: int8 - required: true - multivalued: false - tree_root: true DecompositionSeries: name: DecompositionSeries description: Spectral analysis of a time series, e.g. of an LFP or a speech signal. @@ -140,6 +255,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: @@ -147,28 +263,27 @@ classes: description: Data decomposed into frequency bands. range: DecompositionSeries__data required: true - multivalued: false + inlined: true metric: name: metric description: The metric used, e.g. phase, amplitude, power. range: text required: true - multivalued: false bands: name: bands description: Table for describing the bands that this series was generated from. There should be one row in this table for each band. range: DecompositionSeries__bands required: true - multivalued: false + inlined: true + inlined_as_list: true source_timeseries: name: source_timeseries annotations: source_type: tag: source_type value: link - required: false - multivalued: false + inlined: true any_of: - range: TimeSeries - range: string @@ -180,9 +295,33 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false unit: name: unit description: Base unit of measurement for working with the data. Actual stored @@ -208,6 +347,7 @@ classes: name: name: name ifabsent: string(bands) + identifier: true range: string required: true equals_string: bands @@ -259,10 +399,21 @@ classes: name: name: name ifabsent: string(Units) + identifier: true range: string required: true - spike_times_index: - name: spike_times_index + electrode_group: + name: electrode_group + description: Electrode group that each spike unit came from. + array: + minimum_number_dimensions: 1 + maximum_number_dimensions: false + range: ElectrodeGroup + required: false + multivalued: false + inlined: true + electrodes: + name: electrodes annotations: named: tag: named @@ -270,14 +421,30 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into the spike_times dataset. + description: Electrode that each spike unit came from, specified using a DynamicTableRegion. + range: DynamicTableRegion + inlined: true + electrodes_index: + name: electrodes_index + annotations: + named: + tag: named + value: true + source_type: + tag: source_type + value: neurodata_type_inc + description: Index into electrodes. range: VectorIndex - required: false - multivalued: false - spike_times: - name: spike_times - description: Spike times for each unit. - range: Units__spike_times + inlined: true + obs_intervals: + name: obs_intervals + description: Observation intervals for each unit. + array: + dimensions: + - alias: num_intervals + - alias: start_end + exact_cardinality: 2 + range: float64 required: false multivalued: false obs_intervals_index: @@ -291,21 +458,14 @@ classes: value: neurodata_type_inc description: Index into the obs_intervals dataset. range: VectorIndex - required: false - multivalued: false - obs_intervals: - name: obs_intervals - description: Observation intervals for each unit. - array: - dimensions: - - alias: num_intervals - - alias: start_end - exact_cardinality: 2 - range: float64 - required: false - multivalued: false - electrodes_index: - name: electrodes_index + inlined: true + spike_times: + name: spike_times + description: Spike times for each unit. + range: Units__spike_times + inlined: true + spike_times_index: + name: spike_times_index annotations: named: tag: named @@ -313,61 +473,19 @@ classes: source_type: tag: source_type value: neurodata_type_inc - description: Index into electrodes. + description: Index into the spike_times dataset. range: VectorIndex - required: false - multivalued: false - electrodes: - name: electrodes - annotations: - named: - tag: named - value: true - source_type: - tag: source_type - value: neurodata_type_inc - description: Electrode that each spike unit came from, specified using a DynamicTableRegion. - range: DynamicTableRegion - required: false - multivalued: false - electrode_group: - name: electrode_group - description: Electrode group that each spike unit came from. - range: ElectrodeGroup - required: false - multivalued: true + inlined: true waveform_mean: name: waveform_mean description: Spike waveform mean for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_mean + inlined: true waveform_sd: name: waveform_sd description: Spike waveform standard deviation for each spike unit. - range: float32 - required: false - multivalued: false - any_of: - - array: - dimensions: - - alias: num_units - - alias: num_samples - - array: - dimensions: - - alias: num_units - - alias: num_samples - - alias: num_electrodes + range: Units__waveform_sd + inlined: true tree_root: true Units__spike_times: name: Units__spike_times @@ -377,6 +495,7 @@ classes: name: name: name ifabsent: string(spike_times) + identifier: true range: string required: true equals_string: spike_times @@ -389,3 +508,51 @@ classes: for the spike time to be between samples. range: float64 required: false + Units__waveform_mean: + name: Units__waveform_mean + description: Spike waveform mean for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_mean) + identifier: true + range: string + required: true + equals_string: waveform_mean + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts + Units__waveform_sd: + name: Units__waveform_sd + description: Spike waveform standard deviation for each spike unit. + is_a: VectorData + attributes: + name: + name: name + ifabsent: string(waveform_sd) + identifier: true + range: string + required: true + equals_string: waveform_sd + sampling_rate: + name: sampling_rate + description: Sampling rate, in hertz. + range: float32 + required: false + unit: + name: unit + description: Unit of measurement. This value is fixed to 'volts'. + ifabsent: string(volts) + range: text + required: false + equals_string: volts diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ogen.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ogen.yaml index 08d7a0c..1f47c51 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ogen.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ogen.yaml @@ -21,17 +21,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Applied power for optogenetic stimulus, in watts. - array: - dimensions: - - alias: num_times - range: numeric + range: OptogeneticSeries__data required: true - multivalued: false + inlined: true site: name: site annotations: @@ -39,11 +37,58 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: OptogeneticStimulusSite - range: string tree_root: true + OptogeneticSeries__data: + name: OptogeneticSeries__data + description: Applied power for optogenetic stimulus, in watts. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Unit of measurement for data, which is fixed to 'watts'. + ifabsent: string(watts) + range: text + required: true + equals_string: watts + value: + name: value + array: + dimensions: + - alias: num_times + range: numeric OptogeneticStimulusSite: name: OptogeneticStimulusSite description: A site of optogenetic stimulation. @@ -51,6 +96,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -58,13 +104,11 @@ classes: description: Description of stimulation site. range: text required: true - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false location: name: location description: Location of the stimulation site. Specify the area, layer, comments @@ -72,7 +116,6 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false device: name: device annotations: @@ -80,7 +123,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ophys.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ophys.yaml index f995af9..65ccfe7 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ophys.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.ophys.yaml @@ -23,6 +23,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true pmt_gain: @@ -59,7 +60,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImagingPlane - range: string @@ -72,22 +73,15 @@ classes: attributes: name: name: name + identifier: true range: string required: true data: name: data description: Signals from ROIs. - range: numeric + range: RoiResponseSeries__data required: true - multivalued: false - any_of: - - array: - dimensions: - - alias: num_times - - array: - dimensions: - - alias: num_times - - alias: num_rois + inlined: true rois: name: rois annotations: @@ -101,8 +95,60 @@ classes: on the ROIs stored in this timeseries. range: DynamicTableRegion required: true - multivalued: false + inlined: true tree_root: true + RoiResponseSeries__data: + name: RoiResponseSeries__data + description: Signals from ROIs. + attributes: + name: + name: name + ifabsent: string(data) + identifier: true + range: string + required: true + equals_string: data + conversion: + name: conversion + description: Scalar to multiply each element in data to convert it to the + specified 'unit'. If the data are stored in acquisition system units or + other units that require a conversion to be interpretable, multiply the + data by 'conversion' to convert the data to the specified 'unit'. e.g. if + the data acquisition system stores values in this object as signed 16-bit + integers (int16 range -32,768 to 32,767) that correspond to a 5V range (-2.5V + to 2.5V), and the data acquisition system gain is 8000X, then the 'conversion' + multiplier to get from raw data acquisition values to recorded volts is + 2.5/32768/8000 = 9.5367e-9. + ifabsent: float(1.0) + range: float32 + required: false + resolution: + name: resolution + description: Smallest meaningful difference between values in data, stored + in the specified by unit, e.g., the change in value of the least significant + bit, or a larger number if signal noise is known to be present. If unknown, + use -1.0. + ifabsent: float(-1.0) + range: float32 + required: false + unit: + name: unit + description: Base unit of measurement for working with the data. Actual stored + values are not necessarily stored in these units. To access the data in + these units, multiply 'data' by 'conversion'. + range: text + required: true + value: + name: value + range: numeric + any_of: + - array: + dimensions: + - alias: num_times + - array: + dimensions: + - alias: num_times + - alias: num_rois DfOverF: name: DfOverF description: dF/F information about a region of interest (ROI). Storage hierarchy @@ -110,12 +156,19 @@ classes: for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(DfOverF) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true Fluorescence: name: Fluorescence @@ -124,12 +177,19 @@ classes: for ROIs and for image planes). is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: RoiResponseSeries + name: + name: name + ifabsent: string(Fluorescence) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: RoiResponseSeries tree_root: true ImageSegmentation: name: ImageSegmentation @@ -142,12 +202,19 @@ classes: is required and ROI names should remain consistent between them. is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: PlaneSegmentation + name: + name: name + ifabsent: string(ImageSegmentation) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: PlaneSegmentation tree_root: true PlaneSegmentation: name: PlaneSegmentation @@ -156,15 +223,35 @@ classes: attributes: name: name: name + identifier: true range: string required: true image_mask: name: image_mask description: ROI masks for each ROI. Each image mask is the size of the original imaging plane (or volume) and members of the ROI are finite non-zero. - range: PlaneSegmentation__image_mask + range: AnyType required: false multivalued: false + any_of: + - array: + dimensions: + - alias: num_roi + - alias: num_x + - alias: num_y + - array: + dimensions: + - alias: num_roi + - alias: num_x + - alias: num_y + - alias: num_z + pixel_mask: + name: pixel_mask + description: 'Pixel masks for each ROI: a list of indices and weights for + the ROI. Pixel masks are concatenated and parsing of this dataset is maintained + by the PlaneSegmentation' + range: PlaneSegmentation__pixel_mask + inlined: true pixel_mask_index: name: pixel_mask_index annotations: @@ -176,16 +263,14 @@ classes: value: neurodata_type_inc description: Index into pixel_mask. range: VectorIndex - required: false - multivalued: false - pixel_mask: - name: pixel_mask - description: 'Pixel masks for each ROI: a list of indices and weights for - the ROI. Pixel masks are concatenated and parsing of this dataset is maintained + inlined: true + voxel_mask: + name: voxel_mask + description: 'Voxel masks for each ROI: a list of indices and weights for + the ROI. Voxel masks are concatenated and parsing of this dataset is maintained by the PlaneSegmentation' - range: PlaneSegmentation__pixel_mask - required: false - multivalued: false + range: PlaneSegmentation__voxel_mask + inlined: true voxel_mask_index: name: voxel_mask_index annotations: @@ -197,16 +282,7 @@ classes: value: neurodata_type_inc description: Index into voxel_mask. range: VectorIndex - required: false - multivalued: false - voxel_mask: - name: voxel_mask - description: 'Voxel masks for each ROI: a list of indices and weights for - the ROI. Voxel masks are concatenated and parsing of this dataset is maintained - by the PlaneSegmentation' - range: PlaneSegmentation__voxel_mask - required: false - multivalued: false + inlined: true reference_images: name: reference_images description: Image stacks that the segmentation masks apply to. @@ -222,23 +298,11 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImagingPlane - range: string tree_root: true - PlaneSegmentation__image_mask: - name: PlaneSegmentation__image_mask - description: ROI masks for each ROI. Each image mask is the size of the original - imaging plane (or volume) and members of the ROI are finite non-zero. - is_a: VectorData - attributes: - name: - name: name - ifabsent: string(image_mask) - range: string - required: true - equals_string: image_mask PlaneSegmentation__pixel_mask: name: PlaneSegmentation__pixel_mask description: 'Pixel masks for each ROI: a list of indices and weights for the @@ -249,6 +313,7 @@ classes: name: name: name ifabsent: string(pixel_mask) + identifier: true range: string required: true equals_string: pixel_mask @@ -258,24 +323,18 @@ classes: array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false y: name: y description: Pixel y-coordinate. array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false weight: name: weight description: Weight of the pixel. array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false PlaneSegmentation__voxel_mask: name: PlaneSegmentation__voxel_mask description: 'Voxel masks for each ROI: a list of indices and weights for the @@ -286,6 +345,7 @@ classes: name: name: name ifabsent: string(voxel_mask) + identifier: true range: string required: true equals_string: voxel_mask @@ -295,32 +355,24 @@ classes: array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false y: name: y description: Voxel y-coordinate. array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false z: name: z description: Voxel z-coordinate. array: exact_number_dimensions: 1 range: uint32 - required: false - multivalued: false weight: name: weight description: Weight of the voxel. array: exact_number_dimensions: 1 range: float32 - required: false - multivalued: false ImagingPlane: name: ImagingPlane description: An imaging plane and its metadata. @@ -328,33 +380,28 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: name: description description: Description of the imaging plane. range: text - required: false - multivalued: false excitation_lambda: name: excitation_lambda description: Excitation wavelength, in nm. range: float32 required: true - multivalued: false imaging_rate: name: imaging_rate description: Rate that images are acquired, in Hz. If the corresponding TimeSeries is present, the rate should be stored there instead. range: float32 - required: false - multivalued: false indicator: name: indicator description: Calcium indicator. range: text required: true - multivalued: false location: name: location description: Location of the imaging plane. Specify the area, layer, comments @@ -362,31 +409,27 @@ classes: standard atlas names for anatomical regions when possible. range: text required: true - multivalued: false manifold: name: manifold description: DEPRECATED Physical position of each pixel. 'xyz' represents the position of the pixel relative to the defined coordinate space. Deprecated in favor of origin_coords and grid_spacing. range: ImagingPlane__manifold - required: false - multivalued: false + inlined: true origin_coords: name: origin_coords description: Physical location of the first element of the imaging plane (0, 0) for 2-D data or (0, 0, 0) for 3-D data. See also reference_frame for what the physical location is relative to (e.g., bregma). range: ImagingPlane__origin_coords - required: false - multivalued: false + inlined: true grid_spacing: name: grid_spacing description: Space between pixels in (x, y) or voxels in (x, y, z) directions, in the specified unit. Assumes imaging plane is a regular grid. See also reference_frame to interpret the grid. range: ImagingPlane__grid_spacing - required: false - multivalued: false + inlined: true reference_frame: name: reference_frame description: Describes reference frame of origin_coords and grid_spacing. @@ -407,14 +450,14 @@ classes: axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral)." range: text - required: false - multivalued: false optical_channel: name: optical_channel description: An optical channel used to record from an imaging plane. range: OpticalChannel required: true multivalued: true + inlined: true + inlined_as_list: false device: name: device annotations: @@ -422,7 +465,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: Device - range: string @@ -436,6 +479,7 @@ classes: name: name: name ifabsent: string(manifold) + identifier: true range: string required: true equals_string: manifold @@ -485,6 +529,7 @@ classes: name: name: name ifabsent: string(origin_coords) + identifier: true range: string required: true equals_string: origin_coords @@ -515,6 +560,7 @@ classes: name: name: name ifabsent: string(grid_spacing) + identifier: true range: string required: true equals_string: grid_spacing @@ -543,6 +589,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -550,13 +597,11 @@ classes: description: Description or other notes about the channel. range: text required: true - multivalued: false emission_lambda: name: emission_lambda description: Emission wavelength for channel, in nm. range: float32 required: true - multivalued: false tree_root: true MotionCorrection: name: MotionCorrection @@ -565,12 +610,19 @@ classes: frame at each point in time is assumed to be 2-D (has only x & y dimensions).' is_a: NWBDataInterface attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: CorrectedImageStack + name: + name: name + ifabsent: string(MotionCorrection) + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: CorrectedImageStack tree_root: true CorrectedImageStack: name: CorrectedImageStack @@ -579,6 +631,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true corrected: @@ -586,14 +639,16 @@ classes: description: Image stack with frames shifted to the common coordinates. range: ImageSeries required: true - multivalued: false + inlined: true + inlined_as_list: false xy_translation: name: xy_translation description: Stores the x,y delta necessary to align each frame to the common coordinates, for example, to align each frame to a reference image. range: TimeSeries required: true - multivalued: false + inlined: true + inlined_as_list: false original: name: original annotations: @@ -601,7 +656,7 @@ classes: tag: source_type value: link required: true - multivalued: false + inlined: true any_of: - range: ImageSeries - range: string diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.retinotopy.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.retinotopy.yaml index 457b1cc..dcc5bd1 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.retinotopy.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_2_5/core.nwb.retinotopy.yaml @@ -29,6 +29,7 @@ classes: name: name: name ifabsent: string(ImagingRetinotopy) + identifier: true range: string required: true axis_1_phase_map: @@ -36,27 +37,25 @@ classes: description: Phase response to stimulus on the first measured axis. range: ImagingRetinotopy__axis_1_phase_map required: true - multivalued: false + inlined: true axis_1_power_map: name: axis_1_power_map description: Power response on the first measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: ImagingRetinotopy__axis_1_power_map - required: false - multivalued: false + inlined: true axis_2_phase_map: name: axis_2_phase_map description: Phase response to stimulus on the second measured axis. range: ImagingRetinotopy__axis_2_phase_map required: true - multivalued: false + inlined: true axis_2_power_map: name: axis_2_power_map description: Power response on the second measured axis. Response is scaled so 0.0 is no power in the response and 1.0 is maximum relative power. range: ImagingRetinotopy__axis_2_power_map - required: false - multivalued: false + inlined: true axis_descriptions: name: axis_descriptions description: Two-element array describing the contents of the two response @@ -74,22 +73,20 @@ classes: description: 'Gray-scale image taken with same settings/parameters (e.g., focal depth, wavelength) as data collection. Array format: [rows][columns].' range: ImagingRetinotopy__focal_depth_image - required: false - multivalued: false + inlined: true sign_map: name: sign_map description: Sine of the angle between the direction of the gradient in axis_1 and axis_2. range: ImagingRetinotopy__sign_map - required: false - multivalued: false + inlined: true vasculature_image: name: vasculature_image description: 'Gray-scale anatomical image of cortical surface. Array structure: [rows][columns]' range: ImagingRetinotopy__vasculature_image required: true - multivalued: false + inlined: true tree_root: true ImagingRetinotopy__axis_1_phase_map: name: ImagingRetinotopy__axis_1_phase_map @@ -98,6 +95,7 @@ classes: name: name: name ifabsent: string(axis_1_phase_map) + identifier: true range: string required: true equals_string: axis_1_phase_map @@ -134,6 +132,7 @@ classes: name: name: name ifabsent: string(axis_1_power_map) + identifier: true range: string required: true equals_string: axis_1_power_map @@ -169,6 +168,7 @@ classes: name: name: name ifabsent: string(axis_2_phase_map) + identifier: true range: string required: true equals_string: axis_2_phase_map @@ -205,6 +205,7 @@ classes: name: name: name ifabsent: string(axis_2_power_map) + identifier: true range: string required: true equals_string: axis_2_power_map @@ -241,6 +242,7 @@ classes: name: name: name ifabsent: string(focal_depth_image) + identifier: true range: string required: true equals_string: focal_depth_image @@ -288,6 +290,7 @@ classes: name: name: name ifabsent: string(sign_map) + identifier: true range: string required: true equals_string: sign_map @@ -319,6 +322,7 @@ classes: name: name: name ifabsent: string(vasculature_image) + identifier: true range: string required: true equals_string: vasculature_image diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.nwb.language.yaml index 50aeafe..ae091de 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.sparse.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.sparse.yaml index 8220620..ef78169 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.sparse.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.sparse.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true shape: @@ -35,19 +36,19 @@ classes: description: column indices range: CSRMatrix__indices required: true - multivalued: false + inlined: true indptr: name: indptr description: index pointer range: CSRMatrix__indptr required: true - multivalued: false + inlined: true data: name: data description: values in the matrix range: CSRMatrix__data required: true - multivalued: false + inlined: true tree_root: true CSRMatrix__indices: name: CSRMatrix__indices @@ -56,6 +57,7 @@ classes: name: name: name ifabsent: string(indices) + identifier: true range: string required: true equals_string: indices @@ -66,6 +68,7 @@ classes: name: name: name ifabsent: string(indptr) + identifier: true range: string required: true equals_string: indptr @@ -76,6 +79,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.table.yaml index a38fa1a..e3aa6a7 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_0/hdmf-common.table.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -28,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -35,6 +37,7 @@ classes: description: Target dataset that this index applies to. range: Data required: true + inlined: true tree_root: true VectorData: name: VectorData @@ -50,6 +53,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -67,6 +71,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -74,6 +79,7 @@ classes: description: Reference to the target dataset that this index applies to. range: VectorData required: true + inlined: true tree_root: true ElementIdentifiers: name: ElementIdentifiers @@ -84,6 +90,7 @@ classes: name: name: name ifabsent: string(element_id) + identifier: true range: string required: true value: @@ -108,19 +115,21 @@ classes: attributes: name: name: name + identifier: true range: string required: true + description: + name: description + description: Description of what this table region points to. + range: text + required: true table: name: table description: Reference to the DynamicTable object that this region applies to. range: DynamicTable required: true - description: - name: description - description: Description of what this table region points to. - range: text - required: true + inlined: true tree_root: true Container: name: Container @@ -129,6 +138,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -159,6 +169,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true colnames: @@ -182,16 +193,4 @@ classes: range: int required: true multivalued: false - vector_data: - name: vector_data - description: Vector columns of this dynamic table. - range: VectorData - required: false - multivalued: true - vector_index: - name: vector_index - description: Indices for the vector columns of this dynamic table. - range: VectorIndex - required: false - multivalued: true tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.nwb.language.yaml index 50aeafe..ae091de 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.sparse.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.sparse.yaml index 42a1170..ddbc847 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.sparse.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.sparse.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true shape: @@ -35,19 +36,19 @@ classes: description: column indices range: CSRMatrix__indices required: true - multivalued: false + inlined: true indptr: name: indptr description: index pointer range: CSRMatrix__indptr required: true - multivalued: false + inlined: true data: name: data description: values in the matrix range: CSRMatrix__data required: true - multivalued: false + inlined: true tree_root: true CSRMatrix__indices: name: CSRMatrix__indices @@ -56,6 +57,7 @@ classes: name: name: name ifabsent: string(indices) + identifier: true range: string required: true equals_string: indices @@ -66,6 +68,7 @@ classes: name: name: name ifabsent: string(indptr) + identifier: true range: string required: true equals_string: indptr @@ -76,6 +79,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.table.yaml index a668487..43c39ed 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_2/hdmf-common.table.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -28,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -35,6 +37,7 @@ classes: description: Target dataset that this index applies to. range: Data required: true + inlined: true tree_root: true VectorData: name: VectorData @@ -50,6 +53,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -67,6 +71,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -74,6 +79,7 @@ classes: description: Reference to the target dataset that this index applies to. range: VectorData required: true + inlined: true tree_root: true ElementIdentifiers: name: ElementIdentifiers @@ -84,6 +90,7 @@ classes: name: name: name ifabsent: string(element_id) + identifier: true range: string required: true value: @@ -108,19 +115,21 @@ classes: attributes: name: name: name + identifier: true range: string required: true + description: + name: description + description: Description of what this table region points to. + range: text + required: true table: name: table description: Reference to the DynamicTable object that this region applies to. range: DynamicTable required: true - description: - name: description - description: Description of what this table region points to. - range: text - required: true + inlined: true tree_root: true Container: name: Container @@ -129,6 +138,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -159,6 +169,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true colnames: @@ -182,16 +193,4 @@ classes: range: int required: true multivalued: false - vector_data: - name: vector_data - description: Vector columns of this dynamic table. - range: VectorData - required: false - multivalued: true - vector_index: - name: vector_index - description: Indices for the vector columns of this dynamic table. - range: VectorIndex - required: false - multivalued: true tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.nwb.language.yaml index 50aeafe..ae091de 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.sparse.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.sparse.yaml index bdb5f39..1108ce6 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.sparse.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.sparse.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true shape: @@ -35,19 +36,19 @@ classes: description: column indices range: CSRMatrix__indices required: true - multivalued: false + inlined: true indptr: name: indptr description: index pointer range: CSRMatrix__indptr required: true - multivalued: false + inlined: true data: name: data description: values in the matrix range: CSRMatrix__data required: true - multivalued: false + inlined: true tree_root: true CSRMatrix__indices: name: CSRMatrix__indices @@ -56,6 +57,7 @@ classes: name: name: name ifabsent: string(indices) + identifier: true range: string required: true equals_string: indices @@ -66,6 +68,7 @@ classes: name: name: name ifabsent: string(indptr) + identifier: true range: string required: true equals_string: indptr @@ -76,6 +79,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.table.yaml index 1022ebf..5da5bf4 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_1_3/hdmf-common.table.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -28,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -35,6 +37,7 @@ classes: description: Target dataset that this index applies to. range: Data required: true + inlined: true tree_root: true VectorData: name: VectorData @@ -50,6 +53,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -89,6 +93,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -96,6 +101,7 @@ classes: description: Reference to the target dataset that this index applies to. range: VectorData required: true + inlined: true value: name: value array: @@ -112,6 +118,7 @@ classes: name: name: name ifabsent: string(element_id) + identifier: true range: string required: true value: @@ -136,19 +143,21 @@ classes: attributes: name: name: name + identifier: true range: string required: true + description: + name: description + description: Description of what this table region points to. + range: text + required: true table: name: table description: Reference to the DynamicTable object that this region applies to. range: DynamicTable required: true - description: - name: description - description: Description of what this table region points to. - range: text - required: true + inlined: true tree_root: true Container: name: Container @@ -157,6 +166,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -187,6 +197,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true colnames: @@ -210,16 +221,4 @@ classes: range: int required: true multivalued: false - vector_data: - name: vector_data - description: Vector columns of this dynamic table. - range: VectorData - required: false - multivalued: true - vector_index: - name: vector_index - description: Indices for the vector columns of this dynamic table. - range: VectorIndex - required: false - multivalued: true tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.base.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.base.yaml index ff30beb..ddb4ce8 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.base.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -28,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.nwb.language.yaml index 50aeafe..ae091de 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.sparse.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.sparse.yaml index c32033d..f1634f5 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.sparse.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.sparse.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true shape: @@ -35,19 +36,19 @@ classes: description: column indices range: CSRMatrix__indices required: true - multivalued: false + inlined: true indptr: name: indptr description: index pointer range: CSRMatrix__indptr required: true - multivalued: false + inlined: true data: name: data description: values in the matrix range: CSRMatrix__data required: true - multivalued: false + inlined: true tree_root: true CSRMatrix__indices: name: CSRMatrix__indices @@ -56,6 +57,7 @@ classes: name: name: name ifabsent: string(indices) + identifier: true range: string required: true equals_string: indices @@ -66,6 +68,7 @@ classes: name: name: name ifabsent: string(indptr) + identifier: true range: string required: true equals_string: indptr @@ -76,6 +79,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.table.yaml index e7f4d41..9bab34b 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_0/hdmf-common.table.yaml @@ -27,6 +27,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -68,6 +69,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -75,6 +77,7 @@ classes: description: Reference to the target dataset that this index applies to. range: VectorData required: true + inlined: true tree_root: true ElementIdentifiers: name: ElementIdentifiers @@ -85,6 +88,7 @@ classes: name: name: name ifabsent: string(element_id) + identifier: true range: string required: true value: @@ -109,19 +113,21 @@ classes: attributes: name: name: name + identifier: true range: string required: true + description: + name: description + description: Description of what this table region points to. + range: text + required: true table: name: table description: Reference to the DynamicTable object that this region applies to. range: DynamicTable required: true - description: - name: description - description: Description of what this table region points to. - range: text - required: true + inlined: true tree_root: true VocabData: name: VocabData @@ -131,6 +137,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true vocabulary: @@ -167,6 +174,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true colnames: @@ -190,10 +198,4 @@ classes: range: int required: true multivalued: false - vector_data: - name: vector_data - description: Vector columns, including index columns, of this dynamic table. - range: VectorData - required: false - multivalued: true tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.base.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.base.yaml index 253e3a0..d6ac73a 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.base.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -28,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -36,10 +38,16 @@ classes: description: A simple Container for holding onto multiple containers is_a: Container attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: Container + name: + name: name + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: Container tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.nwb.language.yaml index 50aeafe..ae091de 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.sparse.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.sparse.yaml index 3168d8a..e27c22d 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.sparse.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.sparse.yaml @@ -20,6 +20,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true shape: @@ -37,19 +38,19 @@ classes: description: column indices range: CSRMatrix__indices required: true - multivalued: false + inlined: true indptr: name: indptr description: index pointer range: CSRMatrix__indptr required: true - multivalued: false + inlined: true data: name: data description: values in the matrix range: CSRMatrix__data required: true - multivalued: false + inlined: true tree_root: true CSRMatrix__indices: name: CSRMatrix__indices @@ -58,6 +59,7 @@ classes: name: name: name ifabsent: string(indices) + identifier: true range: string required: true equals_string: indices @@ -68,6 +70,7 @@ classes: name: name: name ifabsent: string(indptr) + identifier: true range: string required: true equals_string: indptr @@ -78,6 +81,7 @@ classes: name: name: name ifabsent: string(data) + identifier: true range: string required: true equals_string: data diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.table.yaml index b506697..3f4a272 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_2_1/hdmf-common.table.yaml @@ -27,6 +27,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -68,6 +69,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -75,6 +77,7 @@ classes: description: Reference to the target dataset that this index applies to. range: VectorData required: true + inlined: true tree_root: true ElementIdentifiers: name: ElementIdentifiers @@ -85,6 +88,7 @@ classes: name: name: name ifabsent: string(element_id) + identifier: true range: string required: true value: @@ -109,19 +113,21 @@ classes: attributes: name: name: name + identifier: true range: string required: true + description: + name: description + description: Description of what this table region points to. + range: text + required: true table: name: table description: Reference to the DynamicTable object that this region applies to. range: DynamicTable required: true - description: - name: description - description: Description of what this table region points to. - range: text - required: true + inlined: true tree_root: true VocabData: name: VocabData @@ -131,6 +137,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true vocabulary: @@ -167,6 +174,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true colnames: @@ -190,10 +198,4 @@ classes: range: int required: true multivalued: false - vector_data: - name: vector_data - description: Vector columns, including index columns, of this dynamic table. - range: VectorData - required: false - multivalued: true tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.base.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.base.yaml index 3f8d165..c0c9a0f 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.base.yaml @@ -18,6 +18,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -28,6 +29,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true tree_root: true @@ -36,10 +38,16 @@ classes: description: A simple Container for holding onto multiple containers. is_a: Container attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: Container + name: + name: name + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: Container tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.nwb.language.yaml index 50aeafe..ae091de 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.nwb.language.yaml @@ -66,6 +66,7 @@ types: numeric: name: numeric typeof: float + repr: float | int text: name: text typeof: string @@ -87,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.resources.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.resources.yaml index 3bbb768..1730e3e 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.resources.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.resources.yaml @@ -22,6 +22,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true keys: @@ -30,26 +31,26 @@ classes: resources. range: ExternalResources__keys required: true - multivalued: false + inlined: true resources: name: resources description: A table for mapping user terms (i.e., keys) to resource entities. range: ExternalResources__resources required: true - multivalued: false + inlined: true objects: name: objects description: A table for identifying which objects in a file contain references to external resources. range: ExternalResources__objects required: true - multivalued: false + inlined: true object_keys: name: object_keys description: A table for identifying which objects use which keys. range: ExternalResources__object_keys required: true - multivalued: false + inlined: true tree_root: true ExternalResources__keys: name: ExternalResources__keys @@ -60,6 +61,7 @@ classes: name: name: name ifabsent: string(keys) + identifier: true range: string required: true equals_string: keys @@ -71,7 +73,6 @@ classes: exact_number_dimensions: 1 range: text required: true - multivalued: false ExternalResources__resources: name: ExternalResources__resources description: A table for mapping user terms (i.e., keys) to resource entities. @@ -80,6 +81,7 @@ classes: name: name: name ifabsent: string(resources) + identifier: true range: string required: true equals_string: resources @@ -90,7 +92,6 @@ classes: exact_number_dimensions: 1 range: uint required: true - multivalued: false resource_name: name: resource_name description: The name of the online resource (e.g., website, database) that @@ -99,7 +100,6 @@ classes: exact_number_dimensions: 1 range: text required: true - multivalued: false resource_id: name: resource_id description: The unique identifier for the resource entity at the resource. @@ -107,7 +107,6 @@ classes: exact_number_dimensions: 1 range: text required: true - multivalued: false uri: name: uri description: The URI for the resource entity this reference applies to. This @@ -116,7 +115,6 @@ classes: exact_number_dimensions: 1 range: text required: true - multivalued: false ExternalResources__objects: name: ExternalResources__objects description: A table for identifying which objects in a file contain references @@ -126,6 +124,7 @@ classes: name: name: name ifabsent: string(objects) + identifier: true range: string required: true equals_string: objects @@ -136,7 +135,6 @@ classes: exact_number_dimensions: 1 range: text required: true - multivalued: false field: name: field description: The field of the object. This can be an empty string if the object @@ -145,7 +143,6 @@ classes: exact_number_dimensions: 1 range: text required: true - multivalued: false ExternalResources__object_keys: name: ExternalResources__object_keys description: A table for identifying which objects use which keys. @@ -154,6 +151,7 @@ classes: name: name: name ifabsent: string(object_keys) + identifier: true range: string required: true equals_string: object_keys @@ -165,7 +163,6 @@ classes: exact_number_dimensions: 1 range: uint required: true - multivalued: false keytable_idx: name: keytable_idx description: The index to the 'keys' table for the key. @@ -173,4 +170,3 @@ classes: exact_number_dimensions: 1 range: uint required: true - multivalued: false diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.sparse.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.sparse.yaml index 55db34f..7e02eaa 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.sparse.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.sparse.yaml @@ -22,6 +22,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true shape: @@ -52,17 +53,10 @@ classes: data: name: data description: The non-zero values in the matrix. - range: CSRMatrix__data + array: + dimensions: + - alias: number_of_non_zero_values + range: AnyType required: true multivalued: false tree_root: true - CSRMatrix__data: - name: CSRMatrix__data - description: The non-zero values in the matrix. - attributes: - name: - name: name - ifabsent: string(data) - range: string - required: true - equals_string: data diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.table.yaml index 94bb9f7..0281a27 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_3_0/hdmf-common.table.yaml @@ -27,6 +27,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true description: @@ -68,6 +69,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true target: @@ -75,6 +77,7 @@ classes: description: Reference to the target dataset that this index applies to. range: VectorData required: true + inlined: true tree_root: true ElementIdentifiers: name: ElementIdentifiers @@ -85,6 +88,7 @@ classes: name: name: name ifabsent: string(element_id) + identifier: true range: string required: true value: @@ -109,19 +113,21 @@ classes: attributes: name: name: name + identifier: true range: string required: true + description: + name: description + description: Description of what this table region points to. + range: text + required: true table: name: table description: Reference to the DynamicTable object that this region applies to. range: DynamicTable required: true - description: - name: description - description: Description of what this table region points to. - range: text - required: true + inlined: true tree_root: true VocabData: name: VocabData @@ -131,6 +137,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true vocabulary: @@ -167,6 +174,7 @@ classes: attributes: name: name: name + identifier: true range: string required: true colnames: @@ -190,10 +198,4 @@ classes: range: int required: true multivalued: false - vector_data: - name: vector_data - description: Vector columns, including index columns, of this dynamic table. - range: VectorData - required: false - multivalued: true tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml index 2a10ba2..b0b87d5 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml @@ -9,7 +9,7 @@ annotations: id: hdmf-experimental.experimental version: 0.1.0 imports: -- ../../hdmf_common/v1_4_0/namespace +- ../../hdmf_common/v1_5_0/namespace - hdmf-experimental.nwb.language default_prefix: hdmf-experimental.experimental/ classes: diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml index a8d955d..9aeb7d0 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml @@ -9,7 +9,7 @@ annotations: id: hdmf-experimental.resources version: 0.1.0 imports: -- ../../hdmf_common/v1_4_0/namespace +- ../../hdmf_common/v1_5_0/namespace - hdmf-experimental.nwb.language default_prefix: hdmf-experimental.resources/ classes: