diff --git a/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/metadata.json b/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/metadata.json
index 57cbd7a..ba44a31 100644
--- a/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/metadata.json
+++ b/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/metadata.json
@@ -8,5 +8,5 @@
"is_multi_dataset_template": true,
"template_format": "jinja",
"is_hidden": false,
- "last_modified_unix_timestamp": 1723749414
+ "last_modified_unix_timestamp": 1771277901
}
diff --git a/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/template.ipynb b/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/template.ipynb
index e7a6f24..859c3f9 100644
--- a/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/template.ipynb
+++ b/src/user_templates_api/templates/jupyter_lab/templates/hra_api_tutorial/template.ipynb
@@ -1,548 +1,826 @@
{
"cells": [
{
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## HRA API Usage\n",
- "This notebook shows how to use the HRA API method calls provided by the `hra_api_client` package. We will show how to set up the client and make a few calls. Refer to the usage notebook [here](https://github.com/x-atlas-consortia/hra-api/blob/main/notebooks/hra-api-client-usage.ipynb) and to the API documentation on for additional documentation, methods, and examples."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Install package\n",
- "For this notebook, we'll install the `hra-api-client` and a set of HRA UI widgets called `hra-jupyter-widgets`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "%pip install hra-api-client hra-jupyter-widgets"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "### Imports \n",
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "40dd5488",
+ "metadata": {},
+ "source": [
+ "## HRA API Usage\n",
+ "This notebook shows how to use the HRA API method calls provided by the `hra_api_client` package. We will show how to set up the client and make a few calls. Refer to the usage notebook [here](https://github.com/x-atlas-consortia/hra-api/blob/main/notebooks/hra-api-client-usage.ipynb) and to the API documentation on for additional documentation, methods, and examples."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b5d71a77",
+ "metadata": {},
+ "source": [
+ "### Install package\n",
+ "For this notebook, we'll install the `hra-api-client` and a set of HRA UI widgets called `hra-jupyter-widgets`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "54983b34",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Requirement already satisfied: hra-api-client in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (0.17.0)\n",
+ "Requirement already satisfied: hra-jupyter-widgets in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (0.4.1)\n",
+ "Requirement already satisfied: lazy-imports<2,>=1 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from hra-api-client) (1.2.0)\n",
+ "Requirement already satisfied: pydantic>=2 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from hra-api-client) (2.12.5)\n",
+ "Requirement already satisfied: python-dateutil>=2.8.2 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from hra-api-client) (2.9.0.post0)\n",
+ "Requirement already satisfied: typing-extensions>=4.7.1 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from hra-api-client) (4.15.0)\n",
+ "Requirement already satisfied: urllib3<3.0.0,>=2.1.0 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from hra-api-client) (2.5.0)\n",
+ "Requirement already satisfied: anywidget in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from hra-jupyter-widgets) (0.9.21)\n",
+ "Requirement already satisfied: traitlets>=5.10 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from hra-jupyter-widgets) (5.14.3)\n",
+ "Requirement already satisfied: annotated-types>=0.6.0 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from pydantic>=2->hra-api-client) (0.7.0)\n",
+ "Requirement already satisfied: pydantic-core==2.41.5 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from pydantic>=2->hra-api-client) (2.41.5)\n",
+ "Requirement already satisfied: typing-inspection>=0.4.2 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from pydantic>=2->hra-api-client) (0.4.2)\n",
+ "Requirement already satisfied: six>=1.5 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from python-dateutil>=2.8.2->hra-api-client) (1.17.0)\n",
+ "Requirement already satisfied: ipywidgets>=7.6.0 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from anywidget->hra-jupyter-widgets) (8.1.8)\n",
+ "Requirement already satisfied: psygnal>=0.8.1 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from anywidget->hra-jupyter-widgets) (0.15.1)\n",
+ "Requirement already satisfied: comm>=0.1.3 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.2.3)\n",
+ "Requirement already satisfied: ipython>=6.1.0 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (9.6.0)\n",
+ "Requirement already satisfied: widgetsnbextension~=4.0.14 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (4.0.15)\n",
+ "Requirement already satisfied: jupyterlab_widgets~=3.0.15 in c:\\users\\abueckle\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (3.0.16)\n",
+ "Requirement already satisfied: colorama in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.4.6)\n",
+ "Requirement already satisfied: decorator in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (5.2.1)\n",
+ "Requirement already satisfied: ipython-pygments-lexers in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (1.1.1)\n",
+ "Requirement already satisfied: jedi>=0.16 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.19.2)\n",
+ "Requirement already satisfied: matplotlib-inline in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.1.7)\n",
+ "Requirement already satisfied: prompt_toolkit<3.1.0,>=3.0.41 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (3.0.52)\n",
+ "Requirement already satisfied: pygments>=2.4.0 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (2.19.2)\n",
+ "Requirement already satisfied: stack_data in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.6.3)\n",
+ "Requirement already satisfied: parso<0.9.0,>=0.8.4 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.8.5)\n",
+ "Requirement already satisfied: wcwidth in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from prompt_toolkit<3.1.0,>=3.0.41->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.2.14)\n",
+ "Requirement already satisfied: executing>=1.2.0 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from stack_data->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (2.2.1)\n",
+ "Requirement already satisfied: asttokens>=2.1.0 in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from stack_data->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (3.0.0)\n",
+ "Requirement already satisfied: pure-eval in c:\\users\\abueckle\\appdata\\roaming\\python\\python312\\site-packages (from stack_data->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget->hra-jupyter-widgets) (0.2.3)\n",
+ "Note: you may need to restart the kernel to use updated packages.\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
"\n",
- "We import the hra-api-client as follows:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import hra_api_client"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Although we can use hra-api-client for all our tasks, it is easier if we have individual imports as follows:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from hra_api_client.api import v1_api\n",
- "from hra_api_client.api import hra_pop_api\n",
- "from hra_api_client.api import ds_graph_api\n",
- "from hra_api_client.models.aggregate_count import AggregateCount\n",
- "from hra_api_client.models.database_status import DatabaseStatus\n",
- "from hra_api_client.models.error_message import ErrorMessage\n",
- "from hra_api_client.models.flat_spatial_placement import FlatSpatialPlacement\n",
- "from hra_api_client.models.get_spatial_placement_request import GetSpatialPlacementRequest\n",
- "from hra_api_client.models.min_max import MinMax\n",
- "from hra_api_client.models.ontology_tree import OntologyTree\n",
- "from hra_api_client.models.sparql_query_request import SparqlQueryRequest\n",
- "from hra_api_client.models.spatial_entity import SpatialEntity\n",
- "from hra_api_client.models.spatial_scene_node import SpatialSceneNode\n",
- "from hra_api_client.models.spatial_search import SpatialSearch\n",
- "from hra_api_client.models.tissue_block import TissueBlock"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For the purposes of this demonstration we need some other libraries imported here: "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import time\n",
- "from pprint import pprint\n",
- "from hra_jupyter_widgets import ModelViewer"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Creating the API Instance \n",
- "We will now create an instance of the API client to use methods provided by the HRA API."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Client configuration, the default API endpoint is https://apps.humanatlas.io/api\n",
- "configuration = hra_api_client.Configuration(\n",
- " host = \"https://apps.humanatlas.io/api\" \n",
- ")\n",
- "\n",
- "# Base Client Object\n",
- "api_client = hra_api_client.ApiClient(configuration)\n",
- "\n",
- "# Instance with which to call the primary /v1 routes from our API\n",
- "api_instance = v1_api.V1Api(api_client)\n",
- "\n",
- "# Instance with which to call the /hra-pop routes\n",
- "hra_pop_api_instance = hra_pop_api.HraPopApi(api_client)\n",
- "\n",
- "# Instance with which to call the /ds-graph routes\n",
- "ds_graph_api_instance = ds_graph_api.DsGraphApi(api_client)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Aggregate statistics\n",
- "To get a quick idea of what data is available in the HRA API, you can use the `aggregate_results` method. With no options, it returns various counts for all default (federated) data."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "api_response = api_instance.aggregate_results()\n",
- "for x in api_response:\n",
- " print(x.count, x.label)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Get a session token for HuBMAP data\n",
- "You can limit to certain sets of data by creating a session token. We will create a session for just HuBMAP data. Filters, discussed later, can also be used here to make a smaller set of data for more targeted studies.\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Session configuration. You can add your HuBMAP token after ?token= to get private data\n",
- "session_configuration = { \"dataSources\": [\"https://apps.humanatlas.io/api/ds-graph/hubmap?token=\"] }\n",
- "\n",
- "# Get a session token for this configuration\n",
- "api_response = api_instance.session_token(session_configuration)\n",
- "token=api_response.token\n",
- "print(token)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "After we get the session token, we wait to make sure the session is ready."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "db_ready = False\n",
- "while not db_ready:\n",
- " api_response = api_instance.db_status(token)\n",
- " print(api_response)\n",
- " if api_response.status == 'Ready':\n",
- " db_ready = True\n",
- " else:\n",
- " print('Database not ready yet! Retrying...')\n",
- " time.sleep(2)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Examine the HuBMAP data\n",
- "Now we can check the data available in the session we created"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# get aggregate statistics\n",
- "api_response = api_instance.aggregate_results(token=token)\n",
- "for x in api_response:\n",
- " print(x.count, x.label)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's get all of the tissue blocks (with a RUI location) in HuBMAP"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# get all tissue blocks\n",
- "api_response = api_instance.tissue_blocks(token=token)\n",
- "\n",
- "# print first five block links\n",
- "for x in api_response[0:5]:\n",
- " print(x.link)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Filter the HuBMAP data"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Certain parameters can be used to filter the data. Most methods that query the data have these filters to use:\n",
- "
\n",
- " age - (MinMax) (optional) (min = 1.0; max = 110.0)\n",
- " bmi - (MinMax) (optional) (min = 13.0; max = 83.0)\n",
- " sex - (string) (optional) (male, female, both)\n",
- " technologies - (string) (optional) (List of technologies - api_instance.technology_names)\n",
- " providers - (string) (optional) \n",
- " ontology_terms - (string) (optional) (List of ontology terms)\n",
- " cell_type_terms - (string) (optional) (List of ontology tems)\n",
- " spatial - SpatialSearch(x, y, z, radius, target) (optional) \n",
- " token - (string) (optional) the session token, if not provided it will use the default dataset\n",
- "
\n",
- "\n",
- "Example instantantiations of the filters are below."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "age = MinMax(min=45.0, max=60.0)\n",
- "bmi = MinMax(min=65.0, max=83.0)\n",
- "sex = \"Female\"\n",
- "technologies = []\n",
- "providers = []\n",
- "ontology_terms = [\"http://purl.obolibrary.org/obo/UBERON_0000955\",]\n",
- "cell_type_terms = [\"http://purl.obolibrary.org/obo/CL_0000000\",] \n",
- "spatial = [SpatialSearch(\n",
- " x=84.0,\n",
- " y=146.0,\n",
- " z=53.0,\n",
- " radius=12.0,\n",
- " target=\"https://purl.humanatlas.io/ref-organ/brain-female#primary\"\n",
- " ),]\n",
- "\n",
- "# get filtered aggregate statistics\n",
- "api_response = api_instance.aggregate_results(\n",
- " age=age,\n",
- " bmi=bmi, \n",
- " ontology_terms=ontology_terms,\n",
- " cell_type_terms=cell_type_terms, \n",
- " providers=providers,\n",
- " sex=sex,\n",
- " spatial=spatial,\n",
- " technologies=technologies,\n",
- " token=token)\n",
- "for x in api_response:\n",
- " print(x.count, x.label)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Another way to manage these filters is to create a Dictionary and use python's `**kwargs` syntax to create and pass around a filter object. We'll use this filter object for several methods below."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "filter = {\n",
- " \"age\": MinMax(min=45.0, max=60.0),\n",
- " \"bmi\": MinMax(min=65.0, max=83.0),\n",
- " \"sex\": \"Female\",\n",
- " \"technologies\": [],\n",
- " \"providers\": [],\n",
- " \"ontology_terms\": [\"http://purl.obolibrary.org/obo/UBERON_0000955\"],\n",
- " \"cell_type_terms\": [\"http://purl.obolibrary.org/obo/CL_0000000\"],\n",
- " \"spatial\": [\n",
- " SpatialSearch(\n",
- " x=84.0,\n",
- " y=146.0,\n",
- " z=53.0,\n",
- " radius=12.0,\n",
- " target=\"https://purl.humanatlas.io/ref-organ/brain-female#primary\"\n",
- " )\n",
- " ]\n",
- "}\n",
- "\n",
- "# get filtered aggregate statistics\n",
- "api_response = api_instance.aggregate_results(token=token, **filter)\n",
- "for x in api_response:\n",
- " print(x.count, x.label)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# get anatomical structures that the tissue blocks collided with\n",
- "api_response = api_instance.ontology_term_occurences(token=token, **filter)\n",
- "\n",
- "# Print the first 5 results\n",
- "for (anatomical_structure, count) in list(api_response.items())[0:5]:\n",
- " print(anatomical_structure, count)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# get cell types located in anatomical structures that the tissue blocks collided with\n",
- "api_response = api_instance.cell_type_term_occurences(token=token, **filter)\n",
- "\n",
- "# Print the first 5 results\n",
- "for (cell_type, count) in list(api_response.items())[0:5]:\n",
- " print(cell_type, count)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Query the HRA Knowledge Graph with SPARQL\n",
- "The HRA API provides a SPARQL endpoint to query the HRA knowledge graph. This allows you to select out very specific data using advanced SPARQL querying. \n",
- "\n",
- "To demonstrate, let's get all the anatomical structures in the latest HRA release."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "query = '''\n",
- "PREFIX ccf: \n",
- "SELECT ?as ?label\n",
- "FROM \n",
- "WHERE {\n",
- " ?as ccf:ccf_asctb_type ?type ;\n",
- " ccf:ccf_pref_label ?label .\n",
- " FILTER(?type = 'AS')\n",
- "}\n",
- "'''\n",
- "api_response = api_instance.sparql(query=query)\n",
- "rows = api_response['results']['bindings']\n",
- "\n",
- "as_lookup = dict([ (row['as']['value'], row['label']['value']) for row in rows ])\n",
- "\n",
- "# Print the first 5 results\n",
- "for (anatomical_structure, label) in list(as_lookup.items())[0:5]:\n",
- " print(anatomical_structure, label)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "If your SPARQL query is longer (thousands of characters), you can do a SPARQL POST which allows for sending more data."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "api_response = api_instance.sparql_post({'query': query})\n",
- "rows = api_response['results']['bindings']\n",
- "\n",
- "as_lookup = dict([ (row['as']['value'], row['label']['value']) for row in rows ])\n",
- "\n",
- "# Print the first 5 results\n",
- "for (anatomical_structure, label) in list(as_lookup.items())[0:5]:\n",
- " print(anatomical_structure, label)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Working with extraction sites (aka RUI locations)\n",
- "After obtaining an extraction site either via the RUI or from queries like above, there are a few things you can do with this data."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Generate a 3D corridor\n",
- "\n",
- "We can compute a corridor from any extraction site. A corridor shows where else an extraction site could go in the same organ and still maintain the same overlaps with anatomical structures. We will take an example extraction site and see what it's corridor looks like."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "An example extraction site:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Provide a RUI location via the RUI at https://apps.humanatlas.io/rui/\n",
- "extraction_site = {\n",
- " \"@context\": \"https://hubmapconsortium.github.io/ccf-ontology/ccf-context.jsonld\",\n",
- " \"@id\": \"http://purl.org/ccf/1.5/cc837df1-2788-4510-9c21-9eb0e9b310a5\",\n",
- " \"@type\": \"SpatialEntity\",\n",
- " \"creator\": \"demo demo\",\n",
- " \"creator_first_name\": \"demo\",\n",
- " \"creator_last_name\": \"demo\",\n",
- " \"creation_date\": \"2024-08-20\",\n",
- " \"ccf_annotations\": [\n",
- " \"http://purl.obolibrary.org/obo/UBERON_0002015\",\n",
- " \"http://purl.obolibrary.org/obo/UBERON_0002189\"\n",
- " ],\n",
- " \"x_dimension\": 10,\n",
- " \"y_dimension\": 10,\n",
- " \"z_dimension\": 10,\n",
- " \"dimension_units\": \"millimeter\",\n",
- " \"placement\": {\n",
- " \"@context\": \"https://hubmapconsortium.github.io/ccf-ontology/ccf-context.jsonld\",\n",
- " \"@id\": \"http://purl.org/ccf/1.5/cc837df1-2788-4510-9c21-9eb0e9b310a5_placement\",\n",
- " \"@type\": \"SpatialPlacement\",\n",
- " \"target\": \"https://purl.humanatlas.io/ref-organ/kidney-female-right/v1.3#primary\",\n",
- " \"placement_date\": \"2024-08-20\",\n",
- " \"x_scaling\": 1,\n",
- " \"y_scaling\": 1,\n",
- " \"z_scaling\": 1,\n",
- " \"scaling_units\": \"ratio\",\n",
- " \"x_rotation\": 0,\n",
- " \"y_rotation\": 0,\n",
- " \"z_rotation\": 0,\n",
- " \"rotation_order\": \"XYZ\",\n",
- " \"rotation_units\": \"degree\",\n",
- " \"x_translation\": 72.366,\n",
- " \"y_translation\": 79.067,\n",
- " \"z_translation\": 34.77,\n",
- " \"translation_units\": \"millimeter\"\n",
- " }\n",
- "}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Generate a corridor for the extraction site\n",
- "model = api_instance.corridor(extraction_site)\n",
- "\n",
- "# Display it in 3D\n",
- "viewer = ModelViewer(data=model)\n",
- "display(viewer)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Find anatomical structure collisions for an extraction site\n",
- "For any extraction site, we can analyze what anatomical structures it collides with in the 3D reference organ and by how much."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Get mesh-based collisions\n",
- "collisions = api_instance.collisions(extraction_site)\n",
- "\n",
- "pprint(collisions[0:5])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Conclusion\n",
- "This concludes this tutorial. Refer to the usage notebook [here](https://github.com/x-atlas-consortia/hra-api/blob/main/notebooks/hra-api-client-usage.ipynb) and to the API documentation on for additional documentation, methods, and examples. If you have any issues, problems, or questions, feel free to file an issue on the HRA API GitHub at ."
- ]
+ "[notice] A new release of pip is available: 25.0.1 -> 25.3\n",
+ "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
+ ]
+ }
+ ],
+ "source": [
+ "%pip install --upgrade hra-api-client hra-jupyter-widgets"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "c3f1f6d5",
+ "metadata": {},
+ "source": [
+ "\n",
+ "### Imports \n",
+ "\n",
+ "We import the hra-api-client as follows:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "e5e21389",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import hra_api_client"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "0d6f2a35",
+ "metadata": {},
+ "source": [
+ "Although we can use hra-api-client for all our tasks, it is easier if we have individual imports as follows:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "d9f69dc1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from hra_api_client.api import v1_api\n",
+ "from hra_api_client.api import hra_pop_api\n",
+ "from hra_api_client.api import ds_graph_api\n",
+ "from hra_api_client.models.min_max import MinMax\n",
+ "from hra_api_client.models.spatial_entity import SpatialEntity\n",
+ "from hra_api_client.models.spatial_search import SpatialSearch\n",
+ "from hra_api_client.models.spatial_entity import SpatialEntity"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "7c4af109",
+ "metadata": {},
+ "source": [
+ "For the purposes of this demonstration we need some other libraries imported here: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "3952039c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import time\n",
+ "from pprint import pprint\n",
+ "from hra_jupyter_widgets import ModelViewer"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "9faf09af",
+ "metadata": {},
+ "source": [
+ "### Creating the API Instance \n",
+ "We will now create an instance of the API client to use methods provided by the HRA API."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "3d7b7374",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Client configuration, the default API endpoint is https://apps.humanatlas.io/api\n",
+ "configuration = hra_api_client.Configuration(\n",
+ " host = \"https://apps.humanatlas.io/api\" \n",
+ ")\n",
+ "\n",
+ "# Base Client Object\n",
+ "api_client = hra_api_client.ApiClient(configuration)\n",
+ "\n",
+ "# Instance with which to call the primary /v1 routes from our API\n",
+ "api_instance = v1_api.V1Api(api_client)\n",
+ "\n",
+ "# Instance with which to call the /hra-pop routes\n",
+ "hra_pop_api_instance = hra_pop_api.HraPopApi(api_client)\n",
+ "\n",
+ "# Instance with which to call the /ds-graph routes\n",
+ "ds_graph_api_instance = ds_graph_api.DsGraphApi(api_client)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "536f4af1",
+ "metadata": {},
+ "source": [
+ "## Aggregate statistics\n",
+ "To get a quick idea of what data is available in the HRA API, you can use the `aggregate_results` method. With no options, it returns various counts for all default (federated) data."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "e42d97af",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "18 Consortia\n",
+ "49 Tissue Data Providers\n",
+ "724 Donors\n",
+ "30 Organs\n",
+ "2135 Extraction Sites\n",
+ "2638 Tissue Blocks\n",
+ "2212 Tissue Sections\n",
+ "8045 Tissue Datasets\n"
+ ]
+ }
+ ],
+ "source": [
+ "api_response = api_instance.aggregate_results()\n",
+ "for x in api_response:\n",
+ " print(x.count, x.label)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9afdfe07",
+ "metadata": {},
+ "source": [
+ "## Get a session token for HuBMAP data\n",
+ "You can limit to certain sets of data by creating a session token. We will create a session for just HuBMAP data. Filters, discussed later, can also be used here to make a smaller set of data for more targeted studies.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "2cd78368",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "ad224e52857dde02cbb05a10bfb807c7\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Session configuration. You can add your HuBMAP token after ?token= to get private data\n",
+ "session_configuration = { \"dataSources\": [\"https://apps.humanatlas.io/api/ds-graph/hubmap?token=\"] }\n",
+ "\n",
+ "# Get a session token for this configuration\n",
+ "api_response = api_instance.session_token(session_configuration)\n",
+ "token=api_response.token\n",
+ "print(token)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f7c9d42e",
+ "metadata": {},
+ "source": [
+ "After we get the session token, we wait to make sure the session is ready."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "49d052a1",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "status='Ready' checkback=3600000 load_time=11388 message='Dataset ready'\n"
+ ]
+ }
+ ],
+ "source": [
+ "db_ready = False\n",
+ "while not db_ready:\n",
+ " api_response = api_instance.db_status(token)\n",
+ " print(api_response)\n",
+ " if api_response.status == 'Ready':\n",
+ " db_ready = True\n",
+ " else:\n",
+ " print('Database not ready yet! Retrying...')\n",
+ " time.sleep(2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "053ef46e",
+ "metadata": {},
+ "source": [
+ "## Examine the HuBMAP data\n",
+ "Now we can check the data available in the session we created"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "180bfa92",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "18 Consortia\n",
+ "49 Tissue Data Providers\n",
+ "724 Donors\n",
+ "30 Organs\n",
+ "2135 Extraction Sites\n",
+ "2638 Tissue Blocks\n",
+ "2212 Tissue Sections\n",
+ "8045 Tissue Datasets\n"
+ ]
+ }
+ ],
+ "source": [
+ "# get aggregate statistics\n",
+ "api_response = api_instance.aggregate_results(token=token)\n",
+ "for x in api_response:\n",
+ " print(x.count, x.label)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4f4c3fcb",
+ "metadata": {},
+ "source": [
+ "Let's get all of the tissue blocks (with a RUI location) in HuBMAP"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "3b35d563",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "http://dx.doi.org/10.1681/ASN.2016091027\n",
+ "http://dx.doi.org/10.1681/ASN.2016091027\n",
+ "http://dx.doi.org/10.1016/j.trsl.2017.07.006\n",
+ "https://portal.hubmapconsortium.org/browse/sample/9d944eb8a61bf85f70762ae3f2b0e22e\n",
+ "https://portal.hubmapconsortium.org/browse/sample/539b8dd38698d191ec284f9f061e7441\n"
+ ]
+ }
+ ],
+ "source": [
+ "# get all tissue blocks\n",
+ "api_response = api_instance.tissue_blocks(token=token)\n",
+ "\n",
+ "# print first five block links\n",
+ "for x in api_response[0:5]:\n",
+ " print(x.link)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ab610593",
+ "metadata": {},
+ "source": [
+ "## Filter the HuBMAP data"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "2e383f49",
+ "metadata": {},
+ "source": [
+ "Certain parameters can be used to filter the data. Most methods that query the data have these filters to use:\n",
+ "\n",
+ " age - (MinMax) (optional) (min = 1.0; max = 110.0)\n",
+ " bmi - (MinMax) (optional) (min = 13.0; max = 83.0)\n",
+ " sex - (string) (optional) (male, female, both)\n",
+ " technologies - (string) (optional) (List of technologies - api_instance.technology_names)\n",
+ " providers - (string) (optional) \n",
+ " ontology_terms - (string) (optional) (List of ontology terms)\n",
+ " cell_type_terms - (string) (optional) (List of ontology tems)\n",
+ " spatial - SpatialSearch(x, y, z, radius, target) (optional) \n",
+ " token - (string) (optional) the session token, if not provided it will use the default dataset\n",
+ "
\n",
+ "\n",
+ "Example instantantiations of the filters are below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "20a78738",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "11 Consortia\n",
+ "34 Tissue Data Providers\n",
+ "293 Donors\n",
+ "21 Organs\n",
+ "983 Extraction Sites\n",
+ "1189 Tissue Blocks\n",
+ "1173 Tissue Sections\n",
+ "3817 Tissue Datasets\n"
+ ]
+ }
+ ],
+ "source": [
+ "age = MinMax(min=10.0, max=100.0)\n",
+ "bmi = MinMax(min=0.0, max=40.0)\n",
+ "sex = 'Male'\n",
+ "technologies = []\n",
+ "providers = []\n",
+ "ontology_terms = []\n",
+ "cell_type_terms = []\n",
+ "\n",
+ "spatial_obj = SpatialSearch(\n",
+ " x=38.0,\n",
+ " y=53.0,\n",
+ " z=41.0,\n",
+ " radius=44.0,\n",
+ " target='https://purl.humanatlas.io/ref-organ/kidney-male-left/v1.3#primary'\n",
+ ")\n",
+ "\n",
+ "api_response = api_instance.aggregate_results(\n",
+ " age=age,\n",
+ " ontology_terms=ontology_terms,\n",
+ " cell_type_terms=cell_type_terms,\n",
+ " providers=providers,\n",
+ " sex=sex,\n",
+ " spatial=[spatial_obj], \n",
+ " technologies=technologies,\n",
+ " token=token\n",
+ ")\n",
+ "\n",
+ "for x in api_response:\n",
+ " print(x.count, x.label)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7ec49d8f",
+ "metadata": {},
+ "source": [
+ "Another way to manage these filters is to create a Dictionary and use python's `**kwargs` syntax to create and pass around a filter object. We'll use this filter object for several methods below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "431c8aac",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "11 Consortia\n",
+ "34 Tissue Data Providers\n",
+ "293 Donors\n",
+ "21 Organs\n",
+ "983 Extraction Sites\n",
+ "1189 Tissue Blocks\n",
+ "1173 Tissue Sections\n",
+ "3817 Tissue Datasets\n"
+ ]
+ }
+ ],
+ "source": [
+ "age = MinMax(min=10.0, max=100.0)\n",
+ "\n",
+ "spatial_obj = SpatialSearch(\n",
+ " x=38.0,\n",
+ " y=53.0,\n",
+ " z=41.0,\n",
+ " radius=44.0,\n",
+ " target='https://purl.humanatlas.io/ref-organ/kidney-male-left/v1.3#primary'\n",
+ ")\n",
+ "\n",
+ "filter = {\n",
+ " \"age\" : age,\n",
+ " \"sex\": \"Male\",\n",
+ " \"technologies\": [],\n",
+ " \"providers\": [],\n",
+ " \"ontology_terms\": [],\n",
+ " \"cell_type_terms\": [\"http://purl.obolibrary.org/obo/CL_0000000\"],\n",
+ " \"spatial\": [spatial_obj]\n",
+ "}\n",
+ "\n",
+ "# get filtered aggregate statistics\n",
+ "api_response = api_instance.aggregate_results(token=token, **filter)\n",
+ "for x in api_response:\n",
+ " print(x.count, x.label)\n",
+ " \n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "f64b8987",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "http://purl.org/sig/ont/fma/fma14926 2\n",
+ "http://purl.org/sig/ont/fma/fma14928 2\n",
+ "http://purl.org/sig/ont/fma/fma14929 9\n",
+ "http://purl.org/sig/ont/fma/fma14930 9\n",
+ "http://purl.org/sig/ont/fma/fma14966 2\n"
+ ]
+ }
+ ],
+ "source": [
+ "# get anatomical structures that the tissue blocks collided with\n",
+ "api_response = api_instance.ontology_term_occurences(token=token, **filter)\n",
+ "\n",
+ "# Print the first 5 results\n",
+ "for (anatomical_structure, count) in list(api_response.items())[0:5]:\n",
+ " print(anatomical_structure, count)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "a972877d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "http://purl.obolibrary.org/obo/CL_0000000 1189\n",
+ "http://purl.obolibrary.org/obo/CL_0000057 35\n",
+ "http://purl.obolibrary.org/obo/CL_0000071 49\n",
+ "http://purl.obolibrary.org/obo/CL_0000084 247\n",
+ "http://purl.obolibrary.org/obo/CL_0000186 49\n"
+ ]
+ }
+ ],
+ "source": [
+ "# get cell types located in anatomical structures that the tissue blocks collided with\n",
+ "api_response = api_instance.cell_type_term_occurences(token=token, **filter)\n",
+ "\n",
+ "# Print the first 5 results\n",
+ "for (cell_type, count) in list(api_response.items())[0:5]:\n",
+ " print(cell_type, count)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "98d83caf",
+ "metadata": {},
+ "source": [
+ "## Query the HRA Knowledge Graph with SPARQL\n",
+ "The HRA API provides a SPARQL endpoint to query the HRA knowledge graph. This allows you to select out very specific data using advanced SPARQL querying. \n",
+ "\n",
+ "To demonstrate, let's get all the anatomical structures in the latest HRA release."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "f2db2619",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "http://purl.obolibrary.org/obo/UBERON_0001399 deep brachial artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001404 radial artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001406 ulnar artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001410 common palmar digital artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001411 basilic vein\n"
+ ]
+ }
+ ],
+ "source": [
+ "query = '''\n",
+ "PREFIX ccf: \n",
+ "SELECT ?as ?label\n",
+ "FROM \n",
+ "WHERE {\n",
+ " ?as ccf:ccf_asctb_type ?type ;\n",
+ " ccf:ccf_pref_label ?label .\n",
+ " FILTER(?type = 'AS')\n",
+ "}\n",
+ "'''\n",
+ "api_response = api_instance.sparql(query=query)\n",
+ "rows = api_response['results']['bindings']\n",
+ "\n",
+ "as_lookup = dict([ (row['as']['value'], row['label']['value']) for row in rows ])\n",
+ "\n",
+ "# Print the first 5 results\n",
+ "for (anatomical_structure, label) in list(as_lookup.items())[0:5]:\n",
+ " print(anatomical_structure, label)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4434af2f",
+ "metadata": {},
+ "source": [
+ "If your SPARQL query is longer (thousands of characters), you can do a SPARQL POST which allows for sending more data."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "70bef89a",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "http://purl.obolibrary.org/obo/UBERON_0001399 deep brachial artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001404 radial artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001406 ulnar artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001410 common palmar digital artery\n",
+ "http://purl.obolibrary.org/obo/UBERON_0001411 basilic vein\n"
+ ]
+ }
+ ],
+ "source": [
+ "api_response = api_instance.sparql_post({'query': query})\n",
+ "rows = api_response['results']['bindings']\n",
+ "\n",
+ "as_lookup = dict([ (row['as']['value'], row['label']['value']) for row in rows ])\n",
+ "\n",
+ "# Print the first 5 results\n",
+ "for (anatomical_structure, label) in list(as_lookup.items())[0:5]:\n",
+ " print(anatomical_structure, label)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "579311b2",
+ "metadata": {},
+ "source": [
+ "## Working with extraction sites (aka RUI locations)\n",
+ "After obtaining an extraction site either via the RUI or from queries like above, there are a few things you can do with this data."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "acbf417a",
+ "metadata": {},
+ "source": [
+ "### Generate a 3D corridor\n",
+ "\n",
+ "We can compute a corridor from any extraction site. A corridor shows where else an extraction site could go in the same organ and still maintain the same overlaps with anatomical structures. We will take an example extraction site and see what it's corridor looks like."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8a5e9e88",
+ "metadata": {},
+ "source": [
+ "An example extraction site:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "4753f26a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Provide a RUI location via the RUI at https://apps.humanatlas.io/rui/\n",
+ "extraction_site = SpatialEntity.from_dict({\n",
+ " \"@context\": \"https://hubmapconsortium.github.io/ccf-ontology/ccf-context.jsonld\",\n",
+ " \"@id\": \"http://purl.org/ccf/1.5/cc837df1-2788-4510-9c21-9eb0e9b310a5\",\n",
+ " \"@type\": \"SpatialEntity\",\n",
+ " \"creator\": \"demo demo\",\n",
+ " \"creator_first_name\": \"demo\",\n",
+ " \"creator_last_name\": \"demo\",\n",
+ " \"creation_date\": \"2024-08-20\",\n",
+ " \"ccf_annotations\": [\n",
+ " \"http://purl.obolibrary.org/obo/UBERON_0002015\",\n",
+ " \"http://purl.obolibrary.org/obo/UBERON_0002189\"\n",
+ " ],\n",
+ " \"x_dimension\": 10,\n",
+ " \"y_dimension\": 10,\n",
+ " \"z_dimension\": 10,\n",
+ " \"dimension_units\": \"millimeter\",\n",
+ " \"placement\": {\n",
+ " \"@context\": \"https://hubmapconsortium.github.io/ccf-ontology/ccf-context.jsonld\",\n",
+ " \"@id\": \"http://purl.org/ccf/1.5/cc837df1-2788-4510-9c21-9eb0e9b310a5_placement\",\n",
+ " \"@type\": \"SpatialPlacement\",\n",
+ " \"target\": \"https://purl.humanatlas.io/ref-organ/kidney-female-right/v1.3#primary\",\n",
+ " \"placement_date\": \"2024-08-20\",\n",
+ " \"x_scaling\": 1,\n",
+ " \"y_scaling\": 1,\n",
+ " \"z_scaling\": 1,\n",
+ " \"scaling_units\": \"ratio\",\n",
+ " \"x_rotation\": 0,\n",
+ " \"y_rotation\": 0,\n",
+ " \"z_rotation\": 0,\n",
+ " \"rotation_order\": \"XYZ\",\n",
+ " \"rotation_units\": \"degree\",\n",
+ " \"x_translation\": 72.366,\n",
+ " \"y_translation\": 79.067,\n",
+ " \"z_translation\": 34.77,\n",
+ " \"translation_units\": \"millimeter\"\n",
+ " }\n",
+ "})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "b7c51796",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "0b097dfb8ee74d449ea88c515efe937c",
+ "version_major": 2,
+ "version_minor": 1
+ },
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Generate a corridor for the extraction site\n",
+ "model = api_instance.corridor(extraction_site)\n",
+ "\n",
+ "# Display it in 3D\n",
+ "viewer = ModelViewer(data=model)\n",
+ "display(viewer)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ebd70311",
+ "metadata": {},
+ "source": [
+ "### Find anatomical structure collisions for an extraction site\n",
+ "For any extraction site, we can analyze what anatomical structures it collides with in the 3D reference organ and by how much."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "8fe568bf",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[{'AS_volume': 10055.261678806379,\n",
+ " 'id': 'https://purl.humanatlas.io/ref-organ/kidney-female-right/v1.3#VH_F_kidney_capsule_R',\n",
+ " 'intersection_volume': 87,\n",
+ " 'is_closed': True,\n",
+ " 'label': 'kidney capsule',\n",
+ " 'node_name': 'VH_F_kidney_capsule_R',\n",
+ " 'organ': 'kidney-female-right',\n",
+ " 'percentage_of_AS': 0.008652186564509919,\n",
+ " 'percentage_of_tissue_block': 0.087,\n",
+ " 'representation_of': 'http://purl.obolibrary.org/obo/UBERON_0002015',\n",
+ " 'tissue_volume': 1000},\n",
+ " {'AS_volume': 84566.4834520329,\n",
+ " 'id': 'https://purl.humanatlas.io/ref-organ/kidney-female-right/v1.3#VH_F_outer_cortex_of_kidney_R',\n",
+ " 'intersection_volume': 366,\n",
+ " 'is_closed': True,\n",
+ " 'label': 'outer cortex of kidney',\n",
+ " 'node_name': 'VH_F_outer_cortex_of_kidney_R',\n",
+ " 'organ': 'kidney-female-right',\n",
+ " 'percentage_of_AS': 0.004327955769942823,\n",
+ " 'percentage_of_tissue_block': 0.366,\n",
+ " 'representation_of': 'http://purl.obolibrary.org/obo/UBERON_0002189',\n",
+ " 'tissue_volume': 1000}]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Get mesh-based collisions\n",
+ "collisions = api_instance.collisions(extraction_site)\n",
+ "\n",
+ "pprint(collisions[0:5])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ee5d1ae3",
+ "metadata": {},
+ "source": [
+ "## Conclusion\n",
+ "This concludes this tutorial. Refer to the usage notebook [here](https://github.com/x-atlas-consortia/hra-api/blob/main/notebooks/hra-api-client-usage.ipynb) and to the API documentation on for additional documentation, methods, and examples. If you have any issues, problems, or questions, feel free to file an issue on the HRA API GitHub at ."
+ ]
}
-],
+ ],
"metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
"language_info": {
- "name": "python"
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.10"
}
},
"nbformat": 4,
- "nbformat_minor": 2
-}
\ No newline at end of file
+ "nbformat_minor": 5
+}