From bc1ac9b5dd3387d0606696e1029bc0b144ff7ce1 Mon Sep 17 00:00:00 2001 From: cszsol Date: Thu, 19 Dec 2024 12:22:23 +0100 Subject: [PATCH] Tool unit tests (#44) * Migrated bluenaas * Migration of the rest of the tools * Some pydantic fixes * Fixed error when calling agents * Removed references from neuroagent in swarm_copy * Remove changelog job * CR fixes * Review fixes * lint * lint * MR comments * Migrated electrophys tool tests * Added test for me_model_tool * Added tests for get_morpho tool * Added tests for kg_morpho_features_tool * Added morpho features test * Added test for resolve entitie tool * added traces tool tests * Added traces tool tests * Update ci.yaml * Run new tests * Fixed unit test problems after mergint main * lint * Removed unneeded imports * Use httpx_mock * Bring back changelog * lint * Update changelog.yml * Fixed fixture * Fixed fixtures * Fixed some failing tests * fix last tool tests * added test_create_query to morpho tool * Small changes --------- Co-authored-by: Csaba Zsolnai Co-authored-by: Csaba Zsolnai Co-authored-by: Boris-Bergsma Co-authored-by: Nicolas Frank --- CHANGELOG.md | 1 + swarm_copy/tools/get_morpho_tool.py | 5 +- swarm_copy/tools/kg_morpho_features_tool.py | 3 +- swarm_copy_tests/data/99111002.nwb | Bin 0 -> 530771 bytes swarm_copy_tests/data/get_traces.json | 201 ++++++++ swarm_copy_tests/data/kg_me_model_output.json | 152 ++++++ .../data/kg_morpho_features_response.json | 412 ++++++++++++++++ swarm_copy_tests/data/knowledge_graph.json | 182 +++++++ .../data/morphology_id_metadata_response.json | 102 ++++ swarm_copy_tests/data/resolve_query.json | 1 + swarm_copy_tests/data/simple.swc | 31 ++ swarm_copy_tests/data/tool_calls.json | 102 ++++ swarm_copy_tests/data/trace_id_metadata.json | 110 +++++ swarm_copy_tests/tools/__init__.py | 0 swarm_copy_tests/tools/test_base_tool.py | 0 .../tools/test_electrophys_tool.py | 206 ++++++++ .../tools/test_get_morpho_tool.py | 175 +++++++ .../tools/test_kg_morpho_features_tool.py | 453 ++++++++++++++++++ .../tools/test_literature_search_tool.py | 50 ++ .../tools/test_morphology_features_tool.py | 114 +++++ .../tools/test_resolve_entities_tool.py | 100 ++++ swarm_copy_tests/tools/test_traces_tool.py | 150 ++++++ 22 files changed, 2547 insertions(+), 3 deletions(-) create mode 100644 swarm_copy_tests/data/99111002.nwb create mode 100644 swarm_copy_tests/data/get_traces.json create mode 100644 swarm_copy_tests/data/kg_me_model_output.json create mode 100644 swarm_copy_tests/data/kg_morpho_features_response.json create mode 100644 swarm_copy_tests/data/knowledge_graph.json create mode 100644 swarm_copy_tests/data/morphology_id_metadata_response.json create mode 100644 swarm_copy_tests/data/resolve_query.json create mode 100644 swarm_copy_tests/data/simple.swc create mode 100644 swarm_copy_tests/data/tool_calls.json create mode 100644 swarm_copy_tests/data/trace_id_metadata.json create mode 100644 swarm_copy_tests/tools/__init__.py create mode 100644 swarm_copy_tests/tools/test_base_tool.py create mode 100644 swarm_copy_tests/tools/test_electrophys_tool.py create mode 100644 swarm_copy_tests/tools/test_get_morpho_tool.py create mode 100644 swarm_copy_tests/tools/test_kg_morpho_features_tool.py create mode 100644 swarm_copy_tests/tools/test_literature_search_tool.py create mode 100644 swarm_copy_tests/tools/test_morphology_features_tool.py create mode 100644 swarm_copy_tests/tools/test_resolve_entities_tool.py create mode 100644 swarm_copy_tests/tools/test_traces_tool.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 285957a..2ab5482 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - LLM evaluation logic - Integrated Alembic for managing chat history migrations - Tool implementations without langchain or langgraph dependencies +- Unit tests for the migrated tools - CRUDs. - BlueNaas CRUD tools - Cell types, resolving and utils tests diff --git a/swarm_copy/tools/get_morpho_tool.py b/swarm_copy/tools/get_morpho_tool.py index 45c72bb..f7e2aa6 100644 --- a/swarm_copy/tools/get_morpho_tool.py +++ b/swarm_copy/tools/get_morpho_tool.py @@ -1,6 +1,7 @@ """Get Morpho tool.""" import logging +from pathlib import Path from typing import Any, ClassVar from pydantic import BaseModel, Field @@ -30,8 +31,8 @@ class GetMorphoMetadata(BaseMetadata): knowledge_graph_url: str token: str morpho_search_size: int - brainregion_path: str - celltypes_path: str + brainregion_path: str | Path + celltypes_path: str | Path class KnowledgeGraphOutput(BaseModel): diff --git a/swarm_copy/tools/kg_morpho_features_tool.py b/swarm_copy/tools/kg_morpho_features_tool.py index 7298636..31023b8 100644 --- a/swarm_copy/tools/kg_morpho_features_tool.py +++ b/swarm_copy/tools/kg_morpho_features_tool.py @@ -1,6 +1,7 @@ """KG Morpho Feature tool.""" import logging +from pathlib import Path from typing import Any, ClassVar, Literal from pydantic import BaseModel, Field, model_validator @@ -151,7 +152,7 @@ class KGMorphoFeatureMetadata(BaseMetadata): knowledge_graph_url: str token: str kg_morpho_feature_search_size: int - brainregion_path: str + brainregion_path: str | Path class KGMorphoFeatureOutput(BaseModel): diff --git a/swarm_copy_tests/data/99111002.nwb b/swarm_copy_tests/data/99111002.nwb new file mode 100644 index 0000000000000000000000000000000000000000..ce6791daea58c5af64c6eed3960928ff1171b22a GIT binary patch literal 530771 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 z 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

}TkUa#uBRQdH;}YMO&Gp0!0W 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 literal 0 HcmV?d00001 diff --git a/swarm_copy_tests/data/get_traces.json b/swarm_copy_tests/data/get_traces.json new file mode 100644 index 0000000..1dc0011 --- /dev/null +++ b/swarm_copy_tests/data/get_traces.json @@ -0,0 +1,201 @@ +{ + "hits": { + "hits": [ + { + "_id": "https://bbp.epfl.ch/data/demo/morpho-demo/1761e604-03fc-452b-9bf2-2214782bb751", + "_index": "nexus_search_d067e019-1398-4eb8-9e28-3af8a717dcd7_41b1545a-cb2e-4848-8c74-195ec79f7bd3_18", + "_score": 6.0860696, + "_source": { + "@id": "https://bbp.epfl.ch/data/demo/morpho-demo/1761e604-03fc-452b-9bf2-2214782bb751", + "@type": [ + "https://neuroshapes.org/Trace", + "https://bbp.epfl.ch/ontologies/core/bmo/ExperimentalTrace" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/382", + "idLabel": "http://api.brain-map.org/api/v2/data/Structure/382|Field CA1", + "identifier": "http://api.brain-map.org/api/v2/data/Structure/382", + "label": "Field CA1" + }, + "contributors": [ + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/859a20a2-9eea-4ab5-9504-d080c3c79311", + "@type": [ + "http://www.w3.org/ns/prov#Agent", + "http://schema.org/Person" + ], + "idLabel": "https://bbp.epfl.ch/neurosciencegraph/data/859a20a2-9eea-4ab5-9504-d080c3c79311|Zsolt Kohus", + "label": "Zsolt Kohus" + } + ], + "createdAt": "2024-04-09T21:47:08.569Z", + "createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/budd", + "deprecated": false, + "derivation": [ + { + "@type": [ + "http://www.w3.org/ns/prov#Entity", + "https://neuroshapes.org/PatchedCell" + ], + "identifier": "https://bbp.epfl.ch/data/data/demo/morpho-demo/7173ea54-8e59-478d-85f3-ff86246ef22b", + "label": "s160106_0201" + } + ], + "distribution": [ + { + "contentSize": 4919928, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/demo/morpho-demo/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F01dffb7b-1122-4e1a-9acf-837e683da4ba", + "encodingFormat": "application/nwb", + "label": "s160106_02.nwb" + } + ], + "generation": { + "@id": "https://bbp.epfl.ch/data/demo/morpho-demo/d857ff82-b558-4117-b643-74d44dbda5e6", + "endedAt": "2016-01-06T23:59:00.000Z", + "startedAt": "2016-01-06T00:00:00.000Z" + }, + "image": [ + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2Fc1ef69e4-0073-481d-9446-fcfd7b5b5f7a", + "about": "https://neuroshapes.org/StimulationTrace", + "identifier": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2Fc1ef69e4-0073-481d-9446-fcfd7b5b5f7a", + "repetition": 0, + "stimulusType": "square" + }, + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F6fd03e92-b2ae-4ab8-8c9e-f0ff52d20a0d", + "about": "https://neuroshapes.org/ResponseTrace", + "identifier": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F6fd03e92-b2ae-4ab8-8c9e-f0ff52d20a0d", + "repetition": 0, + "stimulusType": "square" + } + ], + "name": "s160106_02", + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/demo/morpho-demo", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/demo/morpho-demo", + "label": "demo/morpho-demo" + }, + "subjectAge": { + "label": "59 days Post-natal", + "period": "Post-natal", + "unit": "days", + "value": 59 + }, + "subjectSpecies": { + "@id": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "identifier": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "label": "Mus musculus" + }, + "updatedAt": "2024-04-10T08:40:23.039Z", + "updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/cgonzale", + "_self": "https://bbp.epfl.ch/nexus/v1/resources/demo/morpho-demo/_/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2F1761e604-03fc-452b-9bf2-2214782bb751" + } + }, + { + "_id": "https://bbp.epfl.ch/data/demo/morpho-demo/5f710291-9aac-45d0-94ff-d3d318c6ba2f", + "_index": "nexus_search_d067e019-1398-4eb8-9e28-3af8a717dcd7_41b1545a-cb2e-4848-8c74-195ec79f7bd3_18", + "_score": 6.0860696, + "_source": { + "@id": "https://bbp.epfl.ch/data/demo/morpho-demo/5f710291-9aac-45d0-94ff-d3d318c6ba2f", + "@type": [ + "https://neuroshapes.org/Trace", + "https://bbp.epfl.ch/ontologies/core/bmo/ExperimentalTrace" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/382", + "idLabel": "http://api.brain-map.org/api/v2/data/Structure/382|Field CA1", + "identifier": "http://api.brain-map.org/api/v2/data/Structure/382", + "label": "Field CA1" + }, + "contributors": [ + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/859a20a2-9eea-4ab5-9504-d080c3c79311", + "@type": [ + "http://www.w3.org/ns/prov#Agent", + "http://schema.org/Person" + ], + "idLabel": "https://bbp.epfl.ch/neurosciencegraph/data/859a20a2-9eea-4ab5-9504-d080c3c79311|Zsolt Kohus", + "label": "Zsolt Kohus" + } + ], + "createdAt": "2024-04-10T13:58:37.803Z", + "createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/budd", + "deprecated": false, + "derivation": [ + { + "@type": [ + "https://neuroshapes.org/PatchedCell", + "http://www.w3.org/ns/prov#Entity" + ], + "identifier": "https://bbp.epfl.ch/data/demo/morpho-demo/c5c68107-39e5-4124-8681-8a644ab0f8ce", + "label": "s160106_0201" + } + ], + "distribution": [ + { + "contentSize": 4919928, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/demo/morpho-demo/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2Ff759098b-3db5-4236-a577-eac23191e063", + "encodingFormat": "application/nwb", + "label": "s160106_02.nwb" + } + ], + "generation": { + "@id": "https://bbp.epfl.ch/data/demo/morpho-demo/d47968ad-7644-4153-9bf5-a68277f9e17e", + "endedAt": "2016-01-06T23:59:00.000Z", + "startedAt": "2016-01-06T00:00:00.000Z" + }, + "image": [ + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2F835b1f06-c688-4771-9e45-c9c091666a8d", + "about": "https://neuroshapes.org/ResponseTrace", + "identifier": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2F835b1f06-c688-4771-9e45-c9c091666a8d", + "repetition": 0, + "stimulusType": "square" + }, + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2Fde25efaf-6f6a-4245-a5a5-eeed4eddc83e", + "about": "https://neuroshapes.org/StimulationTrace", + "identifier": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2Fde25efaf-6f6a-4245-a5a5-eeed4eddc83e", + "repetition": 0, + "stimulusType": "square" + } + ], + "name": "s160106_02", + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/demo/morpho-demo", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/demo/morpho-demo", + "label": "demo/morpho-demo" + }, + "subjectAge": { + "label": "59 days Post-natal", + "period": "Post-natal", + "unit": "days", + "value": 59 + }, + "subjectSpecies": { + "@id": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "identifier": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "label": "Mus musculus" + }, + "updatedAt": "2024-04-10T13:58:37.803Z", + "updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/budd", + "_self": "https://bbp.epfl.ch/nexus/v1/resources/demo/morpho-demo/_/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2F5f710291-9aac-45d0-94ff-d3d318c6ba2f" + } + } + ], + "max_score": 6.0860696, + "total": { + "relation": "eq", + "value": 1905 + } + }, + "timed_out": false, + "took": 65, + "_shards": { + "failed": 0, + "skipped": 664, + "successful": 742, + "total": 742 + } +} diff --git a/swarm_copy_tests/data/kg_me_model_output.json b/swarm_copy_tests/data/kg_me_model_output.json new file mode 100644 index 0000000..6db0acd --- /dev/null +++ b/swarm_copy_tests/data/kg_me_model_output.json @@ -0,0 +1,152 @@ +{ + "hits": { + "hits": [ + { + "sort": [ + 1716989796908 + ], + "_id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/eeeeac3c-6bf1-47ed-ab97-460668eba2d2", + "_index": "nexus_search_711d6b8f-1285-42db-9259-b277dd687435_711d6b8f-1285-42db-9259-b277dd687435_21", + "_source": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/eeeeac3c-6bf1-47ed-ab97-460668eba2d2", + "@type": "https://neuroshapes.org/MEModel", + "analysisSuitable": false, + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/322", + "idLabel": "http://api.brain-map.org/api/v2/data/Structure/322|Primary somatosensory area", + "identifier": "http://api.brain-map.org/api/v2/data/Structure/322", + "label": "Primary somatosensory area" + }, + "createdAt": "2024-05-29T13:36:36.908Z", + "createdBy": "https://openbluebrain.com/api/nexus/v1/realms/bbp/users/antonel", + "deprecated": false, + "description": "My me-model", + "eType": { + "@id": "_:b0", + "identifier": "_:b0", + "label": "cNAC" + }, + "generation": {}, + "image": [ + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/2869d500-3c6e-4d15-bcae-b4ece55c5586", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/2869d500-3c6e-4d15-bcae-b4ece55c5586" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/aea6c71b-41a9-4268-96e7-d0f9265693e1", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/parameters_distribution", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/aea6c71b-41a9-4268-96e7-d0f9265693e1" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/ea0b79b5-66bb-48bf-8933-9b43b56959d5", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/traces", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/ea0b79b5-66bb-48bf-8933-9b43b56959d5" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/ba3c8d1a-2839-4fdd-b13f-73950c84954a", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/ba3c8d1a-2839-4fdd-b13f-73950c84954a" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/af301c80-0c51-4726-95b7-dc65e5e180fd", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/scores", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/af301c80-0c51-4726-95b7-dc65e5e180fd" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/798bab6a-4caa-460b-bac7-a6f08672f11b", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/798bab6a-4caa-460b-bac7-a6f08672f11b" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/489673cc-27c1-46bf-ad6a-510ea124a4cc", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/489673cc-27c1-46bf-ad6a-510ea124a4cc" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/3cb119a2-6a3a-4e75-99c5-53f2405d3e91", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/3cb119a2-6a3a-4e75-99c5-53f2405d3e91" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/3819e25e-ace3-4809-9a96-964d5d9fb932", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/3819e25e-ace3-4809-9a96-964d5d9fb932" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/33bcf9d3-b6db-4d2c-b3c6-3ea8a5932202", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/33bcf9d3-b6db-4d2c-b3c6-3ea8a5932202" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/29dc72cb-bb9d-4966-bc3b-70e6ff65c6e3", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/currentscape", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/29dc72cb-bb9d-4966-bc3b-70e6ff65c6e3" + }, + { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/e5e20e7a-87b5-47a2-abda-2d7212ab00e1", + "about": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/thumbnail", + "identifier": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/e5e20e7a-87b5-47a2-abda-2d7212ab00e1" + } + ], + "layer": [ + { + "@id": "http://purl.obolibrary.org/obo/UBERON_0005394", + "idLabel": "http://purl.obolibrary.org/obo/UBERON_0005394|layer 5", + "identifier": "http://purl.obolibrary.org/obo/UBERON_0005394", + "label": "layer 5" + } + ], + "mType": { + "@id": "_:b2", + "identifier": "_:b2", + "label": "L5_TPC:B" + }, + "memodel": { + "emodelResource": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/67acf101-12f6-4b7b-8a89-5237aadf94db", + "name": "EM__hipp_rat__CA1_int_cNAC_010710HP2_20190328163258__2" + }, + "neuronMorphology": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/255e007e-a6d1-4fc9-b984-1e0221e39ea3", + "name": "ch150801A1" + }, + "validated": true + }, + "name": "My me-model", + "objectOfStudy": { + "@id": "http://bbp.epfl.ch/neurosciencegraph/taxonomies/objectsofstudy/singlecells", + "identifier": "http://bbp.epfl.ch/neurosciencegraph/taxonomies/objectsofstudy/singlecells", + "label": "Single Cell" + }, + "project": { + "@id": "https://openbluebrain.com/api/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "identifier": "https://openbluebrain.com/api/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "label": "bbp/mmb-point-neuron-framework-model" + }, + "seed": 2, + "subjectSpecies": { + "@id": "http://purl.obolibrary.org/obo/NCBITaxon_10116", + "identifier": "http://purl.obolibrary.org/obo/NCBITaxon_10116", + "label": "Rattus norvegicus" + }, + "updatedAt": "2024-07-09T10:53:01.208Z", + "updatedBy": "https://openbluebrain.com/api/nexus/v1/realms/bbp/users/ajaquier", + "_self": "https://openbluebrain.com/api/nexus/v1/resources/bbp/mmb-point-neuron-framework-model/_/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fbbp%2Fmmb-point-neuron-framework-model%2Feeeeac3c-6bf1-47ed-ab97-460668eba2d2" + } + } + ], + "total": { + "relation": "eq", + "value": 1 + } + }, + "timed_out": false, + "took": 14, + "_shards": { + "failed": 0, + "skipped": 4, + "successful": 15, + "total": 15 + } +} \ No newline at end of file diff --git a/swarm_copy_tests/data/kg_morpho_features_response.json b/swarm_copy_tests/data/kg_morpho_features_response.json new file mode 100644 index 0000000..70fd8de --- /dev/null +++ b/swarm_copy_tests/data/kg_morpho_features_response.json @@ -0,0 +1,412 @@ +{ + "hits": { + "hits": [ + { + "_id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/9ca1c32b-e9fd-470b-a759-bdaf37d81ec9", + "_index": "nexus_search_711d6b8f-1285-42db-9259-b277dd687435_2a84a9ee-75b2-43c4-90a0-1eb5624e8ca0_15", + "_score": 17.77101, + "_source": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/9ca1c32b-e9fd-470b-a759-bdaf37d81ec9", + "@type": [ + "https://neuroshapes.org/Annotation", + "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologyFeatureAnnotation" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/718", + "idLabel": [ + "http://api.brain-map.org/api/v2/data/Structure/718|Ventral posterolateral nucleus of the thalamus" + ], + "identifier": [ + "http://api.brain-map.org/api/v2/data/Structure/718" + ], + "label": "Ventral posterolateral nucleus of the thalamus" + }, + "compartment": "BasalDendrite", + "contributors": [ + { + "@id": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi" + ], + "@type": [ + "http://www.w3.org/ns/prov#Agent", + "http://schema.org/Person" + ], + "idLabel": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi|Niccolo Ricardi" + ], + "label": "Niccolo Ricardi" + } + ], + "createdAt": "2024-03-20T14:30:24.472Z", + "createdBy": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi" + ], + "deprecated": false, + "featureSeries": [ + { + "compartment": "BasalDendrite", + "label": "Section Strahler Orders", + "statistic": "mean", + "unit": "dimensionless", + "value": 1.7364864864864864 + }, + { + "compartment": "BasalDendrite", + "label": "Section Areas", + "statistic": "median", + "unit": "μm²", + "value": 272.5912248893231 + }, + { + "compartment": "BasalDendrite", + "label": "Section Strahler Orders", + "statistic": "minimum", + "unit": "dimensionless", + "value": 1.0 + }, + { + "compartment": "BasalDendrite", + "label": "Section Volumes", + "statistic": "mean", + "unit": "μm³", + "value": 180.5787321010427 + }, + { + "compartment": "BasalDendrite", + "label": "Local Bifurcation Angles", + "statistic": "maximum", + "unit": "radian", + "value": 2.6143908349883835 + }, + { + "compartment": "BasalDendrite", + "label": "Number Of Leaves", + "statistic": "raw", + "unit": "dimensionless", + "value": 76.0 + }, + { + "compartment": "BasalDendrite", + "label": "Section Radial Distances", + "statistic": "minimum", + "unit": "μm", + "value": 5.518080711364746 + }, + { + "compartment": "BasalDendrite", + "label": "Local Bifurcation Angles", + "statistic": "mean", + "unit": "radian", + "value": 0.9031414351696362 + }, + { + "compartment": "BasalDendrite", + "label": "Section Tortuosity", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 0.08268018811941147 + }, + { + "compartment": "BasalDendrite", + "label": "Diameter Power Relations", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 0.0 + }, + { + "compartment": "BasalDendrite", + "label": "Section Strahler Orders", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 0.9106092887975676 + }, + { + "compartment": "BasalDendrite", + "label": "Section Bif Branch Orders", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 1.7145325641644276 + }, + { + "compartment": "BasalDendrite", + "label": "Section Bif Radial Distances", + "statistic": "standard deviation", + "unit": "μm", + "value": 35.042884826660156 + }, + { + "compartment": "BasalDendrite", + "label": "Terminal Path Lengths", + "statistic": "minimum", + "unit": "μm", + "value": 92.61423313617706 + }, + { + "compartment": "BasalDendrite", + "label": "Section Term Lengths", + "statistic": "median", + "unit": "μm", + "value": 92.60545349121094 + }, + { + "compartment": "BasalDendrite", + "label": "Section Path Distances", + "statistic": "standard deviation", + "unit": "μm", + "value": 71.30703565937296 + }, + { + "compartment": "BasalDendrite", + "label": "Section Bif Branch Orders", + "statistic": "mean", + "unit": "dimensionless", + "value": 3.3194444444444446 + }, + { + "compartment": "BasalDendrite", + "label": "Partition Asymmetry Length", + "statistic": "maximum", + "unit": "μm", + "value": 0.5928827095301132 + }, + { + "compartment": "BasalDendrite", + "label": "Sibling Ratios", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 0.0 + }, + { + "compartment": "BasalDendrite", + "label": "Section Path Distances", + "statistic": "maximum", + "unit": "μm", + "value": 343.71869564056396 + }, + { + "compartment": "BasalDendrite", + "label": "Section Lengths", + "statistic": "standard deviation", + "unit": "μm", + "value": 49.600032806396484 + }, + { + "compartment": "BasalDendrite", + "label": "Remote Bifurcation Angles", + "statistic": "maximum", + "unit": "radian", + "value": 2.2732763128975844 + }, + { + "compartment": "BasalDendrite", + "label": "Diameter Power Relations", + "statistic": "median", + "unit": "dimensionless", + "value": 2.0 + }, + { + "compartment": "BasalDendrite", + "label": "Section Term Branch Orders", + "statistic": "minimum", + "unit": "dimensionless", + "value": 1.0 + }, + { + "compartment": "BasalDendrite", + "label": "Section Strahler Orders", + "statistic": "median", + "unit": "dimensionless", + "value": 1.0 + }, + { + "compartment": "BasalDendrite", + "label": "Section Term Branch Orders", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 1.5169289394042875 + }, + { + "compartment": "BasalDendrite", + "label": "Section Tortuosity", + "statistic": "mean", + "unit": "dimensionless", + "value": 0.9999998807907104 + } + ], + "generation": { + "endedAt": "2024-03-20T14:24:16.000Z", + "startedAt": "2024-03-20T14:24:16.000Z" + }, + "name": "Neuron Morphology Feature Annotation", + "neuronMorphology": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/75e5f49f-4edf-474a-a3fd-47073a38ea38", + "name": "AA0322" + }, + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "label": "bbp/mmb-point-neuron-framework-model" + }, + "updatedAt": "2024-03-20T17:47:15.490Z", + "updatedBy": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi" + ], + "_self": "https://bbp.epfl.ch/nexus/v1/resources/bbp/mmb-point-neuron-framework-model/_/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fbbp%2Fmmb-point-neuron-framework-model%2F9ca1c32b-e9fd-470b-a759-bdaf37d81ec9" + } + }, + { + "_id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/09704e7e-e773-4f2f-a6ab-0c30a73216fc", + "_index": "nexus_search_711d6b8f-1285-42db-9259-b277dd687435_2a84a9ee-75b2-43c4-90a0-1eb5624e8ca0_15", + "_score": 17.77101, + "_source": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/09704e7e-e773-4f2f-a6ab-0c30a73216fc", + "@type": [ + "https://neuroshapes.org/Annotation", + "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologyFeatureAnnotation" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/718", + "idLabel": [ + "http://api.brain-map.org/api/v2/data/Structure/718|Ventral posterolateral nucleus of the thalamus" + ], + "identifier": [ + "http://api.brain-map.org/api/v2/data/Structure/718" + ], + "label": "Ventral posterolateral nucleus of the thalamus" + }, + "compartment": "Axon", + "contributors": [ + { + "@id": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi" + ], + "@type": [ + "http://www.w3.org/ns/prov#Agent", + "http://schema.org/Person" + ], + "idLabel": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi|Niccolo Ricardi" + ], + "label": "Niccolo Ricardi" + } + ], + "createdAt": "2024-03-20T14:30:24.463Z", + "createdBy": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi" + ], + "deprecated": false, + "featureSeries": [ + { + "compartment": "Axon", + "label": "Section Tortuosity", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 0.1429130584001541 + }, + { + "compartment": "Axon", + "label": "Section Tortuosity", + "statistic": "mean", + "unit": "dimensionless", + "value": 1.1262837648391724 + }, + { + "compartment": "Axon", + "label": "Terminal Path Lengths", + "statistic": "minimum", + "unit": "μm", + "value": 5599.079376220703 + }, + { + "compartment": "Axon", + "label": "Section Path Distances", + "statistic": "maximum", + "unit": "μm", + "value": 7780.849250793457 + }, + { + "compartment": "Axon", + "label": "Section Volumes", + "statistic": "mean", + "unit": "μm³", + "value": 136.01814291776782 + }, + { + "compartment": "Axon", + "label": "Diameter Power Relations", + "statistic": "maximum", + "unit": "dimensionless", + "value": 2.0 + }, + { + "compartment": "Axon", + "label": "Section Path Distances", + "statistic": "standard deviation", + "unit": "μm", + "value": 486.26185300130675 + }, + { + "compartment": "Axon", + "label": "Section Radial Distances", + "statistic": "median", + "unit": "μm", + "value": 3837.996337890625 + }, + { + "compartment": "Axon", + "label": "Section Strahler Orders", + "statistic": "median", + "unit": "dimensionless", + "value": 1.0 + }, + { + "compartment": "Axon", + "label": "Diameter Power Relations", + "statistic": "standard deviation", + "unit": "dimensionless", + "value": 0.0 + }, + { + "compartment": "Axon", + "label": "Section Lengths", + "statistic": "mean", + "unit": "μm", + "value": 233.14886474609375 + }, + { + "compartment": "Axon", + "label": "Section Path Distances", + "statistic": "minimum", + "unit": "μm", + "value": 4048.837158203125 + } + ], + "generation": { + "endedAt": "2024-03-20T14:24:16.000Z", + "startedAt": "2024-03-20T14:24:16.000Z" + }, + "name": "Neuron Morphology Feature Annotation", + "neuronMorphology": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/75e5f49f-4edf-474a-a3fd-47073a38ea38", + "name": "AA0322" + }, + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "label": "bbp/mmb-point-neuron-framework-model" + }, + "updatedAt": "2024-03-20T17:47:15.513Z", + "updatedBy": [ + "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi" + ], + "_self": "https://bbp.epfl.ch/nexus/v1/resources/bbp/mmb-point-neuron-framework-model/_/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fbbp%2Fmmb-point-neuron-framework-model%2F09704e7e-e773-4f2f-a6ab-0c30a73216fc" + } + } + ], + "max_score": 17.77101, + "total": {"relation": "eq", "value": 1230} + }, + "timed_out": false, + "took": 342, + "_shards": {"failed": 0, "skipped": 0, "successful": 13, "total": 13} +} diff --git a/swarm_copy_tests/data/knowledge_graph.json b/swarm_copy_tests/data/knowledge_graph.json new file mode 100644 index 0000000..11b0579 --- /dev/null +++ b/swarm_copy_tests/data/knowledge_graph.json @@ -0,0 +1,182 @@ +{ + "hits": { + "hits": [ + { + "_id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/ca1f0e5f-ff08-4476-9b5f-95f3c9d004fd", + "_index": "nexus_search_711d6b8f-1285-42db-9259-b277dd687435_2a84a9ee-75b2-43c4-90a0-1eb5624e8ca0_15", + "_score": 10.407086, + "_source": { + "@id": "https://bbp.epfl.ch/data/bbp/mmb-point-neuron-framework-model/ca1f0e5f-ff08-4476-9b5f-95f3c9d004fd", + "@type": [ + "https://neuroshapes.org/ReconstructedNeuronMorphology", + "https://neuroshapes.org/NeuronMorphology" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/629", + "idLabel": "http://api.brain-map.org/api/v2/data/Structure/629|Ventral anterior-lateral complex of the thalamus", + "identifier": "http://api.brain-map.org/api/v2/data/Structure/629", + "label": "Ventral anterior-lateral complex of the thalamus" + }, + "contributors": [ + { + "@id": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ajaquier", + "@type": [ + "http://www.w3.org/ns/prov#Agent", + "http://schema.org/Person" + ], + "idLabel": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ajaquier|Aurélien Tristan Jaquier", + "label": "Aurélien Tristan Jaquier" + } + ], + "createdAt": "2023-10-30T10:27:09.334Z", + "createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ajaquier", + "curated": true, + "deprecated": false, + "description": "This is a morphology reconstruction of a mouse thalamus cell that was obtained from the Janelia Mouselight project http://ml-neuronbrowser.janelia.org/ . This morphology is positioned in the Mouselight custom 'CCFv2.5' reference space, instead of the Allen Institute CCFv3 reference space.", + "distribution": [ + { + "contentSize": 105248, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mmb-point-neuron-framework-model/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fbbp%2Fmmb-point-neuron-framework-model%2F6ca97d5c-c61b-43d0-8f89-6c041d3e5173", + "encodingFormat": "application/h5", + "label": "AA0519.h5" + }, + { + "contentSize": 480929, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mmb-point-neuron-framework-model/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fbbp%2Fmmb-point-neuron-framework-model%2Fad8ed9fe-9aef-4716-9326-6b15c3219a1b", + "encodingFormat": "application/asc", + "label": "AA0519.asc" + }, + { + "contentSize": 405464, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mmb-point-neuron-framework-model/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fbbp%2Fmmb-point-neuron-framework-model%2F358624e3-3449-4a10-8e31-aa19017d8583", + "encodingFormat": "application/swc", + "label": "AA0519.swc" + } + ], + "mType": { + "@id": "http://uri.interlex.org/base/ilx_0738236", + "idLabel": "http://uri.interlex.org/base/ilx_0738236|VPL_TC", + "identifier": "http://uri.interlex.org/base/ilx_0738236", + "label": "VPL_TC" + }, + "name": "AA0519", + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mmb-point-neuron-framework-model", + "label": "bbp/mmb-point-neuron-framework-model" + }, + "subjectAge": { + "label": "60 days Post-natal", + "period": "Post-natal", + "unit": "days", + "value": 60 + }, + "subjectSpecies": { + "@id": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "identifier": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "label": "Mus musculus" + }, + "updatedAt": "2024-04-30T07:59:30.098Z", + "updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ajaquier", + "_self": "https://bbp.epfl.ch/nexus/v1/resources/bbp/mmb-point-neuron-framework-model/_/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fbbp%2Fmmb-point-neuron-framework-model%2Fca1f0e5f-ff08-4476-9b5f-95f3c9d004fd" + } + }, + { + "_id": "https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9", + "_index": "nexus_search_b5db4c20-8200-47f9-98d9-0ca8fa3be422_d2505573-bdde-4df9-92f9-0652523b3fb2_15", + "_score": 7.05979, + "_source": { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9", + "@type": [ + "https://neuroshapes.org/ReconstructedNeuronMorphology", + "https://neuroshapes.org/NeuronMorphology" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/262", + "idLabel": "http://api.brain-map.org/api/v2/data/Structure/262|Reticular nucleus of the thalamus", + "identifier": "http://api.brain-map.org/api/v2/data/Structure/262", + "label": "Reticular nucleus of the thalamus" + }, + "contributors": [ + { + "@id": "https://www.grid.ac/institutes/grid.443970.d", + "@type": [ + "http://schema.org/Organization", + "http://www.w3.org/ns/prov#Agent" + ], + "idLabel": "https://www.grid.ac/institutes/grid.443970.d|Janelia Research Campus", + "label": "Janelia Research Campus" + } + ], + "coordinatesInBrainAtlas": { + "valueX": "6413.2944", + "valueY": "4899.1997", + "valueZ": "4254.461" + }, + "createdAt": "2022-06-16T12:47:56.777Z", + "createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/akkaufma", + "curated": true, + "deprecated": false, + "description": "Annotation Space: CCFv3.0 Axes> X: Anterior-Posterior; Y: Inferior-Superior; Z:Left-Right. Despite Mouselight metadata for CCFv2.5 and CCFv3 versions of this morphology indicating that this cell belongs to either the 'Ventral anterior-lateral complex of the thalamus' ('VAL') or 'Ventral medial nucleus of the thalamus' ('VM') region, it is almost certainly a reticular cell belonging to the 'Reticular nucleus of the thalamus' or 'RT' region. Reticular cells only exist in the RT region, and while most of the axons of this morphology exist in non-RT thalamus, viewing the morphology alongside the area of RT in the Mouselight browser here http://ml-neuronbrowser.janelia.org/ clearly shows the soma and dendrites existing in or near the RT region. Based on the location of its soma and dendrites, their general structure, and the projection pattern of its axons, this is almost certainly a reticular inhibitory cell from the RT region. In https://doi.org/10.1016/j.celrep.2023.112200 , this morphology was used as reticular inhibitory morphology belonging to the 'Rt_RC' M-type.", + "distribution": [ + { + "contentSize": 137320, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mouselight/https%3A%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2F2ad0380d-c9b2-496e-9855-ab3d173930dd", + "encodingFormat": "application/h5", + "label": "AA0718.h5" + }, + { + "contentSize": 633407, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mouselight/https%3A%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2F5ef4f830-d6ac-4a26-8a39-2c918d2d9fb0", + "encodingFormat": "application/asc", + "label": "AA0718.asc" + }, + { + "contentSize": 413625, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mouselight/https%3A%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2Fad8fec6f-d59c-4998-beb4-274fa115add7", + "encodingFormat": "application/swc", + "label": "AA0718.swc" + } + ], + "license": { + "@id": "https://creativecommons.org/licenses/by-nc/4.0/", + "identifier": "https://creativecommons.org/licenses/by-nc/4.0/" + }, + "mType": { + "@id": "http://uri.interlex.org/base/ilx_0738229", + "idLabel": "http://uri.interlex.org/base/ilx_0738229|Rt_RC", + "identifier": "http://uri.interlex.org/base/ilx_0738229", + "label": "Rt_RC" + }, + "name": "AA0718", + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mouselight", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mouselight", + "label": "bbp/mouselight" + }, + "subjectSpecies": { + "@id": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "identifier": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "label": "Mus musculus" + }, + "updatedAt": "2024-04-10T11:34:30.456Z", + "updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi", + "_self": "https://bbp.epfl.ch/nexus/v1/resources/bbp/mouselight/_/https:%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2Fneuronmorphologies%2F046fb11c-8de8-42e8-9303-9d5a65ac04b9" + } + } + ], + "max_score": 10.407086, + "total": { + "relation": "eq", + "value": 160 + } + }, + "timed_out": false, + "took": 423, + "_shards": { + "failed": 0, + "skipped": 712, + "successful": 742, + "total": 742 + } +} diff --git a/swarm_copy_tests/data/morphology_id_metadata_response.json b/swarm_copy_tests/data/morphology_id_metadata_response.json new file mode 100644 index 0000000..904b6ad --- /dev/null +++ b/swarm_copy_tests/data/morphology_id_metadata_response.json @@ -0,0 +1,102 @@ +{ + "hits": { + "hits": [ + { + "_id": "https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9", + "_index": "nexus_search_b5db4c20-8200-47f9-98d9-0ca8fa3be422_d2505573-bdde-4df9-92f9-0652523b3fb2_15", + "_score": 12.887569, + "_source": { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9", + "@type": [ + "https://neuroshapes.org/ReconstructedNeuronMorphology", + "https://neuroshapes.org/NeuronMorphology" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/262", + "idLabel": "http://api.brain-map.org/api/v2/data/Structure/262|Reticular nucleus of the thalamus", + "identifier": "http://api.brain-map.org/api/v2/data/Structure/262", + "label": "Reticular nucleus of the thalamus" + }, + "contributors": [ + { + "@id": "https://www.grid.ac/institutes/grid.443970.d", + "@type": [ + "http://schema.org/Organization", + "http://www.w3.org/ns/prov#Agent" + ], + "idLabel": "https://www.grid.ac/institutes/grid.443970.d|Janelia Research Campus", + "label": "Janelia Research Campus" + } + ], + "coordinatesInBrainAtlas": { + "valueX": "6413.2944", + "valueY": "4899.1997", + "valueZ": "4254.461" + }, + "createdAt": "2022-06-16T12:47:56.777Z", + "createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/akkaufma", + "curated": true, + "deprecated": false, + "description": "Annotation Space: CCFv3.0 Axes> X: Anterior-Posterior; Y: Inferior-Superior; Z:Left-Right. Despite Mouselight metadata for CCFv2.5 and CCFv3 versions of this morphology indicating that this cell belongs to either the 'Ventral anterior-lateral complex of the thalamus' ('VAL') or 'Ventral medial nucleus of the thalamus' ('VM') region, it is almost certainly a reticular cell belonging to the 'Reticular nucleus of the thalamus' or 'RT' region. Reticular cells only exist in the RT region, and while most of the axons of this morphology exist in non-RT thalamus, viewing the morphology alongside the area of RT in the Mouselight browser here http://ml-neuronbrowser.janelia.org/ clearly shows the soma and dendrites existing in or near the RT region. Based on the location of its soma and dendrites, their general structure, and the projection pattern of its axons, this is almost certainly a reticular inhibitory cell from the RT region. In https://doi.org/10.1016/j.celrep.2023.112200 , this morphology was used as reticular inhibitory morphology belonging to the 'Rt_RC' M-type.", + "distribution": [ + { + "contentSize": 137320, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mouselight/https%3A%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2F2ad0380d-c9b2-496e-9855-ab3d173930dd", + "encodingFormat": "application/h5", + "label": "AA0718.h5" + }, + { + "contentSize": 633407, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mouselight/https%3A%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2F5ef4f830-d6ac-4a26-8a39-2c918d2d9fb0", + "encodingFormat": "application/asc", + "label": "AA0718.asc" + }, + { + "contentSize": 413625, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/bbp/mouselight/https%3A%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2Fad8fec6f-d59c-4998-beb4-274fa115add7", + "encodingFormat": "application/swc", + "label": "AA0718.swc" + } + ], + "license": { + "@id": "https://creativecommons.org/licenses/by-nc/4.0/", + "identifier": "https://creativecommons.org/licenses/by-nc/4.0/" + }, + "mType": { + "@id": "http://uri.interlex.org/base/ilx_0738229", + "idLabel": "http://uri.interlex.org/base/ilx_0738229|Rt_RC", + "identifier": "http://uri.interlex.org/base/ilx_0738229", + "label": "Rt_RC" + }, + "name": "AA0718", + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mouselight", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/bbp/mouselight", + "label": "bbp/mouselight" + }, + "subjectSpecies": { + "@id": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "identifier": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "label": "Mus musculus" + }, + "updatedAt": "2024-04-10T11:34:30.456Z", + "updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/ricardi", + "_self": "https://bbp.epfl.ch/nexus/v1/resources/bbp/mouselight/_/https:%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2Fneuronmorphologies%2F046fb11c-8de8-42e8-9303-9d5a65ac04b9" + } + } + ], + "max_score": 12.887569, + "total": { + "relation": "eq", + "value": 1 + } + }, + "timed_out": false, + "took": 53, + "_shards": { + "failed": 0, + "skipped": 664, + "successful": 742, + "total": 742 + } +} diff --git a/swarm_copy_tests/data/resolve_query.json b/swarm_copy_tests/data/resolve_query.json new file mode 100644 index 0000000..181dc08 --- /dev/null +++ b/swarm_copy_tests/data/resolve_query.json @@ -0,0 +1 @@ +[{"head": {"vars": ["subject", "predicate", "object", "context"]}, "results": {"bindings": [{"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "literal", "value": "Thalamus"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "literal", "value": "Thalamus"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#prefLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "literal", "value": "TH"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#altLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/BrainRegion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "uri", "value": "http://bbp.epfl.ch/neurosciencegraph/ontologies/core/brainregion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#isDefinedBy"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "literal", "value": "TH"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#notation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "literal", "value": "549"}, "predicate": {"type": "uri", "value": "http://schema.org/identifier"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"datatype": "http://www.w3.org/2001/XMLSchema#boolean", "type": "literal", "value": "true"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/representedInAnnotation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/262"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/1129"}, "predicate": {"type": "uri", "value": "http://schema.org/isPartOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/321"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/483"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/549"}}]}}, {"head": {"vars": ["subject", "predicate", "object", "context"]}, "results": {"bindings": [{"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "Interneuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "Interneuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#prefLabel"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "An interneuron is a type of neuron that acts as a connector or messenger between other neurons within the brain and spinal cord, and is often connected using inhibitory synapses. Interneurons process messages between neurons, helping to coordinate and integrate information within the nervous system."}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#definition"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/Neuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "Int"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#notation"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/MType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/BrainCellType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologicalType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}]}}, {"head": {"vars": ["subject", "predicate", "object", "context"]}, "results": {"bindings": [{"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "literal", "value": "Field CA1"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "literal", "value": "Field CA1"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#prefLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "literal", "value": "CA1"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#altLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/BrainRegion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://bbp.epfl.ch/neurosciencegraph/ontologies/core/brainregion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#isDefinedBy"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "literal", "value": "CA1"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#notation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "literal", "value": "382"}, "predicate": {"type": "uri", "value": "http://schema.org/identifier"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"datatype": "http://www.w3.org/2001/XMLSchema#boolean", "type": "literal", "value": "true"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/representedInAnnotation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/391"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/375"}, "predicate": {"type": "uri", "value": "http://schema.org/isPartOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/399"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/407"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/415"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/614454396"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/382"}}, {"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "literal", "value": "Field CA2"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "literal", "value": "Field CA2"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#prefLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "literal", "value": "CA2"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#altLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/BrainRegion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://bbp.epfl.ch/neurosciencegraph/ontologies/core/brainregion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#isDefinedBy"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "literal", "value": "CA2"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#notation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "literal", "value": "423"}, "predicate": {"type": "uri", "value": "http://schema.org/identifier"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"datatype": "http://www.w3.org/2001/XMLSchema#boolean", "type": "literal", "value": "true"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/representedInAnnotation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/431"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/375"}, "predicate": {"type": "uri", "value": "http://schema.org/isPartOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/454"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/446"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/438"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/614454397"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/423"}}, {"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "literal", "value": "Field CA3"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "literal", "value": "Field CA3"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#prefLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "literal", "value": "CA3"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#altLabel"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/BrainRegion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://bbp.epfl.ch/neurosciencegraph/ontologies/core/brainregion"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#isDefinedBy"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "literal", "value": "CA3"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#notation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "literal", "value": "463"}, "predicate": {"type": "uri", "value": "http://schema.org/identifier"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"datatype": "http://www.w3.org/2001/XMLSchema#boolean", "type": "literal", "value": "true"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/representedInAnnotation"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/479"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/375"}, "predicate": {"type": "uri", "value": "http://schema.org/isPartOf"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/486"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/495"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/471"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/504"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}, {"object": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/614454398"}, "predicate": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/hasLeafRegionPart"}, "subject": {"type": "uri", "value": "http://api.brain-map.org/api/v2/data/Structure/463"}}]}}, {"head": {"vars": ["subject", "predicate", "object", "context"]}, "results": {"bindings": [{"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "Interneuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "Interneuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#prefLabel"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "An interneuron is a type of neuron that acts as a connector or messenger between other neurons within the brain and spinal cord, and is often connected using inhibitory synapses. Interneurons process messages between neurons, helping to coordinate and integrate information within the nervous system."}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#definition"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/Neuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "literal", "value": "Int"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#notation"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://neuroshapes.org/MType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/BrainCellType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologicalType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "https://neuroshapes.org/Interneuron"}}, {"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0105044"}}, {"object": {"type": "literal", "value": "Hippocampus CA3 Oriens Interneuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0105044"}}, {"object": {"type": "literal", "value": "CA3 SO interneuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#altLabel"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0105044"}}, {"object": {"type": "literal", "value": "The CA3 stratum oriens interneuron is a fast spiking interneuron in hippocampal area CA3 with a main dendrite arborization extending in the stratum oriens and a widespread axonal arborization in all strata (Kawaguchi et al., 1987). The vast majority of dendritic processes were confined to the same layers as the cell bodies (Kantona et al., 1999)."}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#definition"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0105044"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/BrainCellType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0105044"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0105044"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/NewNeuronType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0105044"}}, {"object": {"type": "uri", "value": "http://www.w3.org/2002/07/owl#Class"}, "predicate": {"type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0110929"}}, {"object": {"type": "literal", "value": "Spinal Cord Ventral Horn Interneuron IA"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#label"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0110929"}}, {"object": {"type": "literal", "value": "Spinal Ia interneuron"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2004/02/skos/core#altLabel"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0110929"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/BrainCellType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0110929"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885"}, "predicate": {"type": "uri", "value": "https://neuroshapes.org/atlasRelease"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0110929"}}, {"object": {"type": "uri", "value": "https://bbp.epfl.ch/ontologies/core/bmo/NewNeuronType"}, "predicate": {"type": "uri", "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf"}, "subject": {"type": "uri", "value": "http://uri.interlex.org/base/ilx_0110929"}}]}}, {"hits": {"hits": [{"_id": "http://api.brain-map.org/api/v2/data/Structure/688", "_index": "nexus_61cab3d6-56e5-4d32-b538-a08c90aca76c_3", "_score": 15.918847, "_source": {"@id": "http://api.brain-map.org/api/v2/data/Structure/688", "@type": "Class", "altLabel": "CTX", "atlasRelease": {"@id": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885", "@type": "BrainAtlasRelease", "_rev": 8}, "atlas_id": 85, "color_hex_triplet": "B0FFB8", "delineates": ["http://purl.obolibrary.org/obo/UBERON_0000956"], "graph_order": 3, "hasHierarchyView": ["https://neuroshapes.org/BrainRegion"], "hasLeafRegionPart": ["http://api.brain-map.org/api/v2/data/Structure/614454511", "http://api.brain-map.org/api/v2/data/Structure/614454297", "http://api.brain-map.org/api/v2/data/Structure/589508447", "http://api.brain-map.org/api/v2/data/Structure/480149218", "http://api.brain-map.org/api/v2/data/Structure/614454726", "http://api.brain-map.org/api/v2/data/Structure/614454762"], "hasPart": ["http://api.brain-map.org/api/v2/data/Structure/695", "http://api.brain-map.org/api/v2/data/Structure/703"], "hemisphere_id": 3, "identifier": "688", "isDefinedBy": "http://bbp.epfl.ch/neurosciencegraph/ontologies/core/brainregion", "isPartOf": ["http://api.brain-map.org/api/v2/data/Structure/567"], "label": "Cerebral cortex", "notation": "CTX", "prefLabel": "Cerebral cortex", "regionVolume": {"unitCode": "cubic micrometer", "value": 221549640625.0}, "regionVolumeRatioToWholeBrain": {"unitCode": "cubic micrometer", "value": 0.4377993777515536}, "representedInAnnotation": true, "st_level": 3, "subClassOf": ["https://neuroshapes.org/BrainRegion"], "_constrainedBy": "https://neuroshapes.org/dash/ontologyentity", "_createdAt": "2019-08-20T11:41:48.761Z", "_createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/sy", "_deprecated": false, "_incoming": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F688/incoming", "_outgoing": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F688/outgoing", "_project": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_rev": 82, "_schemaProject": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_self": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F688", "_tags": ["v1.13.5"], "_updatedAt": "2024-05-28T16:40:32.374948Z", "_updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd"}}, {"_id": "http://api.brain-map.org/api/v2/data/Structure/528", "_index": "nexus_61cab3d6-56e5-4d32-b538-a08c90aca76c_3", "_score": 15.918847, "_source": {"@id": "http://api.brain-map.org/api/v2/data/Structure/528", "@type": "Class", "altLabel": "CBX", "atlasRelease": {"@id": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885", "@type": "BrainAtlasRelease", "_rev": 8}, "atlas_id": 65, "color_hex_triplet": "F0F080", "delineates": ["http://purl.obolibrary.org/obo/UBERON_0002129"], "graph_order": 1015, "hasHierarchyView": ["https://neuroshapes.org/BrainRegion"], "hasLeafRegionPart": ["http://api.brain-map.org/api/v2/data/Structure/10730"], "hasPart": ["http://api.brain-map.org/api/v2/data/Structure/1145", "http://api.brain-map.org/api/v2/data/Structure/645"], "hemisphere_id": 3, "identifier": "528", "isDefinedBy": "http://bbp.epfl.ch/neurosciencegraph/ontologies/core/brainregion", "isPartOf": ["http://api.brain-map.org/api/v2/data/Structure/512"], "label": "Cerebellar cortex", "notation": "CBX", "prefLabel": "Cerebellar cortex", "regionVolume": {"unitCode": "cubic micrometer", "value": 51220765625.0}, "regionVolumeRatioToWholeBrain": {"unitCode": "cubic micrometer", "value": 0.10121622971413098}, "representedInAnnotation": true, "st_level": 5, "subClassOf": ["https://neuroshapes.org/BrainRegion"], "_constrainedBy": "https://neuroshapes.org/dash/ontologyentity", "_createdAt": "2019-08-20T11:40:24.927Z", "_createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/sy", "_deprecated": false, "_incoming": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F528/incoming", "_outgoing": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F528/outgoing", "_project": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_rev": 81, "_schemaProject": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_self": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F528", "_tags": ["v1.12"], "_updatedAt": "2024-05-28T16:37:15.358248Z", "_updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd"}}, {"_id": "http://api.brain-map.org/api/v2/data/Structure/184", "_index": "nexus_61cab3d6-56e5-4d32-b538-a08c90aca76c_3", "_score": 13.0758095, "_source": {"@id": "http://api.brain-map.org/api/v2/data/Structure/184", "@type": "Class", "altLabel": "FRP", "atlasRelease": {"@id": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885", "@type": "BrainAtlasRelease", "_rev": 8}, "atlas_id": 871, "color_hex_triplet": "268F45", "delineates": ["http://purl.obolibrary.org/obo/UBERON_0002795"], "graph_order": 6, "hasHierarchyView": ["https://neuroshapes.org/BrainRegion"], "hasLeafRegionPart": ["http://api.brain-map.org/api/v2/data/Structure/68", "http://api.brain-map.org/api/v2/data/Structure/667"], "hemisphere_id": 3, "identifier": "184", "isDefinedBy": "http://bbp.epfl.ch/neurosciencegraph/ontologies/core/brainregion", "isPartOf": ["http://api.brain-map.org/api/v2/data/Structure/315"], "label": "Frontal pole, cerebral cortex", "notation": "FRP", "prefLabel": "Frontal pole, cerebral cortex", "regionVolume": {"unitCode": "cubic micrometer", "value": 972296875.0}, "regionVolumeRatioToWholeBrain": {"unitCode": "cubic micrometer", "value": 0.0019213344948967013}, "representedInAnnotation": true, "st_level": 8, "subClassOf": ["https://neuroshapes.org/BrainRegion"], "_constrainedBy": "https://neuroshapes.org/dash/ontologyentity", "_createdAt": "2019-08-20T11:37:19.466Z", "_createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/sy", "_deprecated": false, "_incoming": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F184/incoming", "_outgoing": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F184/outgoing", "_project": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_rev": 80, "_schemaProject": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_self": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Fapi.brain-map.org%2Fapi%2Fv2%2Fdata%2FStructure%2F184", "_tags": ["v1.14.0"], "_updatedAt": "2024-05-28T16:30:18.357142Z", "_updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd"}}], "max_score": 15.918847, "total": {"relation": "eq", "value": 48}}, "timed_out": false, "took": 8, "_shards": {"failed": 0, "skipped": 0, "successful": 1, "total": 1}}, {"hits": {"hits": [{"_id": "http://uri.interlex.org/base/ilx_0112352", "_index": "nexus_61cab3d6-56e5-4d32-b538-a08c90aca76c_3", "_score": 13.711583, "_source": {"@id": "http://uri.interlex.org/base/ilx_0112352", "@type": "Class", "altLabel": "Ventral tegmental area DA cell", "atlasRelease": {"@id": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885", "@type": "BrainAtlasRelease", "_rev": 8}, "definition": "Principal neuron of the ventral tegmental area", "label": "Ventral Tegmental Area Dopamine Neuron", "subClassOf": ["https://bbp.epfl.ch/ontologies/core/bmo/NewNeuronType", "https://bbp.epfl.ch/ontologies/core/bmo/BrainCellType"], "_constrainedBy": "https://neuroshapes.org/dash/ontologyentity", "_createdAt": "2022-11-01T10:43:54.694Z", "_createdBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd", "_deprecated": false, "_incoming": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0112352/incoming", "_outgoing": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0112352/outgoing", "_project": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_rev": 73, "_schemaProject": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_self": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0112352", "_tags": ["v1.11.2"], "_updatedAt": "2024-05-28T16:48:32.797241Z", "_updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd"}}, {"_id": "http://uri.interlex.org/base/ilx_0110943", "_ignored": ["definition.keyword"], "_index": "nexus_61cab3d6-56e5-4d32-b538-a08c90aca76c_3", "_score": 11.970262, "_source": {"@id": "http://uri.interlex.org/base/ilx_0110943", "@type": "Class", "altLabel": "fusimotor neuron", "atlasRelease": {"@id": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885", "@type": "BrainAtlasRelease", "_rev": 8}, "definition": "Motor neurons which activate the contractile regions of intrafusal muscle fibers, thus adjusting the sensitivity of the muscle spindles to stretch. Gamma motor neurons may be static or dynamic according to which aspect of responsiveness (or which fiber types) they regulate. The alpha and gamma motor neurons are often activated together (alpha gamma coactivation) which allows the spindles to contribute to the control of movement trajectories despite changes in muscle length (MSH).", "label": "Spinal Cord Ventral Horn Motor Neuron Gamma", "subClassOf": ["https://bbp.epfl.ch/ontologies/core/bmo/NewNeuronType", "https://bbp.epfl.ch/ontologies/core/bmo/BrainCellType"], "_constrainedBy": "https://neuroshapes.org/dash/ontologyentity", "_createdAt": "2022-11-01T10:43:51.808Z", "_createdBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd", "_deprecated": false, "_incoming": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0110943/incoming", "_outgoing": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0110943/outgoing", "_project": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_rev": 73, "_schemaProject": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_self": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0110943", "_tags": ["v1.11.4"], "_updatedAt": "2024-05-28T16:48:26.214141Z", "_updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd"}}, {"_id": "http://uri.interlex.org/base/ilx_0105169", "_index": "nexus_61cab3d6-56e5-4d32-b538-a08c90aca76c_3", "_score": 9.032584, "_source": {"@id": "http://uri.interlex.org/base/ilx_0105169", "@type": "Class", "altLabel": "hypoglossal motor neuron", "atlasRelease": {"@id": "https://bbp.epfl.ch/neurosciencegraph/data/4906ab85-694f-469d-962f-c0174e901885", "@type": "BrainAtlasRelease", "_rev": 8}, "definition": "Motor neuron whose soma lies in the hypoglossal nucleus", "label": "Hypoglossal Nucleus Motor Neuron", "subClassOf": ["https://bbp.epfl.ch/ontologies/core/bmo/NewNeuronType", "https://bbp.epfl.ch/ontologies/core/bmo/BrainCellType"], "_constrainedBy": "https://neuroshapes.org/dash/ontologyentity", "_createdAt": "2022-11-01T10:43:40.761Z", "_createdBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd", "_deprecated": false, "_incoming": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0105169/incoming", "_outgoing": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0105169/outgoing", "_project": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_rev": 73, "_schemaProject": "https://bbp.epfl.ch/nexus/v1/projects/neurosciencegraph/datamodels", "_self": "https://bbp.epfl.ch/nexus/v1/resources/neurosciencegraph/datamodels/_/http:%2F%2Furi.interlex.org%2Fbase%2Filx_0105169", "_tags": ["v1.12.2"], "_updatedAt": "2024-05-28T16:48:06.526340Z", "_updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/serviceaccounts/users/service-account-brain-modeling-ontology-ci-cd"}}], "max_score": 13.711583, "total": {"relation": "eq", "value": 48}}, "timed_out": false, "took": 15, "_shards": {"failed": 0, "skipped": 0, "successful": 1, "total": 1}}] diff --git a/swarm_copy_tests/data/simple.swc b/swarm_copy_tests/data/simple.swc new file mode 100644 index 0000000..ebba216 --- /dev/null +++ b/swarm_copy_tests/data/simple.swc @@ -0,0 +1,31 @@ +# SWC structure: +# index, type, x, y, z, radius, parent +# +# (0, 5) +# (-5, 5)----- ------ (6, 5) +# | +# | +# | +# | Type = 3 +# | +# o origin +# | +# | Type = 2 +# | +# | +#(-5, -4)----- ------ (6, -4) +# (0, -4) +# +# all radii are 1, except for end points, which are 0 +# section types: soma=1, axon=2, basal=3, apical=4 + + + 1 1 0 0 0 1. -1 + 2 3 0 0 0 1. 1 + 3 3 0 5 0 1. 2 + 4 3 -5 5 0 0. 3 + 5 3 6 5 0 0. 3 + 6 2 0 0 0 1. 1 + 7 2 0 -4 0 1. 6 + 8 2 6 -4 0 0. 7 + 9 2 -5 -4 0 0. 7 diff --git a/swarm_copy_tests/data/tool_calls.json b/swarm_copy_tests/data/tool_calls.json new file mode 100644 index 0000000..c8d9066 --- /dev/null +++ b/swarm_copy_tests/data/tool_calls.json @@ -0,0 +1,102 @@ +[ + { + "prompt": "What are the morphological features of neurons in the thalamus?", + "expected_tool_calls": [ + { + "tool_name": "resolve-entities-tool", + "arguments": {"brain_region": "thalamus"} + }, + { + "tool_name": "get-morpho-tool", + "arguments": {"brain_region_id":"http://api.brain-map.org/api/v2/data/Structure/549"} + } + ] + }, + { + "prompt": "Find me articles about the role of the hippocampus in memory formation.", + "expected_tool_calls": [ + { + "tool_name": "literature-search-tool", + "arguments": { + "query": "hippocampus memory formation" + } + } + ] + }, + { + "prompt": "Retrieve electrophysiological features of cortical neurons.", + "expected_tool_calls": [ + { + "tool_name": "resolve-entities-tool", + "arguments": { + "brain_region": "cortex" + } + }, + { + "tool_name": "get-traces-tool", + "arguments": { + "brain_region_id": "http://api.brain-map.org/api/v2/data/Structure/134" + } + }, + { + "tool_name": "electrophys-feature-tool", + "arguments": { + "brain_region": "cortex" + } + } + ] + }, + { + "prompt": "Get traces for neurons in the hippocampus.", + "expected_tool_calls": [ + { + "tool_name": "resolve-entities-tool", + "arguments": { + "brain_region": "hippocampus"} + }, + { + "tool_name": "get-traces-tool", + "arguments": { + "brain_region_id": "http://api.brain-map.org/api/v2/data/Structure/134" + } + }, + { + "tool_name": "electrophys-features-tool" + } + ] + }, + { + "prompt": "Search for literature on synaptic plasticity.", + "expected_tool_calls": [ + { + "tool_name": "literature-search-tool", + "arguments": { + "query": "synaptic plasticity" + } + } + ] + }, + { + "prompt": "Run 1000 ms of simulation of a me model from somatosensory cortex with 34 degree temperature, current clamp stimulation mode with step current for fire pattern detection. use 1 number of step and 0.05 nA current stimulation. Record from soma.", + "expected_tool_calls": [ + { + "tool_name": "resolve-entities-tool", + "arguments": { + "brain_region": "somatosensory area" + } + }, + { + "tool_name": "literature-search-tool" + }, + { + "tool_name": "get-me-model-tool", + "arguments": { + "brain_region_id" : "http://api.brain-map.org/api/v2/data/Structure/322" + } + }, + { + "tool_name": "bluenaas-tool" + } + ] +} +] \ No newline at end of file diff --git a/swarm_copy_tests/data/trace_id_metadata.json b/swarm_copy_tests/data/trace_id_metadata.json new file mode 100644 index 0000000..388651c --- /dev/null +++ b/swarm_copy_tests/data/trace_id_metadata.json @@ -0,0 +1,110 @@ +{ + "hits": { + "hits": [ + { + "_id": "https://bbp.epfl.ch/data/demo/morpho-demo/1761e604-03fc-452b-9bf2-2214782bb751", + "_index": "nexus_search_d067e019-1398-4eb8-9e28-3af8a717dcd7_41b1545a-cb2e-4848-8c74-195ec79f7bd3_18", + "_score": 8.232272, + "_source": { + "@id": "https://bbp.epfl.ch/data/demo/morpho-demo/1761e604-03fc-452b-9bf2-2214782bb751", + "@type": [ + "https://neuroshapes.org/Trace", + "https://bbp.epfl.ch/ontologies/core/bmo/ExperimentalTrace" + ], + "brainRegion": { + "@id": "http://api.brain-map.org/api/v2/data/Structure/382", + "idLabel": "http://api.brain-map.org/api/v2/data/Structure/382|Field CA1", + "identifier": "http://api.brain-map.org/api/v2/data/Structure/382", + "label": "Field CA1" + }, + "contributors": [ + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/859a20a2-9eea-4ab5-9504-d080c3c79311", + "@type": [ + "http://www.w3.org/ns/prov#Agent", + "http://schema.org/Person" + ], + "idLabel": "https://bbp.epfl.ch/neurosciencegraph/data/859a20a2-9eea-4ab5-9504-d080c3c79311|Zsolt Kohus", + "label": "Zsolt Kohus" + } + ], + "createdAt": "2024-04-09T21:47:08.569Z", + "createdBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/budd", + "deprecated": false, + "derivation": [ + { + "@type": [ + "http://www.w3.org/ns/prov#Entity", + "https://neuroshapes.org/PatchedCell" + ], + "identifier": "https://bbp.epfl.ch/data/data/demo/morpho-demo/7173ea54-8e59-478d-85f3-ff86246ef22b", + "label": "s160106_0201" + } + ], + "distribution": [ + { + "contentSize": 4919928, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/demo/morpho-demo/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F01dffb7b-1122-4e1a-9acf-837e683da4ba", + "encodingFormat": "application/nwb", + "label": "s160106_02.nwb" + } + ], + "generation": { + "@id": "https://bbp.epfl.ch/data/demo/morpho-demo/d857ff82-b558-4117-b643-74d44dbda5e6", + "endedAt": "2016-01-06T23:59:00.000Z", + "startedAt": "2016-01-06T00:00:00.000Z" + }, + "image": [ + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2Fc1ef69e4-0073-481d-9446-fcfd7b5b5f7a", + "about": "https://neuroshapes.org/StimulationTrace", + "identifier": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2Fc1ef69e4-0073-481d-9446-fcfd7b5b5f7a", + "repetition": 0, + "stimulusType": "square" + }, + { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F6fd03e92-b2ae-4ab8-8c9e-f0ff52d20a0d", + "about": "https://neuroshapes.org/ResponseTrace", + "identifier": "https://bbp.epfl.ch/neurosciencegraph/data/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F6fd03e92-b2ae-4ab8-8c9e-f0ff52d20a0d", + "repetition": 0, + "stimulusType": "square" + } + ], + "name": "s160106_02", + "project": { + "@id": "https://bbp.epfl.ch/nexus/v1/projects/demo/morpho-demo", + "identifier": "https://bbp.epfl.ch/nexus/v1/projects/demo/morpho-demo", + "label": "demo/morpho-demo" + }, + "subjectAge": { + "label": "59 days Post-natal", + "period": "Post-natal", + "unit": "days", + "value": 59 + }, + "subjectSpecies": { + "@id": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "identifier": "http://purl.obolibrary.org/obo/NCBITaxon_10090", + "label": "Mus musculus" + }, + "updatedAt": "2024-04-10T08:40:23.039Z", + "updatedBy": "https://bbp.epfl.ch/nexus/v1/realms/bbp/users/cgonzale", + "_self": "https://bbp.epfl.ch/nexus/v1/resources/demo/morpho-demo/_/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fdemo%2Fmorpho-demo%2F1761e604-03fc-452b-9bf2-2214782bb751" + } + } + ], + "max_score": 8.232272, + "total": { + "relation": "eq", + "value": 1 + } + }, + "timed_out": false, + "took": 284, + "_shards": { + "failed": 0, + "skipped": 664, + "successful": 742, + "total": 742 + } +} diff --git a/swarm_copy_tests/tools/__init__.py b/swarm_copy_tests/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/swarm_copy_tests/tools/test_base_tool.py b/swarm_copy_tests/tools/test_base_tool.py new file mode 100644 index 0000000..e69de29 diff --git a/swarm_copy_tests/tools/test_electrophys_tool.py b/swarm_copy_tests/tools/test_electrophys_tool.py new file mode 100644 index 0000000..5706ec9 --- /dev/null +++ b/swarm_copy_tests/tools/test_electrophys_tool.py @@ -0,0 +1,206 @@ +"""Tests Electrophys tool.""" + +import json +from pathlib import Path + +import httpx +import pytest + +from swarm_copy.tools import ElectrophysFeatureTool +from swarm_copy.tools.electrophys_tool import ( + CALCULATED_FEATURES, + AmplitudeInput, + ElectrophysInput, + ElectrophysMetadata, +) + + +class TestElectrophysTool: + @pytest.mark.httpx_mock(can_send_already_matched_responses=True) + @pytest.mark.asyncio + async def test_arun(self, httpx_mock): + url = "http://fake_url" + json_path = ( + Path(__file__).resolve().parent.parent / "data" / "trace_id_metadata.json" + ) + with open(json_path) as f: + electrophys_response = json.load(f) + + httpx_mock.add_response( + url=url, + json=electrophys_response, + ) + + trace_path = Path(__file__).resolve().parent.parent / "data" / "99111002.nwb" + with open(trace_path, "rb") as f: + trace_content = f.read() + + httpx_mock.add_response( + url="https://bbp.epfl.ch/nexus/v1/files/demo/morpho-demo/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F01dffb7b-1122-4e1a-9acf-837e683da4ba", + content=trace_content, + ) + + trace_id = "https://bbp.epfl.ch/data/demo/morpho-demo/1761e604-03fc-452b-9bf2-2214782bb751" + + tool = ElectrophysFeatureTool( + input_schema=ElectrophysInput( + trace_id=trace_id, + stimuli_types=[ + "step", + ], + calculated_feature=[ + "mean_frequency", + ], + amplitude=None, + ), + metadata=ElectrophysMetadata( + knowledge_graph_url=url, + search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + ), + ) + response = await tool.arun() + assert isinstance(response, dict) + assert len(response["feature_dict"].keys()) == 1 + assert ( + len(response["feature_dict"]["step_0"].keys()) + == 2 # mean_frequency + 1 for stimulus current added manually + ) + + @pytest.mark.httpx_mock(can_send_already_matched_responses=True) + @pytest.mark.asyncio + async def test_arun_with_amplitude(self, httpx_mock): + url = "http://fake_url" + json_path = ( + Path(__file__).resolve().parent.parent / "data" / "trace_id_metadata.json" + ) + with open(json_path) as f: + electrophys_response = json.load(f) + + httpx_mock.add_response( + url=url, + json=electrophys_response, + ) + + trace_path = Path(__file__).resolve().parent.parent / "data" / "99111002.nwb" + with open(trace_path, "rb") as f: + trace_content = f.read() + + httpx_mock.add_response( + url="https://bbp.epfl.ch/nexus/v1/files/demo/morpho-demo/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F01dffb7b-1122-4e1a-9acf-837e683da4ba", + content=trace_content, + ) + + trace_id = "https://bbp.epfl.ch/data/demo/morpho-demo/1761e604-03fc-452b-9bf2-2214782bb751" + + tool = ElectrophysFeatureTool( + input_schema=ElectrophysInput( + trace_id=trace_id, + stimuli_types=[ + "step", + ], + calculated_feature=[ + "mean_frequency", + ], + amplitude=AmplitudeInput(min_value=-0.5, max_value=1), + ), + metadata=ElectrophysMetadata( + knowledge_graph_url=url, + search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + ), + ) + response = await tool.arun() + assert isinstance(response, dict) + assert len(response["feature_dict"].keys()) == 1 + assert ( + len(response["feature_dict"]["step_0.25"].keys()) + == 2 # mean_frequency + 1 for stimulus current added manually + ) + + @pytest.mark.httpx_mock(can_send_already_matched_responses=True) + @pytest.mark.asyncio + async def test_arun_without_stimuli_types(self, httpx_mock): + url = "http://fake_url" + json_path = ( + Path(__file__).resolve().parent.parent / "data" / "trace_id_metadata.json" + ) + with open(json_path) as f: + electrophys_response = json.load(f) + + httpx_mock.add_response( + url=url, + json=electrophys_response, + ) + + trace_path = Path(__file__).resolve().parent.parent / "data" / "99111002.nwb" + with open(trace_path, "rb") as f: + trace_content = f.read() + + httpx_mock.add_response( + url="https://bbp.epfl.ch/nexus/v1/files/demo/morpho-demo/https%3A%2F%2Fbbp.epfl.ch%2Fdata%2Fdata%2Fdemo%2Fmorpho-demo%2F01dffb7b-1122-4e1a-9acf-837e683da4ba", + content=trace_content, + ) + + trace_id = "https://bbp.epfl.ch/data/demo/morpho-demo/1761e604-03fc-452b-9bf2-2214782bb751" + + tool = ElectrophysFeatureTool( + input_schema=ElectrophysInput( + trace_id=trace_id, + stimuli_types=[ + "step", + ], + calculated_feature=[], + amplitude=None, + ), + metadata=ElectrophysMetadata( + knowledge_graph_url=url, + search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + ), + ) + + # Without stimuli types and calculated features + response = await tool.arun() + assert isinstance(response, dict) + assert len(response["feature_dict"].keys()) == 1 + assert ( + len(response["feature_dict"]["step_0"].keys()) + == len(list(CALCULATED_FEATURES.__args__[0].__args__)) + + 1 # 1 for stimulus current added manually + ) + + @pytest.mark.asyncio + async def test_arun_errors(self): + # Do not receive trace content back + url = "http://fake_url" + + tool = ElectrophysFeatureTool( + input_schema=ElectrophysInput( + trace_id="wrong-trace-id", + stimuli_types=[ + "idrest", + ], + calculated_feature=[ + "mean_frequency", + ], + amplitude=None, + ), + metadata=ElectrophysMetadata( + knowledge_graph_url=url, + search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + ), + ) + + with pytest.raises(ValueError) as tool_exception: + await tool.arun() + + assert ( + tool_exception.value.args[0] + == "The provided ID (wrong-trace-id) is not valid." + ) diff --git a/swarm_copy_tests/tools/test_get_morpho_tool.py b/swarm_copy_tests/tools/test_get_morpho_tool.py new file mode 100644 index 0000000..d316d49 --- /dev/null +++ b/swarm_copy_tests/tools/test_get_morpho_tool.py @@ -0,0 +1,175 @@ +"""Tests Get Morpho tool.""" + +import json +from pathlib import Path + +import httpx +import pytest + +from swarm_copy.tools import GetMorphoTool +from swarm_copy.tools.get_morpho_tool import GetMorphoInput, GetMorphoMetadata + + +class TestGetMorphoTool: + @pytest.mark.asyncio + async def test_arun(self, httpx_mock, brain_region_json_path, tmp_path): + url = "http://fake_url" + json_path = ( + Path(__file__).resolve().parent.parent / "data" / "knowledge_graph.json" + ) + with open(json_path) as f: + knowledge_graph_response = json.load(f) + + httpx_mock.add_response( + url=url, + json=knowledge_graph_response, + ) + tool = GetMorphoTool( + input_schema=GetMorphoInput( + brain_region_id="brain_region_id_link/549", + mtype_id="brain_region_id_link/549", + ), + metadata=GetMorphoMetadata( + knowledge_graph_url=url, + morpho_search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + brainregion_path=brain_region_json_path, + celltypes_path=tmp_path, + ), + ) + response = await tool.arun() + assert isinstance(response, list) + assert len(response) == 2 + assert isinstance(response[0], dict) + + @pytest.mark.asyncio + async def test_arun_errors(self, httpx_mock, brain_region_json_path, tmp_path): + url = "http://fake_url" + httpx_mock.add_response( + url=url, + json={}, + ) + + tool = GetMorphoTool( + input_schema=GetMorphoInput( + brain_region_id="brain_region_id_link/bad", + mtype_id="brain_region_id_link/superbad", + ), + metadata=GetMorphoMetadata( + knowledge_graph_url=url, + morpho_search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + brainregion_path=brain_region_json_path, + celltypes_path=tmp_path, + ), + ) + with pytest.raises(KeyError) as tool_exception: + await tool.arun() + + assert tool_exception.value.args[0] == "hits" + + +def test_create_query(brain_region_json_path, tmp_path): + url = "http://fake_url" + + tool = GetMorphoTool( + input_schema=GetMorphoInput( + brain_region_id="not_needed", + mtype_id="not_needed", + ), + metadata=GetMorphoMetadata( + knowledge_graph_url=url, + morpho_search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + brainregion_path=brain_region_json_path, + celltypes_path=tmp_path, + ), + ) + + # This should be a set, but passing a list here ensures that the test doesn;t rely on order. + brain_regions_ids = ["brain-region-id/68", "brain-region-id/131"] + mtype_id = "mtype-id/1234" + + entire_query = tool.create_query( + brain_regions_ids=brain_regions_ids, mtype_ids={mtype_id} + ) + expected_query = { + "size": 2, + "track_total_hits": True, + "query": { + "bool": { + "must": [ + { + "bool": { + "should": [ + { + "term": { + "brainRegion.@id.keyword": "brain-region-id/68" + } + }, + { + "term": { + "brainRegion.@id.keyword": "brain-region-id/131" + } + }, + ] + } + }, + {"bool": {"should": [{"term": {"mType.@id.keyword": mtype_id}}]}}, + { + "term": { + "@type.keyword": ( + "https://neuroshapes.org/ReconstructedNeuronMorphology" + ) + } + }, + {"term": {"deprecated": False}}, + {"term": {"curated": True}}, + ] + } + }, + } + assert isinstance(entire_query, dict) + assert entire_query == expected_query + + # Case 2 with no mtype + entire_query1 = tool.create_query(brain_regions_ids=brain_regions_ids) + expected_query1 = { + "size": 2, + "track_total_hits": True, + "query": { + "bool": { + "must": [ + { + "bool": { + "should": [ + { + "term": { + "brainRegion.@id.keyword": "brain-region-id/68" + } + }, + { + "term": { + "brainRegion.@id.keyword": "brain-region-id/131" + } + }, + ] + } + }, + { + "term": { + "@type.keyword": ( + "https://neuroshapes.org/ReconstructedNeuronMorphology" + ) + } + }, + {"term": {"deprecated": False}}, + {"term": {"curated": True}}, + ] + } + }, + } + assert entire_query1 == expected_query1 diff --git a/swarm_copy_tests/tools/test_kg_morpho_features_tool.py b/swarm_copy_tests/tools/test_kg_morpho_features_tool.py new file mode 100644 index 0000000..2436acf --- /dev/null +++ b/swarm_copy_tests/tools/test_kg_morpho_features_tool.py @@ -0,0 +1,453 @@ +"""Tests KG Morpho Features tool.""" + +import json +from pathlib import Path + +import httpx +import pytest + +from swarm_copy.tools import KGMorphoFeatureTool +from swarm_copy.tools.kg_morpho_features_tool import ( + KGFeatRangeInput, + KGFeatureInput, + KGMorphoFeatureInput, + KGMorphoFeatureMetadata, +) + + +class TestKGMorphoFeaturesTool: + @pytest.mark.asyncio + async def test_arun(self, httpx_mock, brain_region_json_path): + url = "http://fake_url" + json_path = ( + Path(__file__).resolve().parent.parent + / "data" + / "kg_morpho_features_response.json" + ) + with open(json_path) as f: + kg_morpho_features_response = json.load(f) + + httpx_mock.add_response( + url=url, + json=kg_morpho_features_response, + ) + + feature_input = KGFeatureInput( + label="Section Tortuosity", + ) + + tool = KGMorphoFeatureTool( + input_schema=KGMorphoFeatureInput( + brain_region_id="brain_region_id_link/549", features=feature_input + ), + metadata=KGMorphoFeatureMetadata( + knowledge_graph_url=url, + kg_morpho_feature_search_size=2, + token="fake_token", + brainregion_path=brain_region_json_path, + httpx_client=httpx.AsyncClient(), + ), + ) + response = await tool.arun() + assert isinstance(response, list) + assert len(response) == 2 + assert isinstance(response[0], dict) + + @pytest.mark.asyncio + async def test_arun_errors(self, httpx_mock, brain_region_json_path): + url = "http://fake_url" + + # Mock issue (resolve query without results) + httpx_mock.add_response( + url=url, + json={}, + ) + + feature_input = KGFeatureInput( + label="Section Tortuosity", + ) + tool = KGMorphoFeatureTool( + input_schema=KGMorphoFeatureInput( + brain_region_id="brain_region_id_link/549", features=feature_input + ), + metadata=KGMorphoFeatureMetadata( + knowledge_graph_url=url, + kg_morpho_feature_search_size=2, + token="fake_token", + brainregion_path=brain_region_json_path, + httpx_client=httpx.AsyncClient(), + ), + ) + + with pytest.raises(KeyError) as tool_exception: + await tool.arun() + assert tool_exception.value.args[0] == "hits" + + def test_create_query(self, brain_region_json_path): + url = "http://fake_url" + + feature_input = KGFeatureInput( + label="Soma Radius", + compartment="NeuronMorphology", + ) + + brain_regions_ids = {"brain-region-id/68"} + + tool = KGMorphoFeatureTool( + input_schema=KGMorphoFeatureInput( + brain_region_id="", features=feature_input + ), + metadata=KGMorphoFeatureMetadata( + knowledge_graph_url=url, + kg_morpho_feature_search_size=2, + token="fake_token", + brainregion_path=brain_region_json_path, + httpx_client=httpx.AsyncClient(), + ), + ) + + entire_query = tool.create_query( + brain_regions_ids=brain_regions_ids, features=feature_input + ) + expected_query = { + "size": 2, + "track_total_hits": True, + "query": { + "bool": { + "must": [ + { + "bool": { + "should": [ + { + "term": { + "brainRegion.@id.keyword": ( + "brain-region-id/68" + ) + } + } + ] + } + }, + { + "nested": { + "path": "featureSeries", + "query": { + "bool": { + "must": [ + { + "term": { + "featureSeries.label.keyword": ( + "Soma Radius" + ) + } + }, + { + "term": { + "featureSeries.compartment.keyword": ( + "NeuronMorphology" + ) + } + }, + ] + } + }, + } + }, + { + "term": { + "@type.keyword": "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologyFeatureAnnotation" + } + }, + {"term": {"deprecated": False}}, + ] + } + }, + } + assert isinstance(entire_query, dict) + assert entire_query == expected_query + + def test_create_query_with_max_value(self, brain_region_json_path): + url = "http://fake_url" + + feature_input = KGFeatureInput( + label="Soma Radius", + compartment="NeuronMorphology", + feat_range=KGFeatRangeInput(max_value=5), + ) + + brain_regions_ids = {"brain-region-id/68"} + + tool = KGMorphoFeatureTool( + input_schema=KGMorphoFeatureInput( + brain_region_id="", features=feature_input + ), + metadata=KGMorphoFeatureMetadata( + knowledge_graph_url=url, + kg_morpho_feature_search_size=2, + token="fake_token", + brainregion_path=brain_region_json_path, + httpx_client=httpx.AsyncClient(), + ), + ) + + entire_query = tool.create_query( + brain_regions_ids=brain_regions_ids, features=feature_input + ) + expected_query = { + "size": 2, + "track_total_hits": True, + "query": { + "bool": { + "must": [ + { + "bool": { + "should": [ + { + "term": { + "brainRegion.@id.keyword": ( + "brain-region-id/68" + ) + } + } + ] + } + }, + { + "nested": { + "path": "featureSeries", + "query": { + "bool": { + "must": [ + { + "term": { + "featureSeries.label.keyword": ( + "Soma Radius" + ) + } + }, + { + "term": { + "featureSeries.compartment.keyword": ( + "NeuronMorphology" + ) + } + }, + { + "term": { + "featureSeries.statistic.keyword": ( + "raw" + ) + } + }, + { + "range": { + "featureSeries.value": {"lte": 5.0} + } + }, + ] + } + }, + } + }, + { + "term": { + "@type.keyword": "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologyFeatureAnnotation" + } + }, + {"term": {"deprecated": False}}, + ] + } + }, + } + assert entire_query == expected_query + + def test_create_query_with_min_value(self, brain_region_json_path): + url = "http://fake_url" + + feature_input = KGFeatureInput( + label="Soma Radius", + compartment="NeuronMorphology", + feat_range=KGFeatRangeInput(min_value=2), + ) + + tool = KGMorphoFeatureTool( + input_schema=KGMorphoFeatureInput( + brain_region_id="", features=feature_input + ), + metadata=KGMorphoFeatureMetadata( + knowledge_graph_url=url, + kg_morpho_feature_search_size=2, + token="fake_token", + brainregion_path=brain_region_json_path, + httpx_client=httpx.AsyncClient(), + ), + ) + + brain_regions_ids = {"brain-region-id/68"} + entire_query = tool.create_query( + brain_regions_ids=brain_regions_ids, features=feature_input + ) + expected_query = { + "size": 2, + "track_total_hits": True, + "query": { + "bool": { + "must": [ + { + "bool": { + "should": [ + { + "term": { + "brainRegion.@id.keyword": ( + "brain-region-id/68" + ) + } + } + ] + } + }, + { + "nested": { + "path": "featureSeries", + "query": { + "bool": { + "must": [ + { + "term": { + "featureSeries.label.keyword": ( + "Soma Radius" + ) + } + }, + { + "term": { + "featureSeries.compartment.keyword": ( + "NeuronMorphology" + ) + } + }, + { + "term": { + "featureSeries.statistic.keyword": ( + "raw" + ) + } + }, + { + "range": { + "featureSeries.value": {"gte": 2.0} + } + }, + ] + } + }, + } + }, + { + "term": { + "@type.keyword": "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologyFeatureAnnotation" + } + }, + {"term": {"deprecated": False}}, + ] + } + }, + } + assert entire_query == expected_query + + def test_create_query_with_min_max_value(self, brain_region_json_path): + url = "http://fake_url" + + feature_input = KGFeatureInput( + label="Soma Radius", + compartment="NeuronMorphology", + feat_range=KGFeatRangeInput(min_value=2, max_value=5), + ) + + tool = KGMorphoFeatureTool( + input_schema=KGMorphoFeatureInput( + brain_region_id="", features=feature_input + ), + metadata=KGMorphoFeatureMetadata( + knowledge_graph_url=url, + kg_morpho_feature_search_size=2, + token="fake_token", + brainregion_path=brain_region_json_path, + httpx_client=httpx.AsyncClient(), + ), + ) + + brain_regions_ids = {"brain-region-id/68"} + entire_query = tool.create_query( + brain_regions_ids=brain_regions_ids, features=feature_input + ) + expected_query = { + "size": 2, + "track_total_hits": True, + "query": { + "bool": { + "must": [ + { + "bool": { + "should": [ + { + "term": { + "brainRegion.@id.keyword": ( + "brain-region-id/68" + ) + } + } + ] + } + }, + { + "nested": { + "path": "featureSeries", + "query": { + "bool": { + "must": [ + { + "term": { + "featureSeries.label.keyword": ( + "Soma Radius" + ) + } + }, + { + "term": { + "featureSeries.compartment.keyword": ( + "NeuronMorphology" + ) + } + }, + { + "term": { + "featureSeries.statistic.keyword": ( + "raw" + ) + } + }, + { + "range": { + "featureSeries.value": { + "gte": 2.0, + "lte": 5.0, + } + } + }, + ] + } + }, + } + }, + { + "term": { + "@type.keyword": "https://bbp.epfl.ch/ontologies/core/bmo/NeuronMorphologyFeatureAnnotation" + } + }, + {"term": {"deprecated": False}}, + ] + } + }, + } + assert entire_query == expected_query diff --git a/swarm_copy_tests/tools/test_literature_search_tool.py b/swarm_copy_tests/tools/test_literature_search_tool.py new file mode 100644 index 0000000..c57d8a1 --- /dev/null +++ b/swarm_copy_tests/tools/test_literature_search_tool.py @@ -0,0 +1,50 @@ +"""Tests Literature Search tool.""" + +import httpx +import pytest + +from swarm_copy.tools import LiteratureSearchTool +from swarm_copy.tools.literature_search_tool import ( + LiteratureSearchInput, + LiteratureSearchMetadata, +) + + +class TestLiteratureSearchTool: + @pytest.mark.asyncio + async def test_arun(self, httpx_mock): + url = "http://fake_url?query=covid+19&retriever_k=100&use_reranker=true&reranker_k=5" + reranker_k = 5 + + fake_response = [ + { + "article_title": "Article title", + "article_authors": ["Author1", "Author2"], + "paragraph": "This is the paragraph", + "section": "fake_section", + "article_doi": "fake_doi", + "journal_issn": "fake_journal_issn", + } + for _ in range(reranker_k) + ] + + httpx_mock.add_response( + url=url, + json=fake_response, + ) + + tool = LiteratureSearchTool( + input_schema=LiteratureSearchInput(query="covid 19"), + metadata=LiteratureSearchMetadata( + literature_search_url=url, + httpx_client=httpx.AsyncClient(), + token="fake_token", + retriever_k=100, + use_reranker=True, + reranker_k=reranker_k, + ), + ) + response = await tool.arun() + assert isinstance(response, list) + assert len(response) == reranker_k + assert isinstance(response[0], dict) diff --git a/swarm_copy_tests/tools/test_morphology_features_tool.py b/swarm_copy_tests/tools/test_morphology_features_tool.py new file mode 100644 index 0000000..197b634 --- /dev/null +++ b/swarm_copy_tests/tools/test_morphology_features_tool.py @@ -0,0 +1,114 @@ +"""Tests Morphology features tool.""" + +import json +from pathlib import Path + +import httpx +import pytest + +from swarm_copy.tools import MorphologyFeatureTool +from swarm_copy.tools.morphology_features_tool import ( + MorphologyFeatureInput, + MorphologyFeatureMetadata, +) + + +class TestMorphologyFeatureTool: + @pytest.mark.asyncio + async def test_arun(self, httpx_mock): + url = "http://fake_url" + morphology_id = "https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9" + json_path = ( + Path(__file__).resolve().parent.parent + / "data" + / "morphology_id_metadata_response.json" + ) + with open(json_path) as f: + morphology_metadata_response = json.load(f) + + # Mock get morphology ids + httpx_mock.add_response( + url=url, + json=morphology_metadata_response, + ) + + morphology_path = Path(__file__).resolve().parent.parent / "data" / "simple.swc" + with open(morphology_path) as f: + morphology_content = f.read() + + # Mock get object id request + httpx_mock.add_response( + url="https://bbp.epfl.ch/nexus/v1/files/bbp/mouselight/https%3A%2F%2Fbbp.epfl.ch%2Fneurosciencegraph%2Fdata%2Fad8fec6f-d59c-4998-beb4-274fa115add7", + content=morphology_content, + ) + + tool = MorphologyFeatureTool( + metadata=MorphologyFeatureMetadata( + knowledge_graph_url=url, + httpx_client=httpx.AsyncClient(), + token="fake_token", + ), + input_schema=MorphologyFeatureInput(morphology_id=morphology_id), + ) + + response = await tool.arun() + assert isinstance(response[0], dict) + assert len(response[0]["feature_dict"]) == 23 + + @pytest.mark.asyncio + async def test_arun_errors_404(self, httpx_mock): + url = "http://fake_url" + morphology_id = "https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9" + + tool = MorphologyFeatureTool( + metadata=MorphologyFeatureMetadata( + knowledge_graph_url=url, + httpx_client=httpx.AsyncClient(), + token="fake_token", + ), + input_schema=MorphologyFeatureInput(morphology_id=morphology_id), + ) + + # test different failures + # Failure 1 + httpx_mock.add_response( + url=url, + status_code=404, + ) + with pytest.raises(ValueError) as tool_exception: + await tool.arun() + + assert ( + tool_exception.value.args[0] == "We did not find the object" + " https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9" + " you are asking" + ) + + @pytest.mark.asyncio + async def test_arun_wrong_id(self, httpx_mock): + url = "http://fake_url" + morphology_id = "https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9" + + tool = MorphologyFeatureTool( + metadata=MorphologyFeatureMetadata( + knowledge_graph_url=url, + httpx_client=httpx.AsyncClient(), + token="fake_token", + ), + input_schema=MorphologyFeatureInput(morphology_id=morphology_id), + ) + + # Failure 2 + fake_json = {"hits": {"hits": [{"_source": {"@id": "wrong_id"}}]}} + httpx_mock.add_response( + url=url, + json=fake_json, + ) + with pytest.raises(ValueError) as tool_exception: + await tool.arun() + + assert ( + tool_exception.value.args[0] == "We did not find the object" + " https://bbp.epfl.ch/neurosciencegraph/data/neuronmorphologies/046fb11c-8de8-42e8-9303-9d5a65ac04b9" + " you are asking" + ) diff --git a/swarm_copy_tests/tools/test_resolve_entities_tool.py b/swarm_copy_tests/tools/test_resolve_entities_tool.py new file mode 100644 index 0000000..01014ae --- /dev/null +++ b/swarm_copy_tests/tools/test_resolve_entities_tool.py @@ -0,0 +1,100 @@ +"""Test the revole_brain_region_tool.""" + +import pytest +from httpx import AsyncClient + +from swarm_copy.tools import ResolveEntitiesTool +from swarm_copy.tools.resolve_entities_tool import ( + BRResolveOutput, + EtypeResolveOutput, + MTypeResolveOutput, + ResolveBRMetadata, + ResolveBRInput +) + + +@pytest.mark.asyncio +async def test_arun(httpx_mock, get_resolve_query_output): + # Mock exact match to fail + httpx_mock.add_response( + url="http://fake_sparql_url.com/78", + json={ + "head": {"vars": ["subject", "predicate", "object", "context"]}, + "results": {"bindings": []}, + }, + ) + + # Hit fuzzy match + httpx_mock.add_response( + url="http://fake_sparql_url.com/78", + json=get_resolve_query_output[2], + ) + + # Hit ES match + httpx_mock.add_response( + url="http://fake_class_url.com/78", + json=get_resolve_query_output[4], + ) + + # Mock exact match to fail (mtype) + httpx_mock.add_response( + url="http://fake_sparql_url.com/78", + json={ + "head": {"vars": ["subject", "predicate", "object", "context"]}, + "results": {"bindings": []}, + }, + ) + + # Hit fuzzy match (mtype) + httpx_mock.add_response( + url="http://fake_sparql_url.com/78", + json=get_resolve_query_output[3], + ) + # Hit ES match (mtype). + httpx_mock.add_response( + url="http://fake_class_url.com/78", json=get_resolve_query_output[5] + ) + + tool = ResolveEntitiesTool( + metadata=ResolveBRMetadata( + token="greattokenpleasedontexpire", + httpx_client=AsyncClient(timeout=None), + kg_sparql_url="http://fake_sparql_url.com/78", + kg_class_view_url="http://fake_class_url.com/78", + ), + input_schema=ResolveBRInput( + brain_region="Field", + mtype="Interneu", + etype="bAC" + ) + ) + + response = await tool.arun() + assert response == [ + BRResolveOutput( + brain_region_name="Field CA1", + brain_region_id="http://api.brain-map.org/api/v2/data/Structure/382", + ).model_dump(), + BRResolveOutput( + brain_region_name="Field CA2", + brain_region_id="http://api.brain-map.org/api/v2/data/Structure/423", + ).model_dump(), + BRResolveOutput( + brain_region_name="Field CA3", + brain_region_id="http://api.brain-map.org/api/v2/data/Structure/463", + ).model_dump(), + MTypeResolveOutput( + mtype_name="Interneuron", mtype_id="https://neuroshapes.org/Interneuron" + ).model_dump(), + MTypeResolveOutput( + mtype_name="Hippocampus CA3 Oriens Interneuron", + mtype_id="http://uri.interlex.org/base/ilx_0105044", + ).model_dump(), + MTypeResolveOutput( + mtype_name="Spinal Cord Ventral Horn Interneuron IA", + mtype_id="http://uri.interlex.org/base/ilx_0110929", + ).model_dump(), + EtypeResolveOutput( + etype_name="bAC", etype_id="http://uri.interlex.org/base/ilx_0738199" + ).model_dump(), + ] diff --git a/swarm_copy_tests/tools/test_traces_tool.py b/swarm_copy_tests/tools/test_traces_tool.py new file mode 100644 index 0000000..03bba53 --- /dev/null +++ b/swarm_copy_tests/tools/test_traces_tool.py @@ -0,0 +1,150 @@ +"""Tests Traces tool.""" + +import json +from pathlib import Path + +import httpx +import pytest + +from swarm_copy.tools import GetTracesTool +from swarm_copy.tools.traces_tool import GetTracesInput, GetTracesMetadata + + +class TestTracesTool: + @pytest.mark.httpx_mock(can_send_already_matched_responses=True) + @pytest.mark.asyncio + async def test_arun(self, httpx_mock, brain_region_json_path): + url = "http://fake_url" + json_path = Path(__file__).resolve().parent.parent / "data" / "get_traces.json" + with open(json_path) as f: + get_traces_response = json.load(f) + + httpx_mock.add_response( + url=url, + json=get_traces_response, + ) + + tool = GetTracesTool( + metadata=GetTracesMetadata( + knowledge_graph_url=url, + trace_search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + brainregion_path=brain_region_json_path, + ), + input_schema=GetTracesInput(brain_region_id="brain_region_id_link/549"), + ) + + response = await tool.arun() + assert isinstance(response, list) + assert len(response) == 2 + assert isinstance(response[0], dict) + assert isinstance(response[0], dict) + + @pytest.mark.httpx_mock(can_send_already_matched_responses=True) + @pytest.mark.asyncio + async def test_arun_with_etype(self, httpx_mock, brain_region_json_path): + url = "http://fake_url" + json_path = Path(__file__).resolve().parent.parent / "data" / "get_traces.json" + with open(json_path) as f: + get_traces_response = json.load(f) + + httpx_mock.add_response( + url=url, + json=get_traces_response, + ) + + tool = GetTracesTool( + metadata=GetTracesMetadata( + knowledge_graph_url=url, + trace_search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + brainregion_path=brain_region_json_path, + ), + input_schema=GetTracesInput( + brain_region_id="brain_region_id_link/549", etype_id="bAC_id/123" + ), + ) + response = await tool.arun() + assert isinstance(response, list) + assert len(response) == 2 + assert isinstance(response[0], dict) + + @pytest.mark.asyncio + async def test_arun_errors(self, httpx_mock, brain_region_json_path): + url = "http://fake_url" + + # Mocking an issue + httpx_mock.add_response( + url=url, + json={}, + ) + + tool = GetTracesTool( + metadata=GetTracesMetadata( + knowledge_graph_url=url, + trace_search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + brainregion_path=brain_region_json_path, + ), + input_schema=GetTracesInput(brain_region_id="brain_region_id_link/549"), + ) + with pytest.raises(KeyError) as tool_exception: + await tool.arun() + + assert tool_exception.value.args[0] == "hits" + + def test_create_query(self, brain_region_json_path): + brain_region_ids = {"brain_region_id1"} + etype_id = "bAC_id/123" + url = "http://fake_url" + + tool = GetTracesTool( + metadata=GetTracesMetadata( + knowledge_graph_url=url, + trace_search_size=2, + httpx_client=httpx.AsyncClient(), + token="fake_token", + brainregion_path=brain_region_json_path, + ), + input_schema=GetTracesInput( + brain_region_id="brain_region_id1", etype_id=etype_id + ), + ) + entire_query = tool.create_query( + brain_region_ids=brain_region_ids, etype_id=etype_id + ) + expected_query = { + "size": 2, + "track_total_hits": True, + "query": { + "bool": { + "must": [ + { + "bool": { + "should": [ + { + "term": { + "brainRegion.@id.keyword": ( + "brain_region_id1" + ) + } + }, + ] + } + }, + {"term": {"eType.@id.keyword": ("bAC_id/123")}}, + { + "term": { + "@type.keyword": "https://bbp.epfl.ch/ontologies/core/bmo/ExperimentalTrace" + } + }, + {"term": {"curated": True}}, + {"term": {"deprecated": False}}, + ] + } + }, + } + assert entire_query == expected_query