4545from ..metadata .core import prepare_metadata
4646from ..metadata .nwb import get_metadata , nwb2asset
4747from ..metadata .util import (
48+ _is_mouse ,
4849 extract_age ,
4950 extract_cellLine ,
5051 extract_species ,
52+ extract_wasDerivedFrom ,
5153 parse_age ,
5254 parse_purlobourl ,
5355 process_ndtypes ,
@@ -809,8 +811,6 @@ def test_brain_anatomy_non_mouse_skipped(tmp_path: Path) -> None:
809811@pytest .mark .ai_generated
810812def test_brain_anatomy_with_existing_biosample_chain (tmp_path : Path ) -> None :
811813 """Test that anatomy is added to the deepest BioSample when chain exists."""
812- from ..metadata .util import extract_wasDerivedFrom
813-
814814 metadata = {
815815 "tissue_sample_id" : "tissue01" ,
816816 "slice_id" : "slice01" ,
@@ -834,6 +834,125 @@ def test_brain_anatomy_with_existing_biosample_chain(tmp_path: Path) -> None:
834834 assert len (sample .anatomy ) >= 1
835835
836836
837+ @pytest .mark .ai_generated
838+ def test_brain_anatomy_ophys_imaging_plane (tmp_path : Path ) -> None :
839+ """Test that brain anatomy is extracted from imaging plane locations."""
840+ nwb_path = tmp_path / "test_ophys.nwb"
841+ session_start = datetime (2020 , 1 , 1 , 12 , 0 , 0 , tzinfo = tzutc ())
842+
843+ nwbfile = NWBFile (
844+ session_description = "test ophys" ,
845+ identifier = "test_ophys_123" ,
846+ session_start_time = session_start ,
847+ subject = pynwb .file .Subject (
848+ subject_id = "mouse002" ,
849+ species = "Mus musculus" ,
850+ sex = "U" ,
851+ ),
852+ )
853+
854+ device = nwbfile .create_device (name = "microscope" )
855+ nwbfile .create_imaging_plane (
856+ name = "ImagingPlane" ,
857+ optical_channel = pynwb .ophys .OpticalChannel (
858+ name = "OpticalChannel" ,
859+ description = "test channel" ,
860+ emission_lambda = 500.0 ,
861+ ),
862+ description = "test imaging plane" ,
863+ device = device ,
864+ excitation_lambda = 600.0 ,
865+ indicator = "GCaMP6f" ,
866+ location = "Primary visual area" ,
867+ )
868+
869+ with NWBHDF5IO (str (nwb_path ), "w" ) as io :
870+ io .write (nwbfile )
871+
872+ from ..metadata .nwb import nwb2asset
873+ from ..misctypes import DUMMY_DANDI_ETAG
874+
875+ asset = nwb2asset (nwb_path , digest = DUMMY_DANDI_ETAG )
876+ assert asset .wasDerivedFrom is not None
877+ assert len (asset .wasDerivedFrom ) > 0
878+
879+ sample = asset .wasDerivedFrom [0 ]
880+ while sample .wasDerivedFrom :
881+ sample = sample .wasDerivedFrom [0 ]
882+
883+ assert sample .anatomy is not None
884+ assert len (sample .anatomy ) > 0
885+ assert sample .anatomy [0 ].name == "Primary visual area"
886+
887+
888+ @pytest .mark .ai_generated
889+ def test_brain_anatomy_synthetic_biosample_fallback () -> None :
890+ """Test that a synthetic BioSample is created when no tissue/slice/cell IDs exist."""
891+ metadata = {
892+ "brain_locations" : ["VISp" ],
893+ "species" : "Mus musculus" ,
894+ }
895+ result = extract_wasDerivedFrom (metadata )
896+ assert result is not None
897+ assert len (result ) == 1
898+ sample = result [0 ]
899+ assert sample .identifier == "brain-region-sample"
900+ assert sample .anatomy is not None
901+ assert len (sample .anatomy ) == 1
902+ assert sample .anatomy [0 ].name == "Primary visual area"
903+
904+
905+ @pytest .mark .ai_generated
906+ @pytest .mark .parametrize (
907+ "species" ,
908+ [
909+ "Mus musculus" ,
910+ "mouse" ,
911+ "http://purl.obolibrary.org/obo/NCBITaxon_10090" ,
912+ "Mus musculus - House mouse" ,
913+ "mus musculus" ,
914+ ],
915+ )
916+ def test_is_mouse_positive (species : str ) -> None :
917+ """Test that _is_mouse correctly identifies mouse species variants."""
918+ assert _is_mouse ({"species" : species }) is True
919+
920+
921+ @pytest .mark .ai_generated
922+ @pytest .mark .parametrize (
923+ "species" ,
924+ [
925+ "Rattus norvegicus" ,
926+ "rat" ,
927+ "Homo sapiens" ,
928+ "human" ,
929+ "Drosophila melanogaster" ,
930+ "" ,
931+ ],
932+ )
933+ def test_is_mouse_negative (species : str ) -> None :
934+ """Test that _is_mouse rejects non-mouse species."""
935+ assert _is_mouse ({"species" : species }) is False
936+
937+
938+ @pytest .mark .ai_generated
939+ def test_is_mouse_missing_species () -> None :
940+ """Test that _is_mouse returns False when species is absent."""
941+ assert _is_mouse ({}) is False
942+
943+
944+ @pytest .mark .ai_generated
945+ def test_brain_anatomy_unmatched_tokens_only () -> None :
946+ """Test that only unmatched tokens for a mouse produce no anatomy."""
947+ metadata = {
948+ "brain_locations" : ["nonexistent_area_xyz" , "fake_region_123" ],
949+ "species" : "Mus musculus" ,
950+ }
951+ result = extract_wasDerivedFrom (metadata )
952+ # No matching anatomy → no synthetic BioSample created
953+ assert result is None
954+
955+
837956@mark_xfail_ontobee
838957@mark .skipif_no_network
839958@pytest .mark .obolibrary
0 commit comments