diff --git a/brainglobe_atlasapi/atlas_generation/validate_atlases.py b/brainglobe_atlasapi/atlas_generation/validate_atlases.py index 0dbc1fc6..908fd789 100644 --- a/brainglobe_atlasapi/atlas_generation/validate_atlases.py +++ b/brainglobe_atlasapi/atlas_generation/validate_atlases.py @@ -12,18 +12,21 @@ from brainglobe_atlasapi.list_atlases import ( get_all_atlases_lastversions, get_atlases_lastversions, - get_local_atlas_version, ) from brainglobe_atlasapi.update_atlases import update_atlas def validate_atlas_files(atlas: BrainGlobeAtlas): - """Checks if basic files exist in the atlas folder""" + """ + Checks if basic files exist in the atlas folder + + custom_atlas_path is used when the function is called as part of + the wrapup function in the atlas packaging script. The expected + input is working_dir + """ + + atlas_path = atlas.root_dir - 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", @@ -104,12 +107,12 @@ def validate_mesh_matches_image_extents(atlas: BrainGlobeAtlas): def open_for_visual_check(atlas: BrainGlobeAtlas): # implement visual checks later - pass + return True def validate_checksum(atlas: BrainGlobeAtlas): # implement later - pass + return True def validate_image_dimensions(atlas: BrainGlobeAtlas): @@ -147,14 +150,16 @@ def validate_additional_references(atlas: BrainGlobeAtlas): def catch_missing_mesh_files(atlas: BrainGlobeAtlas): """ Checks if all the structures in the atlas have a corresponding mesh file + + custom_atlas_path is used when the function is called as part of + the wrapup function in the atlas packaging script. The expected + input is working_dir """ 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)}" - ) + atlas_path = atlas.root_dir + obj_path = Path(atlas_path / "meshes") ids_from_mesh_files = [ @@ -184,10 +189,8 @@ def catch_missing_structures(atlas: BrainGlobeAtlas): 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)}" - ) + atlas_path = atlas.root_dir + obj_path = Path(atlas_path / "meshes") ids_from_mesh_files = [ @@ -252,6 +255,8 @@ def get_all_validation_functions(): return [ validate_atlas_files, validate_mesh_matches_image_extents, + open_for_visual_check, + validate_checksum, validate_image_dimensions, validate_additional_references, catch_missing_mesh_files, @@ -298,6 +303,9 @@ def validate_atlas(atlas_name, version, validation_functions): validate_additional_references, catch_missing_mesh_files, catch_missing_structures, + validate_reference_image_pixels, + validate_annotation_symmetry, + validate_atlas_name, ] valid_atlases = [] diff --git a/brainglobe_atlasapi/atlas_generation/wrapup.py b/brainglobe_atlasapi/atlas_generation/wrapup.py index fc86fe1d..ab6e096b 100644 --- a/brainglobe_atlasapi/atlas_generation/wrapup.py +++ b/brainglobe_atlasapi/atlas_generation/wrapup.py @@ -8,7 +8,7 @@ import tifffile import brainglobe_atlasapi.atlas_generation -from brainglobe_atlasapi import descriptors +from brainglobe_atlasapi import BrainGlobeAtlas, descriptors from brainglobe_atlasapi.atlas_generation.metadata_utils import ( create_metadata_files, generate_metadata_dict, @@ -22,6 +22,9 @@ from brainglobe_atlasapi.atlas_generation.structures import ( check_struct_consistency, ) +from brainglobe_atlasapi.atlas_generation.validate_atlases import ( + get_all_validation_functions, +) from brainglobe_atlasapi.utils import atlas_name_from_repr # This should be changed every time we make changes in the atlas @@ -129,6 +132,7 @@ def wrapup_atlas_from_data( atlas_dir_name = atlas_name_from_repr( atlas_name, resolution[0], ATLAS_VERSION, atlas_minor_version ) + dest_dir = Path(working_dir) / atlas_dir_name # exist_ok would be more permissive but error-prone here as there might @@ -231,6 +235,53 @@ def wrapup_atlas_from_data( additional_metadata=additional_metadata, ) + atlas_name_for_validation = atlas_name_from_repr(atlas_name, resolution[0]) + + # creating BrainGlobe object from local folder (working_dir) + atlas_to_validate = BrainGlobeAtlas( + atlas_name=atlas_name_for_validation, + brainglobe_dir=working_dir, + check_latest=False, + ) + + # Run validation functions + print(f"Running atlas validation on {atlas_dir_name}") + + validation_results = {} + + for func in get_all_validation_functions(): + try: + func(atlas_to_validate) + validation_results[func.__name__] = "Pass" + except AssertionError as e: + validation_results[func.__name__] = f"Fail: {str(e)}" + + def _check_validations(validation_results): + # Helper function to check if all validations passed + all_passed = all( + result == "Pass" for result in validation_results.values() + ) + + if all_passed: + print("This atlas is valid") + else: + failed_functions = [ + func + for func, result in validation_results.items() + if result != "Pass" + ] + error_messages = [ + result.split(": ")[1] + for result in validation_results.values() + if result != "Pass" + ] + + print("These validation functions have failed:") + for func, error in zip(failed_functions, error_messages): + print(f"- {func}: {error}") + + _check_validations(validation_results) + # Compress if required: if compress: output_filename = dest_dir.parent / f"{dest_dir.name}.tar.gz" @@ -240,6 +291,7 @@ def wrapup_atlas_from_data( # Cleanup if required: if cleanup_files: + print(f"Cleaning up atlas data at: {dest_dir}") # Clean temporary directory and remove it: shutil.rmtree(dest_dir)