regenerate models

This commit is contained in:
sneakers-the-rat 2024-08-13 21:26:50 -07:00
parent 01e46f7531
commit 980db25b15
Signed by untrusted user who does not match committer: jonny
GPG key ID: 6DCB96EF1E4D232D
63 changed files with 1391 additions and 712 deletions

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -164,7 +164,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -394,7 +394,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: NDArray[Any, float] = Field( x: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -403,7 +403,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: NDArray[Any, float] = Field( y: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -412,7 +412,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: NDArray[Any, float] = Field( z: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -421,7 +421,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: NDArray[Any, float] = Field( imp: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Impedance of the channel.""", description="""Impedance of the channel.""",
json_schema_extra={ json_schema_extra={
@ -430,7 +430,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -439,7 +439,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: NDArray[Any, float] = Field( filtering: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Description of hardware filtering.""", description="""Description of hardware filtering.""",
json_schema_extra={ json_schema_extra={
@ -451,7 +451,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -460,7 +460,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -469,7 +469,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -478,7 +478,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -487,7 +487,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference used for this electrode.""", description="""Description of the reference used for this electrode.""",
json_schema_extra={ json_schema_extra={
@ -501,7 +501,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -864,7 +864,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -893,7 +893,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -401,7 +401,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -410,7 +410,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -424,12 +424,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -439,7 +439,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -489,19 +489,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -530,16 +532,20 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
colnames: List[str] = Field( colnames: List[str] = Field(
@ -547,7 +553,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -164,7 +164,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -394,7 +394,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: NDArray[Any, float] = Field( x: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -403,7 +403,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: NDArray[Any, float] = Field( y: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -412,7 +412,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: NDArray[Any, float] = Field( z: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -421,7 +421,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: NDArray[Any, float] = Field( imp: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Impedance of the channel.""", description="""Impedance of the channel.""",
json_schema_extra={ json_schema_extra={
@ -430,7 +430,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -439,7 +439,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: NDArray[Any, float] = Field( filtering: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Description of hardware filtering.""", description="""Description of hardware filtering.""",
json_schema_extra={ json_schema_extra={
@ -451,7 +451,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -460,7 +460,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -469,7 +469,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -478,7 +478,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -487,7 +487,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference used for this electrode.""", description="""Description of the reference used for this electrode.""",
json_schema_extra={ json_schema_extra={
@ -501,7 +501,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -864,7 +864,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -893,7 +893,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -401,7 +401,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -410,7 +410,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -424,12 +424,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -439,7 +439,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -489,19 +489,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -530,16 +532,20 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
colnames: List[str] = Field( colnames: List[str] = Field(
@ -547,7 +553,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -164,7 +164,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -394,7 +394,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: NDArray[Any, float] = Field( x: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -403,7 +403,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: NDArray[Any, float] = Field( y: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -412,7 +412,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: NDArray[Any, float] = Field( z: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -421,7 +421,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: NDArray[Any, float] = Field( imp: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Impedance of the channel.""", description="""Impedance of the channel.""",
json_schema_extra={ json_schema_extra={
@ -430,7 +430,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -439,7 +439,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: NDArray[Any, float] = Field( filtering: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Description of hardware filtering.""", description="""Description of hardware filtering.""",
json_schema_extra={ json_schema_extra={
@ -451,7 +451,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -460,7 +460,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -469,7 +469,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -478,7 +478,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -487,7 +487,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference used for this electrode.""", description="""Description of the reference used for this electrode.""",
json_schema_extra={ json_schema_extra={
@ -501,7 +501,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -864,7 +864,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -893,7 +893,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -401,7 +401,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -410,7 +410,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -424,12 +424,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -439,7 +439,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -489,19 +489,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -530,16 +532,20 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
colnames: List[str] = Field( colnames: List[str] = Field(
@ -547,7 +553,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -164,7 +164,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -370,7 +370,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: NDArray[Any, float] = Field( x: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -379,7 +379,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: NDArray[Any, float] = Field( y: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -388,7 +388,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: NDArray[Any, float] = Field( z: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -397,7 +397,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: NDArray[Any, float] = Field( imp: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Impedance of the channel.""", description="""Impedance of the channel.""",
json_schema_extra={ json_schema_extra={
@ -406,7 +406,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -415,7 +415,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: NDArray[Any, float] = Field( filtering: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Description of hardware filtering.""", description="""Description of hardware filtering.""",
json_schema_extra={ json_schema_extra={
@ -427,7 +427,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -436,7 +436,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -445,7 +445,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -454,7 +454,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -463,7 +463,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference used for this electrode.""", description="""Description of the reference used for this electrode.""",
json_schema_extra={ json_schema_extra={
@ -477,7 +477,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -864,7 +864,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -893,7 +893,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -401,7 +401,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -410,7 +410,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -424,12 +424,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -439,7 +439,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -489,19 +489,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -530,16 +532,20 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
colnames: List[str] = Field( colnames: List[str] = Field(
@ -547,7 +553,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -369,7 +369,7 @@ class PlaneSegmentation(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -164,7 +164,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -370,7 +370,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: NDArray[Any, float] = Field( x: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -379,7 +379,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: NDArray[Any, float] = Field( y: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -388,7 +388,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: NDArray[Any, float] = Field( z: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -397,7 +397,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: NDArray[Any, float] = Field( imp: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Impedance of the channel.""", description="""Impedance of the channel.""",
json_schema_extra={ json_schema_extra={
@ -406,7 +406,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -415,7 +415,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: NDArray[Any, float] = Field( filtering: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Description of hardware filtering.""", description="""Description of hardware filtering.""",
json_schema_extra={ json_schema_extra={
@ -427,7 +427,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -436,7 +436,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -445,7 +445,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -454,7 +454,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -463,7 +463,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference used for this electrode.""", description="""Description of the reference used for this electrode.""",
json_schema_extra={ json_schema_extra={
@ -477,7 +477,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -864,7 +864,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -893,7 +893,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -401,7 +401,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -410,7 +410,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -424,12 +424,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -439,7 +439,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -489,19 +489,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -530,16 +532,20 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
colnames: List[str] = Field( colnames: List[str] = Field(
@ -547,7 +553,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -371,7 +371,7 @@ class PlaneSegmentation(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -164,7 +164,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -370,7 +370,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: NDArray[Any, float] = Field( x: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -379,7 +379,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: NDArray[Any, float] = Field( y: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -388,7 +388,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: NDArray[Any, float] = Field( z: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -397,7 +397,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: NDArray[Any, float] = Field( imp: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Impedance of the channel, in ohms.""", description="""Impedance of the channel, in ohms.""",
json_schema_extra={ json_schema_extra={
@ -406,7 +406,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -415,7 +415,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: NDArray[Any, float] = Field( filtering: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Description of hardware filtering, including the filter name and frequency cutoffs.""", description="""Description of hardware filtering, including the filter name and frequency cutoffs.""",
json_schema_extra={ json_schema_extra={
@ -427,7 +427,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -436,7 +436,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -445,7 +445,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -454,7 +454,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -463,7 +463,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference used for this electrode.""", description="""Description of the reference used for this electrode.""",
json_schema_extra={ json_schema_extra={
@ -477,7 +477,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -866,7 +866,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -895,7 +895,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -413,7 +413,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -422,7 +422,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -436,12 +436,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -451,7 +451,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -498,19 +498,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -539,26 +541,32 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
waveforms: Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]] = Field( waveforms: VectorData[Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]]] = (
None, Field(
description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""", None,
json_schema_extra={ description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""",
"linkml_meta": { json_schema_extra={
"array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]} "linkml_meta": {
} "array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]}
}, }
},
)
) )
waveforms_index: Named[Optional[VectorIndex]] = Field( waveforms_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -589,7 +597,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -380,7 +380,7 @@ class PlaneSegmentation(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -5,7 +5,20 @@ from enum import Enum
import re import re
import sys import sys
import numpy as np import numpy as np
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, overload, Iterable, Tuple from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator
from ...hdmf_common.v1_5_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_5_0.hdmf_common_base import Data, Container
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
@ -58,8 +71,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -67,7 +82,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -125,6 +140,9 @@ class TimeSeriesReferenceVectorDataMixin(VectorDataMixin):
@model_validator(mode="after") @model_validator(mode="after")
def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin": def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin":
"""
Each of the three indexing columns must be the same length to work!
"""
assert len(self.idx_start) == len(self.timeseries) == len(self.count), ( assert len(self.idx_start) == len(self.timeseries) == len(self.count), (
f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)}," f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)},"
f" timeseries: {len(self.timeseries)}" f" timeseries: {len(self.timeseries)}"

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -164,7 +164,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -378,7 +378,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: NDArray[Any, float] = Field( x: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -387,7 +387,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: NDArray[Any, float] = Field( y: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -396,7 +396,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: NDArray[Any, float] = Field( z: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -405,7 +405,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: NDArray[Any, float] = Field( imp: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Impedance of the channel, in ohms.""", description="""Impedance of the channel, in ohms.""",
json_schema_extra={ json_schema_extra={
@ -414,7 +414,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -423,7 +423,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: NDArray[Any, str] = Field( filtering: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Description of hardware filtering, including the filter name and frequency cutoffs.""", description="""Description of hardware filtering, including the filter name and frequency cutoffs.""",
json_schema_extra={ json_schema_extra={
@ -435,7 +435,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -444,7 +444,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -453,7 +453,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -462,7 +462,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -471,7 +471,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference used for this electrode.""", description="""Description of the reference used for this electrode.""",
json_schema_extra={ json_schema_extra={
@ -485,7 +485,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -873,7 +873,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -902,7 +902,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -939,7 +939,7 @@ class IntracellularElectrodesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -985,7 +985,7 @@ class IntracellularStimuliTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1031,7 +1031,7 @@ class IntracellularResponsesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1097,7 +1097,7 @@ class IntracellularRecordingsTable(AlignedDynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1146,7 +1146,7 @@ class SimultaneousRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1220,7 +1220,7 @@ class SequentialRecordingsTable(DynamicTable):
} }
}, },
) )
stimulus_type: NDArray[Any, str] = Field( stimulus_type: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""The type of stimulus used for the sequential recording.""", description="""The type of stimulus used for the sequential recording.""",
json_schema_extra={ json_schema_extra={
@ -1234,7 +1234,7 @@ class SequentialRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1313,7 +1313,7 @@ class RepetitionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1394,7 +1394,7 @@ class ExperimentalConditionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -413,7 +413,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -422,7 +422,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -436,12 +436,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -451,7 +451,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -498,19 +498,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -539,26 +541,32 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
waveforms: Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]] = Field( waveforms: VectorData[Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]]] = (
None, Field(
description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""", None,
json_schema_extra={ description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""",
"linkml_meta": { json_schema_extra={
"array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]} "linkml_meta": {
} "array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]}
}, }
},
)
) )
waveforms_index: Named[Optional[VectorIndex]] = Field( waveforms_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -589,7 +597,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -380,7 +380,7 @@ class PlaneSegmentation(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -16,12 +16,13 @@ from typing import (
Dict, Dict,
Optional, Optional,
Union, Union,
overload, Generic,
Iterable, Iterable,
Tuple, Tuple,
TypeVar,
overload,
Annotated, Annotated,
Type, Type,
TypeVar,
) )
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -81,8 +82,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -90,7 +93,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -148,6 +151,9 @@ class TimeSeriesReferenceVectorDataMixin(VectorDataMixin):
@model_validator(mode="after") @model_validator(mode="after")
def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin": def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin":
"""
Each of the three indexing columns must be the same length to work!
"""
assert len(self.idx_start) == len(self.timeseries) == len(self.count), ( assert len(self.idx_start) == len(self.timeseries) == len(self.count), (
f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)}," f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)},"
f" timeseries: {len(self.timeseries)}" f" timeseries: {len(self.timeseries)}"

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -173,7 +173,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -381,7 +381,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: Optional[NDArray[Any, float]] = Field( x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -390,7 +390,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: Optional[NDArray[Any, float]] = Field( y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -399,7 +399,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: Optional[NDArray[Any, float]] = Field( z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -408,7 +408,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: Optional[NDArray[Any, float]] = Field( imp: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""Impedance of the channel, in ohms.""", description="""Impedance of the channel, in ohms.""",
json_schema_extra={ json_schema_extra={
@ -417,7 +417,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -426,7 +426,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: Optional[NDArray[Any, str]] = Field( filtering: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of hardware filtering, including the filter name and frequency cutoffs.""", description="""Description of hardware filtering, including the filter name and frequency cutoffs.""",
json_schema_extra={ json_schema_extra={
@ -438,7 +438,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -447,7 +447,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -456,7 +456,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -465,7 +465,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -474,7 +474,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".""", description="""Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".""",
json_schema_extra={ json_schema_extra={
@ -488,7 +488,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -874,7 +874,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -903,7 +903,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -940,7 +940,7 @@ class IntracellularElectrodesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -986,7 +986,7 @@ class IntracellularStimuliTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1032,7 +1032,7 @@ class IntracellularResponsesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1098,7 +1098,7 @@ class IntracellularRecordingsTable(AlignedDynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1147,7 +1147,7 @@ class SimultaneousRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1221,7 +1221,7 @@ class SequentialRecordingsTable(DynamicTable):
} }
}, },
) )
stimulus_type: NDArray[Any, str] = Field( stimulus_type: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""The type of stimulus used for the sequential recording.""", description="""The type of stimulus used for the sequential recording.""",
json_schema_extra={ json_schema_extra={
@ -1235,7 +1235,7 @@ class SequentialRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1314,7 +1314,7 @@ class RepetitionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1395,7 +1395,7 @@ class ExperimentalConditionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -413,7 +413,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -422,7 +422,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -436,12 +436,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -451,7 +451,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -498,19 +498,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -539,26 +541,32 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
waveforms: Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]] = Field( waveforms: VectorData[Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]]] = (
None, Field(
description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""", None,
json_schema_extra={ description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""",
"linkml_meta": { json_schema_extra={
"array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]} "linkml_meta": {
} "array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]}
}, }
},
)
) )
waveforms_index: Named[Optional[VectorIndex]] = Field( waveforms_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -589,7 +597,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -380,7 +380,7 @@ class PlaneSegmentation(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -16,12 +16,13 @@ from typing import (
Dict, Dict,
Optional, Optional,
Union, Union,
overload, Generic,
Iterable, Iterable,
Tuple, Tuple,
TypeVar,
overload,
Annotated, Annotated,
Type, Type,
TypeVar,
) )
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -81,8 +82,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -90,7 +93,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -148,6 +151,9 @@ class TimeSeriesReferenceVectorDataMixin(VectorDataMixin):
@model_validator(mode="after") @model_validator(mode="after")
def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin": def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin":
"""
Each of the three indexing columns must be the same length to work!
"""
assert len(self.idx_start) == len(self.timeseries) == len(self.count), ( assert len(self.idx_start) == len(self.timeseries) == len(self.count), (
f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)}," f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)},"
f" timeseries: {len(self.timeseries)}" f" timeseries: {len(self.timeseries)}"

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -173,7 +173,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -381,7 +381,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: Optional[NDArray[Any, float]] = Field( x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -390,7 +390,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: Optional[NDArray[Any, float]] = Field( y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -399,7 +399,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: Optional[NDArray[Any, float]] = Field( z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -408,7 +408,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: Optional[NDArray[Any, float]] = Field( imp: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""Impedance of the channel, in ohms.""", description="""Impedance of the channel, in ohms.""",
json_schema_extra={ json_schema_extra={
@ -417,7 +417,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -426,7 +426,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: Optional[NDArray[Any, str]] = Field( filtering: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of hardware filtering, including the filter name and frequency cutoffs.""", description="""Description of hardware filtering, including the filter name and frequency cutoffs.""",
json_schema_extra={ json_schema_extra={
@ -438,7 +438,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -447,7 +447,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -456,7 +456,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -465,7 +465,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -474,7 +474,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".""", description="""Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".""",
json_schema_extra={ json_schema_extra={
@ -488,7 +488,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -874,7 +874,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -903,7 +903,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -940,7 +940,7 @@ class IntracellularElectrodesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -986,7 +986,7 @@ class IntracellularStimuliTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1032,7 +1032,7 @@ class IntracellularResponsesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1098,7 +1098,7 @@ class IntracellularRecordingsTable(AlignedDynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1147,7 +1147,7 @@ class SimultaneousRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1221,7 +1221,7 @@ class SequentialRecordingsTable(DynamicTable):
} }
}, },
) )
stimulus_type: NDArray[Any, str] = Field( stimulus_type: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""The type of stimulus used for the sequential recording.""", description="""The type of stimulus used for the sequential recording.""",
json_schema_extra={ json_schema_extra={
@ -1235,7 +1235,7 @@ class SequentialRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1314,7 +1314,7 @@ class RepetitionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1395,7 +1395,7 @@ class ExperimentalConditionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -413,7 +413,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -422,7 +422,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -436,12 +436,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -451,7 +451,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -498,19 +498,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -539,26 +541,32 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
waveforms: Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]] = Field( waveforms: VectorData[Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]]] = (
None, Field(
description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""", None,
json_schema_extra={ description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""",
"linkml_meta": { json_schema_extra={
"array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]} "linkml_meta": {
} "array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]}
}, }
},
)
) )
waveforms_index: Named[Optional[VectorIndex]] = Field( waveforms_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -589,7 +597,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -479,7 +479,7 @@ class PlaneSegmentation(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -1,4 +1,9 @@
from __future__ import annotations from __future__ import annotations
from datetime import datetime, date
from decimal import Decimal
from enum import Enum
import re
import sys
import numpy as np import numpy as np
from ...hdmf_common.v1_8_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_8_0.hdmf_common_base import Data, Container
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
@ -11,18 +16,20 @@ from typing import (
Dict, Dict,
Optional, Optional,
Union, Union,
overload, Generic,
Iterable, Iterable,
Tuple, Tuple,
TypeVar,
overload,
Annotated, Annotated,
Type, Type,
TypeVar,
) )
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
ConfigDict, ConfigDict,
Field, Field,
RootModel, RootModel,
field_validator,
model_validator, model_validator,
ValidationInfo, ValidationInfo,
BeforeValidator, BeforeValidator,
@ -75,8 +82,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -84,7 +93,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -142,6 +151,9 @@ class TimeSeriesReferenceVectorDataMixin(VectorDataMixin):
@model_validator(mode="after") @model_validator(mode="after")
def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin": def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin":
"""
Each of the three indexing columns must be the same length to work!
"""
assert len(self.idx_start) == len(self.timeseries) == len(self.count), ( assert len(self.idx_start) == len(self.timeseries) == len(self.count), (
f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)}," f"Columns have differing lengths: idx: {len(self.idx_start)}, count: {len(self.count)},"
f" timeseries: {len(self.timeseries)}" f" timeseries: {len(self.timeseries)}"

View file

@ -105,7 +105,7 @@ class TimeIntervals(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
start_time: NDArray[Any, float] = Field( start_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Start time of epoch, in seconds.""", description="""Start time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -114,7 +114,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
stop_time: NDArray[Any, float] = Field( stop_time: VectorData[NDArray[Any, float]] = Field(
..., ...,
description="""Stop time of epoch, in seconds.""", description="""Stop time of epoch, in seconds.""",
json_schema_extra={ json_schema_extra={
@ -123,7 +123,7 @@ class TimeIntervals(DynamicTable):
} }
}, },
) )
tags: Optional[NDArray[Any, str]] = Field( tags: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""User-defined tags that identify or categorize events.""", description="""User-defined tags that identify or categorize events.""",
json_schema_extra={ json_schema_extra={
@ -173,7 +173,7 @@ class TimeIntervals(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -389,7 +389,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
"linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"} "linkml_meta": {"equals_string": "electrodes", "ifabsent": "string(electrodes)"}
}, },
) )
x: Optional[NDArray[Any, float]] = Field( x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate of the channel location in the brain (+x is posterior).""", description="""x coordinate of the channel location in the brain (+x is posterior).""",
json_schema_extra={ json_schema_extra={
@ -398,7 +398,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
y: Optional[NDArray[Any, float]] = Field( y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate of the channel location in the brain (+y is inferior).""", description="""y coordinate of the channel location in the brain (+y is inferior).""",
json_schema_extra={ json_schema_extra={
@ -407,7 +407,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
z: Optional[NDArray[Any, float]] = Field( z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate of the channel location in the brain (+z is right).""", description="""z coordinate of the channel location in the brain (+z is right).""",
json_schema_extra={ json_schema_extra={
@ -416,7 +416,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
imp: Optional[NDArray[Any, float]] = Field( imp: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""Impedance of the channel, in ohms.""", description="""Impedance of the channel, in ohms.""",
json_schema_extra={ json_schema_extra={
@ -425,7 +425,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
location: NDArray[Any, str] = Field( location: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Location of the electrode (channel). 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.""", description="""Location of the electrode (channel). 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.""",
json_schema_extra={ json_schema_extra={
@ -434,7 +434,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
filtering: Optional[NDArray[Any, str]] = Field( filtering: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of hardware filtering, including the filter name and frequency cutoffs.""", description="""Description of hardware filtering, including the filter name and frequency cutoffs.""",
json_schema_extra={ json_schema_extra={
@ -446,7 +446,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
group: List[ElectrodeGroup] = Field( group: List[ElectrodeGroup] = Field(
..., description="""Reference to the ElectrodeGroup this electrode is a part of.""" ..., description="""Reference to the ElectrodeGroup this electrode is a part of."""
) )
group_name: NDArray[Any, str] = Field( group_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the ElectrodeGroup this electrode is a part of.""", description="""Name of the ElectrodeGroup this electrode is a part of.""",
json_schema_extra={ json_schema_extra={
@ -455,7 +455,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_x: Optional[NDArray[Any, float]] = Field( rel_x: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""x coordinate in electrode group""", description="""x coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -464,7 +464,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_y: Optional[NDArray[Any, float]] = Field( rel_y: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""y coordinate in electrode group""", description="""y coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -473,7 +473,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
rel_z: Optional[NDArray[Any, float]] = Field( rel_z: VectorData[Optional[NDArray[Any, float]]] = Field(
None, None,
description="""z coordinate in electrode group""", description="""z coordinate in electrode group""",
json_schema_extra={ json_schema_extra={
@ -482,7 +482,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
} }
}, },
) )
reference: Optional[NDArray[Any, str]] = Field( reference: VectorData[Optional[NDArray[Any, str]]] = Field(
None, None,
description="""Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".""", description="""Description of the reference electrode and/or reference scheme used for this electrode, e.g., \"stainless steel skull screw\" or \"online common average referencing\".""",
json_schema_extra={ json_schema_extra={
@ -496,7 +496,7 @@ class ExtracellularEphysElectrodes(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -874,7 +874,7 @@ class SweepTable(DynamicTable):
) )
name: str = Field(...) name: str = Field(...)
sweep_number: NDArray[Any, int] = Field( sweep_number: VectorData[NDArray[Any, int]] = Field(
..., ...,
description="""Sweep number of the PatchClampSeries in that row.""", description="""Sweep number of the PatchClampSeries in that row.""",
json_schema_extra={ json_schema_extra={
@ -903,7 +903,7 @@ class SweepTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -940,7 +940,7 @@ class IntracellularElectrodesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -998,7 +998,7 @@ class IntracellularStimuliTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1044,7 +1044,7 @@ class IntracellularResponsesTable(DynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1110,7 +1110,7 @@ class IntracellularRecordingsTable(AlignedDynamicTable):
..., ...,
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1159,7 +1159,7 @@ class SimultaneousRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1233,7 +1233,7 @@ class SequentialRecordingsTable(DynamicTable):
} }
}, },
) )
stimulus_type: NDArray[Any, str] = Field( stimulus_type: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""The type of stimulus used for the sequential recording.""", description="""The type of stimulus used for the sequential recording.""",
json_schema_extra={ json_schema_extra={
@ -1247,7 +1247,7 @@ class SequentialRecordingsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1326,7 +1326,7 @@ class RepetitionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -1407,7 +1407,7 @@ class ExperimentalConditionsTable(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -413,7 +413,7 @@ class DecompositionSeriesBands(DynamicTable):
"bands", "bands",
json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}}, json_schema_extra={"linkml_meta": {"equals_string": "bands", "ifabsent": "string(bands)"}},
) )
band_name: NDArray[Any, str] = Field( band_name: VectorData[NDArray[Any, str]] = Field(
..., ...,
description="""Name of the band, e.g. theta.""", description="""Name of the band, e.g. theta.""",
json_schema_extra={ json_schema_extra={
@ -422,7 +422,7 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_limits: NDArray[Shape["* num_bands, 2 low_high"], float] = Field( band_limits: VectorData[NDArray[Shape["* num_bands, 2 low_high"], float]] = Field(
..., ...,
description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""", description="""Low and high limit of each band in Hz. If it is a Gaussian filter, use 2 SD on either side of the center.""",
json_schema_extra={ json_schema_extra={
@ -436,12 +436,12 @@ class DecompositionSeriesBands(DynamicTable):
} }
}, },
) )
band_mean: NDArray[Shape["* num_bands"], float] = Field( band_mean: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The mean Gaussian filters, in Hz.""", description="""The mean Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
) )
band_stdev: NDArray[Shape["* num_bands"], float] = Field( band_stdev: VectorData[NDArray[Shape["* num_bands"], float]] = Field(
..., ...,
description="""The standard deviation of Gaussian filters, in Hz.""", description="""The standard deviation of Gaussian filters, in Hz.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_bands"}]}}},
@ -451,7 +451,7 @@ class DecompositionSeriesBands(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -498,19 +498,21 @@ class Units(DynamicTable):
} }
}, },
) )
obs_intervals: Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]] = Field( obs_intervals: VectorData[Optional[NDArray[Shape["* num_intervals, 2 start_end"], float]]] = (
None, Field(
description="""Observation intervals for each unit.""", None,
json_schema_extra={ description="""Observation intervals for each unit.""",
"linkml_meta": { json_schema_extra={
"array": { "linkml_meta": {
"dimensions": [ "array": {
{"alias": "num_intervals"}, "dimensions": [
{"alias": "start_end", "exact_cardinality": 2}, {"alias": "num_intervals"},
] {"alias": "start_end", "exact_cardinality": 2},
]
}
} }
} },
}, )
) )
electrodes_index: Named[Optional[VectorIndex]] = Field( electrodes_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -539,26 +541,32 @@ class Units(DynamicTable):
electrode_group: Optional[List[ElectrodeGroup]] = Field( electrode_group: Optional[List[ElectrodeGroup]] = Field(
None, description="""Electrode group that each spike unit came from.""" None, description="""Electrode group that each spike unit came from."""
) )
waveform_mean: Optional[ waveform_mean: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform mean for each spike unit.""")
waveform_sd: Optional[ waveform_sd: VectorData[
Union[ Optional[
NDArray[Shape["* num_units, * num_samples"], float], Union[
NDArray[Shape["* num_units, * num_samples, * num_electrodes"], float], 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.""") ] = Field(None, description="""Spike waveform standard deviation for each spike unit.""")
waveforms: Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]] = Field( waveforms: VectorData[Optional[NDArray[Shape["* num_waveforms, * num_samples"], float]]] = (
None, Field(
description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""", None,
json_schema_extra={ description="""Individual waveforms for each spike on each electrode. This is a doubly indexed column. The 'waveforms_index' column indexes which waveforms in this column belong to the same spike event for a given unit, where each waveform was recorded from a different electrode. The 'waveforms_index_index' column indexes the 'waveforms_index' column to indicate which spike events belong to a given unit. For example, if the 'waveforms_index_index' column has values [2, 5, 6], then the first 2 elements of the 'waveforms_index' column correspond to the 2 spike events of the first unit, the next 3 elements of the 'waveforms_index' column correspond to the 3 spike events of the second unit, and the next 1 element of the 'waveforms_index' column corresponds to the 1 spike event of the third unit. If the 'waveforms_index' column has values [3, 6, 8, 10, 12, 13], then the first 3 elements of the 'waveforms' column contain the 3 spike waveforms that were recorded from 3 different electrodes for the first spike time of the first unit. See https://nwb-schema.readthedocs.io/en/stable/format_description.html#doubly-ragged-arrays for a graphical representation of this example. When there is only one electrode for each unit (i.e., each spike time is associated with a single waveform), then the 'waveforms_index' column will have values 1, 2, ..., N, where N is the number of spike events. The number of electrodes for each spike event should be the same within a given unit. The 'electrodes' column should be used to indicate which electrodes are associated with each unit, and the order of the waveforms within a given unit x spike event should be in the same order as the electrodes referenced in the 'electrodes' column of this table. The number of samples for each waveform must be the same.""",
"linkml_meta": { json_schema_extra={
"array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]} "linkml_meta": {
} "array": {"dimensions": [{"alias": "num_waveforms"}, {"alias": "num_samples"}]}
}, }
},
)
) )
waveforms_index: Named[Optional[VectorIndex]] = Field( waveforms_index: Named[Optional[VectorIndex]] = Field(
None, None,
@ -589,7 +597,7 @@ class Units(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -479,7 +479,7 @@ class PlaneSegmentation(DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -5,7 +5,20 @@ from enum import Enum
import re import re
import sys import sys
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -67,8 +80,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -76,7 +91,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -119,13 +134,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -406,20 +421,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -569,6 +592,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -698,7 +747,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -5,7 +5,20 @@ from enum import Enum
import re import re
import sys import sys
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -67,8 +80,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -76,7 +91,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -119,13 +134,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -406,20 +421,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -569,6 +592,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -698,7 +747,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -5,7 +5,20 @@ from enum import Enum
import re import re
import sys import sys
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -67,8 +80,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -76,7 +91,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -119,13 +134,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -406,20 +421,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -569,6 +592,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -717,7 +766,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_2_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_2_0.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -711,7 +760,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_2_1.hdmf_common_base import Data, Container from ...hdmf_common.v1_2_1.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -711,7 +760,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_3_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_3_0.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -711,7 +760,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_4_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_4_0.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from numpydantic import NDArray, Shape from numpydantic import NDArray, Shape
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -685,7 +734,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_5_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_5_0.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
ConfigDict, ConfigDict,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -685,7 +734,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -713,7 +762,7 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_5_1.hdmf_common_base import Data, Container from ...hdmf_common.v1_5_1.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
ConfigDict, ConfigDict,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -685,7 +734,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -713,7 +762,7 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_6_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_6_0.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
ConfigDict, ConfigDict,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -685,7 +734,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -713,7 +762,7 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -6,7 +6,20 @@ import re
import sys import sys
from ...hdmf_common.v1_7_0.hdmf_common_base import Data, Container from ...hdmf_common.v1_7_0.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Literal, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
ConfigDict, ConfigDict,
@ -68,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -77,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -120,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -407,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -570,6 +593,32 @@ class AlignedDynamicTableMixin(DynamicTableMixin):
df.set_index((self.name, "id"), drop=True, inplace=True) df.set_index((self.name, "id"), drop=True, inplace=True)
return df return df
@model_validator(mode="before")
@classmethod
def create_categories(cls, model: Dict[str, Any]) -> Dict:
"""
Construct categories from arguments.
the model dict is ordered after python3.6, so we can use that minus
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
"""
if "categories" not in model:
categories = [
k for k in model if k not in cls.NON_CATEGORY_FIELDS and not k.endswith("_index")
]
model["categories"] = categories
else:
# add any columns not explicitly given an order at the end
categories = [
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["categories"]
]
model["categories"].extend(categories)
return model
linkml_meta = LinkMLMeta( linkml_meta = LinkMLMeta(
{ {
@ -685,7 +734,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -713,7 +762,7 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},

View file

@ -1,7 +1,25 @@
from __future__ import annotations from __future__ import annotations
from ...hdmf_common.v1_8_0.hdmf_common_base import Data from datetime import datetime, date
from decimal import Decimal
from enum import Enum
import re
import sys
from ...hdmf_common.v1_8_0.hdmf_common_base import Data, Container
import pandas as pd import pandas as pd
from typing import Any, ClassVar, List, Dict, Optional, Union, Iterable, Tuple, overload from typing import (
Any,
ClassVar,
List,
Literal,
Dict,
Optional,
Union,
Generic,
Iterable,
Tuple,
TypeVar,
overload,
)
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
ConfigDict, ConfigDict,
@ -63,8 +81,10 @@ class LinkMLMeta(RootModel):
NUMPYDANTIC_VERSION = "1.2.1" NUMPYDANTIC_VERSION = "1.2.1"
T = TypeVar("T", bound=NDArray)
class VectorDataMixin(BaseModel):
class VectorDataMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorData indexing abilities Mixin class to give VectorData indexing abilities
""" """
@ -72,7 +92,7 @@ class VectorDataMixin(BaseModel):
_index: Optional["VectorIndex"] = None _index: Optional["VectorIndex"] = None
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
if value is not None and "value" not in kwargs: if value is not None and "value" not in kwargs:
@ -115,13 +135,13 @@ class VectorDataMixin(BaseModel):
return len(self.value) return len(self.value)
class VectorIndexMixin(BaseModel): class VectorIndexMixin(BaseModel, Generic[T]):
""" """
Mixin class to give VectorIndex indexing abilities Mixin class to give VectorIndex indexing abilities
""" """
# redefined in `VectorData`, but included here for testing and type checking # redefined in `VectorData`, but included here for testing and type checking
value: Optional[NDArray] = None value: Optional[T] = None
target: Optional["VectorData"] = None target: Optional["VectorData"] = None
def __init__(self, value: Optional[NDArray] = None, **kwargs): def __init__(self, value: Optional[NDArray] = None, **kwargs):
@ -402,20 +422,28 @@ class DynamicTableMixin(BaseModel):
anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order anything in :attr:`.NON_COLUMN_FIELDS` to determine order implied from passage order
""" """
if "colnames" not in model: if "colnames" not in model:
colnames = [
k for k in model if k not in cls.NON_COLUMN_FIELDS and not k.endswith("_index")
]
model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = [ colnames = [
k k
for k in model for k in model
if k not in cls.NON_COLUMN_FIELDS if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index") and not k.endswith("_index")
and k not in model["colnames"] and not isinstance(model[k], VectorIndexMixin)
] ]
model["colnames"].extend(colnames) model["colnames"] = colnames
else:
# add any columns not explicitly given an order at the end
colnames = model["colnames"].copy()
colnames.extend(
[
k
for k in model
if k not in cls.NON_COLUMN_FIELDS
and not k.endswith("_index")
and k not in model["colnames"]
and not isinstance(model[k], VectorIndexMixin)
]
)
model["colnames"] = colnames
return model return model
@model_validator(mode="after") @model_validator(mode="after")
@ -706,7 +734,7 @@ class DynamicTable(DynamicTableMixin):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},
@ -734,7 +762,7 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable):
description="""The names of the columns in this table. This should be used to specify an order to the columns.""", description="""The names of the columns in this table. This should be used to specify an order to the columns.""",
) )
description: str = Field(..., description="""Description of what is in this dynamic table.""") description: str = Field(..., description="""Description of what is in this dynamic table.""")
id: NDArray[Shape["* num_rows"], int] = Field( id: VectorData[NDArray[Shape["* num_rows"], int]] = Field(
..., ...,
description="""Array of unique identifiers for the rows of this dynamic table.""", description="""Array of unique identifiers for the rows of this dynamic table.""",
json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}}, json_schema_extra={"linkml_meta": {"array": {"dimensions": [{"alias": "num_rows"}]}}},