mirror of
https://github.com/p2p-ld/nwb-linkml.git
synced 2024-11-10 00:34:29 +00:00
working aligned dynamic table and TimeSeriesReferenceVectorData
This commit is contained in:
parent
dd99ac24eb
commit
06a18c23a8
9 changed files with 307 additions and 59 deletions
|
@ -5,7 +5,7 @@
|
||||||
groups = ["default", "dev", "plot", "tests"]
|
groups = ["default", "dev", "plot", "tests"]
|
||||||
strategy = ["inherit_metadata"]
|
strategy = ["inherit_metadata"]
|
||||||
lock_version = "4.5.0"
|
lock_version = "4.5.0"
|
||||||
content_hash = "sha256:903c3aeebf0fb234263b45213693f0eaee7ac290d22633b1d7a4d5aff51d032b"
|
content_hash = "sha256:ed633a147948a9923f6b3a99690d5d8bad0b4b8c0d528abe62d132b05d1d9f39"
|
||||||
|
|
||||||
[[metadata.targets]]
|
[[metadata.targets]]
|
||||||
requires_python = ">=3.10,<3.13"
|
requires_python = ">=3.10,<3.13"
|
||||||
|
@ -1036,7 +1036,7 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "numpydantic"
|
name = "numpydantic"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
requires_python = "<4.0,>=3.9"
|
requires_python = "<4.0,>=3.9"
|
||||||
summary = "Type and shape validation and serialization for numpy arrays in pydantic models"
|
summary = "Type and shape validation and serialization for numpy arrays in pydantic models"
|
||||||
groups = ["default"]
|
groups = ["default"]
|
||||||
|
@ -1046,8 +1046,8 @@ dependencies = [
|
||||||
"typing-extensions>=4.11.0; python_version < \"3.11\"",
|
"typing-extensions>=4.11.0; python_version < \"3.11\"",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "numpydantic-1.3.0-py3-none-any.whl", hash = "sha256:bda3aa2cd858e9211006be8b8e589e1905b2c6a2db17cec0c28563ba1ad66b68"},
|
{file = "numpydantic-1.3.1-py3-none-any.whl", hash = "sha256:c0a37c093fcd0e4ed52c4556f4e804eec76fcf924c546e475509e662336f9f61"},
|
||||||
{file = "numpydantic-1.3.0.tar.gz", hash = "sha256:b3931d51ba7e22d48bdd2ae56cad368f63db99ef74e8570021a7fd176b2ffc1f"},
|
{file = "numpydantic-1.3.1.tar.gz", hash = "sha256:d61868d7912f2dfee9906bd989399d74f470dee10d5028409c2f5d39529fc4af"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1831,29 +1831,29 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.5.6"
|
version = "0.5.7"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "ruff-0.5.6-py3-none-linux_armv6l.whl", hash = "sha256:a0ef5930799a05522985b9cec8290b185952f3fcd86c1772c3bdbd732667fdcd"},
|
{file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"},
|
||||||
{file = "ruff-0.5.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b652dc14f6ef5d1552821e006f747802cc32d98d5509349e168f6bf0ee9f8f42"},
|
{file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"},
|
||||||
{file = "ruff-0.5.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:80521b88d26a45e871f31e4b88938fd87db7011bb961d8afd2664982dfc3641a"},
|
{file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"},
|
||||||
{file = "ruff-0.5.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9bc8f328a9f1309ae80e4d392836e7dbc77303b38ed4a7112699e63d3b066ab"},
|
{file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"},
|
||||||
{file = "ruff-0.5.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d394940f61f7720ad371ddedf14722ee1d6250fd8d020f5ea5a86e7be217daf"},
|
{file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"},
|
||||||
{file = "ruff-0.5.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111a99cdb02f69ddb2571e2756e017a1496c2c3a2aeefe7b988ddab38b416d36"},
|
{file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"},
|
||||||
{file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e395daba77a79f6dc0d07311f94cc0560375ca20c06f354c7c99af3bf4560c5d"},
|
{file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"},
|
||||||
{file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c476acb43c3c51e3c614a2e878ee1589655fa02dab19fe2db0423a06d6a5b1b6"},
|
{file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"},
|
||||||
{file = "ruff-0.5.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2ff8003f5252fd68425fd53d27c1f08b201d7ed714bb31a55c9ac1d4c13e2eb"},
|
{file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"},
|
||||||
{file = "ruff-0.5.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c94e084ba3eaa80c2172918c2ca2eb2230c3f15925f4ed8b6297260c6ef179ad"},
|
{file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"},
|
||||||
{file = "ruff-0.5.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f77c1c3aa0669fb230b06fb24ffa3e879391a3ba3f15e3d633a752da5a3e670"},
|
{file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"},
|
||||||
{file = "ruff-0.5.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f908148c93c02873210a52cad75a6eda856b2cbb72250370ce3afef6fb99b1ed"},
|
{file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"},
|
||||||
{file = "ruff-0.5.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:563a7ae61ad284187d3071d9041c08019975693ff655438d8d4be26e492760bd"},
|
{file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"},
|
||||||
{file = "ruff-0.5.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:94fe60869bfbf0521e04fd62b74cbca21cbc5beb67cbb75ab33fe8c174f54414"},
|
{file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"},
|
||||||
{file = "ruff-0.5.6-py3-none-win32.whl", hash = "sha256:e6a584c1de6f8591c2570e171cc7ce482bb983d49c70ddf014393cd39e9dfaed"},
|
{file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"},
|
||||||
{file = "ruff-0.5.6-py3-none-win_amd64.whl", hash = "sha256:d7fe7dccb1a89dc66785d7aa0ac283b2269712d8ed19c63af908fdccca5ccc1a"},
|
{file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"},
|
||||||
{file = "ruff-0.5.6-py3-none-win_arm64.whl", hash = "sha256:57c6c0dd997b31b536bff49b9eee5ed3194d60605a4427f735eeb1f9c1b8d264"},
|
{file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"},
|
||||||
{file = "ruff-0.5.6.tar.gz", hash = "sha256:07c9e3c2a8e1fe377dd460371c3462671a728c981c3205a5217291422209f642"},
|
{file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2090,44 +2090,44 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchdog"
|
name = "watchdog"
|
||||||
version = "4.0.1"
|
version = "4.0.2"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Filesystem events monitoring"
|
summary = "Filesystem events monitoring"
|
||||||
groups = ["default"]
|
groups = ["default"]
|
||||||
files = [
|
files = [
|
||||||
{file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645"},
|
{file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ede7f010f2239b97cc79e6cb3c249e72962404ae3865860855d5cbe708b0fd22"},
|
||||||
{file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b"},
|
{file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2cffa171445b0efa0726c561eca9a27d00a1f2b83846dbd5a4f639c4f8ca8e1"},
|
||||||
{file = "watchdog-4.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b"},
|
{file = "watchdog-4.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c50f148b31b03fbadd6d0b5980e38b558046b127dc483e5e4505fcef250f9503"},
|
||||||
{file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5"},
|
{file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c7d4bf585ad501c5f6c980e7be9c4f15604c7cc150e942d82083b31a7548930"},
|
||||||
{file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767"},
|
{file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:914285126ad0b6eb2258bbbcb7b288d9dfd655ae88fa28945be05a7b475a800b"},
|
||||||
{file = "watchdog-4.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459"},
|
{file = "watchdog-4.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:984306dc4720da5498b16fc037b36ac443816125a3705dfde4fd90652d8028ef"},
|
||||||
{file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175"},
|
{file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1cdcfd8142f604630deef34722d695fb455d04ab7cfe9963055df1fc69e6727a"},
|
||||||
{file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7"},
|
{file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7ab624ff2f663f98cd03c8b7eedc09375a911794dfea6bf2a359fcc266bff29"},
|
||||||
{file = "watchdog-4.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28"},
|
{file = "watchdog-4.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:132937547a716027bd5714383dfc40dc66c26769f1ce8a72a859d6a48f371f3a"},
|
||||||
{file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7"},
|
{file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:10b6683df70d340ac3279eff0b2766813f00f35a1d37515d2c99959ada8f05fa"},
|
||||||
{file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5"},
|
{file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7c739888c20f99824f7aa9d31ac8a97353e22d0c0e54703a547a218f6637eb3"},
|
||||||
{file = "watchdog-4.0.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253"},
|
{file = "watchdog-4.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:936acba76d636f70db8f3c66e76aa6cb5136a936fc2a5088b9ce1c7a3508fc83"},
|
||||||
{file = "watchdog-4.0.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d"},
|
{file = "watchdog-4.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e252f8ca942a870f38cf785aef420285431311652d871409a64e2a0a52a2174c"},
|
||||||
{file = "watchdog-4.0.1-py3-none-manylinux2014_i686.whl", hash = "sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6"},
|
{file = "watchdog-4.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:0e83619a2d5d436a7e58a1aea957a3c1ccbf9782c43c0b4fed80580e5e4acd1a"},
|
||||||
{file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57"},
|
{file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:88456d65f207b39f1981bf772e473799fcdc10801062c36fd5ad9f9d1d463a73"},
|
||||||
{file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e"},
|
{file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:32be97f3b75693a93c683787a87a0dc8db98bb84701539954eef991fb35f5fbc"},
|
||||||
{file = "watchdog-4.0.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5"},
|
{file = "watchdog-4.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:c82253cfc9be68e3e49282831afad2c1f6593af80c0daf1287f6a92657986757"},
|
||||||
{file = "watchdog-4.0.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84"},
|
{file = "watchdog-4.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c0b14488bd336c5b1845cee83d3e631a1f8b4e9c5091ec539406e4a324f882d8"},
|
||||||
{file = "watchdog-4.0.1-py3-none-win32.whl", hash = "sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429"},
|
{file = "watchdog-4.0.2-py3-none-win32.whl", hash = "sha256:0d8a7e523ef03757a5aa29f591437d64d0d894635f8a50f370fe37f913ce4e19"},
|
||||||
{file = "watchdog-4.0.1-py3-none-win_amd64.whl", hash = "sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a"},
|
{file = "watchdog-4.0.2-py3-none-win_amd64.whl", hash = "sha256:c344453ef3bf875a535b0488e3ad28e341adbd5a9ffb0f7d62cefacc8824ef2b"},
|
||||||
{file = "watchdog-4.0.1-py3-none-win_ia64.whl", hash = "sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d"},
|
{file = "watchdog-4.0.2-py3-none-win_ia64.whl", hash = "sha256:baececaa8edff42cd16558a639a9b0ddf425f93d892e8392a56bf904f5eff22c"},
|
||||||
{file = "watchdog-4.0.1.tar.gz", hash = "sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44"},
|
{file = "watchdog-4.0.2.tar.gz", hash = "sha256:b4dfbb6c49221be4535623ea4474a4d6ee0a9cef4a80b20c28db4d858b64e270"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webcolors"
|
name = "webcolors"
|
||||||
version = "24.6.0"
|
version = "24.8.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "A library for working with the color formats defined by HTML and CSS."
|
summary = "A library for working with the color formats defined by HTML and CSS."
|
||||||
groups = ["default"]
|
groups = ["default"]
|
||||||
files = [
|
files = [
|
||||||
{file = "webcolors-24.6.0-py3-none-any.whl", hash = "sha256:8cf5bc7e28defd1d48b9e83d5fc30741328305a8195c29a8e668fa45586568a1"},
|
{file = "webcolors-24.8.0-py3-none-any.whl", hash = "sha256:fc4c3b59358ada164552084a8ebee637c221e4059267d0f8325b3b560f6c7f0a"},
|
||||||
{file = "webcolors-24.6.0.tar.gz", hash = "sha256:1d160d1de46b3e81e58d0a280d0c78b467dc80f47294b91b1ad8029d2cedb55b"},
|
{file = "webcolors-24.8.0.tar.gz", hash = "sha256:08b07af286a01bcd30d583a7acadf629583d1f79bfef27dd2c2c5c263817277d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2187,11 +2187,11 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zipp"
|
name = "zipp"
|
||||||
version = "3.19.2"
|
version = "3.20.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Backport of pathlib-compatible object wrapper for zip files"
|
summary = "Backport of pathlib-compatible object wrapper for zip files"
|
||||||
groups = ["dev", "plot", "tests"]
|
groups = ["dev", "plot", "tests"]
|
||||||
files = [
|
files = [
|
||||||
{file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"},
|
{file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"},
|
||||||
{file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"},
|
{file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"},
|
||||||
]
|
]
|
||||||
|
|
|
@ -20,7 +20,7 @@ dependencies = [
|
||||||
"pydantic-settings>=2.0.3",
|
"pydantic-settings>=2.0.3",
|
||||||
"tqdm>=4.66.1",
|
"tqdm>=4.66.1",
|
||||||
'typing-extensions>=4.12.2;python_version<"3.11"',
|
'typing-extensions>=4.12.2;python_version<"3.11"',
|
||||||
"numpydantic>=1.3.0",
|
"numpydantic>=1.3.1",
|
||||||
"black>=24.4.2",
|
"black>=24.4.2",
|
||||||
"pandas>=2.2.2",
|
"pandas>=2.2.2",
|
||||||
]
|
]
|
||||||
|
|
|
@ -153,8 +153,8 @@ class Adapter(BaseModel):
|
||||||
# SchemaAdapters that should be located under the same
|
# SchemaAdapters that should be located under the same
|
||||||
# NamespacesAdapter when it's important to query across SchemaAdapters,
|
# NamespacesAdapter when it's important to query across SchemaAdapters,
|
||||||
# so skip to avoid combinatoric walking
|
# so skip to avoid combinatoric walking
|
||||||
# if key == "imports" and type(input).__name__ == "SchemaAdapter":
|
if key == "imports" and type(input).__name__ == "SchemaAdapter":
|
||||||
# continue
|
continue
|
||||||
val = getattr(input, key)
|
val = getattr(input, key)
|
||||||
yield (key, val)
|
yield (key, val)
|
||||||
if isinstance(val, (BaseModel, dict, list)):
|
if isinstance(val, (BaseModel, dict, list)):
|
||||||
|
|
|
@ -26,7 +26,13 @@ from linkml_runtime.utils.compile_python import file_text
|
||||||
from linkml_runtime.utils.formatutils import remove_empty_items
|
from linkml_runtime.utils.formatutils import remove_empty_items
|
||||||
from linkml_runtime.utils.schemaview import SchemaView
|
from linkml_runtime.utils.schemaview import SchemaView
|
||||||
|
|
||||||
from nwb_linkml.includes.hdmf import DYNAMIC_TABLE_IMPORTS, DYNAMIC_TABLE_INJECTS
|
from nwb_linkml.includes.base import BASEMODEL_GETITEM
|
||||||
|
from nwb_linkml.includes.hdmf import (
|
||||||
|
DYNAMIC_TABLE_IMPORTS,
|
||||||
|
DYNAMIC_TABLE_INJECTS,
|
||||||
|
TSRVD_IMPORTS,
|
||||||
|
TSRVD_INJECTS,
|
||||||
|
)
|
||||||
from nwb_linkml.includes.types import ModelTypeString, NamedImports, NamedString, _get_name
|
from nwb_linkml.includes.types import ModelTypeString, NamedImports, NamedString, _get_name
|
||||||
|
|
||||||
OPTIONAL_PATTERN = re.compile(r"Optional\[([\w\.]*)\]")
|
OPTIONAL_PATTERN = re.compile(r"Optional\[([\w\.]*)\]")
|
||||||
|
@ -44,6 +50,7 @@ class NWBPydanticGenerator(PydanticGenerator):
|
||||||
' is stored in an NWB file")'
|
' is stored in an NWB file")'
|
||||||
),
|
),
|
||||||
'object_id: Optional[str] = Field(None, description="Unique UUID for each object")',
|
'object_id: Optional[str] = Field(None, description="Unique UUID for each object")',
|
||||||
|
BASEMODEL_GETITEM,
|
||||||
)
|
)
|
||||||
split: bool = True
|
split: bool = True
|
||||||
imports: list[Import] = field(default_factory=lambda: [Import(module="numpy", alias="np")])
|
imports: list[Import] = field(default_factory=lambda: [Import(module="numpy", alias="np")])
|
||||||
|
@ -232,7 +239,7 @@ class AfterGenerateClass:
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if cls.cls.name == "DynamicTable":
|
if cls.cls.name in "DynamicTable":
|
||||||
cls.cls.bases = ["DynamicTableMixin"]
|
cls.cls.bases = ["DynamicTableMixin"]
|
||||||
|
|
||||||
if cls.injected_classes is None:
|
if cls.injected_classes is None:
|
||||||
|
@ -254,6 +261,21 @@ class AfterGenerateClass:
|
||||||
cls.cls.bases = ["DynamicTableRegionMixin", "VectorData"]
|
cls.cls.bases = ["DynamicTableRegionMixin", "VectorData"]
|
||||||
elif cls.cls.name == "AlignedDynamicTable":
|
elif cls.cls.name == "AlignedDynamicTable":
|
||||||
cls.cls.bases = ["AlignedDynamicTableMixin", "DynamicTable"]
|
cls.cls.bases = ["AlignedDynamicTableMixin", "DynamicTable"]
|
||||||
|
elif cls.cls.name == "TimeSeriesReferenceVectorData":
|
||||||
|
# in core.nwb.base, so need to inject and import again
|
||||||
|
cls.cls.bases = ["TimeSeriesReferenceVectorDataMixin", "VectorData"]
|
||||||
|
if cls.injected_classes is None:
|
||||||
|
cls.injected_classes = TSRVD_INJECTS.copy()
|
||||||
|
else:
|
||||||
|
cls.injected_classes.extend(TSRVD_INJECTS.copy())
|
||||||
|
|
||||||
|
if isinstance(cls.imports, Imports):
|
||||||
|
cls.imports += TSRVD_IMPORTS
|
||||||
|
elif isinstance(cls.imports, list):
|
||||||
|
cls.imports = Imports(imports=cls.imports) + TSRVD_IMPORTS
|
||||||
|
else:
|
||||||
|
cls.imports = TSRVD_IMPORTS.model_copy()
|
||||||
|
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
|
|
14
nwb_linkml/src/nwb_linkml/includes/base.py
Normal file
14
nwb_linkml/src/nwb_linkml/includes/base.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
"""
|
||||||
|
Modifications to the ConfiguredBaseModel used by all generated classes
|
||||||
|
"""
|
||||||
|
|
||||||
|
BASEMODEL_GETITEM = """
|
||||||
|
def __getitem__(self, val: Union[int, slice]) -> Any:
|
||||||
|
\"\"\"Try and get a value from value or "data" if we have it\"\"\"
|
||||||
|
if hasattr(self, "value") and self.value is not None:
|
||||||
|
return self.value[val]
|
||||||
|
elif hasattr(self, "data") and self.data is not None:
|
||||||
|
return self.data[val]
|
||||||
|
else:
|
||||||
|
raise KeyError("No value or data field to index from")
|
||||||
|
"""
|
|
@ -535,6 +535,109 @@ 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
|
||||||
|
|
||||||
|
|
||||||
|
class TimeSeriesReferenceVectorDataMixin(VectorDataMixin):
|
||||||
|
"""
|
||||||
|
Mixin class for TimeSeriesReferenceVectorData -
|
||||||
|
very simple, just indexing the given timeseries object.
|
||||||
|
|
||||||
|
These shouldn't have additional fields in them, just the three columns
|
||||||
|
for index, span, and timeseries
|
||||||
|
"""
|
||||||
|
|
||||||
|
idx_start: NDArray[Any, int]
|
||||||
|
count: NDArray[Any, int]
|
||||||
|
timeseries: NDArray[Any, BaseModel]
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def ensure_equal_length(self) -> "TimeSeriesReferenceVectorDataMixin":
|
||||||
|
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" timeseries: {len(self.timeseries)}"
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
"""Since we have ensured equal length, just return idx_start"""
|
||||||
|
return len(self.idx_start)
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def _slice_helper(self, item: int) -> slice: ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def _slice_helper(self, item: slice) -> List[slice]: ...
|
||||||
|
|
||||||
|
def _slice_helper(self, item: Union[int, slice]) -> Union[slice, List[slice]]:
|
||||||
|
if isinstance(item, (int, np.integer)):
|
||||||
|
return slice(self.idx_start[item], self.idx_start[item] + self.count[item])
|
||||||
|
else:
|
||||||
|
starts = self.idx_start[item]
|
||||||
|
ends = starts + self.count[item]
|
||||||
|
return [slice(start, end) for start, end in zip(starts, ends)]
|
||||||
|
|
||||||
|
def __getitem__(self, item: Union[int, slice, Iterable]) -> Any:
|
||||||
|
if self._index is not None:
|
||||||
|
raise NotImplementedError(
|
||||||
|
"VectorIndexing with TimeSeriesReferenceVectorData is not supported because it is"
|
||||||
|
" never done in the core schema."
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(item, (int, np.integer)):
|
||||||
|
return self.timeseries[self._slice_helper(item)]
|
||||||
|
elif isinstance(item, slice):
|
||||||
|
return [self.timeseries[subitem] for subitem in self._slice_helper(item)]
|
||||||
|
elif isinstance(item, Iterable):
|
||||||
|
return [self.timeseries[self._slice_helper(subitem)] for subitem in item]
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
f"Dont know how to index with {item}, must be an int, slice, or iterable"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __setitem__(self, key: Union[int, slice, Iterable], value: Any) -> None:
|
||||||
|
if self._index is not None:
|
||||||
|
raise NotImplementedError(
|
||||||
|
"VectorIndexing with TimeSeriesReferenceVectorData is not supported because it is"
|
||||||
|
" never done in the core schema."
|
||||||
|
)
|
||||||
|
if isinstance(key, (int, np.integer)):
|
||||||
|
self.timeseries[self._slice_helper(key)] = value
|
||||||
|
elif isinstance(key, slice):
|
||||||
|
for subitem in self._slice_helper(key):
|
||||||
|
self.timeseries[subitem] = value
|
||||||
|
elif isinstance(key, Iterable):
|
||||||
|
for subitem in key:
|
||||||
|
self.timeseries[self._slice_helper(subitem)] = value
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
f"Dont know how to index with {key}, must be an int, slice, or iterable"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
DYNAMIC_TABLE_IMPORTS = Imports(
|
DYNAMIC_TABLE_IMPORTS = Imports(
|
||||||
imports=[
|
imports=[
|
||||||
|
@ -577,3 +680,19 @@ DYNAMIC_TABLE_INJECTS = [
|
||||||
DynamicTableMixin,
|
DynamicTableMixin,
|
||||||
AlignedDynamicTableMixin,
|
AlignedDynamicTableMixin,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
TSRVD_IMPORTS = Imports(
|
||||||
|
imports=[
|
||||||
|
Import(
|
||||||
|
module="typing",
|
||||||
|
objects=[
|
||||||
|
ObjectImport(name="overload"),
|
||||||
|
ObjectImport(name="Iterable"),
|
||||||
|
ObjectImport(name="Tuple"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Import(module="pydantic", objects=[ObjectImport(name="model_validator")]),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
"""Imports for TimeSeriesReferenceVectorData"""
|
||||||
|
TSRVD_INJECTS = [VectorDataMixin, TimeSeriesReferenceVectorDataMixin]
|
||||||
|
|
|
@ -42,6 +42,7 @@ def test_walk_fields(nwb_core_fixture):
|
||||||
dtype = list(nwb_core_fixture.walk_fields(nwb_core_fixture, "dtype"))
|
dtype = list(nwb_core_fixture.walk_fields(nwb_core_fixture, "dtype"))
|
||||||
|
|
||||||
dtype_havers = list(nwb_core_fixture.walk_types(nwb_core_fixture, (Dataset, Attribute)))
|
dtype_havers = list(nwb_core_fixture.walk_types(nwb_core_fixture, (Dataset, Attribute)))
|
||||||
|
dtype_havers = [haver for haver in dtype_havers if haver.dtype is not None]
|
||||||
compound_dtypes = [len(d.dtype) for d in dtype_havers if isinstance(d.dtype, list)]
|
compound_dtypes = [len(d.dtype) for d in dtype_havers if isinstance(d.dtype, list)]
|
||||||
expected_dtypes = np.sum(compound_dtypes) + len(dtype_havers)
|
expected_dtypes = np.sum(compound_dtypes) + len(dtype_havers)
|
||||||
assert expected_dtypes == len(dtype)
|
assert expected_dtypes == len(dtype)
|
||||||
|
|
|
@ -15,6 +15,11 @@ from nwb_linkml.models import (
|
||||||
IntracellularResponsesTable,
|
IntracellularResponsesTable,
|
||||||
IntracellularStimuliTable,
|
IntracellularStimuliTable,
|
||||||
IntracellularRecordingsTable,
|
IntracellularRecordingsTable,
|
||||||
|
VoltageClampSeries,
|
||||||
|
VoltageClampSeriesData,
|
||||||
|
VoltageClampStimulusSeries,
|
||||||
|
VoltageClampStimulusSeriesData,
|
||||||
|
TimeSeriesReferenceVectorData,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,19 +107,68 @@ def units(request) -> Tuple[Units, list[np.ndarray], np.ndarray]:
|
||||||
return units, spike_times, spike_idx
|
return units, spike_times, spike_idx
|
||||||
|
|
||||||
|
|
||||||
|
def _icephys_stimulus_and_response(
|
||||||
|
i: int, electrode: IntracellularElectrode
|
||||||
|
) -> tuple[VoltageClampStimulusSeries, VoltageClampSeries]:
|
||||||
|
generator = np.random.default_rng()
|
||||||
|
n_samples = generator.integers(20, 50)
|
||||||
|
stimulus = VoltageClampStimulusSeries(
|
||||||
|
name=f"vcss_{i}",
|
||||||
|
data=VoltageClampStimulusSeriesData(value=[i] * n_samples),
|
||||||
|
stimulus_description=f"{i}",
|
||||||
|
sweep_number=i,
|
||||||
|
electrode=electrode,
|
||||||
|
)
|
||||||
|
response = VoltageClampSeries(
|
||||||
|
name=f"vcs_{i}",
|
||||||
|
data=VoltageClampSeriesData(value=[i] * n_samples),
|
||||||
|
stimulus_description=f"{i}",
|
||||||
|
electrode=electrode,
|
||||||
|
)
|
||||||
|
return stimulus, response
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def intracellular_recordings_table() -> IntracellularRecordingsTable:
|
def intracellular_recordings_table() -> IntracellularRecordingsTable:
|
||||||
n_recordings = 10
|
n_recordings = 10
|
||||||
|
generator = np.random.default_rng()
|
||||||
device = Device(name="my device")
|
device = Device(name="my device")
|
||||||
electrode = IntracellularElectrode(
|
electrode = IntracellularElectrode(
|
||||||
name="my_electrode", description="an electrode", device=device
|
name="my_electrode", description="an electrode", device=device
|
||||||
)
|
)
|
||||||
|
stims = []
|
||||||
|
responses = []
|
||||||
|
for i in range(n_recordings):
|
||||||
|
stim, response = _icephys_stimulus_and_response(i, electrode)
|
||||||
|
stims.append(stim)
|
||||||
|
responses.append(response)
|
||||||
|
|
||||||
electrodes = IntracellularElectrodesTable(
|
electrodes = IntracellularElectrodesTable(
|
||||||
name="intracellular_electrodes", electrode=[electrode] * n_recordings
|
name="intracellular_electrodes", electrode=[electrode] * n_recordings
|
||||||
)
|
)
|
||||||
stimuli = IntracellularStimuliTable(
|
stimuli = IntracellularStimuliTable(
|
||||||
name="intracellular_stimuli",
|
name="intracellular_stimuli",
|
||||||
|
stimulus=TimeSeriesReferenceVectorData(
|
||||||
|
name="stimulus",
|
||||||
|
description="this should be optional",
|
||||||
|
idx_start=np.arange(n_recordings),
|
||||||
|
count=generator.integers(1, 10, (n_recordings,)),
|
||||||
|
timeseries=stims,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
responses = IntracellularResponsesTable()
|
|
||||||
|
|
||||||
recordings_table = IntracellularRecordingsTable()
|
responses = IntracellularResponsesTable(
|
||||||
|
name="intracellular_responses",
|
||||||
|
response=TimeSeriesReferenceVectorData(
|
||||||
|
name="response",
|
||||||
|
description="this should be optional",
|
||||||
|
idx_start=np.arange(n_recordings),
|
||||||
|
count=generator.integers(1, 10, (n_recordings,)),
|
||||||
|
timeseries=responses,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
recordings_table = IntracellularRecordingsTable(
|
||||||
|
electrodes=electrodes, stimuli=stimuli, responses=responses
|
||||||
|
)
|
||||||
|
return recordings_table
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
# FIXME: Make this just be the output of the provider by patching into import machinery
|
# FIXME: Make this just be the output of the provider by patching into import machinery
|
||||||
from nwb_linkml.models.pydantic.core.v2_7_0.namespace import (
|
from nwb_linkml.models.pydantic.core.v2_7_0.namespace import (
|
||||||
|
@ -6,6 +7,7 @@ from nwb_linkml.models.pydantic.core.v2_7_0.namespace import (
|
||||||
DynamicTableRegion,
|
DynamicTableRegion,
|
||||||
ElectrodeGroup,
|
ElectrodeGroup,
|
||||||
VectorIndex,
|
VectorIndex,
|
||||||
|
VoltageClampStimulusSeries,
|
||||||
)
|
)
|
||||||
from .conftest import _ragged_array
|
from .conftest import _ragged_array
|
||||||
|
|
||||||
|
@ -159,3 +161,39 @@ def test_dynamictable_extra_coercion():
|
||||||
Extra fields should be coerced to VectorData and have their
|
Extra fields should be coerced to VectorData and have their
|
||||||
indexing relationships handled when passed as plain arrays.
|
indexing relationships handled when passed as plain arrays.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_aligned_dynamictable(intracellular_recordings_table):
|
||||||
|
"""
|
||||||
|
Multiple aligned dynamictables should be indexable with a multiindex
|
||||||
|
"""
|
||||||
|
# can get a single row.. (check correctness below)
|
||||||
|
row = intracellular_recordings_table[0]
|
||||||
|
# can get a single table with its name
|
||||||
|
stimuli = intracellular_recordings_table["stimuli"]
|
||||||
|
assert stimuli.shape == (10, 1)
|
||||||
|
|
||||||
|
# nab a few rows to make the dataframe
|
||||||
|
rows = intracellular_recordings_table[0:3]
|
||||||
|
assert all(
|
||||||
|
rows.columns
|
||||||
|
== pd.MultiIndex.from_tuples(
|
||||||
|
[
|
||||||
|
("electrodes", "index"),
|
||||||
|
("electrodes", "electrode"),
|
||||||
|
("stimuli", "index"),
|
||||||
|
("stimuli", "stimulus"),
|
||||||
|
("responses", "index"),
|
||||||
|
("responses", "response"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ensure that we get the actual values from the TimeSeriesReferenceVectorData
|
||||||
|
# also tested separately
|
||||||
|
# each individual cell should be an array of VoltageClampStimulusSeries...
|
||||||
|
# and then we should be able to index within that as well
|
||||||
|
stims = rows["stimuli", "stimulus"][0]
|
||||||
|
for i in range(len(stims)):
|
||||||
|
assert isinstance(stims[i], VoltageClampStimulusSeries)
|
||||||
|
assert all([i == val for val in stims[i][:]])
|
||||||
|
|
Loading…
Reference in a new issue