Skip to content

Commit

Permalink
NickAkhmetov/HMP-540/Update get_view_config_builder to use `get_ass…
Browse files Browse the repository at this point in the history
…aytype` instead of `get_assay` (#82)
  • Loading branch information
NickAkhmetov authored Dec 19, 2023
1 parent ac8e4c3 commit 2db9bbc
Show file tree
Hide file tree
Showing 63 changed files with 381 additions and 151 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,25 @@ $ cd portal-visualization
$ pip install .
...
$ src/vis-preview.py --help
usage: vis-preview.py [-h] (--url URL | --json JSON) [--types_url URL]
usage: vis-preview.py [-h] (--url URL | --json JSON) [--assaytypes_url URL]
[--assets_url URL] [--token TOKEN] [--marker MARKER]
[--to_json]
Given HuBMAP Dataset JSON, generate a Vitessce viewconf, and load vitessce.io.
optional arguments:
-h, --help show this help message and exit
--url URL URL which returns Dataset JSON
--json JSON File containing Dataset JSON
--types_url URL Type service; default:
https://search.api.hubmapconsortium.org/v3
--assets_url URL Assets endpoint; default:
https://assets.hubmapconsortium.org
--token TOKEN Globus groups token; Only needed if data is not public
--marker MARKER Marker to highlight in visualization; Only used in some
visualizations.
--to_json Output viewconf, rather than open in browser.
```
-h, --help show this help message and exit
--url URL URL which returns Dataset JSON
--json JSON File containing Dataset JSON
--assaytypes_url URL AssayType service; default:
https://ingest.api.hubmapconsortium.org/assaytype/
--assets_url URL Assets endpoint; default:
https://assets.hubmapconsortium.org
--token TOKEN Globus groups token; Only needed if data is not public
--marker MARKER Marker to highlight in visualization; Only used in
some visualizations.
--to_json Output viewconf, rather than open in browser.
```

## Background

Expand Down
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.13
0.1.0
4 changes: 2 additions & 2 deletions src/defaults.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"types_url": "https://search.api.hubmapconsortium.org/v3",
"assets_url": "https://assets.hubmapconsortium.org"
"assets_url": "https://assets.hubmapconsortium.org",
"assaytypes_url": "https://ingest.api.hubmapconsortium.org/assaytype/"
}
1 change: 1 addition & 0 deletions src/portal_visualization/assays.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
SCATAC_SEQ_SCI = "sc_atac_seq_sci"
SCATAC_SEQ_SNARE = "sc_atac_seq_snare"
SCATAC_SEQ_SN = "sn_atac_seq"
SALMON_RNASSEQ_SLIDE = "salmon_rnaseq_slideseq"
59 changes: 44 additions & 15 deletions src/portal_visualization/builder_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,76 @@
from .assays import (
SEQFISH,
MALDI_IMS,
NANODESI
NANODESI,
SALMON_RNASSEQ_SLIDE
)


def get_view_config_builder(entity, get_assay):
data_types = entity["data_types"]
assay_objs = [get_assay(dt) for dt in data_types]
assay_names = [assay.name for assay in assay_objs]
hints = [hint for assay in assay_objs for hint in assay.vitessce_hints]
def get_ancestor_assaytypes(entity, get_assaytype):
return [get_assaytype(ancestor).get('assaytype')
for ancestor
in entity.get('immediate_ancestors')]


# This function is the main entrypoint for the builder factory.
# It returns the correct builder for the given entity.
#
# The entity is a dict that contains the entity UUID and metadata.
# `get_assaytype` is a function which takes an entity UUID and returns
# a dict containing the assaytype and vitessce-hints for that entity.
def get_view_config_builder(entity, get_assaytype):
if (entity.get('uuid') is None):
raise ValueError("Provided entity does not have a uuid")
assay = get_assaytype(entity)
assay_name = assay.get('assaytype')
hints = assay.get('vitessce-hints', [])

dag_provenance_list = entity.get('metadata', {}).get('dag_provenance_list', [])
dag_names = [dag['name']
for dag in dag_provenance_list if 'name' in dag]
if "is_image" in hints:
if 'sprm' in hints and 'anndata' in hints:
# e.g. CellDIVE [DeepCell + SPRM]
# sample entity: c3be5650e93907b68ddbdb22b948db32
return MultiImageSPRMAnndataViewConfBuilder
if "codex" in hints:
if ('sprm-to-anndata.cwl' in dag_names):
# e.g. 'CODEX [Cytokit + SPRM]
# sample entity: 43213991a54ce196d406707ffe2e86bd
return StitchedCytokitSPRMViewConfBuilder
# Cannot find an example of this in the wild, every CODEX entity has the
# sprm-to-anndata.cwl in its dag_provenance_list
return TiledSPRMViewConfBuilder
# Both SeqFISH and IMS were submitted very early on, before the
# special image pyramid datasets existed. Their assay names should be in
# the `entity["data_types"]` while newer ones, like NanoDESI, are in the parents
if SEQFISH in assay_names:
# Check types of image pyramid ancestors to determine which builder to use
ancestor_assaytypes = get_ancestor_assaytypes(entity, get_assaytype)
# e.g. c6a254b2dc2ed46b002500ade163a7cc
if SEQFISH in [assaytype for assaytype in ancestor_assaytypes]:
return SeqFISHViewConfBuilder
if MALDI_IMS in assay_names:
# e.g. 3bc3ad124014a632d558255626bf38c9
if MALDI_IMS in [assaytype for assaytype in ancestor_assaytypes]:
return IMSViewConfBuilder
if NANODESI in [dt for e in entity["immediate_ancestors"] for dt in e["data_types"]]:
# e.g. 6b93107731199733f266bbd0f3bc9747
if NANODESI in [assaytype for assaytype in ancestor_assaytypes]:
return NanoDESIViewConfBuilder
# e.g. f9ae931b8b49252f150d7f8bf1d2d13f
return ImagePyramidViewConfBuilder
if "rna" in hints:
# This is the zarr-backed anndata pipeline.
if "anndata-to-ui.cwl" in dag_names:
if "salmon_rnaseq_slideseq" in data_types:
if assay_name == SALMON_RNASSEQ_SLIDE:
# e.g. 2a590db3d7ab1e1512816b165d95cdcf
return SpatialRNASeqAnnDataZarrViewConfBuilder
# e.g. e65175561b4b17da5352e3837aa0e497
return RNASeqAnnDataZarrViewConfBuilder
# e.g. c019a1cd35aab4d2b4a6ff221e92aaab
return RNASeqViewConfBuilder
if "atac" in hints:
# e.g. d4493657cde29702c5ed73932da5317c
return ATACSeqViewConfBuilder
# any entity with no hints, e.g. 2c2179ea741d3bbb47772172a316a2bf
return NullViewConfBuilder


def has_visualization(entity, get_assay):
builder = get_view_config_builder(entity, get_assay)
def has_visualization(entity, get_assaytype):
builder = get_view_config_builder(entity, get_assaytype)
return builder != NullViewConfBuilder
20 changes: 10 additions & 10 deletions src/vis-preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@

import requests

from hubmap_commons.type_client import TypeClient

from portal_visualization.builder_factory import get_view_config_builder


def main(): # pragma: no cover
defaults = json.load((Path(__file__).parent / 'defaults.json').open())
types_default_url = defaults['types_url']
assets_default_url = defaults['assets_url']
assaytypes_default_url = defaults['assaytypes_url']

parser = argparse.ArgumentParser(description='''
Given HuBMAP Dataset JSON, generate a Vitessce viewconf, and load vitessce.io.''')
Expand All @@ -28,9 +26,9 @@ def main(): # pragma: no cover
'--json', type=Path, help='File containing Dataset JSON')

parser.add_argument(
'--types_url', metavar='URL',
help=f'Type service; default: {types_default_url}',
default=types_default_url)
'--assaytypes_url', metavar='URL',
help=f'AssayType service; default: {assaytypes_default_url}',
default=assaytypes_default_url)
parser.add_argument(
'--assets_url', metavar='URL',
help=f'Assets endpoint; default: {assets_default_url}',
Expand Down Expand Up @@ -60,11 +58,13 @@ def main(): # pragma: no cover
json_str = args.json.read_text()
entity = json.loads(json_str)

def get_assay(name):
type_client = TypeClient(args.types_url)
return type_client.getAssayType(name)
def get_assaytype(uuid):
headers = {}
if args.token:
headers['Authorization'] = f'Bearer {args.token}'
requests.get(f'{defaults["assaytypes_url"]}/{uuid}', headers=headers).json()

Builder = get_view_config_builder(entity=entity, get_assay=get_assay)
Builder = get_view_config_builder(entity, get_assaytype)
builder = Builder(entity, args.token, args.assets_url)
print(f'Using: {builder.__class__.__name__}', file=stderr)
conf_cells = builder.get_conf_cells(marker=marker)
Expand Down
11 changes: 11 additions & 0 deletions test/assaytype-fixtures/04e7385339167e541ad42a2636e18398.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"assaytype": "codex_cytokit_v1",
"contains-pii": false,
"description": "CODEX [Cytokit + SPRM]",
"primary": false,
"vitessce-hints": [
"codex",
"is_image",
"is_tiled"
]
}
10 changes: 10 additions & 0 deletions test/assaytype-fixtures/210d118a14c8624b6bb9610a9062656e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"assaytype": "sn_atac_seq",
"contains-pii": false,
"description": "snATAC-seq [SnapATAC]",
"primary": false,
"vitessce-hints": [
"is_sc",
"atac"
]
}
10 changes: 10 additions & 0 deletions test/assaytype-fixtures/2a590db3d7ab1e1512816b165d95cdcf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"assaytype": "salmon_rnaseq_slideseq",
"contains-pii": false,
"description": "Slide-seq [Salmon]",
"primary": false,
"vitessce-hints": [
"is_sc",
"rna"
]
}
9 changes: 9 additions & 0 deletions test/assaytype-fixtures/2c2179ea741d3bbb47772172a316a2bf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"assaytype": "bulk-RNA",
"contains-pii": true,
"description": "Bulk RNA-seq",
"dir-schema": "bulkrnaseq-v0",
"primary": true,
"tbl-schema": "bulkrnaseq-v0",
"vitessce-hints": []
}
11 changes: 11 additions & 0 deletions test/assaytype-fixtures/3bc3ad124014a632d558255626bf38c9.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"assaytype": "MALDI-IMS",
"contains-pii": false,
"description": "MALDI IMS",
"dir-schema": "ims-v0",
"primary": true,
"tbl-schema": "ims-v2",
"vitessce-hints": [
"maldi"
]
}
11 changes: 11 additions & 0 deletions test/assaytype-fixtures/43213991a54ce196d406707ffe2e86bd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"assaytype": "codex_cytokit_v1",
"contains-pii": false,
"description": "CODEX [Cytokit + SPRM]",
"primary": false,
"vitessce-hints": [
"codex",
"is_image",
"is_tiled"
]
}
9 changes: 9 additions & 0 deletions test/assaytype-fixtures/6b93107731199733f266bbd0f3bc9747.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"assaytype": "NanoDESI",
"contains-pii": false,
"description": "NanoDESI",
"dir-schema": "ims-v0",
"primary": true,
"tbl-schema": "ims-v2",
"vitessce-hints": []
}
11 changes: 11 additions & 0 deletions test/assaytype-fixtures/9db61adfc017670a196ea9b3ca1852a0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"assaytype": "image_pyramid",
"contains-pii": false,
"description": "Image Pyramid",
"primary": false,
"vitessce-hints": [
"is_image",
"pyramid",
"is_support"
]
}
11 changes: 11 additions & 0 deletions test/assaytype-fixtures/a6116772446f6d1c1f6b3d2e9735cfe0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"assaytype": "image_pyramid",
"contains-pii": false,
"description": "Image Pyramid",
"primary": false,
"vitessce-hints": [
"is_image",
"pyramid",
"is_support"
]
}
10 changes: 10 additions & 0 deletions test/assaytype-fixtures/c019a1cd35aab4d2b4a6ff221e92aaab.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"assaytype": "salmon_sn_rnaseq_10x",
"contains-pii": false,
"description": "snRNA-seq [Salmon]",
"primary": false,
"vitessce-hints": [
"is_sc",
"rna"
]
}
12 changes: 12 additions & 0 deletions test/assaytype-fixtures/c3be5650e93907b68ddbdb22b948db32.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"assaytype": "celldive_deepcell",
"contains-pii": false,
"description": "CellDIVE [DeepCell + SPRM]",
"primary": false,
"vitessce-hints": [
"sprm",
"anndata",
"is_image",
"is_tiled"
]
}
9 changes: 9 additions & 0 deletions test/assaytype-fixtures/c6a254b2dc2ed46b002500ade163a7cc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"assaytype": "seqFish",
"contains-pii": false,
"description": "seqFISH",
"dir-schema": "seqfish-v0",
"primary": true,
"tbl-schema": "seqfish-v0",
"vitessce-hints": []
}
10 changes: 10 additions & 0 deletions test/assaytype-fixtures/d4493657cde29702c5ed73932da5317c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"assaytype": "sc_atac_seq_sci",
"contains-pii": false,
"description": "sciATAC-seq [SnapATAC]",
"primary": false,
"vitessce-hints": [
"is_sc",
"atac"
]
}
11 changes: 11 additions & 0 deletions test/assaytype-fixtures/e1c4370da5523ab5c9be581d1d76ca20.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"assaytype": "image_pyramid",
"contains-pii": false,
"description": "Image Pyramid",
"primary": false,
"vitessce-hints": [
"is_image",
"pyramid",
"is_support"
]
}
10 changes: 10 additions & 0 deletions test/assaytype-fixtures/e65175561b4b17da5352e3837aa0e497.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"assaytype": "salmon_sn_rnaseq_10x",
"contains-pii": false,
"description": "snRNA-seq [Salmon]",
"primary": false,
"vitessce-hints": [
"is_sc",
"rna"
]
}
10 changes: 10 additions & 0 deletions test/assaytype-fixtures/ea4cfecb8495b36694d9a951510dc3c6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"assaytype": "salmon_rnaseq_slideseq",
"contains-pii": false,
"description": "Slide-seq [Salmon]",
"primary": false,
"vitessce-hints": [
"is_sc",
"rna"
]
}
Loading

0 comments on commit 2db9bbc

Please sign in to comment.