Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality to save stitched image as h5 or zarr #14

Merged
merged 23 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cd97399
Add fuse functions to image_mosaic#
IgorTatarnikov Sep 5, 2024
9b96c14
Added UI for fusing
IgorTatarnikov Sep 5, 2024
83f45b8
Add image_mosaic tests for new functionality
IgorTatarnikov Sep 5, 2024
37c45a2
Fixed resolution to display test as it's dynamic now
IgorTatarnikov Sep 5, 2024
eb431ad
Only run tests on pull requests
IgorTatarnikov Sep 5, 2024
686908d
Remove .brainglobe directory from caching as it's not populated
IgorTatarnikov Sep 5, 2024
50e2cbb
Add tests for stitching widget
IgorTatarnikov Sep 5, 2024
fefd30b
Fixed tests
IgorTatarnikov Sep 5, 2024
7c6fab0
Allow downscaling in z for pyramid construction
IgorTatarnikov Sep 10, 2024
6c974d9
Review comments in file_utils
IgorTatarnikov Oct 1, 2024
96202d1
WIP review comments from image_mosaic.py
IgorTatarnikov Oct 1, 2024
e87957c
Zarr is always 4d
IgorTatarnikov Oct 1, 2024
8422637
Moved write_bdv_xml function
IgorTatarnikov Oct 10, 2024
9d28215
Finish addressing comments in image_mosaic
IgorTatarnikov Oct 10, 2024
21d1c52
Address comments in stitching_widget
IgorTatarnikov Oct 10, 2024
48779b5
Refactored calculate_threshold to be a method of ImageMosaic
IgorTatarnikov Oct 10, 2024
51c2812
Address comments in test_image_mosaic.py
IgorTatarnikov Oct 10, 2024
1cd3799
Fixed tests
IgorTatarnikov Oct 10, 2024
4a3bd10
Merge branch 'main' into fuse-implementation
IgorTatarnikov Oct 10, 2024
2f7b074
Updated hash for test files
IgorTatarnikov Oct 11, 2024
030f75a
Updated tests
IgorTatarnikov Oct 11, 2024
b40584e
Fix tests for windows
IgorTatarnikov Oct 11, 2024
5e55376
Updated tests
IgorTatarnikov Oct 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/test_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: tests
on:
push:
branches:
- '*'
- "main"
tags:
- '*'
- 'v**'
IgorTatarnikov marked this conversation as resolved.
Show resolved Hide resolved
pull_request:

jobs:
Expand Down Expand Up @@ -39,6 +39,13 @@ jobs:
python-version: "3.12"

steps:
- name: Cache brainglobe directory
uses: actions/cache@v4
with:
path: | # ensure we don't cache any interrupted atlas download and extraction, if e.g. we cancel the workflow manually
~/.cache/pooch
!~/.brainglobe/atlas.tar.gz
key: brainglobe
# these libraries enable testing on Qt on linux
- uses: pyvista/setup-headless-display-action@v2
with:
Expand Down
105 changes: 105 additions & 0 deletions brainglobe_stitch/file_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import copy
import xml.etree.ElementTree as ET
from pathlib import Path
from typing import Dict, List, Tuple, Union
Expand Down Expand Up @@ -363,3 +364,107 @@
raise ValueError(f"No element found for query {query}")

return element


def write_bdv_xml(
output_xml_path: Path,
input_xml_path: Path,
hdf5_path: Path,
image_size: Tuple[int, ...],
num_channels: int,
) -> None:
"""
Write a Big Data Viewer (BDV) XML file.
IgorTatarnikov marked this conversation as resolved.
Show resolved Hide resolved

Parameters
----------
output_xml_path: Path
The path to the output BDV XML file.
input_xml_path: Path
The path to the input BDV XML file.
hdf5_path:
The path to the output HDF5 file.
image_size:
The size of the image in pixels.
num_channels:
The number of channels in the image.
"""
input_tree = ET.parse(input_xml_path)
input_root = input_tree.getroot()
base_path = safe_find(input_root, ".//BasePath")

root = ET.Element("SpimData", version="0.2")
root.append(base_path)

sequence_desc = ET.SubElement(root, "SequenceDescription")

image_loader = safe_find(input_root, ".//ImageLoader")
hdf5_path_node = safe_find(image_loader, ".//hdf5")
# Replace the hdf5 path with the new relative path
hdf5_path_node.text = str(hdf5_path.name)
sequence_desc.append(image_loader)

view_setup = safe_find(input_root, ".//ViewSetup")
# Replace the size of the image with the new size
view_setup[2].text = f"{image_size[2]} {image_size[1]} {image_size[0]}"
IgorTatarnikov marked this conversation as resolved.
Show resolved Hide resolved

view_setups = ET.SubElement(sequence_desc, "ViewSetups")
view_setups.append(view_setup)

# Add the view setups for the other channels
for i in range(1, num_channels):
view_setup_copy = copy.deepcopy(view_setup)
view_setup_copy[0].text = f"{i}"
view_setup_copy[1].text = f"setup {i}"
view_setup_copy[4][1].text = f"{i}"
view_setups.append(view_setup_copy)

attributes_illumination = safe_find(
input_root, ".//Attributes[@name='illumination']"
)
view_setups.append(attributes_illumination)

attributes_channel = safe_find(
input_root, ".//Attributes[@name='channel']"
)
view_setups.append(attributes_channel)

attributes_tiles = ET.SubElement(view_setups, "Attributes", name="tile")
tile = safe_find(input_root, ".//Tile/[id='0']")
attributes_tiles.append(tile)

attributes_angles = safe_find(input_root, ".//Attributes[@name='angle']")
view_setups.append(attributes_angles)

timepoints = safe_find(input_root, ".//Timepoints")
sequence_desc.append(timepoints)

# Missing views are not necessary for the BDV XML
# May not be present in all BDV XML files
try:
missing_views = safe_find(input_root, ".//MissingViews")
sequence_desc.append(missing_views)

Check warning on line 446 in brainglobe_stitch/file_utils.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_stitch/file_utils.py#L446

Added line #L446 was not covered by tests
except ValueError as e:
print(e)

view_registrations = ET.SubElement(root, "ViewRegistrations")

# Write the calibrations for each channel
# Allows BDV to convert pixel coordinates to physical coordinates
for i in range(num_channels):
view_registration = ET.SubElement(
view_registrations,
"ViewRegistration",
attrib={"timepoint": "0", "setup": f"{i}"},
)
calibration = safe_find(
input_root, ".//ViewTransform/[Name='calibration']"
)
view_registration.append(calibration)

tree = ET.ElementTree(root)
# Add a two space indentation to the file
ET.indent(tree, space=" ")
tree.write(output_xml_path, encoding="utf-8", xml_declaration=True)

return
IgorTatarnikov marked this conversation as resolved.
Show resolved Hide resolved
IgorTatarnikov marked this conversation as resolved.
Show resolved Hide resolved
Loading