"""Entrypoint for the `ome_zarr` command-line tool."""
import argparse
import logging
import sys
from .csv import csv_to_zarr
from .data import astronaut, coins, create_zarr
from .format import CurrentFormat, Format, format_from_version
from .utils import download as zarr_download
from .utils import finder as bff_finder
from .utils import info as zarr_info
from .utils import view as zarr_view
[docs]
def config_logging(loglevel: int, args: argparse.Namespace) -> None:
"""Configure logging taking the `verbose` and `quiet` arguments into account.
Each `-v` increases the `loglevel` by 10 and each `-q` reduces the loglevel by 10.
For example, an initial loglevel of `INFO` will be converted to `DEBUG` via `-qqv`.
"""
loglevel = loglevel - (10 * args.verbose) + (10 * args.quiet)
logging.basicConfig(level=loglevel)
# DEBUG logging for s3fs so we can track remote calls
logging.getLogger("s3fs").setLevel(logging.DEBUG)
[docs]
def info(args: argparse.Namespace) -> None:
"""Wrap the :func:`~ome_zarr.utils.info` method."""
config_logging(logging.WARNING, args)
list(zarr_info(args.path, stats=args.stats))
[docs]
def view(args: argparse.Namespace) -> None:
"""Wrap the :func:`~ome_zarr.utils.view` method."""
config_logging(logging.WARNING, args)
zarr_view(args.path, args.port, force=args.force)
[docs]
def finder(args: argparse.Namespace) -> None:
"""Wrap the :func:`~ome_zarr.utils.finder` method."""
config_logging(logging.WARNING, args)
bff_finder(args.path, args.port)
[docs]
def download(args: argparse.Namespace) -> None:
"""Wrap the :func:`~ome_zarr.utils.download` method."""
config_logging(logging.WARNING, args)
zarr_download(args.path, args.output)
[docs]
def create(args: argparse.Namespace) -> None:
"""Chooses between data generation methods in :mod:`ome_zarr.utils` like.
:func:`~ome_zarr.data.coins` or :func:`~ome_zarr.data.astronaut`.
"""
config_logging(logging.WARNING, args)
if args.method == "coins":
method = coins
label_name = "coins"
elif args.method == "astronaut":
method = astronaut
label_name = "circles"
else:
raise Exception(f"unknown method: {args.method}")
fmt: Format = CurrentFormat()
if args.format:
fmt = format_from_version(args.format)
create_zarr(args.path, method=method, label_name=label_name, fmt=fmt)
def scale(args: argparse.Namespace) -> None:
import dask.array as da
import zarr
from .writer import write_image
"""Wrap the :func:`~ome_zarr.scale._build_pyramid` method."""
base = zarr.open_array(args.input_array, mode="r")
scale_factors = tuple(args.downscale**i for i in range(1, args.max_layer + 1))
data = da.from_zarr(args.input_array)
write_image(
data,
args.output_directory,
axes=str(args.axes),
method=args.method,
scale_factors=scale_factors,
)
grp = zarr.open_group(args.output_directory, mode="a")
if args.copy_metadata:
print(f"copying attribute keys: {list(base.attrs.keys())}")
grp.attrs.update(base.attrs)
[docs]
def csv_to_labels(args: argparse.Namespace) -> None:
"""Adds csv data to labels properties"""
print("csv_to_labels", args.csv_path, args.zarr_path)
csv_to_zarr(args.csv_path, args.csv_id, args.csv_keys, args.zarr_path, args.zarr_id)
[docs]
def main(args: list[str] | None = None) -> None:
"""Run appropriate function with argparse arguments, handling errors."""
parser = argparse.ArgumentParser()
parser.add_argument(
"-v",
"--verbose",
action="count",
default=0,
help="increase loglevel for each use, e.g. -vvv",
)
parser.add_argument(
"-q",
"--quiet",
action="count",
default=0,
help="decrease loglevel for each use, e.q. -qqq",
)
subparsers = parser.add_subparsers(dest="command")
subparsers.required = True
# info
parser_info = subparsers.add_parser("info")
parser_info.add_argument("path", help="Path to image.zarr")
parser_info.add_argument("--stats", action="store_true")
parser_info.set_defaults(func=info)
# download
parser_download = subparsers.add_parser("download")
parser_download.add_argument("path")
parser_download.add_argument("--output", default=".")
parser_download.set_defaults(func=download)
# view (in ome-ngff-validator in a browser)
parser_view = subparsers.add_parser("view")
parser_view.add_argument(
"path",
help="Path to image.zarr to open in ome-ngff-validator",
)
parser_view.add_argument(
"--port", type=int, default=8000, help="Port to serve the data (default: 8000)"
)
parser_view.add_argument(
"--force",
"-f",
action="store_true",
help="Force open in browser. Don't check for OME-Zarr data first.",
)
parser_view.set_defaults(func=view)
# finder (open a dir of images in BioFile Finder in a browser)
parser_finder = subparsers.add_parser("finder")
parser_finder.add_argument(
"path",
help="Directory to open in BioFile Finder",
)
parser_finder.add_argument(
"--port", type=int, default=8000, help="Port to serve the data (default: 8000)"
)
parser_finder.set_defaults(func=finder)
# create
parser_create = subparsers.add_parser("create")
parser_create.add_argument(
"--method", choices=("coins", "astronaut"), default="coins"
)
parser_create.add_argument("path")
parser_create.add_argument(
"--format", help="OME-Zarr version to create. e.g. '0.4'"
)
parser_create.set_defaults(func=create)
parser_scale = subparsers.add_parser("scale")
parser_scale.add_argument("input_array")
parser_scale.add_argument("output_directory")
parser_scale.add_argument(
"axes", type=str, help="Dimensions of input data, i.e. 'zyx' or 'tczyx'."
)
parser_scale.add_argument(
"--copy-metadata",
action="store_true",
help="copies the array metadata to the new group",
)
parser_scale.add_argument(
"--method",
choices=["nearest", "resize", "laplacian", "local_mean", "zoom"],
default="resize",
)
parser_scale.add_argument(
"--in-place", action="store_true", help="if true, don't write the base array"
)
parser_scale.add_argument("--downscale", type=int, default=2)
parser_scale.add_argument("--max_layer", type=int, default=4)
parser_scale.set_defaults(func=scale)
# csv to label properties
parser_csv_to_labels = subparsers.add_parser("csv_to_labels")
parser_csv_to_labels.add_argument("csv_path", help="path to csv file")
parser_csv_to_labels.add_argument(
"csv_id",
help="csv column name containing ID for identifying label properties to update",
)
parser_csv_to_labels.add_argument(
"csv_keys", help="Comma-separated list of columns to read from csv to zarr"
)
parser_csv_to_labels.add_argument(
"zarr_path", help="path to local zarr plate or image"
)
parser_csv_to_labels.add_argument(
"zarr_id",
help="Labels properties key. Values should match csv_id column values",
)
parser_csv_to_labels.set_defaults(func=csv_to_labels)
if args is None:
ns = parser.parse_args(sys.argv[1:])
else:
ns = parser.parse_args(args)
try:
ns.func(ns)
except AssertionError as error:
logging.getLogger("ome_zarr.cli").error(error)
sys.exit(2)