Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements to support new cell type annotations #159

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion hs-ontology-api-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1395,7 +1395,7 @@ components:
example: multimerin-1
organs:
type: array
description: Organs associated with the cell type, based on relationships in the Human Resource Atlas and Azimuth
description: Organs associated with the cell type, based on relationships in the Human Resource Atlas and various annotations (including Azimuth and STELLAR)
items:
type: object
properties:
Expand All @@ -1411,6 +1411,10 @@ components:
type: string
description: Name (preferred term) for organ in source
example: heart
annotation:
type: string
description: SAB of the cell type annotation
example: AZ
FieldDescriptionsResponse:
type: object
description: Descriptions for ingest metadata fields
Expand Down
23 changes: 15 additions & 8 deletions src/hs_ontology_api/cypher/celltypedetail.cypher
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Return detailed inforomation on cell types, based on a input list of AZ terms.
// Return detailed information on cell types, based on a input list of CL codes.

CALL
// Get CUIs of concepts for cell types that match the criteria.
Expand All @@ -13,9 +13,12 @@ CALL
WITH [$ids] AS ids

// APRIL 2024 Bug fix to use CodeID instead of CODE for cases of leading zeroes in strings.
OPTIONAL MATCH (pCL:Concept)-[:CODE]->(cCL:Code)
WHERE CASE WHEN ids[0]<>'' THEN ANY(id in ids WHERE cCL.CodeID='CL:'+id) ELSE 1=1 END RETURN DISTINCT pCL.CUI AS CLCUI}

// JANUARY 2025 Because PATO and UBERON are ingested prior to CL, some CL codes will associate with multiple concepts.
// Use the concept that is associated with the code during the CL ingestion, which can be identified by the use of a
// preferred term (term of relationship type PT).
OPTIONAL MATCH (pCL:Concept)-[:CODE]->(cCL:Code)-[r:PT]->(tCL:Term)
WHERE r.CUI = pCL.CUI
AND CASE WHEN ids[0]<>'' THEN ANY(id in ids WHERE cCL.CodeID='CL:'+id) ELSE 1=1 END RETURN DISTINCT pCL.CUI AS CLCUI}
CALL
{

Expand Down Expand Up @@ -68,6 +71,9 @@ ORDER BY CLID, ret_value

UNION

// January 2025 - expand to include mappings from STELLAR and DeepCellType annotations. All references to 'AZ' and 'Azimuth' should
// be considered references to an annotation.

// Cell types - Azimuth/UBERON organ list
// The Azimuth ontology:
// 1. Assigns AZ cell codes to AZ organ codes.
Expand All @@ -86,16 +92,17 @@ CALL
WITH CLCUI
OPTIONAL MATCH (pCL:Concept)-[:CODE]->(cCL:Code)-[rCL]->(tCL:Term),
(pCL:Concept)-[:CODE]->(cAZ:Code)-[rAZ]->(tAZ:Term)
WHERE pCL.CUI=CLCUI AND rCL.CUI=pCL.CUI AND cCL.SAB='CL' AND cAZ.SAB='AZ'
WHERE pCL.CUI=CLCUI AND rCL.CUI=pCL.CUI AND cCL.SAB='CL'
AND cAZ.SAB IN['AZ','STELLAR','DCT']
RETURN DISTINCT cCL.CodeID as CLID,cAZ.CodeID AS AZID
}
//Use the AZ codes to map to concepts that have located_in relationships with AZ organ codes.
//The AZ organ codes are cross-referenced to UBERON codes. Limit the located_in relationships to those from AZ.
CALL
{ WITH AZID
OPTIONAL MATCH (cAZ:Code)<-[:CODE]-(pAZ:Concept)-[rAZUB:located_in]->(pUB:Concept)-[:CODE]->(cUB:Code)-[rUB:PT]->(tUB:Term)
WHERE rAZUB.SAB='AZ' AND rUB.CUI=pUB.CUI AND cAZ.CodeID=AZID AND cUB.SAB='UBERON'
RETURN cUB.CodeID+'|'+ tUB.name + '' as UBERONID
MATCH (cAZ:Code)<-[:CODE]-(pAZ:Concept)-[rAZUB:located_in]->(pUB:Concept)-[:CODE]->(cUB:Code)-[rUB:PT]->(tUB:Term)
WHERE rAZUB.SAB IN ['AZ','STELLAR','DCT'] AND rUB.CUI=pUB.CUI AND cAZ.CodeID=AZID AND cUB.SAB='UBERON'
RETURN cUB.CodeID+'|'+ tUB.name + '|' + rAZUB.SAB as UBERONID
}
WITH CLID,UBERONID
RETURN DISTINCT CLID, 'cell_types_organ' as ret_key, apoc.text.join(COLLECT(DISTINCT UBERONID),",") AS ret_value
Expand Down
38 changes: 34 additions & 4 deletions src/hs_ontology_api/models/celltypedetail_organ.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
# Used by the celltypes endpoint.
# Contains information on an organ associated with a cell type identified in Cell Ontology.

# JAS January 2025
# Added annotation key to the organs object, which describes the annotation used assign organs to cell types.
# Annotations include Azimuth (the original annotation), STELLAR, and DeepCellType

from __future__ import absolute_import
from typing import List
from ubkg_api.models.base_model_ import Model
Expand All @@ -17,48 +21,55 @@ def __init__(self, organ=None):

:param organ: delimited string describing the organ.
The format of the string is
<SAB>:<id>|<code>|preferred term
<SAB>:<id>|<code>|preferred term|annotation

"""
# Types for JSON objects
self.openapi_types = {
'id': str,
'source': str,
'name': str
'name': str,
'annotation': str
}
# Attribute mappings used by the base Model class to assert key/value pairs.
self.attribute_map = {
'id': 'id',
'source': 'source',
'name': 'name'
'name': 'name',
'annotation': 'annotation'
}

# Property assignments
if organ is None:
id = 'unknown'
source = 'unknown'
name = 'unknown'
annotation = 'unknown'
else:
organ_info = organ.split('|')
if len(organ_info) == 1:
id = organ_info
source = ''
name = ''
annotation = ''
else:
source = organ_info[0].split(':')[0]
id = organ_info[0].split(':')[1]
name = organ_info[1]
annotation = organ_info[2]

self._id = id
self._source = source
self._name = name
self._annotation = annotation

def serialize(self):
# Key/value format of response.
return {
"id": self._id,
"source": self._source,
"name": self._name
"name": self._name,
"annotation": self._annotation
}

@classmethod
Expand Down Expand Up @@ -131,3 +142,22 @@ def name(self, name):
"""
self._name = name

@property
def annotation(self):
"""
Gets the annotation of this CelltypeDetailOrgan.

:return: The annotation of the organ
:rtype: str
"""
return self._annotation

@annotation.setter
def annotation(self, annotation):
"""
Sets the annotation of this CelltypeDetailOrgan
:param annotation: The name of the organ.
:type annotation: str
"""
self._annotation = annotation

Loading