Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
98 changes: 98 additions & 0 deletions flamingo_tools/extract_block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import os
from typing import Optional, List

import imageio.v3 as imageio
import numpy as np
import zarr

import flamingo_tools.s3_utils as s3_utils
from flamingo_tools.file_utils import read_image_data


def extract_block(
input_path: str,
coords: List[int],
output_dir: Optional[str] = None,
input_key: Optional[str] = None,
output_key: Optional[str] = None,
resolution: float = 0.38,
roi_halo: List[int] = [128, 128, 64],
tif: bool = False,
s3: Optional[bool] = False,
s3_credentials: Optional[str] = None,
s3_bucket_name: Optional[str] = None,
s3_service_endpoint: Optional[str] = None,
):
"""Extract block around coordinate from input data according to a given halo.
Either from a local file or from an S3 bucket.

Args:
input_path: Input folder in n5 / ome-zarr format.
coords: Center coordinates of extracted 3D volume.
output_dir: Output directory for saving output as <basename>_crop.n5. Default: input directory.
input_key: Input key for data in input file.
output_key: Output key for data in n5 output or used as suffix for tif output.
roi_halo: ROI halo of extracted 3D volume.
tif: Flag for tif output
s3: Flag for considering input_path for S3 bucket.
s3_bucket_name: S3 bucket name.
s3_service_endpoint: S3 service endpoint.
s3_credentials: File path to credentials for S3 bucket.
"""
coords = [int(round(c)) for c in coords]
coord_string = "-".join([str(c).zfill(4) for c in coords])

# Dimensions are inversed to view in MoBIE (x y z) -> (z y x)
coords.reverse()
roi_halo.reverse()

input_content = list(filter(None, input_path.split("/")))

if s3:
image_name = input_content[-1].split(".")[0]
if len(image_name.split("_")) > 1:
resized_suffix = "_resized"
image_prefix = image_name.split("_")[0]
else:
resized_suffix = ""
image_prefix = image_name
basename = input_content[0] + resized_suffix
else:
basename = "".join(input_content[-1].split(".")[:-1])
image_prefix = basename.split("_")[-1]

input_dir = input_path.split(basename)[0]
input_dir = os.path.abspath(input_dir)

if output_dir == "":
output_dir = input_dir

if tif:
if output_key is None:
output_name = basename + "_crop_" + coord_string + "_" + image_prefix + ".tif"
else:
output_name = basename + "_" + image_prefix + "_crop_" + coord_string + "_" + output_key + ".tif"

output_file = os.path.join(output_dir, output_name)
else:
output_key = "raw" if output_key is None else output_key
output_file = os.path.join(output_dir, basename + "_crop_" + coord_string + ".n5")

coords = np.array(coords)
coords = coords / resolution
coords = np.round(coords).astype(np.int32)

roi = tuple(slice(co - rh, co + rh) for co, rh in zip(coords, roi_halo))

if s3:
input_path, fs = s3_utils.get_s3_path(input_path, bucket_name=s3_bucket_name,
service_endpoint=s3_service_endpoint, credential_file=s3_credentials)

data_ = read_image_data(input_path, input_key)
data_roi = data_[roi]

if tif:
imageio.imwrite(output_file, data_roi, compression="zlib")
else:
with zarr.open(output_file, mode="w") as f_out:
f_out.create_dataset(output_key, data=data_roi, compression="gzip")
23 changes: 23 additions & 0 deletions reproducibility/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Scripts to ensure/facilitate the reproducbility of pre-/post-processing

The scripts within these folders document steps involved in the pre-/post-processing or analysis of data.
The folders contain a script for reproducibility as well as dictionaries in JSON format, which contain script parameters and additional information.

## Extraction of blocks from a 3D volume

The extraction of blocks from a 3D volume is required for the creation of annotations, empty crops, or others regions of interest.

Usage:
```
python repro_block_extraction.py --input <JSON-file> --output <out-dir>
```

## Post-processing of SGN segmentation

The post-processing of the SGN segmentation may involve the erosion of the segmentation to exclude artifacts, the variation of the minimal number of nodes within a component, or the minimal distance between nodes to consider them the same component.

Usage:
```
python repro_postprocess_sgn_v1.py --input <JSON-file> --output <out-dir>
```

147 changes: 147 additions & 0 deletions reproducibility/block_extraction/2025-05-SGN_annotated_crops.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
[
{
"cochlea": "M_LR_000144_L",
"image_channel": "PV_resized",
"crop_centers": [
[
1040,
700,
1390
],
[
1300,
690,
1191
],
[
1455,
814,
1191
]
],
"halo_size": [
128,
128,
32
]
},
{
"cochlea": "M_LR_000145_L",
"image_channel": "PV_resized",
"crop_centers": [
[
972,
862,
610
],
[
1301,
812,
740
]
],
"halo_size": [
128,
128,
32
]
},
{
"cochlea": "M_LR_000167_R",
"image_channel": "PV",
"crop_centers": [
[
909,
813,
810
],
[
916,
800,
722
],
[
951,
742,
652
],
[
951,
742,
602
],
[
1251,
266,
575
],
[
1210,
148,
606
],
[
1305,
341,
526
],
[
1137,
669,
1044
]
],
"halo_size": [
128,
128,
32
]
},
{
"cochlea": "M_LR_000151_R",
"image_channel": "PV_resized",
"crop_centers": [
[
1275,
806,
578
],
[
875,
539,
747
],
[
1300,
535,
747
]
],
"halo_size": [
128,
128,
32
]
},
{
"cochlea": "M_LR_000184_L",
"image_channel": "PV_resized",
"crop_centers": [
[
1326,
844,
516
],
[
885,
913,
1023
]
],
"halo_size": [
128,
128,
32
]
}
]
102 changes: 102 additions & 0 deletions reproducibility/block_extraction/2025-05-SGN_domain_crops.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
[
{
"cochlea": "M_LR_000144_L",
"image_channel": "PV_resized",
"crop_centers": [
[
1490,
600,
735
],
[
1540,
930,
865
]
],
"halo_size": [
256,
256,
128
]
},
{
"cochlea": "M_LR_000145_L",
"image_channel": "PV_resized",
"crop_centers": [
[
1300,
700,
700
]
],
"halo_size": [
256,
256,
128
]
},
{
"cochlea": "M_LR_000151_R",
"image_channel": "PV_resized",
"crop_centers": [
[
1350,
690,
1000
],
[
1350,
570,
734
]
],
"halo_size": [
256,
256,
128
]
},
{
"cochlea": "M_LR_000155_L",
"image_channel": "PV_resized",
"crop_centers": [
[
900,
1090,
700
],
[
1464,
830,
420
]
],
"halo_size": [
256,
256,
128
]
},
{
"cochlea": "M_LR_000167_R",
"image_channel": "PV",
"crop_centers": [
[
1360,
1040,
840
],
[
900,
780,
780
]
],
"halo_size": [
256,
256,
128
]
}
]
Loading