diff --git a/bia-ingest-shared-models/bia_ingest_sm/conversion.py b/bia-ingest-shared-models/bia_ingest_sm/conversion.py index 0b8d9f83..fd8ee33b 100644 --- a/bia-ingest-shared-models/bia_ingest_sm/conversion.py +++ b/bia-ingest-shared-models/bia_ingest_sm/conversion.py @@ -1,11 +1,89 @@ import re import hashlib import uuid -from typing import List, Any, Dict, Optional, Tuple +from typing import List, Any, Dict, Optional, Tuple, Type +from pydantic import BaseModel from .biostudies import Submission, attributes_to_dict, Section, Attribute from src.bia_models import bia_data_model, semantic_models +def get_experimental_imaging_dataset(submission: Submission) -> List[bia_data_model.ExperimentalImagingDataset]: + """Map biostudies.Submission study components to bia_data_model.ExperimentalImagingDataset + + """ + study_components = find_sections_recursive(submission.section, ["Study Component",], []) + analysis_method_dict = get_image_analysis_method(submission) + + # TODO: Need to persist this (API finally, but initially to disk) + biosamples_in_submission = get_biosample(submission) + + # Index biosamples by title_id. Makes linking with associations more + # straight forward. + # Use for loop instead of dict comprehension to allow biosamples with + # same title to form list + biosamples_in_submission_uuid = {} + for biosample in get_biosample(submission): + if biosample.title_id in biosamples_in_submission_uuid: + biosamples_in_submission_uuid[biosample.title_id].append(biosample.uuid) + else: + biosamples_in_submission_uuid[biosample.title_id] = [biosample.uuid,] + + experimental_imaging_dataset = [] + for section in study_components: + attr_dict = attributes_to_dict(section.attributes) + key_mapping = [ + ("biosample", "Biosample", None,), + ("specimen", "Specimen", None,), + ("image_acquisition", "Image acquisition", None,), + ("image_analysis", "Image analysis", None,), + ("image_correlation", "Image correlation", None,), + ] + associations = get_generic_section_as_list(section, ["Associations",], key_mapping) + + analysis_method_list = [] + biosample_list = [] + image_acquisition_method_list = [] + correlation_method_list = [] + specimen_preparation_method_list = [] + + if len(associations) > 0: + # Image Analysis Method + analysis_methods_from_associations = [a.get("image_analysis") for a in associations] + for analysis_method in analysis_method_dict.values(): + if analysis_method.method_description in analysis_methods_from_associations: + analysis_method_list.append(analysis_method) + + # Biosample + biosamples_from_associations = [a.get("biosample") for a in associations] + for biosample in biosamples_from_associations: + if biosample in biosamples_in_submission_uuid: + biosample_list.extend(biosamples_in_submission_uuid[biosample]) + + + + model_dict = { + "title_id": attr_dict["Name"], + #"description": attr_dict["Description"], + "submitted_in_study": get_study_uuid(submission), + "file": [], + "image": [], + "specimen_preparation_method": specimen_preparation_method_list, + "acquisition_method": image_acquisition_method_list, + "biological_entity": biosample_list, + "analysis_method": analysis_method_list, + "correlation_method": correlation_method_list, + "file_reference_count": 0, + "image_count": 0, + "example_image_uri": [], + } + # TODO: Add 'description' to computation of uuid (Maybe accno?) + model_dict["uuid"] = dict_to_uuid(model_dict, ["title_id", "submitted_in_study", ]) + experimental_imaging_dataset.append( + bia_data_model.ExperimentalImagingDataset.model_validate(model_dict) + ) + + return experimental_imaging_dataset + def get_study(submission: Submission) -> bia_data_model.Study: """Return an API study model populated from the submission @@ -26,6 +104,7 @@ def get_study(submission: Submission) -> bia_data_model.Study: study_attributes.pop("License") study_dict = { + "uuid": get_study_uuid(submission), "accession_id": submission.accno, # TODO: Do more robust search for title - sometimes it is in # actual submission - see old ingest code @@ -42,12 +121,25 @@ def get_study(submission: Submission) -> bia_data_model.Study: "experimental_imaging_component": [], "annotation_component": [], } - study_uuid = dict_to_uuid(study_dict, ["accession_id",]) - study_dict["uuid"] = study_uuid + #study_uuid = dict_to_uuid(study_dict, ["accession_id",]) + #study_dict["uuid"] = study_uuid study = bia_data_model.Study.model_validate(study_dict) return study +def get_image_analysis_method(submission: Submission) -> Dict[str, semantic_models.ImageAnalysisMethod]: + + key_mapping = [ + ("method_description", "Title", None,), + ("features_analysed", "Image analysis overview", None,), + ] + + return get_generic_section_as_dict( + submission, ["Image analysis",], key_mapping, semantic_models.ImageAnalysisMethod + ) + +def get_study_uuid(submission: Submission) -> str: + return dict_to_uuid({"accession_id": submission.accno}, ["accession_id",]) def study_title_from_submission(submission: Submission) -> str: @@ -75,7 +167,7 @@ def get_external_reference( """Map biostudies.Submission.Link to semantic_models.ExternalReference """ - sections = find_sections_recursive(submission.section, ["links",]) + sections = find_sections_recursive(submission.section, ["links",], []) key_mapping = [ ("link", "url", None), @@ -100,8 +192,7 @@ def get_grant(submission: Submission) -> List[semantic_models.Grant]: ("id", "grant_id", None), ] grant_dict = get_generic_section_as_dict( - submission, ["Funding",], semantic_models.Grant, key_mapping - ) + submission, ["Funding",], key_mapping, semantic_models.Grant ) grant_list = [] for k, v in grant_dict.items(): @@ -118,23 +209,26 @@ def get_funding_body(submission: Submission) -> semantic_models.FundingBody: ("display_name", "Agency", None,), ] funding_body = get_generic_section_as_dict( - submission, ["Funding",], semantic_models.FundingBody, key_mapping + submission, ["Funding",], key_mapping, semantic_models.FundingBody ) return funding_body # TODO: Put comments and docstring def get_generic_section_as_list( - submission: Submission, + root: [Submission|Section], section_name: List[str], - mapped_object: [Any], key_mapping: List[Tuple[str, str, [str | None | List]]], + mapped_object: Optional[Any] = None, mapped_attrs_dict: Optional[Dict[str, Any]] = None, -) -> List[Any]: +) -> List[Any|Dict[str,str|List[str]]]: """Map biostudies.Submission objects to either semantic_models or bia_data_model equivalent """ - sections = find_sections_recursive(submission.section, section_name) + if type(root) is Submission: + sections = find_sections_recursive(root.section, section_name, []) + else: + sections = find_sections_recursive(root, section_name, []) return_list = [] for section in sections: @@ -143,27 +237,36 @@ def get_generic_section_as_list( else: attr_dict = mattributes_to_dict(section.attributes, mapped_attrs_dict) model_dict = {k: attr_dict.get(v, default) for k, v, default in key_mapping} - return_list.append(mapped_object.model_validate(model_dict)) + if mapped_object is None: + return_list.append(model_dict) + else: + return_list.append(mapped_object.model_validate(model_dict)) return return_list # TODO: Put comments and docstring def get_generic_section_as_dict( - submission: Submission, + root: [Submission|Section], section_name: List[str], - mapped_object: [Any], key_mapping: List[Tuple[str, str, [str | None | List]]], -) -> Dict[str, Any]: + mapped_object: Optional[Any]=None, +) -> Dict[str, Any|Dict[str, Dict[str,str|List[str]]]]: """Map biostudies.Submission objects to dict containing either semantic_models or bia_data_model equivalent """ - sections = find_sections_recursive(submission.section, section_name) + if type(root) is Submission: + sections = find_sections_recursive(root.section, section_name, []) + else: + sections = find_sections_recursive(root, section_name, []) return_dict = {} for section in sections: attr_dict = attributes_to_dict(section.attributes) model_dict = {k: attr_dict.get(v, default) for k, v, default in key_mapping} - return_dict[section.accno] = mapped_object.model_validate(model_dict) + if mapped_object is None: + return_dict[section.accno] = model_dict + else: + return_dict[section.accno] = mapped_object.model_validate(model_dict) return return_dict @@ -247,6 +350,90 @@ def get_contributor(submission: Submission) -> List[semantic_models.Contributor] return contributors +# This function instantiates any API model given a dict of its attributes +# Hence the use of the pydantic BaseModel which all API models +# are derived from in the type hinting +def dicts_to_api_models( + dicts: List[Dict[str, Any]], api_model_class: Type[BaseModel] +) -> BaseModel: + + api_models = [] + for model_dict in dicts: + api_models.append(api_model_class.model_validate(model_dict)) + + return api_models + +def get_biosample(submission: Submission) -> List[bia_data_model.BioSample]: + + biosample_model_dicts = extract_biosample_dicts(submission) + biosamples = dicts_to_api_models(biosample_model_dicts, bia_data_model.BioSample) + return biosamples + +def extract_biosample_dicts(submission: Submission) -> List[Dict[str, Any]]: + biosample_sections = find_sections_recursive(submission.section, ["Biosample"], []) + + key_mapping = [ + ("title_id", "Title", ""), + ("description", "Description", ""), + # TODO: discuss adding this to semantic model with FS + #("biological_entity", "Biological entity", ""), + ("organism", "Organism", ""), + ] + + model_dicts = [] + for section in biosample_sections: + attr_dict = attributes_to_dict(section.attributes) + + model_dict = {k: attr_dict.get(v, default) for k, v, default in key_mapping} + + model_dict["accno"] = section.__dict__.get("accno", "") + + # Obtain scientic and common names from organism + organism = model_dict.pop("organism", "") + try: + organism_scientific_name, organism_common_name = organism.split("(") + organism_common_name = organism_common_name.rstrip(")") + except ValueError: + organism_scientific_name = organism + organism_common_name = "" + taxon = semantic_models.Taxon.model_validate({ + "common_name": organism_common_name.strip(), + "scientific_name": organism_scientific_name.strip(), + "ncbi_id": None, + }) + model_dict["organism_classification"] = [ taxon.model_dump() ] + + # Populate intrinsic and extrinsic variables + for api_key, biostudies_key in ( + ("intrinsic_variable_description", "Intrinsic variable"), + ("extrinsic_variable_description", "Extrinsic variable",), + ("experimental_variable_description", "Experimental variable",), + ): + model_dict[api_key] = [] + if biostudies_key in attr_dict: + model_dict[api_key].append(attr_dict[biostudies_key]) + + model_dict["accession_id"] = submission.accno + model_dict["uuid"] = generate_biosample_uuid(model_dict) + model_dicts.append(model_dict) + + return model_dicts + + +def generate_biosample_uuid(biosample_dict: Dict[str, Any]) -> str: + attributes_to_consider = [ + "accession_id", + "accno", + "title_id", + "organism_classification", + "description", + # TODO: Discuss including below in semantic_models.BioSample + #"biological_entity", + "intrinsic_variable_description", + "extrinsic_variable_description", + "experimental_variable_description", + ] + return dict_to_uuid(biosample_dict, attributes_to_consider) def find_sections_recursive( section: Section, search_types: List[str], results: Optional[List[Section]] = [] diff --git a/bia-ingest-shared-models/test/data/S-BIADTEST.json b/bia-ingest-shared-models/test/data/S-BIADTEST.json index bea2a603..e60a14c3 100644 --- a/bia-ingest-shared-models/test/data/S-BIADTEST.json +++ b/bia-ingest-shared-models/test/data/S-BIADTEST.json @@ -170,38 +170,76 @@ "type" : "Biosample", "attributes" : [ { "name" : "Title", - "value" : "Test Biosample " + "value" : "Test Biosample 1" }, { "name" : "Organism", "value" : "Homo sapiens (human)" }, { "name" : "Description", - "value" : "Test description (\"with some escaped chars\") " + "value" : "Test description 1 (\"with some escaped chars\") " }, { "name" : "Biological entity", - "value" : "Test biological entity" + "value" : "Test biological entity 1" }, { "name" : "Experimental variable", - "value" : "Test experimental entity" + "value" : "Test experimental entity 1" }, { "name" : "Extrinsic variable", - "value" : "Test extrinsic variable" + "value" : "Test extrinsic variable 1" }, { "name" : "Intrinsic variable", - "value" : "Test intrinsic variable\nwith escaped character" + "value" : "Test intrinsic variable 1\nwith escaped character" + } ] + }, { + "accno" : "Biosample-2", + "type" : "Biosample", + "attributes" : [ { + "name" : "Title", + "value" : "Test Biosample 2 " + }, { + "name" : "Organism", + "value" : "Mus musculus (mouse)" + }, { + "name" : "Description", + "value" : "Test description 2" + }, { + "name" : "Biological entity", + "value" : "Test biological entity 2" + }, { + "name" : "Experimental variable", + "value" : "Test experimental entity 2" + }, { + "name" : "Extrinsic variable", + "value" : "Test extrinsic variable 2" + }, { + "name" : "Intrinsic variable", + "value" : "Test intrinsic variable 2" + } ] + }, { + "accno" : "Specimen-1", + "type" : "Specimen", + "attributes" : [ { + "name" : "Title", + "value" : "Test specimen 1" + }, { + "name" : "Sample preparation protocol", + "value" : "Test sample preparation protocol 1" + }, { + "name" : "Growth protocol", + "value" : "Test growth protocol 1" } ] }, { "accno" : "Specimen-2", "type" : "Specimen", "attributes" : [ { "name" : "Title", - "value" : "Test specimen" + "value" : "Test specimen 2" }, { "name" : "Sample preparation protocol", - "value" : "Test sample preparation protocol" + "value" : "Test sample preparation protocol 2" }, { "name" : "Growth protocol", - "value" : "Test growth protocol" + "value" : "Test growth protocol 2" } ] }, { "accno" : "Image acquisition-3", @@ -246,27 +284,27 @@ "value" : "Test image analysis overview" } ] }, { - "accno" : "Study Component-4", + "accno" : "Study Component-1", "type" : "Study Component", "attributes" : [ { "name" : "Name", - "value" : "Primary and secondary secretome screens" - }, { + "value" : "Study Component 1" + }, { "name" : "Description", - "value" : "Images and analyses from primary and secondary secretome screens" + "value" : "Description of study component 1" }, { "name" : "File List", - "value" : "File_List_secretome_both_final.json" + "value" : "file_list_study_component_1.json" } ], "subsections" : [ { "type" : "Associations", - "accno" : "association0", + "accno" : "association1", "attributes" : [ { "name" : "Biosample", - "value" : "Test Biosample " + "value" : "Test Biosample 1" }, { "name" : "Specimen", - "value" : "Test specimen" + "value" : "Test specimen 1" }, { "name" : "Image acquisition", "value" : "Test Primary Screen Image Acquisition" @@ -276,13 +314,13 @@ } ] }, { "type" : "Associations", - "accno" : "association1", + "accno" : "association2", "attributes" : [ { "name" : "Biosample", - "value" : "Test Biosample " + "value" : "Test Biosample 2 " }, { "name" : "Specimen", - "value" : "Test specimen" + "value" : "Test specimen 1" }, { "name" : "Image acquisition", "value" : "Test Secondary Screen Image Acquisition" @@ -291,6 +329,36 @@ "value" : "Test image analysis" } ] } ] + }, { + "accno" : "Study Component-2", + "type" : "Study Component", + "attributes" : [ { + "name" : "Name", + "value" : "Study Component 2" + }, { + "name" : "Description", + "value" : "Description of study component 2" + }, { + "name" : "File List", + "value" : "file_list_study_component_2.json" + } ], + "subsections" : [ { + "type" : "Associations", + "accno" : "association3", + "attributes" : [ { + "name" : "Biosample", + "value" : "Test Biosample 2 " + }, { + "name" : "Specimen", + "value" : "Test specimen 2" + }, { + "name" : "Image acquisition", + "value" : "Test Primary Screen Image Acquisition" + }, { + "name" : "Image analysis", + "value" : "Test image analysis" + } ] + } ] } ] }, "type" : "submission" diff --git a/bia-ingest-shared-models/test/test_shared_models.py b/bia-ingest-shared-models/test/test_shared_models.py index 94432c68..296a7054 100644 --- a/bia-ingest-shared-models/test/test_shared_models.py +++ b/bia-ingest-shared-models/test/test_shared_models.py @@ -12,6 +12,8 @@ (utils.get_test_contributor, conversion.get_contributor,), (utils.get_test_grant, conversion.get_grant,), (utils.get_test_study, conversion.get_study,), + (utils.get_test_biosample, conversion.get_biosample,), + (utils.get_test_experimental_imaging_dataset, conversion.get_experimental_imaging_dataset,), # Not testing as we need to deal with links that are not proper # urls # (utils.get_test_external_reference, conversion.get_external_reference,), diff --git a/bia-ingest-shared-models/test/utils.py b/bia-ingest-shared-models/test/utils.py index 3c4a6686..3436974c 100644 --- a/bia-ingest-shared-models/test/utils.py +++ b/bia-ingest-shared-models/test/utils.py @@ -61,26 +61,76 @@ def get_template_specimen_preparation_protocol() -> ( return specimen_preparation_protocol -def get_template_biosample() -> bia_data_model.BioSample: - biosample = bia_data_model.BioSample.model_validate( +def get_test_biosample() -> List[bia_data_model.BioSample]: + # For UUID + attributes_to_consider = [ + "accession_id", + "accno", + "title_id", + "organism_classification", + "description", + # TODO: Discuss including below in semantic_models.BioSample + #"biological_entity", + "intrinsic_variable_description", + "extrinsic_variable_description", + "experimental_variable_description", + ] + taxon1 = semantic_models.Taxon.model_validate( { - "uuid": uuid4(), - "title_id": "Template BioSample", + "common_name": "human", + "scientific_name": "Homo sapiens", + "ncbi_id": None, + } + ) + taxon2 = semantic_models.Taxon.model_validate( + { + "common_name": "mouse", + "scientific_name": "Mus musculus", + "ncbi_id": None, + } + ) + biosample_info = [ + { + "accno": "Biosample-1", + "accession_id": "S-BIADTEST", + "title_id": "Test Biosample 1", "organism_classification": [ - template_taxon.model_dump(), + taxon1.model_dump(), ], - "description": "Test biosample description", + "description": "Test description 1 (\"with some escaped chars\") ", "experimental_variable_description": [ - "Description of experimental variable", + "Test experimental entity 1", ], "extrinsic_variable_description": [ - "Description of external treatment", + "Test extrinsic variable 1", ], "intrinsic_variable_description": [ - "Description of internal treatment", + "Test intrinsic variable 1\nwith escaped character", ], - } - ) + }, { + "accno": "Biosample-2", + "accession_id": "S-BIADTEST", + "title_id": "Test Biosample 2 ", + "organism_classification": [ + taxon2.model_dump(), + ], + "description": "Test description 2", + "experimental_variable_description": [ + "Test experimental entity 2", + ], + "extrinsic_variable_description": [ + "Test extrinsic variable 2", + ], + "intrinsic_variable_description": [ + "Test intrinsic variable 2", + ], + }, + ] + + biosample = [] + for biosample_dict in biosample_info: + biosample_dict["uuid"] = dict_to_uuid(biosample_dict, attributes_to_consider) + biosample.append(bia_data_model.BioSample.model_validate(biosample_dict)) return biosample @@ -94,7 +144,7 @@ def get_template_specimen() -> bia_data_model.Specimen: get_template_specimen_preparation_protocol().uuid, ], "sample_of": [ - get_template_biosample().uuid, + biosample.uuid for biosample in get_test_biosample() ], } ) @@ -193,27 +243,47 @@ def get_template_image_annotation_dataset() -> bia_data_model.ImageAnnotationDat return image_annotation_dataset -def get_template_image_acquisition() -> bia_data_model.ImageAcquisition: - image_acquisition = bia_data_model.ImageAcquisition.model_validate( +def get_test_image_acquisition() -> List[bia_data_model.ImageAcquisition]: + attributes_to_consider = [ + "accession_id", + "accno", + "title_id", + "method_description", + "imaging_instrument_description", + "image_acquisition_parameters", + "fbbi_id", + ] + image_acquisition_info = [ { - "uuid": uuid4(), - "title_id": "Template image acquisition", - "method_description": "Template method description", - "imaging_instrument_description": "Template imaging instrument", - "image_acquisition_parameters": "Template image acquisition parameters", - "fbbi_id": [ - "Test FBBI ID", - ], - } - ) + "accno": "Image acquisition-3", + "accession_id": "S-BIADTEST", + "title_id": "Test Primary Screen Image Acquisition", + "method_description": "confocal microscopy", + "imaging_instrument_description": "Test imaging instrument 1", + "image_acquisition_parameters": "Test image acquisition parameters 1", + "fbbi_id": [], + }, { + "accno": "Image acquisition-7", + "accession_id": "S-BIADTEST", + "title_id": "Test Secondary Screen Image Acquisition", + "method_description": "flourescence microscopy", + "imaging_instrument_description": "Test imaging instrument 2", + "image_acquisition_parameters": "Test image acquisition parameters 2", + "fbbi_id": [], + }, + ] + image_acquisition = [] + for image_acquisition_dict in image_acquisition_info: + image_acquisition_dict["uuid"] = dict_to_uuid(image_acquisition_dict, attributes_to_consider) + image_acquisition.append(bia_data_model.ImageAcquisition.model_validate(image_acquisition_dict)) return image_acquisition -def get_template_image_analysis_method() -> semantic_models.ImageAnalysisMethod: +def get_test_image_analysis_method() -> semantic_models.ImageAnalysisMethod: return semantic_models.ImageAnalysisMethod.model_validate( { - "method_description": "Template Analysis method", - "features_analysed": "Template features analysed", + "method_description": "Test image analysis", + "features_analysed": "Test image analysis overview", } ) @@ -228,48 +298,70 @@ def get_template_image_correlation_method() -> semantic_models.ImageCorrelationM ) -# Depends on: -# bia_data_model.ExperimentallyCapturedImage -# bia_data_model.FileReference (this is a circular dependence!) -# bia_data_model.Study -# bia_data_model.SpecimenPreparationProtocol -# bia_data_model.ImageAcquisition -# bia_data_model.BioSample -# -# TODO: Verify that in practice, the Datasets are created then the -# FileReference instances are added. So here we have empty lists -# for the dataset -def get_template_experimental_imaging_dataset() -> ( +# TODO: Create FileReferences and ExperimentallyCapturedImage +def get_test_experimental_imaging_dataset() -> ( bia_data_model.ExperimentalImagingDataset ): - experimental_imaging_dataset = bia_data_model.ExperimentalImagingDataset.model_validate( - { - "uuid": uuid4(), - "title_id": "Template experimental image dataset", - "image": [], # This should be a list of Experimentally captured image UUIDs - "file": [], # This should be a list of FileReference UUIDs ... - "submitted_in_study": get_template_study().uuid, - "specimen_preparation_method": [ - get_template_specimen_preparation_protocol().uuid, - ], - "acquisition_method": [ - get_template_image_acquisition().uuid, - ], - "biological_entity": [ - get_template_biosample().uuid, - ], - "analysis_method": [ - get_template_image_analysis_method().model_dump(), - ], - "correlation_method": [ - get_template_image_correlation_method().model_dump(), - ], - "file_reference_count": 0, - "image_count": 0, - "example_image_uri": ["https://dummy.url.org"], - } - ) - return experimental_imaging_dataset + # Create first study component + experimental_imaging_dataset_dict = { + "title_id": "Study Component 1", + "image": [], # This should be a list of Experimentally captured image UUIDs + "file": [], # This should be a list of FileReference UUIDs ... + "submitted_in_study": get_test_study().uuid, + "specimen_preparation_method": [ + get_template_specimen_preparation_protocol().uuid, + ], + "acquisition_method": [ + get_test_image_acquisition()[0].uuid, + ], + # This study component uses both biosamples + "biological_entity": [ + biosample.uuid for biosample in get_test_biosample() + ], + "analysis_method": [ + get_test_image_analysis_method().model_dump(), + ], + "correlation_method": [ + get_template_image_correlation_method().model_dump(), + ], + "file_reference_count": 0, + "image_count": 0, + "example_image_uri": [], + } + experimental_imaging_dataset_uuid = dict_to_uuid(experimental_imaging_dataset_dict, ["title_id", "submitted_in_study",]) + experimental_imaging_dataset_dict["uuid"] = experimental_imaging_dataset_uuid + experimental_imaging_dataset1 = bia_data_model.ExperimentalImagingDataset.model_validate(experimental_imaging_dataset_dict) + + # Create second study component + experimental_imaging_dataset_dict = { + "title_id": "Study Component 2", + "image": [], # This should be a list of Experimentally captured image UUIDs + "file": [], # This should be a list of FileReference UUIDs ... + "submitted_in_study": get_test_study().uuid, + "specimen_preparation_method": [ + get_template_specimen_preparation_protocol().uuid, + ], + "acquisition_method": [ + get_test_image_acquisition()[1].uuid, + ], + # This study component uses only second biosample + "biological_entity": [ + get_test_biosample()[1].uuid, + ], + "analysis_method": [ + get_test_image_analysis_method().model_dump(), + ], + "correlation_method": [ + get_template_image_correlation_method().model_dump(), + ], + "file_reference_count": 0, + "image_count": 0, + "example_image_uri": [], + } + experimental_imaging_dataset_uuid = dict_to_uuid(experimental_imaging_dataset_dict, ["title_id", "submitted_in_study",]) + experimental_imaging_dataset_dict["uuid"] = experimental_imaging_dataset_uuid + experimental_imaging_dataset2 = bia_data_model.ExperimentalImagingDataset.model_validate(experimental_imaging_dataset_dict) + return [experimental_imaging_dataset1, experimental_imaging_dataset2] # Depends on: