Skip to content

Commit

Permalink
Merge pull request #7 from andreped:linting
Browse files Browse the repository at this point in the history
Implemented linting shell scripts and CI workflow
  • Loading branch information
andreped authored Sep 2, 2024
2 parents 56b9517 + 43a8ec6 commit cc4670b
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 22 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Check linting

on:
push:
branches: ['main']
pull_request:
branches: ['main']
workflow_dispatch:

jobs:
check-linting:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v1

- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: '3.10'

- name: Install lint dependencies
run: pip install black==22.3.0 isort==5.10.1 flake8==4.0.1

- name: Lint the code
run: sh shell/lint.sh
14 changes: 14 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[metadata]
description-file = README.md

[isort]
force_single_line=True
known_first_party=vsi2tif
line_length=120
profile=black

[flake8]
# imported but unused in __init__.py, that's ok.
per-file-ignores=*__init__.py:F401
ignore=E203,W503,W605,F632,E266,E731,E712,E741
max-line-length=120
7 changes: 7 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
]
},
install_requires=["tqdm", "numpy"],
extras_require={"dev": [
"wheel",
"setuptools",
"black==22.3.0",
"isort==5.10.1",
"flake8==4.0.1",
]},
classifiers=[
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
Expand Down
4 changes: 4 additions & 0 deletions shell/format.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
isort --sl vsi2tif
black --line-length 120 vsi2tif
flake8 vsi2tif
23 changes: 23 additions & 0 deletions shell/lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
isort --check --sl -c vsi2tif
if ! [ $? -eq 0 ]
then
echo "Please run \"sh shell/format.sh\" to format the code."
exit 1
fi
echo "no issues with isort"
flake8 vsi2tif
if ! [ $? -eq 0 ]
then
echo "Please fix the code style issue."
exit 1
fi
echo "no issues with flake8"
black --check --line-length 120 vsi2tif
if ! [ $? -eq 0 ]
then
echo "Please run \"sh shell/format.sh\" to format the code."
exit 1
fi
echo "no issues with black"
echo "linting success!"
6 changes: 4 additions & 2 deletions vsi2tif/src/benchmark.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from time import perf_counter
from functools import wraps
from time import perf_counter


def benchmark(func):
@wraps(func)
def wrapper(*args, **kwargs):
time_start = perf_counter()
result = func(*args, **kwargs)
time_duration = perf_counter() - time_start
print(f'Processing took {time_duration:.3f} seconds')
print(f"Processing took {time_duration:.3f} seconds")
return result

return wrapper
37 changes: 29 additions & 8 deletions vsi2tif/src/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@
from tempfile import TemporaryDirectory


def vsi2raw(input_path: str, output_path: str, bfconvert: str, compression: str = "LZW", tz: int = 1024, plane: int = 0, max_mem: int = 32) -> str:
def vsi2raw(
input_path: str,
output_path: str,
bfconvert: str,
compression: str = "LZW",
tz: int = 1024,
plane: int = 0,
max_mem: int = 32,
) -> str:
if not os.path.exists(bfconvert):
raise FileNotFoundError(f"bfconvert not found at: {bfconvert}")
if not os.path.exists(input_path):
raise FileNotFoundError(f"Input file not found at: {input_path}")

cmd = f"{bfconvert} -tilex {tz} -tiley {tz} -nogroup -no-upgrade -overwrite -bigtiff -series {plane} -compression {compression} {input_path} {output_path}"

cmd = f"{bfconvert} -tilex {tz} -tiley {tz} -nogroup -no-upgrade -overwrite -bigtiff -series {plane}"
f"-compression {compression} {input_path} {output_path}"

sp.check_call(cmd, shell=True, env={"BF_MAX_MEM": f"{max_mem}g"})

return output_path
Expand All @@ -18,14 +28,25 @@ def vsi2raw(input_path: str, output_path: str, bfconvert: str, compression: str
def raw2tiff(input_path: str, output_path: str, compression: str = "jpeg", quality: int = 85) -> None:
if not os.path.exists(input_path):
raise FileNotFoundError(f"Input file not found at: {input_path}")
if not os.path.exists(os.path.dirname(output_path)):
if not os.path.exists(os.path.dirname(output_path)):
raise FileNotFoundError(f"Output directory not found at: {os.path.dirname}")

cmd = f"vips tiffsave {input_path} {output_path} --bigtiff --tile --pyramid --compression={compression} --Q={quality}"

cmd = (
f"vips tiffsave {input_path} {output_path} --bigtiff --tile --pyramid --compression={compression} --Q={quality}"
)
sp.check_call(cmd, shell=True)


def vsi2tiff(input_path: str, output_path: str, bfconvert: str, compression: str = "jpeg", tz: int = 1024, plane: int = 0, quality: int = 85, max_mem: int = 32) -> None:
def vsi2tiff(
input_path: str,
output_path: str,
bfconvert: str,
compression: str = "jpeg",
tz: int = 1024,
plane: int = 0,
quality: int = 85,
max_mem: int = 32,
) -> None:
# create temporary directory to store intermediate files
temp_dir = TemporaryDirectory()

Expand All @@ -34,7 +55,7 @@ def vsi2tiff(input_path: str, output_path: str, bfconvert: str, compression: str

# first convert from Olympus format to raw TIFF
vsi2raw(input_path, bigtiff_path, bfconvert, "LZW", tz, plane, max_mem)

# construct tiled, pyramidal TIFF
raw2tiff(bigtiff_path, output_path, compression, quality)

Expand Down
25 changes: 22 additions & 3 deletions vsi2tif/src/process.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
import os

from .benchmark import benchmark
from tqdm import tqdm

from .benchmark import benchmark
from .convert import vsi2tiff


@benchmark
def vsi2tiff_single(input_path: str, output_path:str, bfconvert: str, compression: str = "jpeg", tz: int = 1024, plane: int = 0, quality: int = 85, max_mem: int = 32) -> None:
def vsi2tiff_single(
input_path: str,
output_path: str,
bfconvert: str,
compression: str = "jpeg",
tz: int = 1024,
plane: int = 0,
quality: int = 85,
max_mem: int = 32,
) -> None:
vsi2tiff(input_path, output_path, bfconvert, compression, tz, plane, quality, max_mem)


@benchmark
def vsi2tiff_batch(input_path: str, output_path: str, bfconvert: str, compression: str = "jpeg", tz: int = 1024, plane: int = 0, quality: int = 85, max_mem: int = 32) -> None:
def vsi2tiff_batch(
input_path: str,
output_path: str,
bfconvert: str,
compression: str = "jpeg",
tz: int = 1024,
plane: int = 0,
quality: int = 85,
max_mem: int = 32,
) -> None:
# find path to all cellSens VSI images to convert
paths = [(root, file) for root, _, files in os.walk(input_path) for file in files if file.endswith(".vsi")]

Expand Down
33 changes: 24 additions & 9 deletions vsi2tif/vsi2tif.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import os
from argparse import ArgumentParser
from .src.process import vsi2tiff_single, vsi2tiff_batch

from .src.process import vsi2tiff_batch
from .src.process import vsi2tiff_single


def main():
parser = ArgumentParser(description='vsi2tif - simple tool for converting images from cellSens VSI to Generic TIFF')
parser = ArgumentParser(description="vsi2tif - simple tool for converting images from cellSens VSI to Generic TIFF")
parser.add_argument("-i", "--input", help="folder with input files", required=True)
parser.add_argument("-o", "--output", help="folder for output files", required=True)
parser.add_argument("-b", "--bfconvert", help="path to bfconvert tool", required=True)
parser.add_argument("-c", "--compression", help="compression technique used for last conversion step - default 'jpeg'", default="jpeg")
parser.add_argument(
"-c",
"--compression",
help="compression technique used for last conversion step - default 'jpeg'",
default="jpeg",
)
parser.add_argument("-p", "--plane", help="which image plane to convert image from - default 0", default=0)
parser.add_argument("-s", "--tilesize", help="tile size to use during both conversion steps - default 1024", default=1024)
parser.add_argument("-q", "--quality", help="compression quality used with JPEG compression - default 85", default=85)
parser.add_argument(
"-s", "--tilesize", help="tile size to use during both conversion steps - default 1024", default=1024
)
parser.add_argument(
"-q", "--quality", help="compression quality used with JPEG compression - default 85", default=85
)
argv = parser.parse_args()

if not os.path.isfile(argv.bfconvert):
raise FileNotFoundError(f"bfconvert not found at: {argv.bfconvert}")
if not os.path.exists(argv.input):
Expand All @@ -22,10 +33,14 @@ def main():
os.makedirs(argv.output, exist_ok=True)

if os.path.isdir(argv.input):
vsi2tiff_batch(argv.input, argv.output, argv.bfconvert, argv.compression, argv.tilesize, argv.plane, argv.quality)
vsi2tiff_batch(
argv.input, argv.output, argv.bfconvert, argv.compression, argv.tilesize, argv.plane, argv.quality
)
else:
vsi2tiff_single(argv.input, argv.output, argv.bfconvert, argv.compression, argv.tilesize, argv.plane, argv.quality)
vsi2tiff_single(
argv.input, argv.output, argv.bfconvert, argv.compression, argv.tilesize, argv.plane, argv.quality
)


if __name__ == '__main__':
if __name__ == "__main__":
main()

0 comments on commit cc4670b

Please sign in to comment.