Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
simplify validation function
Browse files Browse the repository at this point in the history
- all validation functions just take an atlas object
- means we don't need a parameters list
- also simplify output list to be dicts of lists mapping the atlas name to values

- another advantage of this is that it simplifies mocking of atlas functions in the tests
  • Loading branch information
alessandrofelder committed Jan 25, 2024
1 parent a4acdb4 commit 1cd2e9f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 45 deletions.
50 changes: 17 additions & 33 deletions bg_atlasgen/validate_atlases.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
from bg_atlasapi.list_atlases import (
get_all_atlases_lastversions,
get_atlases_lastversions,
get_local_atlas_version
)
from bg_atlasapi.update_atlases import update_atlas


def validate_atlas_files(atlas_path: Path):
def validate_atlas_files(atlas: BrainGlobeAtlas):
"""Checks if basic files exist in the atlas folder"""

atlas_path = Path(get_brainglobe_dir())/f"{atlas.atlas_name}_v{get_local_atlas_version(atlas.atlas_name)}"
assert atlas_path.is_dir(), f"Atlas path {atlas_path} not found"
expected_files = [
"annotation.tiff",
Expand Down Expand Up @@ -90,28 +92,28 @@ def validate_mesh_matches_image_extents(atlas: BrainGlobeAtlas):
return True


def open_for_visual_check():
def open_for_visual_check(atlas: BrainGlobeAtlas):
# implement visual checks later
pass


def validate_checksum():
def validate_checksum(atlas: BrainGlobeAtlas):
# implement later
pass


def check_additional_references():
def check_additional_references(atlas: BrainGlobeAtlas):
# check additional references are different, but have same dimensions
pass


def validate_mesh_structure_pairs(atlas_name: str, atlas_path: Path):
# json_path = Path(atlas_path / "structures.json")
atlas = BrainGlobeAtlas(atlas_name)
def validate_mesh_structure_pairs(atlas: BrainGlobeAtlas):
"""Ensure mesh files (.obj) exist for each expected structure in the atlas."""
ids_from_bg_atlas_api = list(atlas.structures.keys())

atlas_path = Path(get_brainglobe_dir())/f"{atlas.atlas_name}_v{get_local_atlas_version(atlas.atlas_name)}"
obj_path = Path(atlas_path / "meshes")

ids_from_bg_atlas_api = list(atlas.structures.keys())
ids_from_mesh_files = [
int(Path(file).stem)
for file in os.listdir(obj_path)
Expand All @@ -135,7 +137,7 @@ def validate_mesh_structure_pairs(atlas_name: str, atlas_path: Path):
)


def validate_atlas(atlas_name, version, all_validation_functions):
def validate_atlas(atlas_name, version, validation_functions):
"""Validates the latest version of a given atlas"""

print(atlas_name, version)
Expand All @@ -144,34 +146,16 @@ def validate_atlas(atlas_name, version, all_validation_functions):
if not updated:
update_atlas(atlas_name)

validation_function_parameters = [
# validate_atlas_files(atlas_path: Path)
(Path(get_brainglobe_dir() / f"{atlas_name}_v{version}"),),
# validate_mesh_matches_image_extents(atlas: BrainGlobeAtlas)
(BrainGlobeAtlas(atlas_name),),
# open_for_visual_check()
(),
# validate_checksum()
(),
# check_additional_references()
(),
# validate_mesh_structure_pairs(atlas_name: str, atlas_path: Path):
(
atlas_name,
Path(get_brainglobe_dir() / f"{atlas_name}_v{version}"),
),
]

# list to store the errors of the failed validations
failed_validations = []
successful_validations = []
failed_validations = {atlas_name: []}
successful_validations = {atlas_name: []}

for i, validation_function in enumerate(all_validation_functions):
for i, validation_function in enumerate(validation_functions):
try:
validation_function(*validation_function_parameters[i])
successful_validations.append((atlas_name, validation_function))
validation_function(atlas_name)
successful_validations[atlas_name].append(validation_function)
except AssertionError as error:
failed_validations.append((atlas_name, validation_function, error))
failed_validations[atlas_name].append((validation_function, error))

return successful_validations, failed_validations

Expand Down
37 changes: 25 additions & 12 deletions tests/test_unit/test_validation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pathlib import Path
import os

import numpy as np
import pytest
Expand All @@ -11,14 +12,30 @@
validate_mesh_matches_image_extents,
)

@pytest.fixture
def atlas():
"""A fixture providing a low-res Allen Mouse atlas for testing.
Tests assume this atlas is valid"""
return BrainGlobeAtlas("allen_mouse_100um")

def test_validate_mesh_matches_image_extents():
atlas = BrainGlobeAtlas("allen_mouse_100um")

@pytest.fixture
def atlas_with_bad_reference_file():
"""A fixture providing an invalid version of Allen Mouse atlas for testing.
The atlas will have a misnamed template file that won't be found by the API
This fixture also does the clean-up after the test has run
"""
good_name = get_brainglobe_dir()/"allen_mouse_100um_v1.2/reference.tiff"
bad_name = get_brainglobe_dir()/"allen_mouse_100um_v1.2/reference_bad.tiff"
os.rename(good_name, bad_name)
yield BrainGlobeAtlas("allen_mouse_100um")
os.rename(bad_name, good_name)

def test_validate_mesh_matches_image_extents(atlas):
assert validate_mesh_matches_image_extents(atlas)


def test_validate_mesh_matches_image_extents_negative(mocker):
atlas = BrainGlobeAtlas("allen_mouse_100um")
def test_validate_mesh_matches_image_extents_negative(mocker, atlas):
flipped_annotation_image = np.transpose(atlas.annotation)
mocker.patch(
"bg_atlasapi.BrainGlobeAtlas.annotation",
Expand All @@ -31,16 +48,12 @@ def test_validate_mesh_matches_image_extents_negative(mocker):
validate_mesh_matches_image_extents(atlas)


def test_valid_atlas_files():
_ = BrainGlobeAtlas("allen_mouse_100um")
atlas_path = Path(get_brainglobe_dir()) / "allen_mouse_100um_v1.2"
assert validate_atlas_files(atlas_path)

def test_valid_atlas_files(atlas):
assert validate_atlas_files(atlas)

def test_invalid_atlas_path():
atlas_path = Path.home()
def test_invalid_atlas_path(atlas_with_bad_reference_file):
with pytest.raises(AssertionError, match="Expected file not found"):
validate_atlas_files(atlas_path)
validate_atlas_files(atlas_with_bad_reference_file)


def test_assert_close():
Expand Down

0 comments on commit 1cd2e9f

Please sign in to comment.