Skip to content

Commit

Permalink
Add doc-strings.
Browse files Browse the repository at this point in the history
  • Loading branch information
tibuch committed Dec 13, 2023
1 parent d8f3a11 commit 4a0c9c5
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 9 deletions.
51 changes: 50 additions & 1 deletion src/faim_hcs/hcs/acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,20 @@ def get_channel_metadata(self) -> dict[int, ChannelMetadata]:
raise NotImplementedError()

def get_well_names(self) -> Iterable[str]:
"""
Get the names of all wells in the acquisition.
"""
for well in self.get_well_acquisitions():
yield well.name

def get_omero_channel_metadata(self) -> list[dict]:
"""
Get the channel metadata in OMERO format.
Returns
-------
List of channel metadata.
"""
ome_channels = []
ch_metadata = self.get_channel_metadata()
max_channel = max(list(ch_metadata.keys()))
Expand Down Expand Up @@ -115,7 +125,6 @@ def get_common_well_shape(self) -> tuple[int, int, int, int, int]:
Returns
-------
tuple[int, int, int, int, int]
(time, channel, z, y, x)
"""
well_shapes = []
Expand All @@ -126,6 +135,10 @@ def get_common_well_shape(self) -> tuple[int, int, int, int, int]:


class WellAcquisition(ABC):
"""
A single well of a plate acquisition.
"""

name: str = None
_files = None
_alignment: TileAlignmentOptions = None
Expand Down Expand Up @@ -157,6 +170,13 @@ def _assemble_tiles(self) -> list[Tile]:
raise NotImplementedError()

def get_dtype(self) -> np.dtype:
"""
Get the data type of the well acquisition.
Returns
-------
type
"""
return self._tiles[0].load_data().dtype

def _align_tiles(self, tiles: list[Tile]) -> list[Tile]:
Expand All @@ -177,23 +197,52 @@ def get_tiles(self) -> list[Tile]:
return self._tiles

def get_row_col(self) -> tuple[str, str]:
"""
Get the row and column of the well acquisition.
Returns
-------
row, column
"""
return self.name[0], self.name[1:]

@abstractmethod
def get_axes(self) -> list[str]:
"""
Get the axes of the well acquisition.
"""
raise NotImplementedError()

@abstractmethod
def get_yx_spacing(self) -> tuple[float, float]:
"""
Get the yx spacing of the well acquisition.
"""
raise NotImplementedError()

@abstractmethod
def get_z_spacing(self) -> Optional[float]:
"""
Get the z spacing of the well acquisition.
"""
raise NotImplementedError()

def get_coordinate_transformations(
self, max_layer: int, yx_binning: int
) -> list[dict[str, Any]]:
"""
Get the NGFF conform coordinate transformations for the well
acquisition.
Parameters
----------
max_layer : Maximum layer of the resolution pyramid.
yx_binning : Bin factor of the yx resolution.
Returns
-------
List of coordinate transformations.
"""
transformations = []
for s in range(max_layer + 1):
if self.get_z_spacing() is not None:
Expand Down
4 changes: 4 additions & 0 deletions src/faim_hcs/hcs/cellvoyager/CellVoyagerWellAcquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@


class CellVoyagerWellAcquisition(WellAcquisition):
"""
Data structure for a CellVoyager well acquisition.
"""

def __init__(
self,
files: pd.DataFrame,
Expand Down
39 changes: 39 additions & 0 deletions src/faim_hcs/hcs/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ class NGFFPlate(BaseModel):


class ConvertToNGFFPlate:
"""
Convert a plate acquisition to an NGFF plate.
"""

_ngff_plate: NGFFPlate

def __init__(
Expand All @@ -37,6 +41,21 @@ def __init__(
warp_func: Callable = stitching_utils.translate_tiles_2d,
fuse_func: Callable = stitching_utils.fuse_mean,
):
"""
Parameters
----------
ngff_plate :
NGFF plate information.
yx_binning :
YX binning factor.
dask_chunk_size_factor :
Dask chunk size factor. Increasing this will increase the memory
usage.
warp_func :
Function used to warp tile images.
fuse_func :
Function used to fuse tile images.
"""
assert (
isinstance(yx_binning, int) and yx_binning >= 1
), "yx_binning must be an integer >= 1."
Expand Down Expand Up @@ -84,6 +103,26 @@ def run(
max_layer: int = 3,
storage_options: dict = None,
) -> zarr.Group:
"""
Convert a plate acquisition to an NGFF plate.
Parameters
----------
plate_acquisition :
A single plate acquisition.
well_sub_group :
Name of the well sub-group.
chunks :
Chunk size in (Z)YX.
max_layer :
Maximum layer of the resolution pyramid layers.
storage_options :
Zarr storage options.
Returns
-------
zarr.Group of the plate.
"""
assert 2 <= len(chunks) <= 3, "Chunks must be 2D or 3D."
plate = self._create_zarr_plate(plate_acquisition)
for well_acquisition in tqdm(plate_acquisition.get_well_acquisitions()):
Expand Down
4 changes: 2 additions & 2 deletions src/faim_hcs/hcs/imagexpress/ImageXpressPlateAcquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ def _parse_files(self) -> pd.DataFrame:
Table of all files in the acquisition.
"""
return pd.DataFrame(
self._list_and_match_files(
ImageXpressPlateAcquisition._list_and_match_files(
root_dir=self._acquisition_dir,
root_re=self._get_root_re(),
filename_re=self._get_filename_re(),
)
)

@staticmethod
def _list_and_match_files(
self,
root_dir: Union[Path, str],
root_re: re.Pattern,
filename_re: re.Pattern,
Expand Down
30 changes: 30 additions & 0 deletions src/faim_hcs/hcs/imagexpress/MixedAcquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@


class MixedAcquisition(StackAcquisition):
"""Image stack acquisition with Projectsion acquired with a Molecular
Devices ImageXpress Micro Confocal system.
MIP-2P-2sub-Stack --> {name} [Optional]
└── 2023-02-21 --> {date}
└── 1334 --> {acquisition id}
├── Projection-Mix_E07_s1_w1E94C24BD-45E4-450A-9919-257C714278F7.tif
├── Projection-Mix_E07_s1_w1_thumb4BFD4018-E675-475E-B5AB-2E959E6B6DA1.tif
├── ...
├── Projection-Mix_E08_s2_w3CCE83D85-0912-429E-9F18-716A085BB5BC.tif
├── Projection-Mix_E08_s2_w3_thumb4D88636E-181E-4AF6-BC53-E7A435959C8F.tif
├── ZStep_1
│   ├── Projection-Mix_E07_s1_w1E78EB128-BD0D-4D94-A6AD-3FF28BB1B105.tif
│   ├── Projection-Mix_E07_s1_w1_thumb187DE64B-038A-4671-BF6B-683721723769.tif
│   ├── Projection-Mix_E07_s1_w2C0A49256-E289-4C0F-ADC9-F7728ABDB141.tif
│   ├── Projection-Mix_E07_s1_w2_thumb57D4B151-71BF-480E-8CC4-C23A2690B763.tif
│   ├── Projection-Mix_E07_s1_w427CCB2E4-1BF4-45E7-8BC7-264B48EF9C4A.tif
│   ├── Projection-Mix_E07_s1_w4_thumb555647D0-77F1-4A43-9472-AE509F95E236.tif
│   ├── ...
│   └── Projection-Mix_E08_s2_w4_thumbD2785594-4F49-464F-9F80-1B82E30A560A.tif
├── ...
└── ZStep_9
├── Projection-Mix_E07_s1_w1091EB8A5-272A-466D-B8A0-7547C6BA392B.tif
├── ...
└── Projection-Mix_E08_s2_w2_thumb210C0D5D-C20E-484D-AFB2-EFE669A56B84.tif
Image data is stored in {name}_{well}_{field}_w{channel}{md_id}.tif.
The *_thumb*.tif files, used by Molecular Devices as preview, are ignored.
"""

def __init__(
self,
acquisition_dir: Union[Path, str],
Expand Down
5 changes: 0 additions & 5 deletions src/faim_hcs/hcs/imagexpress/StackAcquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ class StackAcquisition(ImageXpressPlateAcquisition):
MIP-2P-2sub-Stack --> {name} [Optional]
└── 2023-02-21 --> {date}
└── 1334 --> {acquisition id}
├── Projection-Mix_E07_s1_w1E94C24BD-45E4-450A-9919-257C714278F7.tif
├── Projection-Mix_E07_s1_w1_thumb4BFD4018-E675-475E-B5AB-2E959E6B6DA1.tif
├── ...
├── Projection-Mix_E08_s2_w3CCE83D85-0912-429E-9F18-716A085BB5BC.tif
├── Projection-Mix_E08_s2_w3_thumb4D88636E-181E-4AF6-BC53-E7A435959C8F.tif
├── ZStep_1
│   ├── Projection-Mix_E07_s1_w1E78EB128-BD0D-4D94-A6AD-3FF28BB1B105.tif
│   ├── Projection-Mix_E07_s1_w1_thumb187DE64B-038A-4671-BF6B-683721723769.tif
Expand Down
14 changes: 13 additions & 1 deletion src/faim_hcs/stitching/DaskTileStitcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ def __init__(
output_shape: Optional[tuple[int, int, int, int, int]] = None,
dtype: np.dtype = np.uint16,
):
"""
Parameters
----------
tiles :
Tiles to stitch.
yx_chunk_shape :
Chunk shape in y and x.
output_shape :
Shape of the output image. If None, the shape is computed from the tiles.
dtype :
Data type of the output image.
"""
self.tiles: list[Tile] = stitching_utils.shift_to_origin(tiles)
self.chunk_shape = (
1,
Expand Down Expand Up @@ -96,7 +108,7 @@ def get_stitched_dask_array(
Returns
-------
Dask array of the stitched image.
"""
func = partial(
stitching_utils.assemble_chunk,
Expand Down
38 changes: 38 additions & 0 deletions src/faim_hcs/stitching/stitching_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,24 @@ def fuse_sum(warped_tiles: NDArray, warped_masks: NDArray) -> NDArray:

@threadpool_limits.wrap(limits=1, user_api="blas")
def translate_tiles_2d(block_info, yx_chunk_shape, dtype, tiles):
"""
Translate tiles to their relative position inside the given block.
Parameters
----------
block_info :
da.map_blocks block_info.
yx_chunk_shape :
shape of the chunk in yx.
dtype :
dtype of the tiles.
tiles :
list of tiles.
Returns
-------
translated tiles, translated masks
"""
array_location = block_info[None]["array-location"]
chunk_yx_origin = np.array([array_location[3][0], array_location[4][0]])
warped_tiles = []
Expand Down Expand Up @@ -126,6 +144,26 @@ def translate_tiles_2d(block_info, yx_chunk_shape, dtype, tiles):
def assemble_chunk(
block_info=None, tile_map=None, warp_func=None, fuse_func=None, dtype=None
):
"""
Assemble a chunk of the stitched image.
Parameters
----------
block_info :
da.map_blocks block_info.
tile_map :
map of block positions to tiles.
warp_func :
function used to warp tiles.
fuse_func :
function used to fuse tiles.
dtype :
tile data type.
Returns
-------
fused tiles corresponding to this block/chunk
"""
chunk_location = block_info[None]["chunk-location"]
chunk_shape = block_info[None]["chunk-shape"]
tiles = tile_map[chunk_location]
Expand Down

0 comments on commit 4a0c9c5

Please sign in to comment.