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

rename-wells CLI utility #232

Merged
merged 29 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
91e7fdd
Updated rename wells functionality at CLI level, fixed style errors
Jul 7, 2024
d336cd8
CLI changes
Jul 9, 2024
e3f7029
fix click options
talonchandler Jul 9, 2024
4fb8b03
basic test for help message
talonchandler Jul 9, 2024
1f27a19
Updated decorator
Jul 11, 2024
66e5d12
Exception changes
Jul 11, 2024
75a9327
Updated rename wells and testing
Jul 12, 2024
f256cfe
Updated test
Jul 12, 2024
65a0394
Updated test
Jul 15, 2024
01132dc
test_rename_wells_basic
Jul 15, 2024
c7c42ed
Updated tests, converting well names back to original
Jul 15, 2024
452f8ed
Context manager update
Jul 15, 2024
c753a87
well-mapping.csv
Jul 17, 2024
6851360
Updating row and column indices
Jul 21, 2024
ce70316
Style changes
Jul 21, 2024
92e53dd
Merge branch 'main' into renamewells
talonchandler Sep 19, 2024
31888c6
rework API with `self.zgroup.move`
talonchandler Sep 19, 2024
5b59dec
test API
talonchandler Sep 19, 2024
fb0685a
simplify and document CLI
talonchandler Sep 19, 2024
410f482
test CLI w/ round trip
talonchandler Sep 19, 2024
5caa257
style
talonchandler Sep 19, 2024
d1f7639
make example typical
talonchandler Sep 19, 2024
2c0c083
move rename_wells to its own file
ieivanov Oct 1, 2024
eb40820
add checks for correct well names
ieivanov Oct 1, 2024
49740fe
Merge branch 'main' into pr/232
ieivanov Oct 1, 2024
f9b6847
add tests for invalid well names
ieivanov Oct 1, 2024
799ccfe
Merge branch 'main' into pr/232
ieivanov Oct 3, 2024
27cda8d
remove test_rename_wells deadline
ieivanov Oct 3, 2024
33a61a4
remove test_set_scale deadline
ieivanov Oct 3, 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
59 changes: 59 additions & 0 deletions iohub/cli/cli.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import csv
import pathlib

import click

from iohub._version import __version__
from iohub.convert import TIFFConverter
from iohub.ngff import open_ome_zarr
from iohub.reader import print_info

VERSION = __version__
Expand Down Expand Up @@ -87,3 +89,60 @@ def convert(input, output, grid_layout, chunks):
chunks=chunks,
)
converter()


@click.command()
josephschull marked this conversation as resolved.
Show resolved Hide resolved
@click.help_option("-h", "--help")
@click.argument(
"csvfile",
type=click.File("r"),
)
@click.argument(
"zarrfile",
type=click.Path(
exists=True,
file_okay=True,
dir_okay=False,
josephschull marked this conversation as resolved.
Show resolved Hide resolved
josephschull marked this conversation as resolved.
Show resolved Hide resolved
resolve_path=True,
path_type=pathlib.Path,
),
)
def rename_wells_cli(csvfile, zarrfile):
josephschull marked this conversation as resolved.
Show resolved Hide resolved
"""Rename wells based on CSV file

The CSV file should have two columns: old_well_path and new_well_path.
"""
names = []

csvreader = csv.reader(csvfile)
for row in csvreader:
if len(row) != 2:
raise ValueError(
f"Invalid row format: {row}."
f"Each row must have two columns."
)
names.append([row[0], row[1]])

plate = open_ome_zarr(zarrfile, mode="a")

modified = {}
modified["wells"] = []
modified["rows"] = []
modified["columns"] = []

well_paths = [
plate.metadata.wells[i].path for i in range(len(plate.metadata.wells))
]

for old_well_path, new_well_path in names:
if old_well_path not in well_paths:
raise ValueError(
f"Old well path '{old_well_path}' not found "
f"in the plate metadata."
)
for well in plate.metadata.wells:
if well.path == old_well_path and well not in modified["wells"]:
plate.rename_well(
plate, well, old_well_path, new_well_path, modified, False
josephschull marked this conversation as resolved.
Show resolved Hide resolved
)
modified["wells"].append(well)
44 changes: 44 additions & 0 deletions iohub/ngff.py
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,50 @@ def positions(self) -> Generator[tuple[str, Position], None, None]:
for _, position in well.positions():
yield position.zgroup.path, position

def rename_well(
self,
well,
old_well_path: str,
josephschull marked this conversation as resolved.
Show resolved Hide resolved
new_well_path: str,
modified={},
single_well=True,
):
"""Rename a well.

Parameters
----------
old_well_path : str
Old name of well
new_well_path : str
New name of well
modified : dict, optional
Tracks modified wells
single well: bool, optional
True: renaming one well, False: renaming multiple wells
josephschull marked this conversation as resolved.
Show resolved Hide resolved
"""
old_row, old_column = old_well_path.split("/")
new_row, new_column = new_well_path.split("/")

if well.path == old_well_path:
well.path = new_well_path # update well metadata
zarr.storage.rename(
self.zgroup._store, old_well_path, new_well_path
) # update well paths

for column in self.metadata.columns:
if column.name == old_column and column not in modified["columns"]:
column.name = new_column # update column metadata
if not single_well:
modified["columns"].append(column)

for row in self.metadata.rows:
if row.name == old_row and row not in modified["rows"]:
row.name = new_row # update row metadata
if not single_well:
modified["rows"].append(row)

self.dump_meta()


def open_ome_zarr(
store_path: StrOrBytesPath,
Expand Down
Loading