From 5bae21e2b04cf86efa9ad44b30d6c25e21975f22 Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Mon, 16 Mar 2026 15:09:05 -0400 Subject: [PATCH 1/5] Add `spatial` field for datasets with `spatial` hint --- .../portal/add_assay_details.py | 4 ++ .../portal/tests/test_assay_details.py | 51 +++++++++++++++++++ src/search-adaptor | 2 +- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py index e06aab78..80a7ab76 100644 --- a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py +++ b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py @@ -211,6 +211,10 @@ def get_assay_type_for_viz(doc): # Check if the main entity can be visualized by portal-visualization. doc['visualization'] = has_visualization(doc, get_assay_type_for_viz) + # Set the 'spatial' field for search based off of the presence of the 'spatial' hint + if ('spatial' in assay_details.get('vitessce-hints', [])): + doc['spatial'] = True + if not doc['visualization']: # If an entity doesn't have a visualization, # check its descendants for a supporting image pyramid. diff --git a/src/hubmap_translation/addl_index_transformations/portal/tests/test_assay_details.py b/src/hubmap_translation/addl_index_transformations/portal/tests/test_assay_details.py index dae5872c..ddcd1d28 100644 --- a/src/hubmap_translation/addl_index_transformations/portal/tests/test_assay_details.py +++ b/src/hubmap_translation/addl_index_transformations/portal/tests/test_assay_details.py @@ -125,6 +125,57 @@ def test_processed_dataset_type(mocker): assert input_processed_doc == output_processed_doc +def mock_spatial_soft_assay(uuid=None, headers=None): + return mock_response({ + "assaytype": "salmon_rnaseq_sciseq", + "contains-pii": True, + "pipeline-shorthand": "Salmon", + "description": "sciRNA-seq [Salmon]", + "primary": False, + "vitessce-hints": [ + "is_sc", + "rna", + "spatial" + ] + }) + + +def test_spatial_dataset_type(mocker): + mocker.patch('requests.get', side_effect=[ + mock_spatial_soft_assay(), + mock_empty_descendants()]) + input_processed_doc = { + 'uuid': '22684b9011fc5aea5cb3f89670a461e8', + 'dataset_type': 'RNAseq [Salmon]', + 'entity_type': 'Dataset', + 'creation_action': 'Central Process' + } + + output_processed_doc = { + 'assay_display_name': ['sciRNA-seq [Salmon]'], + 'dataset_type': 'RNAseq [Salmon]', + 'entity_type': 'Dataset', + 'mapped_data_types': ['sciRNA-seq [Salmon]'], + 'pipeline': 'Salmon', + 'raw_dataset_type': 'RNAseq', + 'assay_modality': 'single', + 'creation_action': 'Central Process', + 'processing': 'processed', + 'processing_type': 'hubmap', + 'uuid': '22684b9011fc5aea5cb3f89670a461e8', + 'soft_assaytype': 'salmon_rnaseq_sciseq', + 'vitessce-hints': [ + "is_sc", + "rna", + "spatial" + ], + 'visualization': True, + 'spatial': True, + } + add_assay_details(input_processed_doc, mock_transformation_resources) + assert input_processed_doc == output_processed_doc + + def mock_empty_soft_assay(uuid=None, headers=None): return mock_response({}) diff --git a/src/search-adaptor b/src/search-adaptor index 386a117d..b4065ed4 160000 --- a/src/search-adaptor +++ b/src/search-adaptor @@ -1 +1 @@ -Subproject commit 386a117dc361d3aae55004a07e6d5b101a6ecc92 +Subproject commit b4065ed491c30f58e90f17e477fed419a725f84e From 7948392a0db826692377db0acdb5b49bcd746bac Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Mon, 16 Mar 2026 15:30:50 -0400 Subject: [PATCH 2/5] update search-adaptor commit hash --- src/search-adaptor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search-adaptor b/src/search-adaptor index b4065ed4..5aae76e2 160000 --- a/src/search-adaptor +++ b/src/search-adaptor @@ -1 +1 @@ -Subproject commit b4065ed491c30f58e90f17e477fed419a725f84e +Subproject commit 5aae76e2a50039ed8592877a98d880389925ca90 From 1e70906a9d1d27254871fa446cf9075c2cf5b16c Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Mon, 16 Mar 2026 15:48:14 -0400 Subject: [PATCH 3/5] Exclude multi-assay split descendants from descendants responses --- .../addl_index_transformations/portal/add_assay_details.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py index 80a7ab76..cf234ff6 100644 --- a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py +++ b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py @@ -122,7 +122,9 @@ def _get_descendants(doc, transformation_resources): response = requests.get( f'{descendants_url}/{uuid}', headers={'Authorization': f'Bearer {token}'}) response.raise_for_status() - return response.json() + descendants = response.json() + # Filter any multi-assay split descendants - these are component datasets that should not be considered for visualization purposes. + descendants = [descendant for descendant in descendants if descendant.get('creation_action') != CreationAction.MULTI_ASSAY_SPLIT] except requests.exceptions.HTTPError as e: logger.error(e.response.text) raise From f2d1ca4d7ca9eb31e39a5815319525ae7aff3c7e Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Mon, 16 Mar 2026 16:07:02 -0400 Subject: [PATCH 4/5] move filtering to be done in the add_assay_details function itself --- .../portal/add_assay_details.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py index cf234ff6..e46262a9 100644 --- a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py +++ b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py @@ -122,9 +122,7 @@ def _get_descendants(doc, transformation_resources): response = requests.get( f'{descendants_url}/{uuid}', headers={'Authorization': f'Bearer {token}'}) response.raise_for_status() - descendants = response.json() - # Filter any multi-assay split descendants - these are component datasets that should not be considered for visualization purposes. - descendants = [descendant for descendant in descendants if descendant.get('creation_action') != CreationAction.MULTI_ASSAY_SPLIT] + return response.json() except requests.exceptions.HTTPError as e: logger.error(e.response.text) raise @@ -231,9 +229,9 @@ def get_assay_type_for_descendants(descendant): uuid = descendant return _get_assay_details_by_uuid(uuid, transformation_resources) - # Filter any unpublished/non-QA descendants + # Filter any unpublished/non-QA descendants and multi-assay splits descendants = [descendant for descendant in descendants if [ - 'Published', 'QA'].count(descendant.get('status')) > 0] + 'Published', 'QA'].count(descendant.get('status')) > 0 and descendant.get('creation_action') != CreationAction.MULTI_ASSAY_SPLIT] # Sort by the descendant's last modified timestamp, descending descendants.sort( key=lambda x: x['last_modified_timestamp'], From 0d169e6a94534da7231c05f38d48ed408ae4761a Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Wed, 25 Mar 2026 10:08:06 -0400 Subject: [PATCH 5/5] Fix backwards has_visualization call --- .../addl_index_transformations/portal/add_assay_details.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py index e46262a9..837f7f5a 100644 --- a/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py +++ b/src/hubmap_translation/addl_index_transformations/portal/add_assay_details.py @@ -254,6 +254,6 @@ def get_assay_type_for_descendants(descendant): _set_soft_assaytype(parent, parent_assay_info) - if has_visualization(parent, get_assay_type_for_viz): + if has_visualization(doc, get_assay_type_for_viz, parent): doc['visualization'] = True break