Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 4 additions & 0 deletions formats/czi-extract-plugin/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.venv
out
tests
__pycache__
23 changes: 23 additions & 0 deletions formats/czi-extract-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Jupyter Notebook
.ipynb_checkpoints
poetry.lock
../../poetry.lock
# Environments
.env
.myenv
.venv
env/
venv/
# test data directory
data
# yaml file
.pre-commit-config.yaml
# hidden files
.DS_Store
.ds_store
# flake8
.flake8
../../.flake8
__pycache__
.mypy_cache
requirements.txt
10 changes: 10 additions & 0 deletions formats/czi-extract-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## [1.1.2-dev] - 2024-01-10
### Added
- Pytests to test this plugin
- This plugin is now installable with pip.

### Changed
- Updated dependencies (bfio, filepattern, preadator) to latest
- Argparse package is replaced with Typer package for command line arguments
- Replaced docker base image with latest container image with pre-installed bfio

19 changes: 19 additions & 0 deletions formats/czi-extract-plugin/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM polusai/bfio:2.3.3

# environment variables defined in polusai/bfio
ENV EXEC_DIR="/opt/executables"
ENV POLUS_IMG_EXT=".ome.tif"
ENV POLUS_TAB_EXT=".csv"

# Work directory defined in the base container
WORKDIR ${EXEC_DIR}

COPY pyproject.toml ${EXEC_DIR}
COPY VERSION ${EXEC_DIR}
COPY README.md ${EXEC_DIR}
COPY src ${EXEC_DIR}/src

RUN pip3 install ${EXEC_DIR} --no-cache-dir

ENTRYPOINT ["python3", "-m", "polus.plugins.formats.czi_extract"]
CMD ["--help"]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Polus CZI Extraction Plugin (v1.1.0)
# Polus CZI Extraction Plugin (v1.1.2-dev)

This WIPP plugin will import individual fields of view from a CZI file (will
only import one scene or collection of images). Images are exported as tiled
Expand Down Expand Up @@ -39,19 +39,22 @@ the contents of `plugin.json` into the pop-up window and submit.

## Options

This plugin takes one input argument and one output argument:
This plugin takes two input arguments and one output argument:

| Name | Description | I/O | Type |
| -------- | ----------------------- | ------ | ---- |
| `inpDir` | Input image collection | Input | Path |
| `outDir` | Output image collection | Output | List |
| `--inpDir` | Input image collection | Input | genericData |
| `--filePattern` | Pattern to parse image files | Input | string |
| `--outDir` | Output image collection | Output | collection |
| `--preview` | Generate a JSON file with outputs | Output | JSON |

## Run the plugin

### Run the Docker Container

```bash
docker run -v /path/to/data:/data polus-czi-extract-plugin \
docker run -v /path/to/data:/data polusai/czi-extract-plugin:1.1.2-dev \
--inpDir /data/input \
--filePattern ".*.czi" \
--outDir /data/output
```
1 change: 1 addition & 0 deletions formats/czi-extract-plugin/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.1.2-dev
4 changes: 4 additions & 0 deletions formats/czi-extract-plugin/build-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

version=$(<VERSION)
docker build . -t polusai/czi-extract-plugin:${version}
27 changes: 27 additions & 0 deletions formats/czi-extract-plugin/bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[bumpversion]
current_version = 1.1.2-dev
commit = True
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+)(?P<dev>\d+))?
serialize =
{major}.{minor}.{patch}-{release}{dev}
{major}.{minor}.{patch}

[bumpversion:part:release]
optional_value = _
first_value = dev
values =
dev
_

[bumpversion:part:dev]

[bumpversion:file:pyproject.toml]
search = version = "{current_version}"
replace = version = "{new_version}"

[bumpversion:file:plugin.json]

[bumpversion:file:VERSION]

[bumpversion:file:src/polus/plugins/formats/czi_extract/__init__.py]
63 changes: 63 additions & 0 deletions formats/czi-extract-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"name": "Czi Extraction",
"version": "1.1.2-dev",
"title": "Extract TIFFs From CZI",
"description": "Extracts individual fields of view from a CZI file. Saves as OME TIFF.",
"author": "Nick Schaub (nick.schaub@nih.gov), Hamdah Shafqat Abbasi (hamdahshafqat.abbasi@nih.gov)",
"institution": "National Center for Advancing Translational Sciences, National Institutes of Health",
"repository": "https://github.com/PolusAI/polus-plugins",
"website": "https://ncats.nih.gov/preclinical/core/informatics",
"containerId": "polusai/czi-extract-plugin:1.1.2-dev",
"baseCommand": [
"python3",
"-m",
"polus.plugins.formats.czi_extract"
],
"inputs": {
"inpDir": {
"type": "collection",
"title": "Input collection",
"description": "Input image collection to be processed by this plugin.",
"required": "True"
},
"filePattern": {
"type": "string",
"title": "Filename pattern",
"description": "Filename pattern used to separate data.",
"required": "False"
},
"preview": {
"type": "boolean",
"title": "Preview",
"description": "Generate an output preview.",
"required": "False"
}
},
"outputs": {
"outDir": {
"type": "collection",
"description": "Output collection."
}
},
"ui": {
"inpDir": {
"type": "collection",
"title": "Input collection",
"description": "Input image collection to be processed by this plugin.",
"required": "True"
},
"filePattern": {
"type": "string",
"title": "Filename pattern",
"description": "Filename pattern used to separate data.",
"required": "False",
"default": ".*.czi"
},
"preview": {
"type": "boolean",
"title": "Preview example output of this plugin",
"description": "Generate an output preview.",
"required": "False"
}
}
}
34 changes: 34 additions & 0 deletions formats/czi-extract-plugin/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[tool.poetry]
name = "polus-plugins-formats-czi-extract"
version = "1.1.2-dev"
description = "Extracts individual fields of view from a CZI file. Saves as OME TIFF."
authors = [
"Nick Schaub <nick.schaub@nih.gov>",
"Hamdah Shafqat abbasi <hamdahshafqat.abbasi@nih.gov>"
]
readme = "README.md"
packages = [{include = "polus", from = "src"}]

[tool.poetry.dependencies]
python = ">=3.9,<3.12"
filepattern = "^2.0.4"
typer = "^0.7.0"
tqdm = "^4.64.1"
bfio = {version = "2.3.3", extras = ["all"]}
preadator="0.4.0.dev2"
czifile="^2019.7.2"

[tool.poetry.group.dev.dependencies]
bump2version = "^1.0.1"
pre-commit = "^3.0.4"
black = "^23.1.0"
flake8 = "^6.0.0"
mypy = "^1.0.0"
pytest = "^7.2.1"
ipykernel = "^6.21.2"
requests = "^2.28.2"
scikit-image = "^0.22.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ datapath=$(readlink --canonicalize ../data)
# Inputs
inpDir=/data/path_to_files

filePattern=".*.czi"

# Output paths
outDir=/data/path_to_output

Expand All @@ -15,7 +17,7 @@ LOGLEVEL=INFO
docker run --mount type=bind,source=${datapath},target=/data/ \
--user $(id -u):$(id -g) \
--env POLUS_LOG=${LOGLEVEL} \
labshare/polus-polus-czi-extract-plugin:${version} \
polusai/czi-extract-plugin:${version} \
--inpDir ${inpDir} \
--outDir ${outDir}

--filePattern ${filePattern} \
--outDir ${outDir}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"""Czi Extract Plugin."""
__version__ = "1.1.2-dev"
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""Czi Extract Plugin."""
import json
import logging
import os
from multiprocessing import cpu_count
from pathlib import Path
from typing import Any
from typing import Optional

import filepattern as fp
import polus.plugins.formats.czi_extract.czi as cz
import typer

# Import environment variables
POLUS_EXT = os.environ.get("POLUS_EXT", ".ome.tif")

app = typer.Typer()

# Initialize the logger
logging.basicConfig(
format="%(asctime)s - %(name)-8s - %(levelname)-8s - %(message)s",
datefmt="%d-%b-%y %H:%M:%S",
)
logger = logging.getLogger("polus.plugins.formats.czi_extract")


@app.command()
def main(
inp_dir: Path = typer.Option(
...,
"--inpDir",
"-i",
help="Path to folder with CZI files",
),
file_pattern: str = typer.Option(
".*.czi",
"--filePattern",
"-f",
help="Pattern use to parse filenames",
),
out_dir: Path = typer.Option(
...,
"--outDir",
"-o",
help="Output directory",
),
preview: Optional[bool] = typer.Option(
False,
"--preview",
help="Output a JSON preview of files",
),
) -> None:
"""Extracts individual fields of view from a CZI file and saves as OME TIFF."""
logger.info(f"--inpDir = {inp_dir}")
logger.info(f"--filePattern = {file_pattern}")
logger.info(f"--outDir = {out_dir}")

inp_dir = inp_dir.resolve()
out_dir = out_dir.resolve()

assert inp_dir.exists(), f"{inp_dir} does not exist!! Please check input path again"
assert (
out_dir.exists()
), f"{out_dir} does not exist!! Please check output path again"

files = fp.FilePattern(inp_dir, file_pattern)

file_ext = all(Path(f[1][0].name).suffix for f in files())
assert (
file_ext is True
), f"{inp_dir} does not contain all czi files!! Please check input directory again"

if preview:
with Path.open(Path(out_dir, "preview.json"), "w") as jfile:
out_json: dict[str, Any] = {
"filepattern": file_pattern,
"outDir": [],
}
for file in files():
out_name = file[1][0].name.replace(
"".join(file[1][0].suffixes),
".ome.tif",
)
out_json["outDir"].append(out_name)
json.dump(out_json, jfile, indent=2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running with the preview option, we should return here and not run the rest of the code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

else:
for file in files():
cz.extract_fovs(file[1][0], out_dir)

if __name__ == "__main__":
app()
Loading