From ebc41a4e0dc822ac5ee406f9ccc66742aded782a Mon Sep 17 00:00:00 2001 From: Lisa-Ann B <115558393+libpitt@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:14:00 -0400 Subject: [PATCH 1/8] Update methods for hierarchy --- src/lib/ontology.py | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/lib/ontology.py b/src/lib/ontology.py index 9f28293c..be4a5eca 100644 --- a/src/lib/ontology.py +++ b/src/lib/ontology.py @@ -21,9 +21,50 @@ def organs_by_organ_uberon(cls: Ontology) -> dict: return cls.ops( as_data_dict=True, prop_callback=None, data_as_val=True, key="organ_uberon" ).organ_types() + + + @classmethod + def dataset_types_hierarchy(cls: Ontology, dataset_type: str = None) -> dict: + def prop_callback(dict): + return dict['dataset_type']['name'] + + def val_callback(dict): + if 'modalities' not in dict: + return [] + + list_of_facets = [] + for modality in dict['modalities']: + for analyte in modality['analytes']: + list_of_facets.append({ + "modality": modality['name'], + "analyte": analyte['name'], + "dataset_type": dict['dataset_type']['name'] + }) + return list_of_facets + + all_facets = cls.ops( + as_data_dict=True, prop_callback=prop_callback, val_callback=val_callback, data_as_val=False, key="dataset_types", val_key="dataset_types" + ).transform_ontology(current_app.ubkg.dataset_types_hierarchy, 'DatasetTypesHierarchy') + + if dataset_type is not None and dataset_type in all_facets: + matrix = all_facets[dataset_type] + else: + matrix = list(all_facets.values()) + + return [item for sublist in matrix for item in sublist] @classmethod def dataset_type_hierarchy(cls: Ontology) -> dict: + def prop_callback(dict): + return dict['dataset_type']['name'] + + def val_callback(dict): + modalities = [] + if 'modalities' in dict: + for modality in dict['modalities']: + modalities.append(modality['name']) + return modalities + return cls.ops( - as_data_dict=True, prop_callback=None, data_as_val=False, key="dataset_type", val_key="dataset_modalities" - ).dataset_types() + as_data_dict=True, prop_callback=prop_callback, val_callback=val_callback, data_as_val=False, key="dataset_type", val_key="dataset_modalities" + ).transform_ontology(current_app.ubkg.dataset_types_hierarchy, 'DatasetTypesHierarchy') From 184975b1a86481bf4bff07a14a840e3e9e9a7214 Mon Sep 17 00:00:00 2001 From: Lisa-Ann B <115558393+libpitt@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:04:55 -0400 Subject: [PATCH 2/8] Update schema trigger - #961 --- src/lib/ontology.py | 31 +++++++++---------------------- src/schema/schema_triggers.py | 25 ++++++++----------------- 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/src/lib/ontology.py b/src/lib/ontology.py index be4a5eca..52c45e03 100644 --- a/src/lib/ontology.py +++ b/src/lib/ontology.py @@ -19,12 +19,15 @@ def modify_entities_cache(): @classmethod def organs_by_organ_uberon(cls: Ontology) -> dict: return cls.ops( - as_data_dict=True, prop_callback=None, data_as_val=True, key="organ_uberon" + as_data_dict=True, key_callback=None, data_as_val=True, key="organ_uberon" ).organ_types() + @classmethod + def dataset_types_hierarchy(cls: Ontology): + return UbkgSDK.transform_ontology(current_app.ubkg.dataset_types_hierarchy, 'DatasetTypesHierarchy') @classmethod - def dataset_types_hierarchy(cls: Ontology, dataset_type: str = None) -> dict: + def dataset_type_hierarchy(cls: Ontology, dataset_type: str = None) -> dict: def prop_callback(dict): return dict['dataset_type']['name'] @@ -43,28 +46,12 @@ def val_callback(dict): return list_of_facets all_facets = cls.ops( - as_data_dict=True, prop_callback=prop_callback, val_callback=val_callback, data_as_val=False, key="dataset_types", val_key="dataset_types" - ).transform_ontology(current_app.ubkg.dataset_types_hierarchy, 'DatasetTypesHierarchy') + as_data_dict=True, key_callback=prop_callback, val_callback=val_callback, data_as_val=False, key="dataset_types", val_key="dataset_types" + ).dataset_types_hierarchy() if dataset_type is not None and dataset_type in all_facets: - matrix = all_facets[dataset_type] + return all_facets[dataset_type] else: matrix = list(all_facets.values()) - return [item for sublist in matrix for item in sublist] - - @classmethod - def dataset_type_hierarchy(cls: Ontology) -> dict: - def prop_callback(dict): - return dict['dataset_type']['name'] - - def val_callback(dict): - modalities = [] - if 'modalities' in dict: - for modality in dict['modalities']: - modalities.append(modality['name']) - return modalities - - return cls.ops( - as_data_dict=True, prop_callback=prop_callback, val_callback=val_callback, data_as_val=False, key="dataset_type", val_key="dataset_modalities" - ).transform_ontology(current_app.ubkg.dataset_types_hierarchy, 'DatasetTypesHierarchy') + return [item for sublist in matrix for item in sublist] \ No newline at end of file diff --git a/src/schema/schema_triggers.py b/src/schema/schema_triggers.py index bab3bab5..b02158c1 100644 --- a/src/schema/schema_triggers.py +++ b/src/schema/schema_triggers.py @@ -1844,7 +1844,7 @@ def get_dataset_title(property_key, normalized_type, user_token, existing_data_d # the threshold, we will just use the number in the title. organs_description_phrase = f"{len(organ_abbrev_set)} organs" organ_types_dict = Ontology.ops( - as_data_dict=True, prop_callback=None, key="organ_uberon", val_key="term" + as_data_dict=True, key_callback=None, key="organ_uberon", val_key="term" ).organ_types() if len(organ_abbrev_set) <= MAX_ENTITY_LIST_LENGTH: @@ -2029,7 +2029,7 @@ def get_display_subtype( ): if "organ" in existing_data_dict: organ_types = Ontology.ops( - as_data_dict=True, prop_callback=None, key="organ_uberon", val_key="term" + as_data_dict=True, key_callback=None, key="organ_uberon", val_key="term" ).organ_types() display_subtype = get_val_by_key( existing_data_dict["organ"], organ_types, "ubkg.organ_types" @@ -2042,7 +2042,7 @@ def get_display_subtype( else: sample_categories = Ontology.ops( - as_data_dict=True, prop_callback=None + as_data_dict=True, key_callback=None ).specimen_categories() display_subtype = get_val_by_key( existing_data_dict["sample_category"], @@ -3995,7 +3995,7 @@ def _get_organ_description(organ_code): str: The organ code description """ ORGAN_TYPES = Ontology.ops( - as_arr=False, prop_callback=None, as_data_dict=True, data_as_val=True + as_arr=False, key_callback=None, as_data_dict=True, data_as_val=True ).organ_types() for key in ORGAN_TYPES: @@ -4318,7 +4318,7 @@ def get_organ_hierarchy( organ_hierarchy = None if equals(existing_data_dict["sample_category"], "organ"): organ_types_categories = Ontology.ops( - as_data_dict=True, prop_callback=None, key="organ_uberon", val_key="category" + as_data_dict=True, key_callback=None, key="organ_uberon", val_key="category" ).organ_types() organ_hierarchy = existing_data_dict["organ"] @@ -4326,7 +4326,7 @@ def get_organ_hierarchy( return property_key, organ_types_categories[organ_hierarchy]["term"] organ_types = Ontology.ops( - as_data_dict=True, prop_callback=None, key="organ_uberon", val_key="term" + as_data_dict=True, key_callback=None, key="organ_uberon", val_key="term" ).organ_types() if existing_data_dict["organ"] in organ_types: organ_name = organ_types[organ_hierarchy] @@ -4368,17 +4368,8 @@ def get_dataset_type_hierarchy( """ if equals(existing_data_dict["entity_type"], "Dataset"): - dataset_type_hierarchy = Ontology.dataset_type_hierarchy() - if existing_data_dict["dataset_type"] not in dataset_type_hierarchy: - return property_key, { - "first_level": existing_data_dict["dataset_type"], - "second_level": existing_data_dict["dataset_type"], - } - - return property_key, { - "first_level": dataset_type_hierarchy[existing_data_dict["dataset_type"]], - "second_level": existing_data_dict["dataset_type"], - } + dataset_type_hierarchy = Ontology.dataset_type_hierarchy(dataset_type=existing_data_dict["dataset_type"]) + return property_key, dataset_type_hierarchy else: return property_key, None From f51ba9d035b0b45b859dc8c4f2fd7f7bbde68ac1 Mon Sep 17 00:00:00 2001 From: Lisa-Ann B <115558393+libpitt@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:40:41 -0400 Subject: [PATCH 3/8] Add missing commit --- src/app.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app.py b/src/app.py index 862a42d5..a5062952 100644 --- a/src/app.py +++ b/src/app.py @@ -4160,7 +4160,7 @@ def get_prov_info(): HEADER_PROCESSED_DATASET_STATUS = "processed_dataset_status" HEADER_PROCESSED_DATASET_PORTAL_URL = "processed_dataset_portal_url" ORGAN_TYPES = Ontology.ops( - as_data_dict=True, data_as_val=True, val_key="organ_uberon", prop_callback=None + as_data_dict=True, data_as_val=True, val_key="organ_uberon", key_callback=None ).organ_types() HEADER_PREVIOUS_VERSION_SENNET_IDS = "previous_version_sennet_ids" @@ -4536,7 +4536,7 @@ def get_prov_info_for_dataset(id): HEADER_PROCESSED_DATASET_PORTAL_URL = "processed_dataset_portal_url" HEADER_DATASET_SAMPLES = "dataset_samples" ORGAN_TYPES = Ontology.ops( - as_data_dict=True, data_as_val=True, val_key="organ_uberon", prop_callback=None + as_data_dict=True, data_as_val=True, val_key="organ_uberon", key_callback=None ).organ_types() headers = [ @@ -4781,7 +4781,7 @@ def get_sample_prov_info(): HEADER_ORGAN_TYPE = "organ_type" HEADER_ORGAN_SENNET_ID = "organ_sennet_id" ORGAN_TYPES = Ontology.ops( - as_data_dict=True, data_as_val=True, val_key="organ_uberon", prop_callback=None + as_data_dict=True, data_as_val=True, val_key="organ_uberon", key_callback=None ).organ_types() # Processing and validating query parameters @@ -6754,7 +6754,7 @@ def verify_ubkg_properties(json_data_dict): SOURCE_TYPES = Ontology.ops(as_data_dict=True).source_types() SAMPLE_CATEGORIES = Ontology.ops(as_data_dict=True).specimen_categories() ORGAN_TYPES = Ontology.ops( - as_data_dict=True, key="organ_uberon", prop_callback=None + as_data_dict=True, key="organ_uberon", key_callback=None ).organ_types() DATASET_TYPE = Ontology.ops(as_data_dict=True).dataset_types() @@ -6849,7 +6849,7 @@ def check_multiple_organs_constraint( ) if count >= 1: organ_codes = Ontology.ops( - as_data_dict=True, val_key="term", key="organ_uberon", prop_callback=None + as_data_dict=True, val_key="term", key="organ_uberon", key_callback=None ).organ_types() organ = organ_codes[organ_code] abort_bad_req( From c3e4bbc5c7607ed2abc4a142347c7a5b65e0dc58 Mon Sep 17 00:00:00 2001 From: Lisa-Ann B <115558393+libpitt@users.noreply.github.com> Date: Mon, 22 Jun 2026 15:01:08 -0400 Subject: [PATCH 4/8] Update with ubkg updates --- src/lib/ontology.py | 8 ++------ src/requirements.txt | 4 +++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/lib/ontology.py b/src/lib/ontology.py index 52c45e03..b131f599 100644 --- a/src/lib/ontology.py +++ b/src/lib/ontology.py @@ -21,15 +21,11 @@ def organs_by_organ_uberon(cls: Ontology) -> dict: return cls.ops( as_data_dict=True, key_callback=None, data_as_val=True, key="organ_uberon" ).organ_types() - - @classmethod - def dataset_types_hierarchy(cls: Ontology): - return UbkgSDK.transform_ontology(current_app.ubkg.dataset_types_hierarchy, 'DatasetTypesHierarchy') @classmethod def dataset_type_hierarchy(cls: Ontology, dataset_type: str = None) -> dict: def prop_callback(dict): - return dict['dataset_type']['name'] + return dict['name'] def val_callback(dict): if 'modalities' not in dict: @@ -46,7 +42,7 @@ def val_callback(dict): return list_of_facets all_facets = cls.ops( - as_data_dict=True, key_callback=prop_callback, val_callback=val_callback, data_as_val=False, key="dataset_types", val_key="dataset_types" + as_data_dict=True, key_callback=prop_callback, val_callback=val_callback, data_as_val=True, ).dataset_types_hierarchy() if dataset_type is not None and dataset_type in all_facets: diff --git a/src/requirements.txt b/src/requirements.txt index 745aa265..94b9261a 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,3 +1,5 @@ +--extra-index-url https://test.pypi.org/simple/ + Flask==3.1.3 prov==2.0.1 @@ -19,7 +21,7 @@ neo4j==5.28.1 # Default is main branch specified in docker-compose.development.yml if not set # git+https://github.com/hubmapconsortium/commons.git@${COMMONS_BRANCH}#egg=hubmap-commons hubmap-commons==2.1.21 -atlas-consortia-commons==1.1.5 +atlas-consortia-commons==1.1.7a0 #git+https://github.com/x-atlas-consortia/commons.git@{COMMONS_BRANCH}#egg=atlas_consortia_commons deepdiff==8.6.2 From b8637c41a564c0de8f7cd2af557eab70ad771cdb Mon Sep 17 00:00:00 2001 From: Lisa-Ann B <115558393+libpitt@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:01:27 -0400 Subject: [PATCH 5/8] Only set for primary - #961 --- src/schema/schema_triggers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema/schema_triggers.py b/src/schema/schema_triggers.py index b02158c1..a4aaf8dc 100644 --- a/src/schema/schema_triggers.py +++ b/src/schema/schema_triggers.py @@ -4367,7 +4367,7 @@ def get_dataset_type_hierarchy( dict: The dataset type hierarchy with keys of 'first_level' and 'second_level' """ - if equals(existing_data_dict["entity_type"], "Dataset"): + if equals(existing_data_dict["entity_type"], "Dataset") and equals(existing_data_dict["creation_action"], "Create Dataset Activity"): dataset_type_hierarchy = Ontology.dataset_type_hierarchy(dataset_type=existing_data_dict["dataset_type"]) return property_key, dataset_type_hierarchy else: From e6786cc5aed5d51114b6c6764f3e67cd655d18a1 Mon Sep 17 00:00:00 2001 From: Lisa-Ann B <115558393+libpitt@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:28:37 -0400 Subject: [PATCH 6/8] Set default return - #961 --- src/lib/ontology.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lib/ontology.py b/src/lib/ontology.py index b131f599..5ef06b2d 100644 --- a/src/lib/ontology.py +++ b/src/lib/ontology.py @@ -45,8 +45,15 @@ def val_callback(dict): as_data_dict=True, key_callback=prop_callback, val_callback=val_callback, data_as_val=True, ).dataset_types_hierarchy() - if dataset_type is not None and dataset_type in all_facets: - return all_facets[dataset_type] + if dataset_type is not None: + if dataset_type in all_facets: + return all_facets[dataset_type] + else: + return [{ + "modality": 'N/A', + "analyte": 'N/A', + "dataset_type": dataset_type + }] else: matrix = list(all_facets.values()) From 60e59a89b5909437821a882be6665bddfe6ba9fb Mon Sep 17 00:00:00 2001 From: Lisa-Ann B <115558393+libpitt@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:52:20 -0400 Subject: [PATCH 7/8] Update requirements - #961 --- src/requirements.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/requirements.txt b/src/requirements.txt index 94b9261a..b95d964b 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,5 +1,3 @@ ---extra-index-url https://test.pypi.org/simple/ - Flask==3.1.3 prov==2.0.1 @@ -21,7 +19,7 @@ neo4j==5.28.1 # Default is main branch specified in docker-compose.development.yml if not set # git+https://github.com/hubmapconsortium/commons.git@${COMMONS_BRANCH}#egg=hubmap-commons hubmap-commons==2.1.21 -atlas-consortia-commons==1.1.7a0 +atlas-consortia-commons==1.1.7 #git+https://github.com/x-atlas-consortia/commons.git@{COMMONS_BRANCH}#egg=atlas_consortia_commons deepdiff==8.6.2 From 7ecae4d0e340ac689a67d8db024dae8c58d6b8d3 Mon Sep 17 00:00:00 2001 From: maxsibilla Date: Tue, 23 Jun 2026 15:58:56 -0400 Subject: [PATCH 8/8] Bumping hubmap commons --- src/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/requirements.txt b/src/requirements.txt index b95d964b..99c4e8ab 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -18,7 +18,7 @@ neo4j==5.28.1 # Use the branch name of commons from github for testing new changes made in commons from different branch # Default is main branch specified in docker-compose.development.yml if not set # git+https://github.com/hubmapconsortium/commons.git@${COMMONS_BRANCH}#egg=hubmap-commons -hubmap-commons==2.1.21 +hubmap-commons==2.1.26 atlas-consortia-commons==1.1.7 #git+https://github.com/x-atlas-consortia/commons.git@{COMMONS_BRANCH}#egg=atlas_consortia_commons