Skip to content

Commit

Permalink
Merge pull request #2 from pontikos-lab/fix_py_dcm_version
Browse files Browse the repository at this point in the history
Fix py dcm version in metadata.json
  • Loading branch information
alanwilter authored Sep 30, 2024
2 parents adb84dd + c9fda5d commit 57a540b
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 180 deletions.
38 changes: 28 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
name: Test and Release
name: Test and Release Workflow

on:
pull_request:
branches:
- "*" # Run tests on all branches for PRs
push:
branches:
- main
- main # Run tests and potentially release on pushes to main
paths:
- "**/*.py"
- pyproject.toml
- poetry.lock

jobs:
test-and-release:
name: Test and Release
run-tests:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install poetry
poetry install
- name: Run tests
run: poetry run pytest -k 'not test_main_mapping_example_dir_relative and not test_main_mapping_example_dir and not test_process_dcm'

release:
name: Release
needs: run-tests
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: write
Expand All @@ -20,20 +42,14 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install dependencies
run: |
pip install poetry commitizen
poetry install
- name: Run tests
run: poetry run pytest -k 'not test_main_mapping_example_dir_relative and not test_main_mapping_example_dir and not test_process_dcm'

- name: Check if version bump is needed
id: check
continue-on-error: true
Expand All @@ -42,6 +58,7 @@ jobs:
echo "bump=$(cz bump --dry-run 2>&1 | grep -q 'bump:' && echo 'yes' || echo 'no')" >> $GITHUB_OUTPUT
- name: Set up Git user
if: steps.check.outputs.bump == 'yes'
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
Expand All @@ -54,6 +71,7 @@ jobs:
echo "version=$(git describe --tags --abbrev=0)" >> $GITHUB_OUTPUT
- name: Build project
if: steps.check.outputs.bump == 'yes'
run: poetry build

- name: Generate Changelog
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ repos:
- id: check-merge-conflict
- id: check-docstring-first
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.5
rev: v0.6.8
hooks:
- id: ruff
args: ["--fix"]
files: ^hooks
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.5
rev: v0.6.8
hooks:
- id: ruff-format
files: ^hooks
- repo: https://github.com/commitizen-tools/commitizen
rev: v3.29.0
rev: v3.29.1
hooks:
- id: commitizen
stages:
Expand Down
8 changes: 1 addition & 7 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
fileignoreconfig:
- filename: poetry.lock
checksum: 1c2b16ed82e9ee932d71256bd8951b7bb6615a0bed7b0aae452ba97e5fcbe769
- filename: tests/test_utils.py
checksum: a674113efa3a5e2dba900599efe3bdbe16ce88dca297ec57752ad20afb399908
- filename: tests/test_main.py
checksum: 59a23ed618d9f4f2b0e357444be748cd00233bcf7428a8afde1b3be89258a103
- filename: process_dcm/utils.py
checksum: c7e686f07cf036a427a8dcb3719affc72d5de9357b48625c688aab01614f57f3
checksum: 0ad40dc799769c4734b1f5791c32eb5657f6a337fd70492d16b4b8878bdcbf9f
version: ""
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
"source.organizeImports": "explicit"
},
"editor.formatOnType": true
}
},
"conventionalCommits.scopes": ["deps"]
}
199 changes: 100 additions & 99 deletions poetry.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions process_dcm/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def main(
fg=typer.colors.BRIGHT_YELLOW,
)

len_sf, base_dir, subfolders = find_dicom_folders_with_base(input_dir)
len_sf, base_dir, subfolders = find_dicom_folders_with_base(os.path.abspath(input_dir))
output_dirs = []

if os.path.isabs(output_dir):
Expand All @@ -121,7 +121,7 @@ def main(
output_dirs = [os.path.join(x, output_dir) for x in subfolders]
else:
output_dir = os.path.abspath(output_dir)
output_dirs = [x.replace(base_dir, output_dir) for x in subfolders]
output_dirs = [x.replace(os.path.abspath(base_dir), output_dir) for x in subfolders]

tasks = list(zip(subfolders, output_dirs))

Expand Down
25 changes: 15 additions & 10 deletions process_dcm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from pydicom.dataset import FileDataset
from pydicom.filereader import dcmread

from process_dcm import __version__
from process_dcm.const import RESERVED_CSV, ImageModality

warnings.filterwarnings("ignore", category=UserWarning, message="A value of type *")
Expand Down Expand Up @@ -153,7 +154,7 @@ def process_dcm_meta(
metadata["series"] = {}
metadata["images"]["images"] = []
metadata["parser_version"] = [1, 5, 2]
metadata["py_dcm_version"] = [0, 1, 0]
metadata["py_dcm_version"] = list(map(int, __version__.split(".")))

keep_gender = "g" in keep
keep_names = "n" in keep
Expand Down Expand Up @@ -449,18 +450,22 @@ def find_dicom_folders_with_base(root_folder: str) -> tuple[int, str, list[str]]
return len_ins, base_dir, natsorted(folders)


def get_md5(file_path: Path | str | list[str]) -> str:
"""Calculate the MD5 checksum of a file or list of files."""
def get_md5(file_path: Path | str | list[str], minus: int = 0) -> str:
"""Calculate the MD5 checksum of a file or list of files, optionally suppressing lines from the bottom."""
md5_hash = hashlib.md5()
if isinstance(file_path, str) or isinstance(file_path, Path):
with open(file_path, "rb") as f:
while chunk := f.read(4096):
md5_hash.update(chunk)

def process_file(file: Path | str) -> None:
with open(file, "rb") as f:
lines = f.readlines()
for line in lines[:-minus] if minus > 0 else lines:
md5_hash.update(line)

if isinstance(file_path, str | Path):
process_file(file_path)
elif isinstance(file_path, list):
for fname in file_path:
with open(fname, "rb") as f:
while chunk := f.read(4096):
md5_hash.update(chunk)
process_file(fname)

return md5_hash.hexdigest()


Expand Down
12 changes: 6 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ classifiers = [
python = "^3.10"
opencv-python-headless = "^4.10.0.84"
typer = "^0.12.5"
pydicom = "^3.0.0"
pydicom = "^3.0.1"
natsort = "^8.4.0"
pillow = "^10.4.0"
python-gdcm = "^3.0.24.1"
Expand All @@ -30,21 +30,21 @@ python-gdcm = "^3.0.24.1"
process-dcm = "process_dcm.main:cli"

[tool.poetry.group.dev.dependencies]
boto3-stubs = { extras = ["lambda", "s3"], version = "1.35.19" }
boto3-stubs = { extras = ["lambda", "s3"], version = "1.35.29" }
ipdb = "0.13.13"
ipython = "8.27.0"
jupyterlab = "4.2.5"
mypy = "1.11.2"
mypy-boto3-lambda = "1.35.3"
mypy-boto3-s3 = "1.35.16"
mypy-boto3-lambda = "1.35.28"
mypy-boto3-s3 = "1.35.22"
pandas-stubs = "2.2.2.240909"
pdbpp = "0.10.3"
pip = "24.2"
pre-commit = "3.8.0"
pytest-cov = "5.0.0"
pytest-env = "1.1.4"
pytest-env = "1.1.5"
pytest-xdist = "3.6.1"
ruff = "0.6.5"
ruff = "0.6.8"
typed-argument-parser = "1.10.1"
wheel = "0.44.0"
pytest-mock = "^3.14.0"
Expand Down
5 changes: 4 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from process_dcm import __version__ as version
from process_dcm.const import ImageModality

bottom = 11


def pytest_report_header():
return f">>>\tVersion: {version}\n"
Expand Down Expand Up @@ -46,7 +48,8 @@ def del_file_paths(file_paths: list[str]) -> None:
os.rmdir(path)


def create_directory_structure(base_path, structure):
def create_directory_structure(base_path: Path, structure: dict) -> None:
"""Creates a directory structure recursively."""
for item, content in structure.items():
path = base_path / item
if isinstance(content, dict):
Expand Down
41 changes: 22 additions & 19 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from process_dcm.const import RESERVED_CSV
from process_dcm.main import app, process_task
from process_dcm.utils import get_md5
from tests.conftest import remove_ansi_codes
from tests.conftest import bottom, remove_ansi_codes


def test_main_defaults(runner):
Expand Down Expand Up @@ -59,9 +59,9 @@ def test_cli_without_args(runner):
@pytest.mark.parametrize(
"md5, meta, keep",
[
(["837808d746aef8e2dd08defbdbc70818"], "0a9a930806f2784aa4e60d47b3bad6ed", "pndg"),
(["7a355bb7e0c95155d1541c7fe0941c5e"], "fd6c5a84aca6499b0ea8b99d4e25dc92", "pnDg"),
(["2319181ecfc33d35b01dcec65ab2c568"], "35fe295648681e3521da8dddaed63705", ""),
(["5ba37cc43233db423394cf98c81d5fbc"], "27e4fa04ad730718b2509af36743c995", "pndg"),
(["5ba37cc43233db423394cf98c81d5fbc"], "3a15fdd18a67b3d4ce7be6164f58f073", "pnDg"),
(["5ba37cc43233db423394cf98c81d5fbc"], "ba5973bc8dd8e15aa6bef95bcd248fbf", ""),
],
)
def test_main(md5, meta, keep, janitor, runner):
Expand All @@ -83,9 +83,10 @@ def test_main(md5, meta, keep, janitor, runner):
]
result = runner.invoke(app, args)
assert result.exit_code == 0
of = sorted(glob(f"{output_dir}/**/*"))
assert len(of) == 51
assert get_md5(output_dir / "example-dcms/metadata.json") == meta
tof = sorted(glob(f"{output_dir}/**/*"))
of = [x for x in tof if "metadata.json" not in x]
assert len(tof) == 51
assert get_md5(output_dir / "example-dcms/metadata.json", bottom) == meta
assert get_md5(of) in md5


Expand All @@ -94,10 +95,11 @@ def test_main_dummy(janitor, runner):
args = ["tests/dummy_ex", "-o", "dummy_dir", "-k", "p"]
result = runner.invoke(app, args)
assert result.exit_code == 0
of = sorted(glob("dummy_dir/**/*"))
assert len(of) == 2
assert get_md5("dummy_dir/dummy_ex/metadata.json") == "1cabdb14492a0e62d80cfc0a3fe304e9"
assert get_md5(of) in "b19bbfca59584915295f67e9259880d7"
tof = sorted(glob("dummy_dir/**/*"))
of = [x for x in tof if "metadata.json" not in x]
assert len(tof) == 2
assert get_md5("dummy_dir/dummy_ex/metadata.json", bottom) == "0fbf0de5556e77447925ff3bfaf8168e"
assert get_md5(of) in ["377b5a17c284226518ccef9bddff25af"]


def test_main_mapping(janitor, runner):
Expand All @@ -121,10 +123,11 @@ def test_main_mapping(janitor, runner):
result = runner.invoke(app, args)
assert result.exit_code == 0
assert "WARN: '--relative' x 'absolute --output_dir'" in result.output
of = sorted(glob(f"{output_dir}/**/*"))
assert len(of) == 51
assert get_md5(output_dir / "example-dcms/metadata.json") == "261826ad2e067e9adb7143bb6c053dbc"
assert get_md5(of) in "6ff8e2fe69c5fbe86f81f44f74496cab"
tof = sorted(glob(f"{output_dir}/**/*"))
of = [x for x in tof if "metadata.json" not in x]
assert len(tof) == 51
assert get_md5(output_dir / "example-dcms/metadata.json", bottom) == "450e2e40d321a24219c1c9ec15b2c80e"
assert get_md5(of) in ["5ba37cc43233db423394cf98c81d5fbc"]


def test_main_abort(runner):
Expand All @@ -151,8 +154,8 @@ def test_main_mapping_example_dir(janitor, runner):
assert result.exit_code == 0
of = sorted(glob(f"{output_dir}/**/**/*"))
assert len(of) == 262
assert get_md5(output_dir / "012345/20180724_L/metadata.json") == "1b46961177c80daf69e7dea7379fcc31"
assert get_md5(output_dir / "3517807670/20180926_R/metadata.json") == "bbf5c47f9fb28f46b4cc1bf08c311593"
assert get_md5(output_dir / "012345/20180724_L/metadata.json", bottom) == "93fff12758d6c0f9098e7fd5e8c8304e"
assert get_md5(output_dir / "3517807670/20180926_R/metadata.json", bottom) == "b9ff35a765db6b1eaeac4253c93a6044"


# skip this test for CI
Expand All @@ -170,8 +173,8 @@ def test_main_mapping_example_dir_relative(janitor, runner):
janitor.append(path1)
janitor.append(path2)
assert len(of) == 262
assert get_md5(path1 / "20180724_L/dummy/metadata.json") == "1b46961177c80daf69e7dea7379fcc31"
assert get_md5(path2 / "20180926_R/dummy/metadata.json") == "bbf5c47f9fb28f46b4cc1bf08c311593"
assert get_md5(path1 / "20180724_L/dummy/metadata.json", bottom) == "93fff12758d6c0f9098e7fd5e8c8304e"
assert get_md5(path2 / "20180926_R/dummy/metadata.json", bottom) == "b9ff35a765db6b1eaeac4253c93a6044"


def test_process_task():
Expand Down
Loading

0 comments on commit 57a540b

Please sign in to comment.