diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e1eeb92c6b..f7024f1a08 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -12,6 +12,6 @@ A few sentences describing the changes proposed in this pull request. - [ ] Breaking change (fix or new feature that would cause existing functionality to change). - [ ] New tests added to cover the changes. - [ ] Integration tests passed locally by running `./runtests.sh -f -u --net --coverage`. -- [ ] Quick tests passed locally by running `./runtests.sh --quick --unittests --disttests`. +- [ ] Quick tests passed locally by running `./runtests.sh --quick --unittests`. - [ ] In-line docstrings updated. - [ ] Documentation updated, tested `make html` command in the `docs/` folder. diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 4e72a7dbcf..0000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,71 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ dev, main ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ dev ] - schedule: - - cron: '18 1 * * 0' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'cpp', 'python' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://git.io/codeql-language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - # - name: Autobuild - # uses: github/codeql-action/autobuild@v1 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - - name: Build - run: | - python -m pip install -r requirements-dev.txt - BUILD_MONAI=1 ./runtests.sh --build - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/cron-mmar.yml b/.github/workflows/cron-mmar.yml index f61ba59368..735c23117c 100644 --- a/.github/workflows/cron-mmar.yml +++ b/.github/workflows/cron-mmar.yml @@ -37,6 +37,6 @@ jobs: - name: Loading MMARs run: | # clean up temporary files - $(pwd)/runtests.sh --build --clean + $(pwd)/runtests.sh --clean # run tests python -m tests.ngc_mmar_loading diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index f50363b1e0..835069c833 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -48,8 +48,8 @@ jobs: python -c $'import torch\na,b=torch.zeros(1,device="cuda:0"),torch.zeros(1,device="cuda:1");\nwhile True:print(a,b)' > /dev/null & python -c "import torch; print(torch.__version__); print('{} of GPUs available'.format(torch.cuda.device_count()))" python -c 'import torch; print(torch.rand(5, 3, device=torch.device("cuda:0")))' - BUILD_MONAI=1 ./runtests.sh --build --coverage --unittests --disttests # unit tests with coverage report - BUILD_MONAI=1 ./runtests.sh --build --coverage --net # integration tests with coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --unittests # unit tests with coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --net # integration tests with coverage report coverage xml if pgrep python; then pkill python; fi - name: Upload coverage @@ -62,7 +62,7 @@ jobs: if: github.repository == 'Project-MONAI/MONAI' strategy: matrix: - container: ["pytorch:21.02", "pytorch:21.12"] # 21.02 for backward comp. + container: ["pytorch:21.02", "pytorch:21.10"] # 21.02 for backward comp. container: image: nvcr.io/nvidia/${{ matrix.container }}-py3 # testing with the latest pytorch base image options: "--gpus all" @@ -91,8 +91,8 @@ jobs: python -c $'import torch\na,b=torch.zeros(1,device="cuda:0"),torch.zeros(1,device="cuda:1");\nwhile True:print(a,b)' > /dev/null & python -c "import torch; print(torch.__version__); print('{} of GPUs available'.format(torch.cuda.device_count()))" python -c 'import torch; print(torch.rand(5, 3, device=torch.device("cuda:0")))' - BUILD_MONAI=1 ./runtests.sh --build --coverage --unittests --disttests # unit tests with coverage report - BUILD_MONAI=1 ./runtests.sh --build --coverage --net # integration tests with coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --unittests # unit tests with coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --net # integration tests with coverage report coverage xml if pgrep python; then pkill python; fi - name: Upload coverage @@ -106,7 +106,7 @@ jobs: if: github.repository == 'Project-MONAI/MONAI' strategy: matrix: - container: ["pytorch:21.02", "pytorch:21.12"] # 21.02 for backward comp. + container: ["pytorch:21.02", "pytorch:21.10"] # 21.02 for backward comp. container: image: nvcr.io/nvidia/${{ matrix.container }}-py3 # testing with the latest pytorch base image options: "--gpus all" @@ -190,8 +190,8 @@ jobs: python -c "import torch; print(torch.__version__); print('{} of GPUs available'.format(torch.cuda.device_count()))" python -c 'import torch; print(torch.rand(5,3, device=torch.device("cuda:0")))' ngc --version - BUILD_MONAI=1 ./runtests.sh --build --coverage --pytype --unittests --disttests # unit tests with pytype checks, coverage report - BUILD_MONAI=1 ./runtests.sh --build --coverage --net # integration tests with coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --pytype --unittests # unit tests with pytype checks, coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --net # integration tests with coverage report coverage xml if pgrep python; then pkill python; fi - name: Upload coverage diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 4b93632723..ff77a171ee 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -34,7 +34,7 @@ jobs: which python python -m pip install --upgrade pip wheel python -m pip uninstall -y torch torchvision - python -m pip install torch==1.10.1+cu111 torchvision==0.11.2+cu111 -f https://download.pytorch.org/whl/torch_stable.html + python -m pip install torch==1.10.0+cu111 torchvision==0.11.1+cu111 -f https://download.pytorch.org/whl/torch_stable.html python -m pip install -r requirements-dev.txt - name: Run integration tests run: | @@ -46,8 +46,8 @@ jobs: python -c $'import torch\na,b=torch.zeros(1,device="cuda:0"),torch.zeros(1,device="cuda:1");\nwhile True:print(a,b)' > /dev/null & python -c "import torch; print(torch.__version__); print('{} of GPUs available'.format(torch.cuda.device_count()))" python -c 'import torch; print(torch.rand(5,3, device=torch.device("cuda:0")))' - BUILD_MONAI=1 ./runtests.sh --build --net - BUILD_MONAI=1 ./runtests.sh --build --unittests --disttests + BUILD_MONAI=1 ./runtests.sh --net + BUILD_MONAI=1 ./runtests.sh --unittests if pgrep python; then pkill python; fi shell: bash - name: Add reaction diff --git a/.github/workflows/pythonapp-gpu.yml b/.github/workflows/pythonapp-gpu.yml index 848eaedcd6..6e460a2ade 100644 --- a/.github/workflows/pythonapp-gpu.yml +++ b/.github/workflows/pythonapp-gpu.yml @@ -20,36 +20,34 @@ jobs: matrix: environment: - "PT17+CUDA102" + - "PT17+CUDA110" - "PT18+CUDA102" - - "PT18+CUDA112" + - "PT18+CUDA110" - "PT19+CUDA114" - - "PT110+CUDA115" - "PT110+CUDA102" include: - # https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes - environment: PT17+CUDA102 pytorch: "torch==1.7.1 torchvision==0.8.2" base: "nvcr.io/nvidia/cuda:10.2-devel-ubuntu18.04" + - environment: PT17+CUDA110 + # we explicitly set pytorch to -h to avoid pip install error + pytorch: "-h" + base: "nvcr.io/nvidia/pytorch:20.09-py3" - environment: PT18+CUDA102 pytorch: "torch==1.8.1 torchvision==0.9.1" base: "nvcr.io/nvidia/cuda:10.2-devel-ubuntu18.04" - - environment: PT18+CUDA112 + - environment: PT18+CUDA110 # we explicitly set pytorch to -h to avoid pip install error - # 21.03: 1.9.0a0+df837d0 pytorch: "-h" - base: "nvcr.io/nvidia/pytorch:21.03-py3" + base: "nvcr.io/nvidia/pytorch:21.02-py3" - environment: PT19+CUDA114 # we explicitly set pytorch to -h to avoid pip install error + # https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes # 21.10: 1.10.0a0+0aef44c pytorch: "-h" base: "nvcr.io/nvidia/pytorch:21.10-py3" - - environment: PT110+CUDA115 - # we explicitly set pytorch to -h to avoid pip install error - # 21.12: 1.11.0a0+b6df043 - pytorch: "-h" - base: "nvcr.io/nvidia/pytorch:21.12-py3" - environment: PT110+CUDA102 - pytorch: "torch==1.10.1 torchvision==0.11.2" + pytorch: "torch==1.10.0 torchvision==0.11.1" base: "nvcr.io/nvidia/cuda:10.2-devel-ubuntu18.04" container: image: ${{ matrix.base }} @@ -63,7 +61,7 @@ jobs: [ ${{ matrix.environment }} = "PT18+CUDA102" ] || \ [ ${{ matrix.environment }} = "PT110+CUDA102" ] then - PYVER=3.7 PYSFX=3 DISTUTILS=python3-distutils && \ + PYVER=3.6 PYSFX=3 DISTUTILS=python3-distutils && \ apt-get update && apt-get install -y --no-install-recommends \ curl \ pkg-config \ @@ -124,7 +122,7 @@ jobs: python -c 'import torch; print(torch.rand(5, 3, device=torch.device("cuda:0")))' python -c "import monai; monai.config.print_config()" # build for the current self-hosted CI Tesla V100 - BUILD_MONAI=1 TORCH_CUDA_ARCH_LIST="7.0" ./runtests.sh --build --quick --unittests --disttests + BUILD_MONAI=1 TORCH_CUDA_ARCH_LIST="7.0" ./runtests.sh --quick --unittests if [ ${{ matrix.environment }} = "PT110+CUDA102" ]; then # test the clang-format tool downloading once coverage run -m tests.clang_format_utils diff --git a/.github/workflows/pythonapp-min.yml b/.github/workflows/pythonapp-min.yml index b7816542ea..e2ed6c7513 100644 --- a/.github/workflows/pythonapp-min.yml +++ b/.github/workflows/pythonapp-min.yml @@ -51,11 +51,11 @@ jobs: - if: runner.os == 'windows' name: Install torch cpu from pytorch.org (Windows only) run: | - python -m pip install torch==1.10.1+cpu -f https://download.pytorch.org/whl/torch_stable.html + python -m pip install torch==1.10.0+cpu -f https://download.pytorch.org/whl/torch_stable.html - name: Install the dependencies run: | # min. requirements - python -m pip install torch==1.10.1 + python -m pip install torch==1.10.0 python -m pip install -r requirements-min.txt python -m pip list BUILD_MONAI=0 python setup.py develop # no compile of extensions @@ -74,7 +74,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.7, 3.8, 3.9] + python-version: [3.6, 3.7, 3.8, 3.9] timeout-minutes: 40 steps: - uses: actions/checkout@v2 @@ -101,7 +101,7 @@ jobs: - name: Install the dependencies run: | # min. requirements - python -m pip install torch==1.10.1 + python -m pip install torch==1.10.0 python -m pip install -r requirements-min.txt python -m pip list BUILD_MONAI=0 python setup.py develop # no compile of extensions diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 7237c8d54d..2e2318c8a8 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -44,9 +44,9 @@ jobs: - name: Lint and type check run: | # clean up temporary files - $(pwd)/runtests.sh --build --clean + $(pwd)/runtests.sh --clean # Git hub actions have 2 cores, so parallize pytype - $(pwd)/runtests.sh --build --codeformat -j 2 + $(pwd)/runtests.sh --codeformat -j 2 quick-py3: # full dependencies installed tests for different OS runs-on: ${{ matrix.os }} @@ -87,10 +87,10 @@ jobs: - if: runner.os == 'windows' name: Install torch cpu from pytorch.org (Windows only) run: | - python -m pip install torch==1.10.1+cpu torchvision==0.11.2+cpu -f https://download.pytorch.org/whl/torch_stable.html + python -m pip install torch==1.10.0+cpu torchvision==0.11.1+cpu -f https://download.pytorch.org/whl/torch_stable.html - name: Install the dependencies run: | - python -m pip install torch==1.10.1 torchvision==0.11.2 + python -m pip install torch==1.10.0 torchvision==0.11.1 cat "requirements-dev.txt" python -m pip install -r requirements-dev.txt python -m pip list diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9cef1ff090..34f8390fa9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9] + python-version: [3.6, 3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 with: diff --git a/.github/workflows/setupapp.yml b/.github/workflows/setupapp.yml index ede2c87b92..eaf91f8876 100644 --- a/.github/workflows/setupapp.yml +++ b/.github/workflows/setupapp.yml @@ -44,7 +44,7 @@ jobs: python -m pip install --upgrade pip wheel python -m pip uninstall -y torch torchvision rm -rf $(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")/ruamel* - python -m pip install torch==1.10.1 torchvision==0.11.2 + python -m pip install torch==1.10.0 torchvision==0.11.1 python -m pip install -r requirements-dev.txt - name: Run unit tests report coverage run: | @@ -59,8 +59,8 @@ jobs: python -c $'import torch\na,b=torch.zeros(1,device="cuda:0"),torch.zeros(1,device="cuda:1");\nwhile True:print(a,b)' > /dev/null & python -c "import torch; print(torch.__version__); print('{} of GPUs available'.format(torch.cuda.device_count()))" python -c 'import torch; print(torch.rand(5, 3, device=torch.device("cuda:0")))' - BUILD_MONAI=1 ./runtests.sh --build --coverage --unittests --disttests # unit tests with coverage report - BUILD_MONAI=1 ./runtests.sh --build --coverage --net # integration tests with coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --unittests # unit tests with coverage report + BUILD_MONAI=1 ./runtests.sh --coverage --net # integration tests with coverage report coverage xml if pgrep python; then pkill python; fi shell: bash @@ -74,7 +74,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9] + python-version: [3.6, 3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 with: @@ -98,13 +98,13 @@ jobs: - name: Install the dependencies run: | python -m pip install --upgrade pip wheel - python -m pip install torch==1.10.1 torchvision==0.11.2 + python -m pip install torch==1.10.0 torchvision==0.11.1 python -m pip install -r requirements-dev.txt - name: Run quick tests CPU ubuntu run: | python -m pip list python -c 'import torch; print(torch.__version__); print(torch.rand(5,3))' - BUILD_MONAI=1 ./runtests.sh --build --quick --unittests --disttests + BUILD_MONAI=1 ./runtests.sh --quick --unittests coverage xml - name: Upload coverage uses: codecov/codecov-action@v1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3fc762db46..ea637fe329 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.0.1 hooks: - id: end-of-file-fixer - id: trailing-whitespace @@ -23,10 +23,10 @@ repos: - id: detect-private-key - repo: https://github.com/asottile/pyupgrade - rev: v2.31.0 + rev: v2.29.0 hooks: - id: pyupgrade - args: [--py37-plus] + args: [--py36-plus] name: Upgrade code exclude: | (?x)^( @@ -35,7 +35,7 @@ repos: )$ - repo: https://github.com/asottile/yesqa - rev: v1.3.0 + rev: v1.2.3 hooks: - id: yesqa name: Unused noqa diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec6bf35ef9..954549581a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,7 @@ python -m pip install -U -r requirements-dev.txt License information: all source code files should start with this paragraph: ``` -# Copyright (c) MONAI Consortium +# Copyright MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -113,7 +113,7 @@ or (for new features that would not break existing functionality): ``` It is recommended that the new test `test_[module_name].py` is constructed by using only -python 3.7+ build-in functions, `torch`, `numpy`, `coverage` (for reporting code coverages) and `parameterized` (for organising test cases) packages. +python 3.6+ build-in functions, `torch`, `numpy`, `coverage` (for reporting code coverages) and `parameterized` (for organising test cases) packages. If it requires any other external packages, please make sure: - the packages are listed in [`requirements-dev.txt`](requirements-dev.txt) - the new test `test_[module_name].py` is added to the `exclude_cases` in [`./tests/min_tests.py`](./tests/min_tests.py) so that @@ -228,7 +228,7 @@ Notably, for example, ``import monai.transforms.Spacing`` is the equivalent of ``monai.transforms.spatial.array.Spacing`` if ``class Spacing`` defined in file `monai/transforms/spatial/array.py` is decorated with ``@export("monai.transforms")``. -For string definition, [f-string](https://www.python.org/dev/peps/pep-0498/) is recommended to use over `%-print` and `format-print`. So please try to use `f-string` if you need to define any string object. +For string definition, [f-string](https://www.python.org/dev/peps/pep-0498/) is recommended to use over `%-print` and `format-print` from python 3.6. So please try to use `f-string` if you need to define any string object. #### Backwards compatibility MONAI is currently under active development, and with major version zero (following the [Semantic Versioning](https://semver.org/)). diff --git a/Dockerfile b/Dockerfile index 43dc103e0f..a76613f14a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -11,7 +11,7 @@ # To build with a different base image # please run `docker build` using the `--build-arg PYTORCH_IMAGE=...` flag. -ARG PYTORCH_IMAGE=nvcr.io/nvidia/pytorch:21.12-py3 +ARG PYTORCH_IMAGE=nvcr.io/nvidia/pytorch:21.10-py3 FROM ${PYTORCH_IMAGE} LABEL maintainer="monai.contact@gmail.com" diff --git a/docs/requirements.txt b/docs/requirements.txt index b56fd970d2..ac9c7f38a7 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,6 +1,6 @@ -f https://download.pytorch.org/whl/cpu/torch-1.6.0%2Bcpu-cp37-cp37m-linux_x86_64.whl torch>=1.6 -pytorch-ignite==0.4.7 +pytorch-ignite==0.4.6 numpy>=1.17 itk>=5.2 nibabel diff --git a/docs/source/apps.rst b/docs/source/apps.rst index f4f7aff2d2..11d60767ec 100644 --- a/docs/source/apps.rst +++ b/docs/source/apps.rst @@ -114,11 +114,7 @@ Clara MMARs .. automodule:: monai.apps.pathology.transforms.spatial.array .. autoclass:: SplitOnGrid :members: -.. autoclass:: TileOnGrid - :members: .. automodule:: monai.apps.pathology.transforms.spatial.dictionary .. autoclass:: SplitOnGridd :members: -.. autoclass:: TileOnGridd - :members: diff --git a/docs/source/conf.py b/docs/source/conf.py index 47a45a78e8..fe10c546cd 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -22,7 +22,7 @@ # -- Project information ----------------------------------------------------- project = "MONAI" -copyright = "MONAI Consortium" +copyright = "2020 - 2021 MONAI Consortium" author = "MONAI Contributors" # The full version, including alpha/beta/rc tags diff --git a/docs/source/data.rst b/docs/source/data.rst index 7f95354e8c..0ab64edb7b 100644 --- a/docs/source/data.rst +++ b/docs/source/data.rst @@ -21,12 +21,6 @@ Generic Interfaces :members: :special-members: __next__ -`DatasetFunc` -~~~~~~~~~~~~~ -.. autoclass:: DatasetFunc - :members: - :special-members: __next__ - `ShuffleBuffer` ~~~~~~~~~~~~~~~ .. autoclass:: ShuffleBuffer @@ -208,7 +202,6 @@ Decathlon Datalist .. autofunction:: monai.data.load_decathlon_datalist .. autofunction:: monai.data.load_decathlon_properties .. autofunction:: monai.data.check_missing_files -.. autofunction:: monai.data.create_cross_validation_datalist DataLoader diff --git a/docs/source/engines.rst b/docs/source/engines.rst index 0cd40afb78..cc0ec3c659 100644 --- a/docs/source/engines.rst +++ b/docs/source/engines.rst @@ -11,21 +11,20 @@ Multi-GPU data parallel .. automodule:: monai.engines.multi_gpu_supervised_trainer :members: + Workflows --------- -.. currentmodule:: monai.engines - -`BaseWorkflow` -~~~~~~~~~~~~~~ -.. autoclass:: BaseWorkflow - :members: +.. automodule:: monai.engines.workflow +.. currentmodule:: monai.engines.workflow `Workflow` ~~~~~~~~~~ .. autoclass:: Workflow :members: +.. currentmodule:: monai.engines + `Trainer` ~~~~~~~~~ .. autoclass:: Trainer @@ -55,8 +54,3 @@ Workflows ~~~~~~~~~~~~~~~~~~~ .. autoclass:: EnsembleEvaluator :members: - -Utilities ---------- -.. automodule:: monai.engines.utils - :members: diff --git a/docs/source/installation.md b/docs/source/installation.md index 2635a6c386..c431b3389a 100644 --- a/docs/source/installation.md +++ b/docs/source/installation.md @@ -14,7 +14,7 @@ --- -MONAI's core functionality is written in Python 3 (>= 3.7) and only requires [Numpy](https://numpy.org/) and [Pytorch](https://pytorch.org/). +MONAI's core functionality is written in Python 3 (>= 3.6) and only requires [Numpy](https://numpy.org/) and [Pytorch](https://pytorch.org/). The package is currently distributed via Github as the primary source code repository, and the Python package index (PyPI). The pre-built Docker images are made available on DockerHub. diff --git a/docs/source/metrics.rst b/docs/source/metrics.rst index 332571d345..d6e2aff75b 100644 --- a/docs/source/metrics.rst +++ b/docs/source/metrics.rst @@ -8,8 +8,6 @@ Metrics `FROC` ------ -.. autofunction:: compute_fp_tp_probs -.. autofunction:: compute_froc_curve_data .. autofunction:: compute_froc_score `Metric` @@ -49,7 +47,6 @@ Metrics `Confusion matrix` ------------------ .. autofunction:: get_confusion_matrix -.. autofunction:: compute_confusion_matrix_metric .. autoclass:: ConfusionMatrixMetric :members: @@ -57,7 +54,6 @@ Metrics `Hausdorff distance` -------------------- .. autofunction:: compute_hausdorff_distance -.. autofunction:: compute_percent_hausdorff_distance .. autoclass:: HausdorffDistanceMetric :members: @@ -93,8 +89,3 @@ Metrics -------------------- .. autoclass:: CumulativeAverage :members: - -Utilities ---------- -.. automodule:: monai.metrics.utils - :members: diff --git a/docs/source/networks.rst b/docs/source/networks.rst index 720a3723dc..bb9d24e6f7 100644 --- a/docs/source/networks.rst +++ b/docs/source/networks.rst @@ -21,7 +21,7 @@ Blocks :members: `CRF` -~~~~~ +~~~~~~~~~~~~~ .. autoclass:: CRF :members: @@ -73,8 +73,6 @@ Blocks :members: .. autoclass:: UnetUpBlock :members: -.. autoclass:: UnetOutBlock - :members: `SegResnet Block` ~~~~~~~~~~~~~~~~~ @@ -256,11 +254,6 @@ Layers .. automodule:: monai.networks.layers.Conv :members: -`Pad` -~~~~~ -.. automodule:: monai.networks.layers.Pad - :members: - `Pool` ~~~~~~ .. automodule:: monai.networks.layers.Pool @@ -307,7 +300,7 @@ Layers :members: `PHLFilter` -~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~ .. autoclass:: PHLFilter `GaussianMixtureModel` @@ -393,11 +386,6 @@ Nets .. autoclass:: EfficientNet :members: -`BlockArgs` -~~~~~~~~~~~ -.. autoclass:: BlockArgs - :members: - `EfficientNetBN` ~~~~~~~~~~~~~~~~ .. autoclass:: EfficientNetBN @@ -418,11 +406,6 @@ Nets .. autoclass:: SegResNetVAE :members: -`ResNet` -~~~~~~~~ -.. autoclass:: ResNet - :members: - `SENet` ~~~~~~~ .. autoclass:: SENet @@ -530,11 +513,6 @@ Nets .. autoclass:: FullyConnectedNet :members: -`VarFullyConnectedNet` -~~~~~~~~~~~~~~~~~~~~~~ -.. autoclass:: VarFullyConnectedNet - :members: - `Generator` ~~~~~~~~~~~ .. autoclass:: Generator diff --git a/docs/source/optimizers.rst b/docs/source/optimizers.rst index 67cbdc0951..c766ac3cf9 100644 --- a/docs/source/optimizers.rst +++ b/docs/source/optimizers.rst @@ -6,11 +6,6 @@ Optimizers ========== .. currentmodule:: monai.optimizers -`LearningRateFinder` --------------------- -.. autoclass:: LearningRateFinder - :members: - `Novograd` ---------- .. autoclass:: Novograd @@ -19,18 +14,3 @@ Optimizers `Generate parameter groups` --------------------------- .. autofunction:: generate_param_groups - -`ExponentialLR` ---------------- -.. autoclass:: ExponentialLR - :members: - -`LinearLR` ----------- -.. autoclass:: LinearLR - :members: - -`WarmupCosineSchedule` ----------------------- -.. autoclass:: WarmupCosineSchedule - :members: diff --git a/docs/source/transforms.rst b/docs/source/transforms.rst index 49ed4c9e6c..37a4a4cf44 100644 --- a/docs/source/transforms.rst +++ b/docs/source/transforms.rst @@ -43,11 +43,6 @@ Generic Interfaces .. autoclass:: InvertibleTransform :members: -`TraceableTransform` -^^^^^^^^^^^^^^^^^^^^ -.. autoclass:: TraceableTransform - :members: - `BatchInverseTransform` ^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: BatchInverseTransform @@ -69,12 +64,6 @@ Vanilla Transforms Crop and Pad ^^^^^^^^^^^^ -`PadListDataCollate` -"""""""""""""""""""" -.. autoclass:: PadListDataCollate - :members: - :special-members: __call__ - `Pad` """"" .. autoclass:: Pad @@ -324,8 +313,6 @@ Intensity `SavitzkyGolaySmooth` """"""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/SavitzkyGolaySmooth.png - :alt: example of SavitzkyGolaySmooth .. autoclass:: SavitzkyGolaySmooth :members: :special-members: __call__ @@ -408,14 +395,6 @@ Intensity :members: :special-members: __call__ -`RandRicianNoise` -""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandRicianNoise.png - :alt: example of RandRicianNoise -.. autoclass:: RandRicianNoise - :members: - :special-members: __call__ - `RandCoarseTransform` """"""""""""""""""""" .. autoclass:: RandCoarseTransform @@ -647,8 +626,6 @@ Spatial `GridDistortion` """""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/GridDistortion.png - :alt: example of GridDistortion .. autoclass:: GridDistortion :members: :special-members: __call__ @@ -725,33 +702,28 @@ Spatial :members: :special-members: __call__ +`AddCoordinateChannels` +""""""""""""""""""""""" +.. autoclass:: AddCoordinateChannels + :members: + :special-members: __call__ + + Smooth Field ^^^^^^^^^^^^ `RandSmoothFieldAdjustContrast` """"""""""""""""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandSmoothFieldAdjustContrast.png - :alt: example of RandSmoothFieldAdjustContrast .. autoclass:: RandSmoothFieldAdjustContrast :members: :special-members: __call__ `RandSmoothFieldAdjustIntensity` """""""""""""""""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandSmoothFieldAdjustIntensity.png - :alt: example of RandSmoothFieldAdjustIntensity .. autoclass:: RandSmoothFieldAdjustIntensity :members: :special-members: __call__ -`RandSmoothDeform` -"""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandSmoothDeform.png - :alt: example of RandSmoothDeform -.. autoclass:: RandSmoothDeform - :members: - :special-members: __call__ - Utility ^^^^^^^ @@ -858,12 +830,6 @@ Utility :members: :special-members: __call__ -`RemoveRepeatedChannel` -""""""""""""""""""""""" -.. autoclass:: RemoveRepeatedChannel - :members: - :special-members: __call__ - `LabelToMask` """"""""""""" .. autoclass:: LabelToMask @@ -936,12 +902,6 @@ Utility :members: :special-members: __call__ -`AddCoordinateChannels` -""""""""""""""""""""""" -.. autoclass:: AddCoordinateChannels - :members: - :special-members: __call__ - Dictionary Transforms --------------------- @@ -1190,14 +1150,6 @@ Intensity (Dict) :members: :special-members: __call__ -`RandRicianNoised` -"""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandRicianNoised.png - :alt: example of RandRicianNoised -.. autoclass:: RandRicianNoised - :members: - :special-members: __call__ - `ScaleIntensityRangePercentilesd` """"""""""""""""""""""""""""""""" .. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/ScaleIntensityRangePercentilesd.png @@ -1230,14 +1182,6 @@ Intensity (Dict) :members: :special-members: __call__ -`SavitzkyGolaySmoothd` -"""""""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/SavitzkyGolaySmoothd.png - :alt: example of SavitzkyGolaySmoothd -.. autoclass:: SavitzkyGolaySmoothd - :members: - :special-members: __call__ - `GaussianSmoothd` """"""""""""""""" .. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/GaussianSmoothd.png @@ -1526,10 +1470,14 @@ Spatial (Dict) :members: :special-members: __call__ +`AddCoordinateChannelsd` +"""""""""""""""""""""""" +.. autoclass:: AddCoordinateChannelsd + :members: + :special-members: __call__ + `GridDistortiond` """"""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/GridDistortiond.png - :alt: example of GridDistortiond .. autoclass:: GridDistortiond :members: :special-members: __call__ @@ -1547,28 +1495,16 @@ Smooth Field (Dict) `RandSmoothFieldAdjustContrastd` """""""""""""""""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandSmoothFieldAdjustContrastd.png - :alt: example of RandSmoothFieldAdjustContrastd .. autoclass:: RandSmoothFieldAdjustContrastd :members: :special-members: __call__ `RandSmoothFieldAdjustIntensityd` """"""""""""""""""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandSmoothFieldAdjustIntensityd.png - :alt: example of RandSmoothFieldAdjustIntensityd .. autoclass:: RandSmoothFieldAdjustIntensityd :members: :special-members: __call__ -`RandSmoothDeformd` -""""""""""""""""""" -.. image:: https://github.com/Project-MONAI/DocImages/raw/main/transforms/RandSmoothDeformd.png - :alt: example of RandSmoothDeformd -.. autoclass:: RandSmoothDeformd - :members: - :special-members: __call__ - Utility (Dict) ^^^^^^^^^^^^^^ @@ -1632,12 +1568,6 @@ Utility (Dict) :members: :special-members: __call__ -`ToPIL` -""""""" -.. autoclass:: ToPIL - :members: - :special-members: __call__ - `ToCupyd` """"""""" .. autoclass:: ToCupyd @@ -1776,21 +1706,10 @@ Utility (Dict) :members: :special-members: __call__ -`AddCoordinateChannelsd` -"""""""""""""""""""""""" -.. autoclass:: AddCoordinateChannelsd - :members: - :special-members: __call__ - Transform Adaptors ------------------ .. automodule:: monai.transforms.adaptors -`FunctionSignature` -^^^^^^^^^^^^^^^^^^^ -.. autoclass:: FunctionSignature - :members: - `adaptor` ^^^^^^^^^ .. autofunction:: monai.transforms.adaptors.adaptor diff --git a/docs/source/utils.rst b/docs/source/utils.rst index 881519936b..c97d16de17 100644 --- a/docs/source/utils.rst +++ b/docs/source/utils.rst @@ -51,28 +51,3 @@ Type conversion --------------- .. automodule:: monai.utils.type_conversion :members: - -Decorators ----------- -.. automodule:: monai.utils.decorators - :members: - -Distributed Data Parallel -------------------------- -.. automodule:: monai.utils.dist - :members: - -Enums ------ -.. automodule:: monai.utils.enums - :members: - -Jupyter Utilities ------------------ -.. automodule:: monai.utils.jupyter_utils - :members: - -State Cacher ------------- -.. automodule:: monai.utils.state_cacher - :members: diff --git a/docs/source/visualize.rst b/docs/source/visualize.rst index 3779feec88..850fd51770 100644 --- a/docs/source/visualize.rst +++ b/docs/source/visualize.rst @@ -24,8 +24,3 @@ Occlusion sensitivity .. automodule:: monai.visualize.occlusion_sensitivity :members: - -Utilities ---------- -.. automodule:: monai.visualize.utils - :members: diff --git a/matshow3d_rgb_test.png b/matshow3d_rgb_test.png new file mode 100644 index 0000000000..7c8e224c0e Binary files /dev/null and b/matshow3d_rgb_test.png differ diff --git a/monai/__init__.py b/monai/__init__.py index 68a232b46d..dbe0a0aa03 100644 --- a/monai/__init__.py +++ b/monai/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -15,24 +15,22 @@ from ._version import get_versions PY_REQUIRED_MAJOR = 3 -PY_REQUIRED_MINOR = 7 +PY_REQUIRED_MINOR = 6 version_dict = get_versions() __version__: str = version_dict.get("version", "0+unknown") __revision_id__: str = version_dict.get("full-revisionid") del get_versions, version_dict -__copyright__ = "(c) MONAI Consortium" +__copyright__ = "(c) 2020 - 2021 MONAI Consortium" __basedir__ = os.path.dirname(__file__) if sys.version_info.major != PY_REQUIRED_MAJOR or sys.version_info.minor < PY_REQUIRED_MINOR: - import warnings - - warnings.warn( - f"MONAI requires Python {PY_REQUIRED_MAJOR}.{PY_REQUIRED_MINOR} or higher. " - f"But the current Python is: {sys.version}", - category=RuntimeWarning, + raise RuntimeError( + "MONAI requires Python {}.{} or higher. But the current Python is: {}".format( + PY_REQUIRED_MAJOR, PY_REQUIRED_MINOR, sys.version + ) ) from .utils.module import load_submodules # noqa: E402 diff --git a/monai/_extensions/__init__.py b/monai/_extensions/__init__.py index fd32d71840..3718894b7c 100644 --- a/monai/_extensions/__init__.py +++ b/monai/_extensions/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/_extensions/gmm/gmm.cpp b/monai/_extensions/gmm/gmm.cpp index 686fddb721..ecb85e252a 100644 --- a/monai/_extensions/gmm/gmm.cpp +++ b/monai/_extensions/gmm/gmm.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/_extensions/gmm/gmm.h b/monai/_extensions/gmm/gmm.h index 6317baa41a..9a43351eb9 100644 --- a/monai/_extensions/gmm/gmm.h +++ b/monai/_extensions/gmm/gmm.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/_extensions/gmm/gmm_cpu.cpp b/monai/_extensions/gmm/gmm_cpu.cpp index c9b55490eb..87ab1c4dab 100644 --- a/monai/_extensions/gmm/gmm_cpu.cpp +++ b/monai/_extensions/gmm/gmm_cpu.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/_extensions/gmm/gmm_cuda.cu b/monai/_extensions/gmm/gmm_cuda.cu index 765ffe5b1c..36af48b06c 100644 --- a/monai/_extensions/gmm/gmm_cuda.cu +++ b/monai/_extensions/gmm/gmm_cuda.cu @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/_extensions/gmm/gmm_cuda_linalg.cuh b/monai/_extensions/gmm/gmm_cuda_linalg.cuh index 9d54d80d3b..49e68c8442 100644 --- a/monai/_extensions/gmm/gmm_cuda_linalg.cuh +++ b/monai/_extensions/gmm/gmm_cuda_linalg.cuh @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/_extensions/loader.py b/monai/_extensions/loader.py index 2b57302fb0..d7ebca64e3 100644 --- a/monai/_extensions/loader.py +++ b/monai/_extensions/loader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/__init__.py b/monai/apps/__init__.py index 893f7877d2..1df6d74f9d 100644 --- a/monai/apps/__init__.py +++ b/monai/apps/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/datasets.py b/monai/apps/datasets.py index 8b03393fd6..2b2f48f5d0 100644 --- a/monai/apps/datasets.py +++ b/monai/apps/datasets.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -51,12 +51,6 @@ class MedNISTDataset(Randomizable, CacheDataset): will take the minimum of (cache_num, data_length x cache_rate, data_length). num_workers: the number of worker threads to use. if 0 a single thread will be used. Default is 0. - progress: whether to display a progress bar when downloading dataset and computing the transform cache content. - copy_cache: whether to `deepcopy` the cache content before applying the random transforms, - default to `True`. if the random transforms don't modify the cached content - (for example, randomly crop from the cached image and deepcopy the crop region) - or if every cache item is only used once in a `multi-processing` environment, - may set `copy=False` for better performance. Raises: ValueError: When ``root_dir`` is not a directory. @@ -81,8 +75,6 @@ def __init__( cache_num: int = sys.maxsize, cache_rate: float = 1.0, num_workers: int = 0, - progress: bool = True, - copy_cache: bool = True, ) -> None: root_dir = Path(root_dir) if not root_dir.is_dir(): @@ -95,14 +87,7 @@ def __init__( dataset_dir = root_dir / self.dataset_folder_name self.num_class = 0 if download: - download_and_extract( - url=self.resource, - filepath=tarfile_name, - output_dir=root_dir, - hash_val=self.md5, - hash_type="md5", - progress=progress, - ) + download_and_extract(self.resource, tarfile_name, root_dir, self.md5) if not dataset_dir.is_dir(): raise RuntimeError( @@ -112,17 +97,10 @@ def __init__( if transform == (): transform = LoadImaged("image") CacheDataset.__init__( - self, - data=data, - transform=transform, - cache_num=cache_num, - cache_rate=cache_rate, - num_workers=num_workers, - progress=progress, - copy_cache=copy_cache, + self, data, transform, cache_num=cache_num, cache_rate=cache_rate, num_workers=num_workers ) - def randomize(self, data: np.ndarray) -> None: + def randomize(self, data: List[int]) -> None: self.R.shuffle(data) def get_num_classes(self) -> int: @@ -199,12 +177,6 @@ class DecathlonDataset(Randomizable, CacheDataset): will take the minimum of (cache_num, data_length x cache_rate, data_length). num_workers: the number of worker threads to use. if 0 a single thread will be used. Default is 0. - progress: whether to display a progress bar when downloading dataset and computing the transform cache content. - copy_cache: whether to `deepcopy` the cache content before applying the random transforms, - default to `True`. if the random transforms don't modify the cached content - (for example, randomly crop from the cached image and deepcopy the crop region) - or if every cache item is only used once in a `multi-processing` environment, - may set `copy=False` for better performance. Raises: ValueError: When ``root_dir`` is not a directory. @@ -269,8 +241,6 @@ def __init__( cache_num: int = sys.maxsize, cache_rate: float = 1.0, num_workers: int = 0, - progress: bool = True, - copy_cache: bool = True, ) -> None: root_dir = Path(root_dir) if not root_dir.is_dir(): @@ -283,14 +253,7 @@ def __init__( dataset_dir = root_dir / task tarfile_name = f"{dataset_dir}.tar" if download: - download_and_extract( - url=self.resource[task], - filepath=tarfile_name, - output_dir=root_dir, - hash_val=self.md5[task], - hash_type="md5", - progress=progress, - ) + download_and_extract(self.resource[task], tarfile_name, root_dir, self.md5[task]) if not dataset_dir.exists(): raise RuntimeError( @@ -314,14 +277,7 @@ def __init__( if transform == (): transform = LoadImaged(["image", "label"]) CacheDataset.__init__( - self, - data=data, - transform=transform, - cache_num=cache_num, - cache_rate=cache_rate, - num_workers=num_workers, - progress=progress, - copy_cache=copy_cache, + self, data, transform, cache_num=cache_num, cache_rate=cache_rate, num_workers=num_workers ) def get_indices(self) -> np.ndarray: @@ -331,7 +287,7 @@ def get_indices(self) -> np.ndarray: """ return self.indices - def randomize(self, data: np.ndarray) -> None: + def randomize(self, data: List[int]) -> None: self.R.shuffle(data) def get_properties(self, keys: Optional[Union[Sequence[str], str]] = None): diff --git a/monai/apps/deepedit/__init__.py b/monai/apps/deepedit/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/apps/deepedit/__init__.py +++ b/monai/apps/deepedit/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/deepedit/transforms.py b/monai/apps/deepedit/transforms.py index abd9e01473..33054f4a13 100644 --- a/monai/apps/deepedit/transforms.py +++ b/monai/apps/deepedit/transforms.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/deepgrow/__init__.py b/monai/apps/deepgrow/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/apps/deepgrow/__init__.py +++ b/monai/apps/deepgrow/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/deepgrow/dataset.py b/monai/apps/deepgrow/dataset.py index 763377763a..1dcdc4ec25 100644 --- a/monai/apps/deepgrow/dataset.py +++ b/monai/apps/deepgrow/dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/deepgrow/interaction.py b/monai/apps/deepgrow/interaction.py index 73bc8e7e0b..81e82c958d 100644 --- a/monai/apps/deepgrow/interaction.py +++ b/monai/apps/deepgrow/interaction.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -22,7 +22,6 @@ class Interaction: """ Ignite process_function used to introduce interactions (simulation of clicks) for Deepgrow Training/Evaluation. - For more details please refer to: https://pytorch.org/ignite/generated/ignite.engine.engine.Engine.html. This implementation is based on: Sakinis et al., Interactive segmentation of medical images through diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index d70eb31c99..4954c1c5fb 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/mmars/__init__.py b/monai/apps/mmars/__init__.py index 8f1448bb06..396be2e87d 100644 --- a/monai/apps/mmars/__init__.py +++ b/monai/apps/mmars/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/mmars/mmars.py b/monai/apps/mmars/mmars.py index 801b826bd1..6356e9a027 100644 --- a/monai/apps/mmars/mmars.py +++ b/monai/apps/mmars/mmars.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/mmars/model_desc.py b/monai/apps/mmars/model_desc.py index ae0e9cae30..fca6f60da5 100644 --- a/monai/apps/mmars/model_desc.py +++ b/monai/apps/mmars/model_desc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/__init__.py b/monai/apps/pathology/__init__.py index 81742caf65..80f32403ea 100644 --- a/monai/apps/pathology/__init__.py +++ b/monai/apps/pathology/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/data/__init__.py b/monai/apps/pathology/data/__init__.py index e1b2ef7bd2..64556b6f6e 100644 --- a/monai/apps/pathology/data/__init__.py +++ b/monai/apps/pathology/data/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/data/datasets.py b/monai/apps/pathology/data/datasets.py index bfab7c49da..c9521b1201 100644 --- a/monai/apps/pathology/data/datasets.py +++ b/monai/apps/pathology/data/datasets.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -122,10 +122,6 @@ class SmartCachePatchWSIDataset(SmartCacheDataset): num_replace_workers: the number of worker threads to prepare the replacement cache for every epoch. If num_replace_workers is None then the number returned by os.cpu_count() is used. progress: whether to display a progress bar when caching for the first epoch. - copy_cache: whether to `deepcopy` the cache content before applying the random transforms, - default to `True`. if the random transforms don't modify the cache content - or every cache item is only used once in a `multi-processing` environment, - may set `copy=False` for better performance. """ @@ -143,7 +139,6 @@ def __init__( num_init_workers: Optional[int] = None, num_replace_workers: Optional[int] = None, progress: bool = True, - copy_cache: bool = True, ): patch_wsi_dataset = PatchWSIDataset( data=data, @@ -162,7 +157,6 @@ def __init__( num_replace_workers=num_replace_workers, progress=progress, shuffle=False, - copy_cache=copy_cache, ) diff --git a/monai/apps/pathology/handlers/__init__.py b/monai/apps/pathology/handlers/__init__.py index 0638950bd8..3a788ffa26 100644 --- a/monai/apps/pathology/handlers/__init__.py +++ b/monai/apps/pathology/handlers/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/handlers/prob_map_producer.py b/monai/apps/pathology/handlers/prob_map_producer.py index 0615b44b8f..469e9d3c25 100644 --- a/monai/apps/pathology/handlers/prob_map_producer.py +++ b/monai/apps/pathology/handlers/prob_map_producer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/metrics/__init__.py b/monai/apps/pathology/metrics/__init__.py index f19811dcaf..ad62df524a 100644 --- a/monai/apps/pathology/metrics/__init__.py +++ b/monai/apps/pathology/metrics/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/metrics/lesion_froc.py b/monai/apps/pathology/metrics/lesion_froc.py index 6073bd0cda..1a7f61b921 100644 --- a/monai/apps/pathology/metrics/lesion_froc.py +++ b/monai/apps/pathology/metrics/lesion_froc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/transforms/__init__.py b/monai/apps/pathology/transforms/__init__.py index 290c0ba6a8..b418e20279 100644 --- a/monai/apps/pathology/transforms/__init__.py +++ b/monai/apps/pathology/transforms/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/transforms/spatial/__init__.py b/monai/apps/pathology/transforms/spatial/__init__.py index eed111d2b6..c9971254e7 100644 --- a/monai/apps/pathology/transforms/spatial/__init__.py +++ b/monai/apps/pathology/transforms/spatial/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/transforms/spatial/array.py b/monai/apps/pathology/transforms/spatial/array.py index fe1383c08d..47c95ed814 100644 --- a/monai/apps/pathology/transforms/spatial/array.py +++ b/monai/apps/pathology/transforms/spatial/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -60,7 +60,7 @@ def __call__(self, image: NdarrayOrTensor) -> NdarrayOrTensor: if isinstance(image, torch.Tensor): return torch.stack([image]) elif isinstance(image, np.ndarray): - return np.stack([image]) # type: ignore + return np.stack([image]) else: raise ValueError(f"Input type [{type(image)}] is not supported.") diff --git a/monai/apps/pathology/transforms/spatial/dictionary.py b/monai/apps/pathology/transforms/spatial/dictionary.py index d5c34a0840..aae98e7c8d 100644 --- a/monai/apps/pathology/transforms/spatial/dictionary.py +++ b/monai/apps/pathology/transforms/spatial/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/transforms/stain/__init__.py b/monai/apps/pathology/transforms/stain/__init__.py index dfa235de55..824f40a579 100644 --- a/monai/apps/pathology/transforms/stain/__init__.py +++ b/monai/apps/pathology/transforms/stain/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/transforms/stain/array.py b/monai/apps/pathology/transforms/stain/array.py index 3b3a293451..3a03777299 100644 --- a/monai/apps/pathology/transforms/stain/array.py +++ b/monai/apps/pathology/transforms/stain/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/transforms/stain/dictionary.py b/monai/apps/pathology/transforms/stain/dictionary.py index eb8eba43f8..976af1e7c7 100644 --- a/monai/apps/pathology/transforms/stain/dictionary.py +++ b/monai/apps/pathology/transforms/stain/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/pathology/utils.py b/monai/apps/pathology/utils.py index 5a57364a11..30bdde91bb 100644 --- a/monai/apps/pathology/utils.py +++ b/monai/apps/pathology/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/apps/utils.py b/monai/apps/utils.py index 9db62f336d..f1619b9964 100644 --- a/monai/apps/utils.py +++ b/monai/apps/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -21,7 +21,6 @@ from pathlib import Path from typing import TYPE_CHECKING, Optional from urllib.error import ContentTooShortError, HTTPError, URLError -from urllib.parse import urlparse from urllib.request import urlretrieve from monai.config.type_definitions import PathLike @@ -186,7 +185,7 @@ def download_url( with tempfile.TemporaryDirectory() as tmp_dir: tmp_name = Path(tmp_dir, _basename(filepath)) - if urlparse(url).netloc == "drive.google.com": + if url.startswith("https://drive.google.com"): if not has_gdown: raise RuntimeError("To download files from Google Drive, please install the gdown dependency.") gdown.download(url, f"{tmp_name}", quiet=not progress) diff --git a/monai/config/__init__.py b/monai/config/__init__.py index bf1b66fe92..e3f623823c 100644 --- a/monai/config/__init__.py +++ b/monai/config/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -12,9 +12,7 @@ from .deviceconfig import ( USE_COMPILED, IgniteInfo, - get_config_values, get_gpu_info, - get_optional_config_values, get_system_info, print_config, print_debug_info, diff --git a/monai/config/deviceconfig.py b/monai/config/deviceconfig.py index 91b944bde5..e542da14ab 100644 --- a/monai/config/deviceconfig.py +++ b/monai/config/deviceconfig.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -90,7 +90,6 @@ def print_config(file=sys.stdout): print(f"{k} version: {v}", file=file, flush=True) print(f"MONAI flags: HAS_EXT = {HAS_EXT}, USE_COMPILED = {USE_COMPILED}") print(f"MONAI rev id: {monai.__revision_id__}") - print(f"MONAI __file__: {monai.__file__}") print("\nOptional dependencies:", file=file, flush=True) for k, v in get_optional_config_values().items(): @@ -201,7 +200,8 @@ def get_gpu_info() -> OrderedDict: if num_gpus > 0: _dict_append(output, "Current device", torch.cuda.current_device) - _dict_append(output, "Library compiled for CUDA architectures", torch.cuda.get_arch_list) + if hasattr(torch.cuda, "get_arch_list"): # get_arch_list is new in torch 1.7.1 + _dict_append(output, "Library compiled for CUDA architectures", torch.cuda.get_arch_list) for gpu in range(num_gpus): gpu_info = torch.cuda.get_device_properties(gpu) diff --git a/monai/config/type_definitions.py b/monai/config/type_definitions.py index 686befb2eb..f5f5fc2626 100644 --- a/monai/config/type_definitions.py +++ b/monai/config/type_definitions.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -60,8 +60,8 @@ # container must be iterable. IndexSelection = Union[Iterable[int], int] -#: Type of datatypes: Adapted from https://github.com/numpy/numpy/blob/v1.21.4/numpy/typing/_dtype_like.py#L121 -DtypeLike = Union[np.dtype, type, str, None] +#: Type of datatypes: Adapted from https://github.com/numpy/numpy/blob/master/numpy/typing/_dtype_like.py +DtypeLike = Union[np.dtype, type, None] #: NdarrayTensor # diff --git a/monai/csrc/ext.cpp b/monai/csrc/ext.cpp index a2fa8bfc56..b4bb0f2c04 100644 --- a/monai/csrc/ext.cpp +++ b/monai/csrc/ext.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/bilateral/bilateral.cpp b/monai/csrc/filtering/bilateral/bilateral.cpp index 183e13bb23..2720d312e2 100644 --- a/monai/csrc/filtering/bilateral/bilateral.cpp +++ b/monai/csrc/filtering/bilateral/bilateral.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/bilateral/bilateral.h b/monai/csrc/filtering/bilateral/bilateral.h index 288684666a..c7a68d7457 100644 --- a/monai/csrc/filtering/bilateral/bilateral.h +++ b/monai/csrc/filtering/bilateral/bilateral.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/bilateral/bilateralfilter_cpu.cpp b/monai/csrc/filtering/bilateral/bilateralfilter_cpu.cpp index 51573ebbc0..2e6c7dbe20 100644 --- a/monai/csrc/filtering/bilateral/bilateralfilter_cpu.cpp +++ b/monai/csrc/filtering/bilateral/bilateralfilter_cpu.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/bilateral/bilateralfilter_cpu_phl.cpp b/monai/csrc/filtering/bilateral/bilateralfilter_cpu_phl.cpp index ec28c05520..847a452396 100644 --- a/monai/csrc/filtering/bilateral/bilateralfilter_cpu_phl.cpp +++ b/monai/csrc/filtering/bilateral/bilateralfilter_cpu_phl.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -57,7 +57,7 @@ void BilateralFilterPHLCpu( int coord = offsetRemainder / desc.strides[d]; offsetRemainder -= coord * desc.strides[d]; - features[i * featureChannels + desc.channelCount + d] = (scalar_t)invSpatialSigma * coord; + features[i * featureChannels + desc.channelCount + d] = invSpatialSigma * coord; } } diff --git a/monai/csrc/filtering/bilateral/bilateralfilter_cuda.cu b/monai/csrc/filtering/bilateral/bilateralfilter_cuda.cu index a24e6ed092..f73ae19ac9 100644 --- a/monai/csrc/filtering/bilateral/bilateralfilter_cuda.cu +++ b/monai/csrc/filtering/bilateral/bilateralfilter_cuda.cu @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/bilateral/bilateralfilter_cuda_phl.cu b/monai/csrc/filtering/bilateral/bilateralfilter_cuda_phl.cu index 20df9419fa..719d1643d3 100644 --- a/monai/csrc/filtering/bilateral/bilateralfilter_cuda_phl.cu +++ b/monai/csrc/filtering/bilateral/bilateralfilter_cuda_phl.cu @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/filtering.h b/monai/csrc/filtering/filtering.h index 3e680010ed..3dcdfc473b 100644 --- a/monai/csrc/filtering/filtering.h +++ b/monai/csrc/filtering/filtering.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/permutohedral/hash_table.cuh b/monai/csrc/filtering/permutohedral/hash_table.cuh index 5507034dea..1acff5f276 100644 --- a/monai/csrc/filtering/permutohedral/hash_table.cuh +++ b/monai/csrc/filtering/permutohedral/hash_table.cuh @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/permutohedral/permutohedral.cpp b/monai/csrc/filtering/permutohedral/permutohedral.cpp index 6ffe966f2c..d8fd3eaaeb 100644 --- a/monai/csrc/filtering/permutohedral/permutohedral.cpp +++ b/monai/csrc/filtering/permutohedral/permutohedral.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/permutohedral/permutohedral.h b/monai/csrc/filtering/permutohedral/permutohedral.h index cdc0f693d0..1c9d1a031e 100644 --- a/monai/csrc/filtering/permutohedral/permutohedral.h +++ b/monai/csrc/filtering/permutohedral/permutohedral.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/permutohedral/permutohedral_cpu.cpp b/monai/csrc/filtering/permutohedral/permutohedral_cpu.cpp index bc4b2cabc7..8c0dc8e546 100644 --- a/monai/csrc/filtering/permutohedral/permutohedral_cpu.cpp +++ b/monai/csrc/filtering/permutohedral/permutohedral_cpu.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/filtering/permutohedral/permutohedral_cuda.cu b/monai/csrc/filtering/permutohedral/permutohedral_cuda.cu index fa06590fa9..d1d78eb940 100644 --- a/monai/csrc/filtering/permutohedral/permutohedral_cuda.cu +++ b/monai/csrc/filtering/permutohedral/permutohedral_cuda.cu @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/lltm/lltm.h b/monai/csrc/lltm/lltm.h index 398ea92bb9..33e17416f8 100644 --- a/monai/csrc/lltm/lltm.h +++ b/monai/csrc/lltm/lltm.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/lltm/lltm_cpu.cpp b/monai/csrc/lltm/lltm_cpu.cpp index 7cd2251f9f..295c592d00 100644 --- a/monai/csrc/lltm/lltm_cpu.cpp +++ b/monai/csrc/lltm/lltm_cpu.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/lltm/lltm_cuda.cu b/monai/csrc/lltm/lltm_cuda.cu index 1293bec7e9..4633348477 100644 --- a/monai/csrc/lltm/lltm_cuda.cu +++ b/monai/csrc/lltm/lltm_cuda.cu @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/resample/bounds_common.h b/monai/csrc/resample/bounds_common.h index 2a7778b76b..4997c7d968 100644 --- a/monai/csrc/resample/bounds_common.h +++ b/monai/csrc/resample/bounds_common.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/resample/interpolation_common.h b/monai/csrc/resample/interpolation_common.h index 8e2edbc8b7..35899298bf 100644 --- a/monai/csrc/resample/interpolation_common.h +++ b/monai/csrc/resample/interpolation_common.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/resample/pushpull.h b/monai/csrc/resample/pushpull.h index b056bb77c2..1c20cc0114 100644 --- a/monai/csrc/resample/pushpull.h +++ b/monai/csrc/resample/pushpull.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/resample/pushpull_cpu.cpp b/monai/csrc/resample/pushpull_cpu.cpp index d83557c6c3..dd10dd76ee 100644 --- a/monai/csrc/resample/pushpull_cpu.cpp +++ b/monai/csrc/resample/pushpull_cpu.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/resample/pushpull_cuda.cu b/monai/csrc/resample/pushpull_cuda.cu index 4a2d6c27ef..38d34ffe98 100644 --- a/monai/csrc/resample/pushpull_cuda.cu +++ b/monai/csrc/resample/pushpull_cuda.cu @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/utils/common_utils.h b/monai/csrc/utils/common_utils.h index aabea3c99f..4d09377e65 100644 --- a/monai/csrc/utils/common_utils.h +++ b/monai/csrc/utils/common_utils.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/utils/meta_macros.h b/monai/csrc/utils/meta_macros.h index 0f15b623e3..980b253bbe 100644 --- a/monai/csrc/utils/meta_macros.h +++ b/monai/csrc/utils/meta_macros.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/utils/resample_utils.h b/monai/csrc/utils/resample_utils.h index 77df65e924..bbdf258b4c 100644 --- a/monai/csrc/utils/resample_utils.h +++ b/monai/csrc/utils/resample_utils.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/csrc/utils/tensor_description.h b/monai/csrc/utils/tensor_description.h index c604003b9d..dadd26c5f5 100644 --- a/monai/csrc/utils/tensor_description.h +++ b/monai/csrc/utils/tensor_description.h @@ -1,5 +1,5 @@ /* -Copyright (c) MONAI Consortium +Copyright 2020 - 2021 MONAI Consortium Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/monai/data/__init__.py b/monai/data/__init__.py index ae0bb86c35..e7fa2b3107 100644 --- a/monai/data/__init__.py +++ b/monai/data/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,7 +17,6 @@ CacheNTransDataset, CSVDataset, Dataset, - DatasetFunc, LMDBDataset, NPZDictItemDataset, PersistentDataset, @@ -43,7 +42,6 @@ from .synthetic import create_test_image_2d, create_test_image_3d from .test_time_augmentation import TestTimeAugmentation from .thread_buffer import ThreadBuffer, ThreadDataLoader -from .torchscript_utils import load_net_with_metadata, save_net_with_metadata from .utils import ( compute_importance_map, compute_shape_offset, diff --git a/monai/data/box_utils.py b/monai/data/box_utils.py deleted file mode 100644 index daca40ef85..0000000000 --- a/monai/data/box_utils.py +++ /dev/null @@ -1,383 +0,0 @@ -# Copyright 2020 - 2021 MONAI Consortium -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from copy import deepcopy -from typing import Sequence, Union - -import numpy as np -import torch - -import point_utils - -SUPPORT_MODE = ["xxyy", "xxyyzz", "xyxy", "xyzxyz", "xywh", "xyzwhd"] -STANDARD_MODE = ["xxyy", "xxyyzz"] # [2d_mode, 3d_mode] - -# TO_REMOVE = 0 if in 'xxyy','xxyyzz' mode, the bottom-right corner is not included in the box, -# i.e., when x_min=1, x_max=2, we have w = 1 -# if in 'xxyy','xxyyzz' mode, the bottom-right corner is included in the box, -# i.e., when x_min=1, x_max=2, we have w = 2 -TO_REMOVE = 0 # x_max-x_min = w -TO_REMOVE - -""" -The following variables share the same definition across the functions in this file. -Args: - bbox: Nx4 or Nx6 torch tensor - mode: choose from SUPPORT_MODE. If mode is not given, these funcs will assume mode is STANDARD_MODE - image_size: Length of 2 or 3. Data format is list, or np.ndarray, or tensor of int -""" - - -def check_support_mode(mode): - """ - Check if the mode is supported - """ - if mode not in SUPPORT_MODE: - raise ValueError("mode should be a string in {}.".format(SUPPORT_MODE)) - return - - -def check_standard_mode(mode): - """ - Check if the mode is supported - """ - if mode not in STANDARD_MODE: - raise ValueError("Standard mode should be a string in {}.".format(STANDARD_MODE)) - return - - -def convert_to_list(in_sequence: Union[Sequence, torch.Tensor, np.ndarray]) -> list: - """ - convert a torch.Tensor, or np array input to list - Args: - in_sequence: - Returns: in_sequence_list - - """ - in_sequence_list = deepcopy(in_sequence) - if torch.is_tensor(in_sequence): - in_sequence_list.cpu().detach().numpy().tolist() - elif isinstance(in_sequence, np.ndarray): - in_sequence_list.tolist() - elif not isinstance(in_sequence, list): - in_sequence_list = list(in_sequence_list) - return in_sequence_list - - -def get_dimension( - bbox: torch.Tensor = None, image_size: Union[Sequence[int], torch.Tensor, np.ndarray] = None, mode: str = None -) -> int: - """ - Get spatial dimension for the giving setting. - Missing input is allowed. But at least one of the input value should be given. - Returns: spatial_dimension - """ - spatial_dims = set() - if image_size is not None: - spatial_dims.add(len(image_size)) - if mode is not None: - spatial_dims.add(len(mode) / 2) - if bbox is not None: - spatial_dims.add(int(bbox.shape[1] / 2)) - spatial_dims = list(spatial_dims) - if len(spatial_dims) == 0: - raise ValueError("At least one of bbox, image_size, and mode needs to be non-empty.") - elif len(spatial_dims) == 1: - if spatial_dims[0] not in [2, 3]: - raise ValueError("Images should have 2 or 3 dimensions, got {}".format(spatial_dims[0])) - return int(spatial_dims[0]) - else: - raise ValueError("The dimension of bbox, image_size, mode should match with each other.") - - -def get_standard_mode(spatial_dims: int) -> str: - """ - Get the mode name for the given spatial dimension - Args: - spatial_dims: 2 or 3 - - Returns: mode - - """ - if spatial_dims == 2: - return STANDARD_MODE[0] - elif spatial_dims == 3: - return STANDARD_MODE[1] - else: - ValueError("Images should have 2 or 3 dimensions, got {}".format(spatial_dims)) - - -def point_interp( - point1: Union[Sequence, torch.Tensor, np.ndarray], zoom: Union[Sequence[float], float] -) -> Union[Sequence, torch.Tensor, np.ndarray]: - """ - Convert point position from one pixel/voxel size to another pixel/voxel size - Args: - point1: point coordinate on an image with pixel/voxel size of pix_size1 - zoom: The zoom factor along the spatial axes. - If a float, zoom is the same for each spatial axis. - If a sequence, zoom should contain one value for each spatial axis. - Returns: - point2: point coordinate on an image with pixel/voxel size of pix_size2 - """ - # make sure the spatial dimensions of the inputs match with each other - spatial_dims = len(point1) - if spatial_dims not in [2, 3]: - raise ValueError("Images should have 2 or 3 dimensions, got {}".format(spatial_dims)) - - # compute new point - point2 = deepcopy(point1) - _zoom = monai.utils.misc.ensure_tuple_rep(zoom, spatial_dims) - for axis in range(0, spatial_dims): - point2[axis] = point1[axis] * _zoom[axis] - return point2 - - -def box_interp(bbox1: torch.Tensor, zoom: Union[Sequence[float], float], mode1: str = None) -> torch.Tensor: - """ - Interpolate bbox - Args: - zoom: The zoom factor along the spatial axes. - If a float, zoom is the same for each spatial axis. - If a sequence, zoom should contain one value for each spatial axis. - - Returns: - bbox2: returned bbox has the same mode as bbox1 - """ - if mode1 is None: - mode1 = get_standard_mode(int(bbox1.shape[1] / 2)) - check_support_mode(mode1) - spatial_dims = get_dimension(bbox=bbox1, mode=mode1) - - mode_standard = get_standard_mode(spatial_dims) - bbox1_standard = box_convert_mode(bbox1=bbox1, mode1=mode1, mode2=mode_standard) - - corner_lt = point_utils.point_interp(bbox1_standard[:, ::2], zoom) - corner_rb = point_utils.point_interp(bbox1_standard[:, 1::2], zoom) - - bbox2_standard_interp = deepcopy(bbox2_standard) - bbox2_standard_interp[:, ::2] = corner_lt - bbox2_standard_interp[:, 1::2] = corner_rb - - return box_convert_mode(bbox1=bbox2_standard_interp, mode1=mode_standard, mode2=mode1) - - -def split_into_corners(bbox: torch.Tensor, mode: str): - """ - This internal function outputs the corner coordinates of the bbox - - Returns: - if 2D image, outputs (xmin, xmax, ymin, ymax) - if 3D images, outputs (xmin, xmax, ymin, ymax, zmin, zmax) - xmin for example, is a Nx1 tensor - - """ - check_support_mode(mode) - if mode in STANDARD_MODE: - return bbox.split(1, dim=-1) - elif mode == "xyzxyz": - xmin, ymin, zmin, xmax, ymax, zmax = bbox.split(1, dim=-1) - return ( - xmin, - xmax, - ymin, - ymax, - zmin, - zmax, - ) - elif mode == "xyxy": - xmin, ymin, xmax, ymax = bbox.split(1, dim=-1) - return (xmin, xmax, ymin, ymax) - elif mode == "xyzwhd": - xmin, ymin, zmin, w, h, d = bbox.split(1, dim=-1) - return ( - xmin, - xmin + (w - TO_REMOVE).clamp(min=0), - ymin, - ymin + (h - TO_REMOVE).clamp(min=0), - zmin, - zmin + (d - TO_REMOVE).clamp(min=0), - ) - elif mode == "xywh": - xmin, ymin, w, h = bbox.split(1, dim=-1) - return (xmin, xmin + (w - TO_REMOVE).clamp(min=0), ymin, ymin + (h - TO_REMOVE).clamp(min=0)) - else: - raise RuntimeError("Should not be here") - - -def box_convert_mode(bbox1: torch.Tensor, mode1: str, mode2: str) -> torch.Tensor: - """ - This function converts the bbox1 in mode 1 to the mode2 - """ - # 1. check whether the bbox and the new mode is valid - check_support_mode(mode1) - check_support_mode(mode2) - - spatial_dims = get_dimension(bbox=bbox1, mode=mode1) - if len(mode1) != len(mode2): - raise ValueError("The dimension of the new mode should have the same spatial dimension as the old mode.") - - # 2. if mode not changed, return original boxlist - if mode1 == mode2: - return deepcopy(bbox1) - - # 3. convert mode for bbox - if mode2 in STANDARD_MODE: - corners = split_into_corners(deepcopy(bbox1), mode1) - return torch.cat(corners, dim=-1) - - if spatial_dims == 3: - xmin, xmax, ymin, ymax, zmin, zmax = split_into_corners(deepcopy(bbox1), mode1) - if mode2 == "xyzxyz": - bbox2 = torch.cat((xmin, ymin, zmin, xmax, ymax, zmax), dim=-1) - elif mode2 == "xyzwhd": - bbox2 = torch.cat( - (xmin, ymin, zmin, xmax - xmin + TO_REMOVE, ymax - ymin + TO_REMOVE, zmax - zmin + TO_REMOVE), dim=-1 - ) - else: - raise ValueError("We support only bbox mode in " + str(SUPPORT_MODE) + ", got {}".format(mode2)) - elif spatial_dims == 2: - xmin, xmax, ymin, ymax = split_into_corners(deepcopy(bbox1), mode1) - if mode2 == "xyxy": - bbox2 = torch.cat((xmin, ymin, xmax, ymax), dim=-1) - elif mode2 == "xywh": - bbox2 = torch.cat((xmin, ymin, xmax - xmin + TO_REMOVE, ymax - ymin + TO_REMOVE), dim=-1) - else: - raise ValueError("We support only bbox mode in " + str(SUPPORT_MODE) + ", got {}".format(mode2)) - else: - raise ValueError("Images should have 2 or 3 dimensions, got {}".format(spatial_dims)) - - return bbox2 - - -def box_convert_standard_mode(bbox: torch.Tensor, mode: str) -> torch.Tensor: - """ - This function convert the bbox in mode 1 to 'xyxy' or 'xyzxyz' - """ - check_support_mode(mode) - spatial_dims = get_dimension(bbox=bbox, mode=mode) - mode_standard = get_standard_mode(spatial_dims) - return box_convert_mode(bbox1=bbox, mode1=mode, mode2=mode_standard) - - -def box_area(bbox: torch.Tensor, mode: str = None) -> torch.tensor: - """ - This function computes the area of each box - Returns: - area: 1-D tensor - """ - - if mode is None: - mode = get_standard_mode(int(bbox.shape[1] / 2)) - check_standard_mode(mode) - spatial_dims = get_dimension(bbox=bbox, mode=mode) - - area = bbox[:, 1] - bbox[:, 0] + TO_REMOVE - for axis in range(1, spatial_dims): - area = area * (bbox[:, 2 * axis + 1] - bbox[:, 2 * axis] + TO_REMOVE) - - return area - - -def box_clip_to_image( - bbox: torch.Tensor, - image_size: Union[Sequence[int], torch.Tensor, np.ndarray], - mode: str = None, - remove_empty: bool = True, -) -> dict: - """ - This function makes sure the bounding boxes are within the image. - Args: - remove_empty: whether to remove the boxes that are actually empty - Returns: - updated box - """ - if mode is None: - mode = get_standard_mode(int(bbox.shape[1] / 2)) - check_standard_mode(mode) - spatial_dims = get_dimension(bbox=bbox, image_size=image_size, mode=mode) - new_bbox = deepcopy(bbox) - if bbox.shape[0] == 0: - return deepcopy(bbox) - - # 1. convert to standard mode - mode_standard = get_standard_mode(spatial_dims) - new_bbox = box_convert_mode(bbox1=new_bbox, mode1=mode, mode2=mode_standard) - - # 2. makes sure the bounding boxes are within the image - for axis in range(0, spatial_dims): - new_bbox[:, 2 * axis].clamp_(min=0, max=image_size[axis] - TO_REMOVE) - new_bbox[:, 2 * axis + 1].clamp_(min=0, max=image_size[axis] - TO_REMOVE) - - # 3. remove the boxes that are actually empty - if remove_empty: - keep = (new_bbox[:, 1] > new_bbox[:, 0]) & (new_bbox[:, 3] > new_bbox[:, 2]) - if spatial_dims == 3: - keep = keep & (new_bbox[:, 5] > new_bbox[:, 4]) - new_bbox = new_bbox[keep] - - # 4. return updated boxlist - new_bbox = box_convert_mode(bbox1=new_bbox, mode1=mode_standard, mode2=mode) - - return new_bbox - - -def box_iou(bbox1: torch.Tensor, bbox2: torch.Tensor, mode1: str = None, mode2: str = None, gpubool: bool = True): - """ - Compute the intersection over union of two set of boxes. This function is not differentialable. - - IMPORTANT: Please run box_clip_to_image(bbox, image_size, mode, remove_empty=True) before computing IoU - - Implementation from https://github.com/kuangliu/torchcv/blob/master/torchcv/utils/box.py - with slight modifications. - - Arguments: - bbox1: Nx4 or Nx6, make sure they are non-empty - bbox2: Mx4 or Mx6, make sure they are non-empty - gpubool: whether to send the final IoU results to GPU - - Returns: - (tensor) iou, sized [N,M]. - - Reference: - https://github.com/chainer/chainercv/blob/master/chainercv/utils/bbox/bbox_iou.py - """ - - if mode1 is None: - mode1 = get_standard_mode(int(bbox1.shape[1] / 2)) - if mode2 is None: - mode2 = get_standard_mode(int(bbox2.shape[1] / 2)) - check_standard_mode(mode1) - check_standard_mode(mode2) - spatial_dims = get_dimension(bbox=bbox1, mode=mode1) - - # we do computation on cpu - device = bbox1.device - - # compute area for the bbox - area1 = box_area(bbox=bbox1, mode=mode1).cpu() # Nx1 - area2 = box_area(bbox=bbox2, mode=mode2).cpu() # Mx1 - - # get the left top and right bottom points for the NxM combinations - lt = torch.max(bbox1[:, None, ::2], bbox2[:, ::2]) # [N,M,spatial_dims] left top - rb = torch.min(bbox1_corner[:, None, 1::2], bbox2_corner[:, 1::2]) # [N,M,spatial_dims] right bottom - # compute size for the intersection region for the NxM combinations - wh = (rb - lt + TO_REMOVE).clamp(min=0) # [N,M,spatial_dims] - inter = wh[:, :, 0] # [N,M] - for axis in range(1, spatial_dims): - inter = inter * wh[:, :, axis] - - # compute IoU - iou = inter / (area1[:, None] + area2 - inter + torch.finfo(torch.float32).eps) # [N,M,spatial_dims] - - if gpubool: - iou = iou.to(device) # [N,M,spatial_dims] - - return iou diff --git a/monai/data/csv_saver.py b/monai/data/csv_saver.py index d4ca0e7576..d4005b528e 100644 --- a/monai/data/csv_saver.py +++ b/monai/data/csv_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/dataloader.py b/monai/data/dataloader.py index 3117a27c02..bfb6c01c4e 100644 --- a/monai/data/dataloader.py +++ b/monai/data/dataloader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/dataset.py b/monai/data/dataset.py index cbb534f04a..f1b481d598 100644 --- a/monai/data/dataset.py +++ b/monai/data/dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -32,7 +32,7 @@ from monai.data.utils import SUPPORTED_PICKLE_MOD, convert_tables_to_dicts, pickle_hashing from monai.transforms import Compose, Randomizable, ThreadUnsafe, Transform, apply_transform -from monai.utils import MAX_SEED, deprecated_arg, get_seed, look_up_option, min_version, optional_import +from monai.utils import MAX_SEED, ensure_tuple, get_seed, look_up_option, min_version, optional_import from monai.utils.misc import first if TYPE_CHECKING: @@ -97,56 +97,6 @@ def __getitem__(self, index: Union[int, slice, Sequence[int]]): return self._transform(index) -class DatasetFunc(Dataset): - """ - Execute function on the input dataset and leverage the output to act as a new Dataset. - It can be used to load / fetch the basic dataset items, like the list of `image, label` paths. - Or chain together to execute more complicated logic, like `partition_dataset`, `resample_datalist`, etc. - The `data` arg of `Dataset` will be applied to the first arg of callable `func`. - Usage example:: - - data_list = DatasetFunc( - data="path to file", - func=monai.data.load_decathlon_datalist, - data_list_key="validation", - base_dir="path to base dir", - ) - # partition dataset for every rank - data_partition = DatasetFunc( - data=data_list, - func=lambda **kwargs: monai.data.partition_dataset(**kwargs)[torch.distributed.get_rank()], - num_partitions=torch.distributed.get_world_size(), - ) - dataset = Dataset(data=data_partition, transform=transforms) - - Args: - data: input data for the func to process, will apply to `func` as the first arg. - func: callable function to generate dataset items. - kwargs: other arguments for the `func` except for the first arg. - - """ - - def __init__(self, data: Any, func: Callable, **kwargs) -> None: - super().__init__(data=None, transform=None) # type:ignore - self.src = data - self.func = func - self.kwargs = kwargs - self.reset() - - def reset(self, data: Optional[Any] = None, func: Optional[Callable] = None, **kwargs): - """ - Reset the dataset items with specified `func`. - - Args: - data: if not None, execute `func` on it, default to `self.src`. - func: if not None, execute the `func` with specified `kwargs`, default to `self.func`. - kwargs: other arguments for the `func` except for the first arg. - - """ - src = self.src if data is None else data - self.data = self.func(src, **self.kwargs) if func is None else func(src, **kwargs) - - class PersistentDataset(Dataset): """ Persistent storage of pre-computed values to efficiently manage larger than memory dictionary format data, @@ -1272,9 +1222,8 @@ class CSVDataset(Dataset): ] Args: - src: if provided the filename of CSV file, it can be a str, URL, path object or file-like object to load. - also support to provide pandas `DataFrame` directly, will skip loading from filename. - if provided a list of filenames or pandas `DataFrame`, it will join the tables. + filename: the filename of expected CSV file to load. if providing a list + of filenames, it will load all the files and join tables. row_indices: indices of the expected rows to load. it should be a list, every item can be a int number or a range `[start, end)` for the indices. for example: `row_indices=[[0, 100], 200, 201, 202, 300]`. if None, @@ -1300,15 +1249,11 @@ class CSVDataset(Dataset): transform: transform to apply on the loaded items of a dictionary data. kwargs: additional arguments for `pandas.merge()` API to join tables. - .. deprecated:: 0.8.0 - ``filename`` is deprecated, use ``src`` instead. - """ - @deprecated_arg(name="filename", new_name="src", since="0.8", msg_suffix="please use `src` instead.") def __init__( self, - src: Optional[Union[str, Sequence[str]]] = None, # also can be `DataFrame` or sequense of `DataFrame` + filename: Union[str, Sequence[str]], row_indices: Optional[Sequence[Union[int, str]]] = None, col_names: Optional[Sequence[str]] = None, col_types: Optional[Dict[str, Optional[Dict[str, Any]]]] = None, @@ -1316,19 +1261,8 @@ def __init__( transform: Optional[Callable] = None, **kwargs, ): - srcs = (src,) if not isinstance(src, (tuple, list)) else src - dfs: List = [] - for i in srcs: - if isinstance(i, str): - dfs.append(pd.read_csv(i)) - elif isinstance(i, pd.DataFrame): - dfs.append(i) - else: - raise ValueError("`src` must be file path or pandas `DataFrame`.") - - # in case treating deprecated arg `filename` as kwargs, remove it from `kwargs` - kwargs.pop("filename", None) - + files = ensure_tuple(filename) + dfs = [pd.read_csv(f) for f in files] data = convert_tables_to_dicts( dfs=dfs, row_indices=row_indices, col_names=col_names, col_types=col_types, col_groups=col_groups, **kwargs ) diff --git a/monai/data/dataset_summary.py b/monai/data/dataset_summary.py index dd8a94143b..dfc22f9bc8 100644 --- a/monai/data/dataset_summary.py +++ b/monai/data/dataset_summary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -15,11 +15,8 @@ import numpy as np import torch -from monai.config import KeysCollection from monai.data.dataloader import DataLoader from monai.data.dataset import Dataset -from monai.transforms import concatenate -from monai.utils import convert_data_type class DatasetSummary: @@ -41,7 +38,6 @@ def __init__( dataset: Dataset, image_key: Optional[str] = "image", label_key: Optional[str] = "label", - meta_key: Optional[KeysCollection] = None, meta_key_postfix: str = "meta_dict", num_workers: int = 0, **kwargs, @@ -51,16 +47,11 @@ def __init__( dataset: dataset from which to load the data. image_key: key name of images (default: ``image``). label_key: key name of labels (default: ``label``). - meta_key: explicitly indicate the key of the corresponding meta data dictionary. - for example, for data with key `image`, the metadata by default is in `image_meta_dict`. - the meta data is a dictionary object which contains: filename, affine, original_shape, etc. - if None, will try to construct meta_keys by `{image_key}_{meta_key_postfix}`. meta_key_postfix: use `{image_key}_{meta_key_postfix}` to fetch the meta data from dict, the meta data is a dictionary object (default: ``meta_dict``). num_workers: how many subprocesses to use for data loading. ``0`` means that the data will be loaded in the main process (default: ``0``). - kwargs: other parameters (except `batch_size` and `num_workers`) for DataLoader, - this class forces to use ``batch_size=1``. + kwargs: other parameters (except batch_size) for DataLoader (this class forces to use ``batch_size=1``). """ @@ -68,17 +59,18 @@ def __init__( self.image_key = image_key self.label_key = label_key - self.meta_key = meta_key or f"{image_key}_{meta_key_postfix}" + if image_key: + self.meta_key = f"{image_key}_{meta_key_postfix}" self.all_meta_data: List = [] def collect_meta_data(self): """ This function is used to collect the meta data for all images of the dataset. """ + if not self.meta_key: + raise ValueError("To collect meta data for the dataset, `meta_key` should exist.") for data in self.data_loader: - if self.meta_key not in data: - raise ValueError(f"To collect meta data for the dataset, key `{self.meta_key}` must exist in `data`.") self.all_meta_data.append(data[self.meta_key]) def get_target_spacing(self, spacing_key: str = "pixdim", anisotropic_threshold: int = 3, percentile: float = 10.0): @@ -86,8 +78,8 @@ def get_target_spacing(self, spacing_key: str = "pixdim", anisotropic_threshold: Calculate the target spacing according to all spacings. If the target spacing is very anisotropic, decrease the spacing value of the maximum axis according to percentile. - So far, this function only supports NIFTI images which store spacings in headers with key "pixdim". - After loading with `monai.DataLoader`, "pixdim" is in the form of `torch.Tensor` with size `(batch_size, 8)`. + So far, this function only supports NIFTI images which store spacings in headers with key "pixdim". After loading + with `monai.DataLoader`, "pixdim" is in the form of `torch.Tensor` with size `(batch_size, 8)`. Args: spacing_key: key of spacing in meta data (default: ``pixdim``). @@ -100,8 +92,8 @@ def get_target_spacing(self, spacing_key: str = "pixdim", anisotropic_threshold: self.collect_meta_data() if spacing_key not in self.all_meta_data[0]: raise ValueError("The provided spacing_key is not in self.all_meta_data.") - all_spacings = concatenate(to_cat=[data[spacing_key][:, 1:4] for data in self.all_meta_data], axis=0) - all_spacings, *_ = convert_data_type(data=all_spacings, output_type=np.ndarray, wrap_sequence=True) + + all_spacings = torch.cat([data[spacing_key][:, 1:4] for data in self.all_meta_data], dim=0).numpy() target_spacing = np.median(all_spacings, axis=0) if max(target_spacing) / min(target_spacing) >= anisotropic_threshold: @@ -134,8 +126,6 @@ def calculate_statistics(self, foreground_threshold: int = 0): image, label = data[self.image_key], data[self.label_key] else: image, label = data - image, *_ = convert_data_type(data=image, output_type=torch.Tensor) - label, *_ = convert_data_type(data=label, output_type=torch.Tensor) voxel_max.append(image.max().item()) voxel_min.append(image.min().item()) @@ -179,8 +169,6 @@ def calculate_percentiles( image, label = data[self.image_key], data[self.label_key] else: image, label = data - image, *_ = convert_data_type(data=image, output_type=torch.Tensor) - label, *_ = convert_data_type(data=label, output_type=torch.Tensor) intensities = image[torch.where(label > foreground_threshold)].tolist() if sampling_flag: diff --git a/monai/data/decathlon_datalist.py b/monai/data/decathlon_datalist.py index d2a9c3d220..134d8a9fcb 100644 --- a/monai/data/decathlon_datalist.py +++ b/monai/data/decathlon_datalist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/grid_dataset.py b/monai/data/grid_dataset.py index 7a0f79d00e..5c330f10e4 100644 --- a/monai/data/grid_dataset.py +++ b/monai/data/grid_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/image_dataset.py b/monai/data/image_dataset.py index 0ab71cd444..874b9dc004 100644 --- a/monai/data/image_dataset.py +++ b/monai/data/image_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 207430d933..6e9cbca809 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -155,31 +155,16 @@ class ITKReader(ImageReader): series_name: the name of the DICOM series if there are multiple ones. used when loading DICOM series. - reverse_indexing: whether to use a reversed spatial indexing convention for the returned data array. - If ``False``, the spatial indexing follows the numpy convention; - otherwise, the spatial indexing convention is reversed to be compatible with ITK. Default is ``False``. - This option does not affect the metadata. - series_meta: whether to load the metadata of the DICOM series (using the metadata from the first slice). - This flag is checked only when loading DICOM series. Default is ``False``. kwargs: additional args for `itk.imread` API. more details about available args: https://github.com/InsightSoftwareConsortium/ITK/blob/master/Wrapping/Generators/Python/itk/support/extras.py """ - def __init__( - self, - channel_dim: Optional[int] = None, - series_name: str = "", - reverse_indexing: bool = False, - series_meta: bool = False, - **kwargs, - ): + def __init__(self, channel_dim: Optional[int] = None, series_name: str = "", **kwargs): super().__init__() self.kwargs = kwargs self.channel_dim = channel_dim self.series_name = series_name - self.reverse_indexing = reverse_indexing - self.series_meta = series_meta def verify_suffix(self, filename: Union[Sequence[PathLike], PathLike]) -> bool: """ @@ -229,17 +214,7 @@ def read(self, data: Union[Sequence[PathLike], PathLike], **kwargs): series_identifier = series_uid[0] if not self.series_name else self.series_name name = names_generator.GetFileNames(series_identifier) - _obj = itk.imread(name, **kwargs_) - if self.series_meta: - _reader = itk.ImageSeriesReader.New(FileNames=name) - _reader.Update() - _meta = _reader.GetMetaDataDictionaryArray() - if len(_meta) > 0: - # TODO: using the first slice's meta. this could be improved to filter unnecessary tags. - _obj.SetMetaDataDictionary(_meta[0]) - img_.append(_obj) - else: - img_.append(itk.imread(name, **kwargs_)) + img_.append(itk.imread(name, **kwargs_)) return img_ if len(filenames) > 1 else img_[0] def get_data(self, img): @@ -333,21 +308,19 @@ def _get_array_data(self, img): Following PyTorch conventions, the returned array data has contiguous channels, e.g. for an RGB image, all red channel image pixels are contiguous in memory. - The last axis of the returned array is the channel axis. - - See also: - - - https://github.com/InsightSoftwareConsortium/ITK/blob/v5.2.1/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in + The first axis of the returned array is the channel axis. Args: img: an ITK image object loaded from an image file. """ - np_img = itk.array_view_from_image(img, keep_axes=False) - if img.GetNumberOfComponentsPerPixel() == 1: # handling spatial images - return np_img if self.reverse_indexing else np_img.T - # handling multi-channel images - return np_img if self.reverse_indexing else np.moveaxis(np_img.T, 0, -1) + channels = img.GetNumberOfComponentsPerPixel() + np_data = itk.array_view_from_image(img).T + if channels == 1: + return np_data + if channels != np_data.shape[0]: + warnings.warn("itk_img.GetNumberOfComponentsPerPixel != numpy data channels") + return np.moveaxis(np_data, 0, -1) # channel last is compatible with `write_nifti` @require_pkg(pkg_name="nibabel") @@ -708,14 +681,14 @@ class WSIReader(ImageReader): Read whole slide images and extract patches. Args: - backend: backend library to load the images, available options: "cuCIM", "OpenSlide" and "TiffFile". + backend: backend library to load the images, available options: "cuCIM", "OpenSlide" and "Tifffile". level: the whole slide image level at which the image is extracted. (default=0) This is overridden if the level argument is provided in `get_data`. Note: - While "cuCIM" and "OpenSlide" backends both can load patches from large whole slide images - without loading the entire image into memory, "TiffFile" backend needs to load the entire image into memory - before extracting any patch; thus, memory consideration is needed when using "TiffFile" backend for + While "cucim" and "OpenSlide" backends both can load patches from large whole slide images + without loading the entire image into memory, "Tifffile" backend needs to load the entire image into memory + before extracting any patch; thus, memory consideration is needed when using "Tifffile" backend for patch extraction. """ @@ -792,22 +765,19 @@ def get_data( grid_shape: (row, columns) tuple define a grid to extract patches on that patch_size: (height, width) the size of extracted patches at the given level """ - # Verify inputs if level is None: - level = self._check_level(img, level) + level = self.level + + if self.backend == "openslide" and size is None: + # the maximum size is set to WxH at the specified level + size = (img.shape[0] // (2 ** level) - location[0], img.shape[1] // (2 ** level) - location[1]) - # Extract a region or the entire image region = self._extract_region(img, location=location, size=size, level=level, dtype=dtype) - # Add necessary metadata metadata: Dict = {} metadata["spatial_shape"] = np.asarray(region.shape[:-1]) metadata["original_channel_dim"] = -1 - - # Make it channel first region = EnsureChannelFirst()(region, metadata) - - # Split into patches if patch_size is None: patches = region else: @@ -818,45 +788,6 @@ def get_data( return patches, metadata - def _check_level(self, img, level): - level = self.level - - level_count = 0 - if self.backend == "openslide": - level_count = img.level_count - elif self.backend == "cucim": - level_count = img.resolutions["level_count"] - elif self.backend == "tifffile": - level_count = len(img.pages) - - if level > level_count - 1: - raise ValueError(f"The maximum level of this image is {level_count - 1} while level={level} is requested)!") - - return level - - def _get_image_size(self, img, size, level, location): - """ - Calculate the maximum region size for the given level and starting location (if size is None). - Note that region size in OpenSlide and cuCIM are WxH (but the final image output would be HxW) - """ - if size is not None: - return size[::-1] - - max_size = [] - downsampling_factor = [] - if self.backend == "openslide": - downsampling_factor = img.level_downsamples[level] - max_size = img.level_dimensions[level] - elif self.backend == "cucim": - downsampling_factor = img.resolutions["level_downsamples"][level] - max_size = img.resolutions["level_dimensions"][level] - - # subtract the top left corner of the patch (at given level) from maximum size - location_at_level = (round(location[1] / downsampling_factor), round(location[0] / downsampling_factor)) - size = [max_size[i] - location_at_level[i] for i in range(len(max_size))] - - return size - def _extract_region( self, img_obj, @@ -866,25 +797,21 @@ def _extract_region( dtype: DtypeLike = np.uint8, ): if self.backend == "tifffile": - # Read the entire image - if size is not None: - raise ValueError( - f"TiffFile backend reads the entire image only, so size '{size}'' should not be provided!", - "For more flexibility or extracting regions, please use cuCIM or OpenSlide backend.", - ) - if location != (0, 0): - raise ValueError( - f"TiffFile backend reads the entire image only, so location '{location}' should not be provided!", - "For more flexibility and extracting regions, please use cuCIM or OpenSlide backend.", - ) - region = img_obj.asarray(level=level) + with img_obj: + region = img_obj.asarray(level=level) + if size is None: + region = region[location[0] :, location[1] :] + else: + region = region[location[0] : location[0] + size[0], location[1] : location[1] + size[1]] + else: - # Get region size to be extracted - region_size = self._get_image_size(img_obj, size, level, location) - # reverse the order of location's dimensions to become WxH (for cuCIM and OpenSlide) - region_location = location[::-1] - # Extract a region (or the entire image) - region = img_obj.read_region(location=region_location, size=region_size, level=level) + # reverse the order of dimensions for size and location to be compatible with image shape + location = location[::-1] + if size is None: + region = img_obj.read_region(location=location, level=level) + else: + size = size[::-1] + region = img_obj.read_region(location=location, size=size, level=level) region = self.convert_to_rgb_array(region, dtype) return region @@ -897,7 +824,6 @@ def convert_to_rgb_array(self, raw_region, dtype: DtypeLike = np.uint8): # convert to numpy (if not already in numpy) raw_region = np.asarray(raw_region, dtype=dtype) - # remove alpha channel if exist (RGBA) if raw_region.shape[-1] > 3: raw_region = raw_region[..., :3] diff --git a/monai/data/iterable_dataset.py b/monai/data/iterable_dataset.py index 19efc925fc..d1365fa220 100644 --- a/monai/data/iterable_dataset.py +++ b/monai/data/iterable_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -9,7 +9,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Union +from typing import Any, Callable, Dict, Iterable, Optional, Sequence, Union import numpy as np from torch.utils.data import IterableDataset as _TorchIterableDataset @@ -18,7 +18,7 @@ from monai.data.utils import convert_tables_to_dicts from monai.transforms import apply_transform from monai.transforms.transform import Randomizable -from monai.utils import deprecated_arg, optional_import +from monai.utils import ensure_tuple, optional_import pd, _ = optional_import("pandas") @@ -147,9 +147,8 @@ class CSVIterableDataset(IterableDataset): ] Args: - src: if provided the filename of CSV file, it can be a str, URL, path object or file-like object to load. - also support to provide iter for stream input directly, will skip loading from filename. - if provided a list of filenames or iters, it will join the tables. + filename: the filename of CSV file to load. it can be a str, URL, path object or file-like object. + if providing a list of filenames, it will load all the files and join tables. chunksize: rows of a chunk when loading iterable data from CSV files, default to 1000. more details: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html. buffer_size: size of the buffer to store the loaded chunks, if None, set to `2 x chunksize`. @@ -178,15 +177,11 @@ class CSVIterableDataset(IterableDataset): https://github.com/pytorch/pytorch/blob/v1.10.0/torch/utils/data/distributed.py#L98. kwargs: additional arguments for `pandas.merge()` API to join tables. - .. deprecated:: 0.8.0 - ``filename`` is deprecated, use ``src`` instead. - """ - @deprecated_arg(name="filename", new_name="src", since="0.8", msg_suffix="please use `src` instead.") def __init__( self, - src: Union[Union[str, Sequence[str]], Union[Iterable, Sequence[Iterable]]], + filename: Union[str, Sequence[str]], chunksize: int = 1000, buffer_size: Optional[int] = None, col_names: Optional[Sequence[str]] = None, @@ -197,7 +192,7 @@ def __init__( seed: int = 0, **kwargs, ): - self.src = src + self.files = ensure_tuple(filename) self.chunksize = chunksize self.buffer_size = 2 * chunksize if buffer_size is None else buffer_size self.col_names = col_names @@ -205,50 +200,17 @@ def __init__( self.col_groups = col_groups self.shuffle = shuffle self.seed = seed - # in case treating deprecated arg `filename` as kwargs, remove it from `kwargs` - kwargs.pop("filename", None) self.kwargs = kwargs - - self.iters: List[Iterable] = self.reset() + self.iters = self.reset() super().__init__(data=None, transform=transform) # type: ignore - @deprecated_arg(name="filename", new_name="src", since="0.8", msg_suffix="please use `src` instead.") - def reset(self, src: Optional[Union[Union[str, Sequence[str]], Union[Iterable, Sequence[Iterable]]]] = None): - """ - Reset the pandas `TextFileReader` iterable object to read data. For more details, please check: - https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html?#iteration. - - Args: - src: if not None and provided the filename of CSV file, it can be a str, URL, path object - or file-like object to load. also support to provide iter for stream input directly, - will skip loading from filename. if provided a list of filenames or iters, it will join the tables. - default to `self.src`. - - """ - src = self.src if src is None else src - srcs = (src,) if not isinstance(src, (tuple, list)) else src - self.iters = [] - for i in srcs: - if isinstance(i, str): - self.iters.append(pd.read_csv(i, chunksize=self.chunksize)) - elif isinstance(i, Iterable): - self.iters.append(i) - else: - raise ValueError("`src` must be file path or iterable object.") + def reset(self, filename: Optional[Union[str, Sequence[str]]] = None): + if filename is not None: + # update files if necessary + self.files = ensure_tuple(filename) + self.iters = [pd.read_csv(f, chunksize=self.chunksize) for f in self.files] return self.iters - def close(self): - """ - Close the pandas `TextFileReader` iterable objects. - If the input src is file path, TextFileReader was created internally, need to close it. - If the input src is iterable object, depends on users requirements whether to close it in this function. - For more details, please check: - https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html?#iteration. - - """ - for i in self.iters: - i.close() - def _flattened(self): for chunks in zip(*self.iters): yield from convert_tables_to_dicts( diff --git a/monai/data/nifti_saver.py b/monai/data/nifti_saver.py index f31926cb6c..75805479d7 100644 --- a/monai/data/nifti_saver.py +++ b/monai/data/nifti_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/nifti_writer.py b/monai/data/nifti_writer.py index 35044977e0..078ea2e605 100644 --- a/monai/data/nifti_writer.py +++ b/monai/data/nifti_writer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/png_saver.py b/monai/data/png_saver.py index 2e31597837..5154ac1ab4 100644 --- a/monai/data/png_saver.py +++ b/monai/data/png_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/png_writer.py b/monai/data/png_writer.py index 6f3b2ef86e..ea028a07be 100644 --- a/monai/data/png_writer.py +++ b/monai/data/png_writer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/samplers.py b/monai/data/samplers.py index 40eed03187..f69c6091ca 100644 --- a/monai/data/samplers.py +++ b/monai/data/samplers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/synthetic.py b/monai/data/synthetic.py index 46d555cf11..0a1c179a7f 100644 --- a/monai/data/synthetic.py +++ b/monai/data/synthetic.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/test_time_augmentation.py b/monai/data/test_time_augmentation.py index c06d567b54..28a172beac 100644 --- a/monai/data/test_time_augmentation.py +++ b/monai/data/test_time_augmentation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/thread_buffer.py b/monai/data/thread_buffer.py index cdd7c05f31..4b6db4f6a4 100644 --- a/monai/data/thread_buffer.py +++ b/monai/data/thread_buffer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/data/torchscript_utils.py b/monai/data/torchscript_utils.py deleted file mode 100644 index 585db14712..0000000000 --- a/monai/data/torchscript_utils.py +++ /dev/null @@ -1,149 +0,0 @@ -# Copyright (c) MONAI Consortium -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -import json -import os -from typing import IO, Any, Mapping, Optional, Sequence, Tuple, Union - -import torch - -from monai.config import get_config_values -from monai.utils import JITMetadataKeys -from monai.utils.module import pytorch_after - -METADATA_FILENAME = "metadata.json" - - -def save_net_with_metadata( - jit_obj: torch.nn.Module, - filename_prefix_or_stream: Union[str, IO[Any]], - include_config_vals: bool = True, - append_timestamp: bool = False, - meta_values: Optional[Mapping[str, Any]] = None, - more_extra_files: Optional[Mapping[str, bytes]] = None, -) -> None: - """ - Save the JIT object (script or trace produced object) `jit_obj` to the given file or stream with metadata - included as a JSON file. The Torchscript format is a zip file which can contain extra file data which is used - here as a mechanism for storing metadata about the network being saved. The data in `meta_values` should be - compatible with conversion to JSON using the standard library function `dumps`. The intent is this metadata will - include information about the network applicable to some use case, such as describing the input and output format, - a network name and version, a plain language description of what the network does, and other relevant scientific - information. Clients can use this information to determine automatically how to use the network, and users can - read what the network does and keep track of versions. - - Examples:: - - net = torch.jit.script(monai.networks.nets.UNet(2, 1, 1, [8, 16], [2])) - - meta = { - "name": "Test UNet", - "used_for": "demonstration purposes", - "input_dims": 2, - "output_dims": 2 - } - - # save the Torchscript bundle with the above dictionary stored as an extra file - save_net_with_metadata(m, "test", meta_values=meta) - - # load the network back, `loaded_meta` has same data as `meta` plus version information - loaded_net, loaded_meta, _ = load_net_with_metadata("test.pt") - - - Args: - jit_obj: object to save, should be generated by `script` or `trace`. - filename_prefix_or_stream: filename or file-like stream object, if filename has no extension it becomes `.pt`. - include_config_vals: if True, MONAI, Pytorch, and Numpy versions are included in metadata. - append_timestamp: if True, a timestamp for "now" is appended to the file's name before the extension. - meta_values: metadata values to store with the object, not limited just to keys in `JITMetadataKeys`. - more_extra_files: other extra file data items to include in bundle, see `_extra_files` of `torch.jit.save`. - """ - - now = datetime.datetime.now() - metadict = {} - - if include_config_vals: - metadict.update(get_config_values()) - metadict[JITMetadataKeys.TIMESTAMP.value] = now.astimezone().isoformat() - - if meta_values is not None: - metadict.update(meta_values) - - json_data = json.dumps(metadict) - - # Pytorch>1.6 can use dictionaries directly, otherwise need to use special map object - if pytorch_after(1, 7): - extra_files = {METADATA_FILENAME: json_data.encode()} - - if more_extra_files is not None: - extra_files.update(more_extra_files) - else: - extra_files = torch._C.ExtraFilesMap() # type:ignore[attr-defined] - extra_files[METADATA_FILENAME] = json_data.encode() - - if more_extra_files is not None: - for k, v in more_extra_files.items(): - extra_files[k] = v - - if isinstance(filename_prefix_or_stream, str): - filename_no_ext, ext = os.path.splitext(filename_prefix_or_stream) - if ext == "": - ext = ".pt" - - if append_timestamp: - filename_prefix_or_stream = now.strftime(f"{filename_no_ext}_%Y%m%d%H%M%S{ext}") - else: - filename_prefix_or_stream = filename_no_ext + ext - - torch.jit.save(jit_obj, filename_prefix_or_stream, extra_files) - - -def load_net_with_metadata( - filename_prefix_or_stream: Union[str, IO[Any]], - map_location: Optional[torch.device] = None, - more_extra_files: Sequence[str] = (), -) -> Tuple[torch.nn.Module, dict, dict]: - """ - Load the module object from the given Torchscript filename or stream, and convert the stored JSON metadata - back to a dict object. This will produce an empty dict if the metadata file is not present. - - Args: - filename_prefix_or_stream: filename or file-like stream object. - map_location: network map location as in `torch.jit.load`. - more_extra_files: other extra file data names to load from bundle, see `_extra_files` of `torch.jit.load`. - Returns: - Triple containing loaded object, metadata dict, and extra files dict containing other file data if present - """ - # Pytorch>1.6 can use dictionaries directly, otherwise need to use special map object - if pytorch_after(1, 7): - extra_files = {f: "" for f in more_extra_files} - extra_files[METADATA_FILENAME] = "" - else: - extra_files = torch._C.ExtraFilesMap() # type:ignore[attr-defined] - extra_files[METADATA_FILENAME] = "" - - for f in more_extra_files: - extra_files[f] = "" - - jit_obj = torch.jit.load(filename_prefix_or_stream, map_location, extra_files) - - extra_files = dict(extra_files.items()) # compatibility with ExtraFilesMap - - if METADATA_FILENAME in extra_files: - json_data = extra_files[METADATA_FILENAME] - del extra_files[METADATA_FILENAME] - else: - json_data = "{}" - - json_data_dict = json.loads(json_data) - - return jit_obj, json_data_dict, extra_files diff --git a/monai/data/utils.py b/monai/data/utils.py index 0cd3c1594a..61c773c204 100644 --- a/monai/data/utils.py +++ b/monai/data/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -539,7 +539,7 @@ def rectify_header_sform_qform(img_nii): return img_nii -def zoom_affine(affine: np.ndarray, scale: Union[np.ndarray, Sequence[float]], diagonal: bool = True): +def zoom_affine(affine: np.ndarray, scale: Sequence[float], diagonal: bool = True): """ To make column norm of `affine` the same as `scale`. If diagonal is False, returns an affine that combines orthogonal rotation and the new scale. @@ -676,15 +676,14 @@ def create_file_basename( folder_path: PathLike, data_root_dir: PathLike = "", separate_folder: bool = True, - patch_index=None, - makedirs: bool = True, + patch_index: Optional[int] = None, ) -> str: """ Utility function to create the path to the output file based on the input filename (file name extension is not added by this function). When `data_root_dir` is not specified, the output file name is: - `folder_path/input_file_name (no ext.) /input_file_name (no ext.)[_postfix][_patch_index]` + `folder_path/input_file_name (no ext.) /input_file_name (no ext.)[_postfix]` otherwise the relative path with respect to `data_root_dir` will be inserted, for example: input_file_name: /foo/bar/test1/image.png, @@ -705,7 +704,6 @@ def create_file_basename( `image.nii`, postfix is `seg` and folder_path is `output`, if `True`, save as: `output/image/image_seg.nii`, if `False`, save as `output/image_seg.nii`. default to `True`. patch_index: if not None, append the patch index to filename. - makedirs: whether to create the folder if it does not exist. """ # get the filename and directory @@ -724,10 +722,8 @@ def create_file_basename( if separate_folder: output = os.path.join(output, filename) - - if makedirs: - # create target folder if no existing - os.makedirs(output, exist_ok=True) + # create target folder if no existing + os.makedirs(output, exist_ok=True) # add the sub-folder plus the postfix name to become the file basename in the output path output = os.path.join(output, (filename + "_" + postfix) if len(postfix) > 0 else filename) @@ -735,7 +731,7 @@ def create_file_basename( if patch_index is not None: output += f"_{patch_index}" - return os.path.normpath(output) + return os.path.abspath(output) def compute_importance_map( diff --git a/monai/engines/__init__.py b/monai/engines/__init__.py index 88f094c732..d04401829f 100644 --- a/monai/engines/__init__.py +++ b/monai/engines/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -24,4 +24,3 @@ engine_apply_transform, get_devices_spec, ) -from .workflow import BaseWorkflow, Workflow diff --git a/monai/engines/evaluator.py b/monai/engines/evaluator.py index b329462e24..3ddbca45bf 100644 --- a/monai/engines/evaluator.py +++ b/monai/engines/evaluator.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -9,7 +9,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union +from typing import TYPE_CHECKING, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union import torch from torch.utils.data import DataLoader @@ -45,13 +45,9 @@ class Evaluator(Workflow): epoch_length: number of iterations for one epoch, default to `len(val_data_loader)`. non_blocking: if True and this copy is between CPU and GPU, the copy may occur asynchronously with respect to the host. For other cases, this argument has no effect. - prepare_batch: function to parse expected data (usually `image`, `label` and other network args) - from `engine.state.batch` for every iteration, for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.create_supervised_trainer.html. + prepare_batch: function to parse image and label for current iteration. iteration_update: the callable function for every iteration, expect to accept `engine` - and `engine.state.batch` as inputs, return data will be stored in `engine.state.output`. - if not provided, use `self._iteration()` instead. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.engine.Engine.html. + and `batchdata` as input parameters. if not provided, use `self._iteration()` instead. postprocessing: execute additional transformation for the model output data. Typically, several Tensor based transforms composed by `Compose`. key_val_metric: compute metric when every iteration completed, and save average value to @@ -84,7 +80,7 @@ def __init__( epoch_length: Optional[int] = None, non_blocking: bool = False, prepare_batch: Callable = default_prepare_batch, - iteration_update: Optional[Callable[[Engine, Any], Any]] = None, + iteration_update: Optional[Callable] = None, postprocessing: Optional[Transform] = None, key_val_metric: Optional[Dict[str, Metric]] = None, additional_metrics: Optional[Dict[str, Metric]] = None, @@ -151,13 +147,9 @@ class SupervisedEvaluator(Evaluator): epoch_length: number of iterations for one epoch, default to `len(val_data_loader)`. non_blocking: if True and this copy is between CPU and GPU, the copy may occur asynchronously with respect to the host. For other cases, this argument has no effect. - prepare_batch: function to parse expected data (usually `image`, `label` and other network args) - from `engine.state.batch` for every iteration, for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.create_supervised_trainer.html. + prepare_batch: function to parse image and label for current iteration. iteration_update: the callable function for every iteration, expect to accept `engine` - and `engine.state.batch` as inputs, return data will be stored in `engine.state.output`. - if not provided, use `self._iteration()` instead. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.engine.Engine.html. + and `batchdata` as input parameters. if not provided, use `self._iteration()` instead. inferer: inference method that execute model forward on input data, like: SlidingWindow, etc. postprocessing: execute additional transformation for the model output data. Typically, several Tensor based transforms composed by `Compose`. @@ -192,7 +184,7 @@ def __init__( epoch_length: Optional[int] = None, non_blocking: bool = False, prepare_batch: Callable = default_prepare_batch, - iteration_update: Optional[Callable[[Engine, Any], Any]] = None, + iteration_update: Optional[Callable] = None, inferer: Optional[Inferer] = None, postprocessing: Optional[Transform] = None, key_val_metric: Optional[Dict[str, Metric]] = None, @@ -283,13 +275,9 @@ class EnsembleEvaluator(Evaluator): the length must exactly match the number of networks. non_blocking: if True and this copy is between CPU and GPU, the copy may occur asynchronously with respect to the host. For other cases, this argument has no effect. - prepare_batch: function to parse expected data (usually `image`, `label` and other network args) - from `engine.state.batch` for every iteration, for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.create_supervised_trainer.html. + prepare_batch: function to parse image and label for current iteration. iteration_update: the callable function for every iteration, expect to accept `engine` - and `engine.state.batch` as inputs, return data will be stored in `engine.state.output`. - if not provided, use `self._iteration()` instead. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.engine.Engine.html. + and `batchdata` as input parameters. if not provided, use `self._iteration()` instead. inferer: inference method that execute model forward on input data, like: SlidingWindow, etc. postprocessing: execute additional transformation for the model output data. Typically, several Tensor based transforms composed by `Compose`. @@ -325,7 +313,7 @@ def __init__( epoch_length: Optional[int] = None, non_blocking: bool = False, prepare_batch: Callable = default_prepare_batch, - iteration_update: Optional[Callable[[Engine, Any], Any]] = None, + iteration_update: Optional[Callable] = None, inferer: Optional[Inferer] = None, postprocessing: Optional[Transform] = None, key_val_metric: Optional[Dict[str, Metric]] = None, diff --git a/monai/engines/multi_gpu_supervised_trainer.py b/monai/engines/multi_gpu_supervised_trainer.py index 7c59b670b7..3736d257cb 100644 --- a/monai/engines/multi_gpu_supervised_trainer.py +++ b/monai/engines/multi_gpu_supervised_trainer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/engines/trainer.py b/monai/engines/trainer.py index 774e535e7f..c7a8b49e30 100644 --- a/monai/engines/trainer.py +++ b/monai/engines/trainer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -9,7 +9,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union +from typing import TYPE_CHECKING, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union import torch from torch.optim.optimizer import Optimizer @@ -75,13 +75,9 @@ class SupervisedTrainer(Trainer): epoch_length: number of iterations for one epoch, default to `len(train_data_loader)`. non_blocking: if True and this copy is between CPU and GPU, the copy may occur asynchronously with respect to the host. For other cases, this argument has no effect. - prepare_batch: function to parse expected data (usually `image`, `label` and other network args) - from `engine.state.batch` for every iteration, for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.create_supervised_trainer.html. + prepare_batch: function to parse image and label for current iteration. iteration_update: the callable function for every iteration, expect to accept `engine` - and `engine.state.batch` as inputs, return data will be stored in `engine.state.output`. - if not provided, use `self._iteration()` instead. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.engine.Engine.html. + and `batchdata` as input parameters. if not provided, use `self._iteration()` instead. inferer: inference method that execute model forward on input data, like: SlidingWindow, etc. postprocessing: execute additional transformation for the model output data. Typically, several Tensor based transforms composed by `Compose`. @@ -119,7 +115,7 @@ def __init__( epoch_length: Optional[int] = None, non_blocking: bool = False, prepare_batch: Callable = default_prepare_batch, - iteration_update: Optional[Callable[[Engine, Any], Any]] = None, + iteration_update: Optional[Callable] = None, inferer: Optional[Inferer] = None, postprocessing: Optional[Transform] = None, key_train_metric: Optional[Dict[str, Metric]] = None, @@ -245,16 +241,12 @@ class GanTrainer(Trainer): non_blocking: if True and this copy is between CPU and GPU, the copy may occur asynchronously with respect to the host. For other cases, this argument has no effect. d_prepare_batch: callback function to prepare batchdata for D inferer. - Defaults to return ``GanKeys.REALS`` in batchdata dict. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.create_supervised_trainer.html. + Defaults to return ``GanKeys.REALS`` in batchdata dict. g_prepare_batch: callback function to create batch of latent input for G inferer. - Defaults to return random latents. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.create_supervised_trainer.html. + Defaults to return random latents. g_update_latents: Calculate G loss with new latent codes. Defaults to ``True``. iteration_update: the callable function for every iteration, expect to accept `engine` - and `engine.state.batch` as inputs, return data will be stored in `engine.state.output`. - if not provided, use `self._iteration()` instead. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.engine.Engine.html. + and `batchdata` as input parameters. if not provided, use `self._iteration()` instead. postprocessing: execute additional transformation for the model output data. Typically, several Tensor based transforms composed by `Compose`. key_train_metric: compute metric when every iteration completed, and save average value to @@ -294,7 +286,7 @@ def __init__( d_prepare_batch: Callable = default_prepare_batch, g_prepare_batch: Callable = default_make_latent, g_update_latents: bool = True, - iteration_update: Optional[Callable[[Engine, Any], Any]] = None, + iteration_update: Optional[Callable] = None, postprocessing: Optional[Transform] = None, key_train_metric: Optional[Dict[str, Metric]] = None, additional_metrics: Optional[Dict[str, Metric]] = None, diff --git a/monai/engines/utils.py b/monai/engines/utils.py index 726dfc8e98..25e09fe2b6 100644 --- a/monai/engines/utils.py +++ b/monai/engines/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -166,9 +166,9 @@ class PrepareBatchExtraInput(PrepareBatch): Args: extra_keys: if a string or list provided, every item is the key of extra data in current batch, - and will pass the extra data to the `network(*args)` in order. + and will pass the extra data to the network(*args) in order. If a dictionary is provided, every `{k, v}` pair is the key of extra data in current batch, - `k` is the param name in network, `v` is the key of extra data in current batch, + `k` the param name in network, `v` is the key of extra data in current batch, and will pass the `{k1: batch[v1], k2: batch[v2], ...}` as kwargs to the network. """ diff --git a/monai/engines/workflow.py b/monai/engines/workflow.py index 4222db0593..48e2dc1774 100644 --- a/monai/engines/workflow.py +++ b/monai/engines/workflow.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -10,8 +10,7 @@ # limitations under the License. import warnings -from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Sequence, Union +from typing import TYPE_CHECKING, Callable, Dict, Iterable, List, Optional, Sequence, Union import torch import torch.distributed as dist @@ -20,7 +19,7 @@ from monai.config import IgniteInfo from monai.engines.utils import IterationEvents, default_metric_cmp_fn, default_prepare_batch -from monai.transforms import Decollated +from monai.transforms import Decollated, Transform from monai.utils import ensure_tuple, is_scalar, min_version, optional_import from .utils import engine_apply_transform @@ -38,18 +37,6 @@ EventEnum, _ = optional_import("ignite.engine", IgniteInfo.OPT_IMPORT_VERSION, min_version, "EventEnum") -class BaseWorkflow(ABC): - """ - Base class for any MONAI style workflow. - `run()` is designed to execute the train, evaluation or inference logic. - - """ - - @abstractmethod - def run(self, *args, **kwargs): - raise NotImplementedError(f"Subclass {self.__class__.__name__} must implement this method.") - - class Workflow(IgniteEngine): # type: ignore[valid-type, misc] # due to optional_import """ Workflow defines the core work process inheriting from Ignite engine. @@ -67,13 +54,9 @@ class Workflow(IgniteEngine): # type: ignore[valid-type, misc] # due to optiona epoch_length: number of iterations for one epoch, default to `len(data_loader)`. non_blocking: if True and this copy is between CPU and GPU, the copy may occur asynchronously with respect to the host. For other cases, this argument has no effect. - prepare_batch: function to parse expected data (usually `image`, `label` and other network args) - from `engine.state.batch` for every iteration, for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.create_supervised_trainer.html. + prepare_batch: function to parse image and label for every iteration. iteration_update: the callable function for every iteration, expect to accept `engine` - and `engine.state.batch` as inputs, return data will be stored in `engine.state.output`. - if not provided, use `self._iteration()` instead. for more details please refer to: - https://pytorch.org/ignite/generated/ignite.engine.engine.Engine.html. + and `batchdata` as input parameters. if not provided, use `self._iteration()` instead. postprocessing: execute additional transformation for the model output data. Typically, several Tensor based transforms composed by `Compose`. key_metric: compute metric when every iteration completed, and save average value to @@ -111,7 +94,7 @@ def __init__( epoch_length: Optional[int] = None, non_blocking: bool = False, prepare_batch: Callable = default_prepare_batch, - iteration_update: Optional[Callable[[Engine, Any], Any]] = None, + iteration_update: Optional[Callable] = None, postprocessing: Optional[Callable] = None, key_metric: Optional[Dict[str, Metric]] = None, additional_metrics: Optional[Dict[str, Metric]] = None, @@ -186,8 +169,8 @@ def set_sampler_epoch(engine: Engine): self._register_decollate() if postprocessing is not None: - # tips: if `decollate=False` and `postprocessing` is MONAI transforms, it may not work well - # because all the MONAI transforms expect `channel-first` data + if not decollate and isinstance(postprocessing, Transform): + warnings.warn("MONAI transforms expect `channel-first` data, `decollate=False` may not work here.") self._register_postprocessing(postprocessing) if key_metric is not None: self._register_metrics(key_metric, additional_metrics) diff --git a/monai/handlers/__init__.py b/monai/handlers/__init__.py index 03aaa37412..520af0a94c 100644 --- a/monai/handlers/__init__.py +++ b/monai/handlers/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/checkpoint_loader.py b/monai/handlers/checkpoint_loader.py index 91cfca354a..7c30584b13 100644 --- a/monai/handlers/checkpoint_loader.py +++ b/monai/handlers/checkpoint_loader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/checkpoint_saver.py b/monai/handlers/checkpoint_saver.py index f7abca4aa0..607cd11b25 100644 --- a/monai/handlers/checkpoint_saver.py +++ b/monai/handlers/checkpoint_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/classification_saver.py b/monai/handlers/classification_saver.py index bb37e36826..4481ae0fec 100644 --- a/monai/handlers/classification_saver.py +++ b/monai/handlers/classification_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -98,14 +98,7 @@ def attach(self, engine: Engine) -> None: if not engine.has_event_handler(self._finalize, Events.EPOCH_COMPLETED): engine.add_event_handler(Events.EPOCH_COMPLETED, self._finalize) - def _started(self, _engine: Engine) -> None: - """ - Initialize internal buffers. - - Args: - _engine: Ignite Engine, unused argument. - - """ + def _started(self, engine: Engine) -> None: self._outputs = [] self._filenames = [] @@ -127,12 +120,12 @@ def __call__(self, engine: Engine) -> None: o = o.detach() self._outputs.append(o) - def _finalize(self, _engine: Engine) -> None: + def _finalize(self, engine: Engine) -> None: """ All gather classification results from ranks and save to CSV file. Args: - _engine: Ignite Engine, unused argument. + engine: Ignite Engine, it can be a trainer, validator or evaluator. """ ws = idist.get_world_size() if self.save_rank >= ws: diff --git a/monai/handlers/confusion_matrix.py b/monai/handlers/confusion_matrix.py index e3fc4bfbf1..a3a896ccb9 100644 --- a/monai/handlers/confusion_matrix.py +++ b/monai/handlers/confusion_matrix.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/decollate_batch.py b/monai/handlers/decollate_batch.py index a0d0ef3ad2..0905ee6ebc 100644 --- a/monai/handlers/decollate_batch.py +++ b/monai/handlers/decollate_batch.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/earlystop_handler.py b/monai/handlers/earlystop_handler.py index 8d57526676..e194b50d59 100644 --- a/monai/handlers/earlystop_handler.py +++ b/monai/handlers/earlystop_handler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/garbage_collector.py b/monai/handlers/garbage_collector.py index 74ccac8a72..1eb970e795 100644 --- a/monai/handlers/garbage_collector.py +++ b/monai/handlers/garbage_collector.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/hausdorff_distance.py b/monai/handlers/hausdorff_distance.py index 739c9e9935..3a1580f714 100644 --- a/monai/handlers/hausdorff_distance.py +++ b/monai/handlers/hausdorff_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/ignite_metric.py b/monai/handlers/ignite_metric.py index f28923af68..fa17fe8970 100644 --- a/monai/handlers/ignite_metric.py +++ b/monai/handlers/ignite_metric.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/lr_schedule_handler.py b/monai/handlers/lr_schedule_handler.py index 207af306d4..3e57ac7bbd 100644 --- a/monai/handlers/lr_schedule_handler.py +++ b/monai/handlers/lr_schedule_handler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -36,7 +36,6 @@ def __init__( name: Optional[str] = None, epoch_level: bool = True, step_transform: Callable[[Engine], Any] = lambda engine: (), - logger_handler: Optional[logging.Handler] = None, ) -> None: """ Args: @@ -48,9 +47,6 @@ def __init__( `True` is epoch level, `False` is iteration level. step_transform: a callable that is used to transform the information from `engine` to expected input data of lr_scheduler.step() function if necessary. - logger_handler: if `print_lr` is True, add additional handler to log the learning rate: save to file, etc. - all the existing python logging handlers: https://docs.python.org/3/library/logging.handlers.html. - the handler should have a logging level of at least `INFO`. Raises: TypeError: When ``step_transform`` is not ``callable``. @@ -63,8 +59,6 @@ def __init__( if not callable(step_transform): raise TypeError(f"step_transform must be callable but is {type(step_transform).__name__}.") self.step_transform = step_transform - if logger_handler is not None: - self.logger.addHandler(logger_handler) self._name = name diff --git a/monai/handlers/mean_dice.py b/monai/handlers/mean_dice.py index c5609c6746..ec62d4d64b 100644 --- a/monai/handlers/mean_dice.py +++ b/monai/handlers/mean_dice.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/metric_logger.py b/monai/handlers/metric_logger.py index 350d1978de..048f230d1a 100644 --- a/monai/handlers/metric_logger.py +++ b/monai/handlers/metric_logger.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/metrics_saver.py b/monai/handlers/metrics_saver.py index 1ec26eece7..d6aa0c7b9f 100644 --- a/monai/handlers/metrics_saver.py +++ b/monai/handlers/metrics_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -105,14 +105,7 @@ def attach(self, engine: Engine) -> None: engine.add_event_handler(Events.ITERATION_COMPLETED, self._get_filenames) engine.add_event_handler(Events.EPOCH_COMPLETED, self) - def _started(self, _engine: Engine) -> None: - """ - Initialize internal buffers. - - Args: - _engine: Ignite Engine, unused argument. - - """ + def _started(self, engine: Engine) -> None: self._filenames = [] def _get_filenames(self, engine: Engine) -> None: diff --git a/monai/handlers/mlflow_handler.py b/monai/handlers/mlflow_handler.py index 9475b2be35..7bf6596437 100644 --- a/monai/handlers/mlflow_handler.py +++ b/monai/handlers/mlflow_handler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/nvtx_handlers.py b/monai/handlers/nvtx_handlers.py index 327c156f63..8e44248f7d 100644 --- a/monai/handlers/nvtx_handlers.py +++ b/monai/handlers/nvtx_handlers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/parameter_scheduler.py b/monai/handlers/parameter_scheduler.py index c0e18edcd0..b6eb35562f 100644 --- a/monai/handlers/parameter_scheduler.py +++ b/monai/handlers/parameter_scheduler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/postprocessing.py b/monai/handlers/postprocessing.py index 4a89c86f47..29029306d2 100644 --- a/monai/handlers/postprocessing.py +++ b/monai/handlers/postprocessing.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/regression_metrics.py b/monai/handlers/regression_metrics.py index bf4ac3af1d..2132e2914e 100644 --- a/monai/handlers/regression_metrics.py +++ b/monai/handlers/regression_metrics.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/roc_auc.py b/monai/handlers/roc_auc.py index 31b046064e..125a4991ea 100644 --- a/monai/handlers/roc_auc.py +++ b/monai/handlers/roc_auc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/segmentation_saver.py b/monai/handlers/segmentation_saver.py index 79ebfd3a22..8af92cbf2a 100644 --- a/monai/handlers/segmentation_saver.py +++ b/monai/handlers/segmentation_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/smartcache_handler.py b/monai/handlers/smartcache_handler.py index 56fee78b1d..e3adcbf4a0 100644 --- a/monai/handlers/smartcache_handler.py +++ b/monai/handlers/smartcache_handler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/stats_handler.py b/monai/handlers/stats_handler.py index 8410aaec87..9251453b50 100644 --- a/monai/handlers/stats_handler.py +++ b/monai/handlers/stats_handler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -82,8 +82,7 @@ def __init__( tag_name: scalar_value to logger. Defaults to ``'Loss'``. key_var_format: a formatting string to control the output string format of key: value. logger_handler: add additional handler to handle the stats data: save to file, etc. - all the existing python logging handlers: https://docs.python.org/3/library/logging.handlers.html. - the handler should have a logging level of at least `INFO`. + Add existing python logging handlers: https://docs.python.org/3/library/logging.handlers.html """ self.epoch_print_logger = epoch_print_logger @@ -144,14 +143,14 @@ def iteration_completed(self, engine: Engine) -> None: else: self._default_iteration_print(engine) - def exception_raised(self, _engine: Engine, e: Exception) -> None: + def exception_raised(self, engine: Engine, e: Exception) -> None: """ Handler for train or validation/evaluation exception raised Event. Print the exception information and traceback. This callback may be skipped because the logic with Ignite can only trigger the first attached handler for `EXCEPTION_RAISED` event. Args: - _engine: Ignite Engine, unused argument. + engine: Ignite Engine, it can be a trainer, validator or evaluator. e: the exception caught in Ignite during engine.run(). """ diff --git a/monai/handlers/surface_distance.py b/monai/handlers/surface_distance.py index 77f0debfe9..22eb1646c3 100644 --- a/monai/handlers/surface_distance.py +++ b/monai/handlers/surface_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/tensorboard_handlers.py b/monai/handlers/tensorboard_handlers.py index dcf60973b0..11b487ec99 100644 --- a/monai/handlers/tensorboard_handlers.py +++ b/monai/handlers/tensorboard_handlers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -173,21 +173,6 @@ def iteration_completed(self, engine: Engine) -> None: else: self._default_iteration_writer(engine, self._writer) - def _write_scalar(self, _engine: Engine, writer: SummaryWriter, tag: str, value: Any, step: int) -> None: - """ - Write scale value into TensorBoard. - Default to call `SummaryWriter.add_scalar()`. - - Args: - _engine: Ignite Engine, unused argument. - writer: TensorBoard or TensorBoardX writer, passed or created in TensorBoardHandler. - tag: tag name in the TensorBoard. - value: value of the scalar data for current step. - step: index of current step. - - """ - writer.add_scalar(tag, value, step) - def _default_epoch_writer(self, engine: Engine, writer: SummaryWriter) -> None: """ Execute epoch level event write operation. @@ -203,11 +188,11 @@ def _default_epoch_writer(self, engine: Engine, writer: SummaryWriter) -> None: summary_dict = engine.state.metrics for name, value in summary_dict.items(): if is_scalar(value): - self._write_scalar(engine, writer, name, value, current_epoch) + writer.add_scalar(name, value, current_epoch) if self.state_attributes is not None: for attr in self.state_attributes: - self._write_scalar(engine, writer, attr, getattr(engine.state, attr, None), current_epoch) + writer.add_scalar(attr, getattr(engine.state, attr, None), current_epoch) writer.flush() def _default_iteration_writer(self, engine: Engine, writer: SummaryWriter) -> None: @@ -236,20 +221,12 @@ def _default_iteration_writer(self, engine: Engine, writer: SummaryWriter) -> No " {}:{}".format(name, type(value)) ) continue # not plot multi dimensional output - self._write_scalar( - _engine=engine, - writer=writer, - tag=name, - value=value.item() if isinstance(value, torch.Tensor) else value, - step=engine.state.iteration, + writer.add_scalar( + name, value.item() if isinstance(value, torch.Tensor) else value, engine.state.iteration ) elif is_scalar(loss): # not printing multi dimensional output - self._write_scalar( - _engine=engine, - writer=writer, - tag=self.tag_name, - value=loss.item() if isinstance(loss, torch.Tensor) else loss, - step=engine.state.iteration, + writer.add_scalar( + self.tag_name, loss.item() if isinstance(loss, torch.Tensor) else loss, engine.state.iteration ) else: warnings.warn( diff --git a/monai/handlers/utils.py b/monai/handlers/utils.py index 23947d3054..06766c3e14 100644 --- a/monai/handlers/utils.py +++ b/monai/handlers/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/handlers/validation_handler.py b/monai/handlers/validation_handler.py index 171c901fbb..6214461a4f 100644 --- a/monai/handlers/validation_handler.py +++ b/monai/handlers/validation_handler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/inferers/__init__.py b/monai/inferers/__init__.py index 20d829297f..030344728d 100644 --- a/monai/inferers/__init__.py +++ b/monai/inferers/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/inferers/inferer.py b/monai/inferers/inferer.py index c7b70e06ca..25d9fd1fb0 100644 --- a/monai/inferers/inferer.py +++ b/monai/inferers/inferer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/inferers/utils.py b/monai/inferers/utils.py index b27e13eef6..0ca53529c7 100644 --- a/monai/inferers/utils.py +++ b/monai/inferers/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/losses/__init__.py b/monai/losses/__init__.py index 1922996fb6..3eca68cc4f 100644 --- a/monai/losses/__init__.py +++ b/monai/losses/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/losses/contrastive.py b/monai/losses/contrastive.py index aef596a492..22caf3fe7d 100644 --- a/monai/losses/contrastive.py +++ b/monai/losses/contrastive.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -9,11 +9,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Union + import torch from torch.nn import functional as F from torch.nn.modules.loss import _Loss -from monai.utils import deprecated_arg +from monai.utils import LossReduction class ContrastiveLoss(_Loss): @@ -29,23 +31,19 @@ class ContrastiveLoss(_Loss): """ - @deprecated_arg(name="reduction", since="0.8", msg_suffix="`reduction` is no longer supported.") - def __init__(self, temperature: float = 0.5, batch_size: int = 1, reduction="sum") -> None: + def __init__( + self, temperature: float = 0.5, batch_size: int = 1, reduction: Union[LossReduction, str] = LossReduction.SUM + ) -> None: """ Args: temperature: Can be scaled between 0 and 1 for learning from negative samples, ideally set to 0.5. - batch_size: The number of samples. Raises: - ValueError: When an input of dimension length > 2 is passed - ValueError: When input and target are of different shapes - - .. deprecated:: 0.8.0 - - `reduction` is no longer supported. + AssertionError: When an input of dimension length > 2 is passed + AssertionError: When input and target are of different shapes """ - super().__init__() + super().__init__(reduction=LossReduction(reduction).value) self.batch_size = batch_size self.temperature = temperature @@ -55,15 +53,18 @@ def forward(self, input: torch.Tensor, target: torch.Tensor) -> torch.Tensor: Args: input: the shape should be B[F]. target: the shape should be B[F]. + + Raises: + ValueError: When ``self.reduction`` is not one of ["sum", "none"]. """ if len(target.shape) > 2 or len(input.shape) > 2: - raise ValueError( + raise AssertionError( f"Either target or input has dimensions greater than 2 where target " f"shape is ({target.shape}) and input shape is ({input.shape})" ) if target.shape != input.shape: - raise ValueError(f"ground truth has differing shape ({target.shape}) from input ({input.shape})") + raise AssertionError(f"ground truth has differing shape ({target.shape}) from input ({input.shape})") temperature_tensor = torch.tensor(self.temperature).to(input.device) @@ -85,4 +86,6 @@ def forward(self, input: torch.Tensor, target: torch.Tensor) -> torch.Tensor: loss_partial = -torch.log(nominator / torch.sum(denominator, dim=1)) - return torch.sum(loss_partial) / (2 * self.batch_size) + if self.reduction == LossReduction.SUM.value: + return torch.sum(loss_partial) / (2 * self.batch_size) + raise ValueError(f"Unsupported reduction: {self.reduction}, " f'available options are ["mean", "sum", "none"].') diff --git a/monai/losses/deform.py b/monai/losses/deform.py index 0f5e263a53..fea56010c7 100644 --- a/monai/losses/deform.py +++ b/monai/losses/deform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -52,12 +52,9 @@ class BendingEnergyLoss(_Loss): DeepReg (https://github.com/DeepRegNet/DeepReg) """ - def __init__(self, normalize: bool = False, reduction: Union[LossReduction, str] = LossReduction.MEAN) -> None: + def __init__(self, reduction: Union[LossReduction, str] = LossReduction.MEAN) -> None: """ Args: - normalize: - Whether to divide out spatial sizes in order to make the computation roughly - invariant to image scale (i.e. vector field sampling resolution). Defaults to False. reduction: {``"none"``, ``"mean"``, ``"sum"``} Specifies the reduction to apply to the output. Defaults to ``"mean"``. @@ -66,7 +63,6 @@ def __init__(self, normalize: bool = False, reduction: Union[LossReduction, str] - ``"sum"``: the output will be summed. """ super().__init__(reduction=LossReduction(reduction).value) - self.normalize = normalize def forward(self, pred: torch.Tensor) -> torch.Tensor: """ @@ -78,35 +74,20 @@ def forward(self, pred: torch.Tensor) -> torch.Tensor: """ if pred.ndim not in [3, 4, 5]: - raise ValueError(f"Expecting 3-d, 4-d or 5-d pred, instead got pred of shape {pred.shape}") + raise ValueError(f"expecting 3-d, 4-d or 5-d pred, instead got pred of shape {pred.shape}") for i in range(pred.ndim - 2): if pred.shape[-i - 1] <= 4: - raise ValueError(f"All spatial dimensions must be > 4, got spatial dimensions {pred.shape[2:]}") - if pred.shape[1] != pred.ndim - 2: - raise ValueError( - f"Number of vector components, {pred.shape[1]}, does not match number of spatial dimensions, {pred.ndim-2}" - ) + raise ValueError("all spatial dimensions must > 4, got pred of shape {pred.shape}") # first order gradient first_order_gradient = [spatial_gradient(pred, dim) for dim in range(2, pred.ndim)] - # spatial dimensions in a shape suited for broadcasting below - if self.normalize: - spatial_dims = torch.tensor(pred.shape, device=pred.device)[2:].reshape((1, -1) + (pred.ndim - 2) * (1,)) - energy = torch.tensor(0) for dim_1, g in enumerate(first_order_gradient): dim_1 += 2 - if self.normalize: - g *= pred.shape[dim_1] / spatial_dims - energy = energy + (spatial_gradient(g, dim_1) * pred.shape[dim_1]) ** 2 - else: - energy = energy + spatial_gradient(g, dim_1) ** 2 + energy = spatial_gradient(g, dim_1) ** 2 + energy for dim_2 in range(dim_1 + 1, pred.ndim): - if self.normalize: - energy = energy + 2 * (spatial_gradient(g, dim_2) * pred.shape[dim_2]) ** 2 - else: - energy = energy + 2 * spatial_gradient(g, dim_2) ** 2 + energy = 2 * spatial_gradient(g, dim_2) ** 2 + energy if self.reduction == LossReduction.MEAN.value: energy = torch.mean(energy) # the batch and channel average diff --git a/monai/losses/dice.py b/monai/losses/dice.py index 7f2037ca54..484433f676 100644 --- a/monai/losses/dice.py +++ b/monai/losses/dice.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/losses/focal_loss.py b/monai/losses/focal_loss.py index bf31682748..39f36c368f 100644 --- a/monai/losses/focal_loss.py +++ b/monai/losses/focal_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/losses/image_dissimilarity.py b/monai/losses/image_dissimilarity.py index b527522cd7..ce38dfd08d 100644 --- a/monai/losses/image_dissimilarity.py +++ b/monai/losses/image_dissimilarity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/losses/multi_scale.py b/monai/losses/multi_scale.py index 5e80af30bc..182cb2f7a6 100644 --- a/monai/losses/multi_scale.py +++ b/monai/losses/multi_scale.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/losses/spatial_mask.py b/monai/losses/spatial_mask.py index aa232f882e..387300e507 100644 --- a/monai/losses/spatial_mask.py +++ b/monai/losses/spatial_mask.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/losses/tversky.py b/monai/losses/tversky.py index ee6d7d933b..1cc0e1d8d7 100644 --- a/monai/losses/tversky.py +++ b/monai/losses/tversky.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/__init__.py b/monai/metrics/__init__.py index d18c20f7b2..752f226b7d 100644 --- a/monai/metrics/__init__.py +++ b/monai/metrics/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/confusion_matrix.py b/monai/metrics/confusion_matrix.py index dd1f81a4b4..956ac214ff 100644 --- a/monai/metrics/confusion_matrix.py +++ b/monai/metrics/confusion_matrix.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/cumulative_average.py b/monai/metrics/cumulative_average.py index 090d65a44c..985c0a914e 100644 --- a/monai/metrics/cumulative_average.py +++ b/monai/metrics/cumulative_average.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/froc.py b/monai/metrics/froc.py index 1c3e64579d..011021f33b 100644 --- a/monai/metrics/froc.py +++ b/monai/metrics/froc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/hausdorff_distance.py b/monai/metrics/hausdorff_distance.py index 082311aa67..203abe8bb8 100644 --- a/monai/metrics/hausdorff_distance.py +++ b/monai/metrics/hausdorff_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/meandice.py b/monai/metrics/meandice.py index 1e6065b59c..7ccd3bd587 100644 --- a/monai/metrics/meandice.py +++ b/monai/metrics/meandice.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/metric.py b/monai/metrics/metric.py index 60dcd0b52d..59c8396bc5 100644 --- a/monai/metrics/metric.py +++ b/monai/metrics/metric.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/regression.py b/monai/metrics/regression.py index bd63134d6c..91e602e66f 100644 --- a/monai/metrics/regression.py +++ b/monai/metrics/regression.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/rocauc.py b/monai/metrics/rocauc.py index 341d4cba2f..4c71fe6374 100644 --- a/monai/metrics/rocauc.py +++ b/monai/metrics/rocauc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/surface_distance.py b/monai/metrics/surface_distance.py index 04eed97a5d..78aeb0b18f 100644 --- a/monai/metrics/surface_distance.py +++ b/monai/metrics/surface_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/metrics/utils.py b/monai/metrics/utils.py index ccb6d93862..1cd42ed302 100644 --- a/monai/metrics/utils.py +++ b/monai/metrics/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -28,7 +28,6 @@ def ignore_background(y_pred: Union[np.ndarray, torch.Tensor], y: Union[np.ndarray, torch.Tensor]): """ This function is used to remove background (the first channel) for `y_pred` and `y`. - Args: y_pred: predictions. As for classification tasks, `y_pred` should has the shape [BN] where N is larger than 1. As for segmentation tasks, @@ -36,7 +35,6 @@ def ignore_background(y_pred: Union[np.ndarray, torch.Tensor], y: Union[np.ndarr y: ground truth, the first dim is batch. """ - y = y[:, 1:] if y.shape[1] > 1 else y y_pred = y_pred[:, 1:] if y_pred.shape[1] > 1 else y_pred return y_pred, y diff --git a/monai/networks/__init__.py b/monai/networks/__init__.py index 4e607dd298..4dec09c889 100644 --- a/monai/networks/__init__.py +++ b/monai/networks/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/__init__.py b/monai/networks/blocks/__init__.py index 0fdc944760..01a5bfca2a 100644 --- a/monai/networks/blocks/__init__.py +++ b/monai/networks/blocks/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/acti_norm.py b/monai/networks/blocks/acti_norm.py index d07d78f1ad..593ca6baa7 100644 --- a/monai/networks/blocks/acti_norm.py +++ b/monai/networks/blocks/acti_norm.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/activation.py b/monai/networks/blocks/activation.py index 1526b37056..b136eb7f1f 100644 --- a/monai/networks/blocks/activation.py +++ b/monai/networks/blocks/activation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -19,6 +19,7 @@ def monai_mish(x, inplace: bool = False): return torch.nn.functional.mish(x, inplace=inplace) + else: def monai_mish(x, inplace: bool = False): @@ -30,6 +31,7 @@ def monai_mish(x, inplace: bool = False): def monai_swish(x, inplace: bool = False): return torch.nn.functional.silu(x, inplace=inplace) + else: def monai_swish(x, inplace: bool = False): diff --git a/monai/networks/blocks/aspp.py b/monai/networks/blocks/aspp.py index 8d43530fa7..9796ea8148 100644 --- a/monai/networks/blocks/aspp.py +++ b/monai/networks/blocks/aspp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/convolutions.py b/monai/networks/blocks/convolutions.py index 37530668a3..e12eb6fc8f 100644 --- a/monai/networks/blocks/convolutions.py +++ b/monai/networks/blocks/convolutions.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/crf.py b/monai/networks/blocks/crf.py index ccaef17679..21da3bb74f 100644 --- a/monai/networks/blocks/crf.py +++ b/monai/networks/blocks/crf.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/dints_block.py b/monai/networks/blocks/dints_block.py index f76e125fe0..316627d774 100644 --- a/monai/networks/blocks/dints_block.py +++ b/monai/networks/blocks/dints_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/downsample.py b/monai/networks/blocks/downsample.py index 9b0d5dd4b9..9bee4c596e 100644 --- a/monai/networks/blocks/downsample.py +++ b/monai/networks/blocks/downsample.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/dynunet_block.py b/monai/networks/blocks/dynunet_block.py index 8b22cb16a9..43d3c46cc9 100644 --- a/monai/networks/blocks/dynunet_block.py +++ b/monai/networks/blocks/dynunet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/fcn.py b/monai/networks/blocks/fcn.py index 5833d4a262..09d5d4779e 100644 --- a/monai/networks/blocks/fcn.py +++ b/monai/networks/blocks/fcn.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/localnet_block.py b/monai/networks/blocks/localnet_block.py index 41b76c7d4c..d3b81ff494 100644 --- a/monai/networks/blocks/localnet_block.py +++ b/monai/networks/blocks/localnet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/mlp.py b/monai/networks/blocks/mlp.py index a1728365cf..9f6d12594e 100644 --- a/monai/networks/blocks/mlp.py +++ b/monai/networks/blocks/mlp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/patchembedding.py b/monai/networks/blocks/patchembedding.py index 063a1fded1..492e7bf236 100644 --- a/monai/networks/blocks/patchembedding.py +++ b/monai/networks/blocks/patchembedding.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -97,6 +97,7 @@ def __init__( Rearrange(f"{from_chars} -> {to_chars}", **axes_len), nn.Linear(self.patch_dim, hidden_size) ) self.position_embeddings = nn.Parameter(torch.zeros(1, self.n_patches, hidden_size)) + self.cls_token = nn.Parameter(torch.zeros(1, 1, hidden_size)) self.dropout = nn.Dropout(dropout_rate) self.trunc_normal_(self.position_embeddings, mean=0.0, std=0.02, a=-2.0, b=2.0) self.apply(self._init_weights) diff --git a/monai/networks/blocks/regunet_block.py b/monai/networks/blocks/regunet_block.py index 78e2598b4b..b65f08a443 100644 --- a/monai/networks/blocks/regunet_block.py +++ b/monai/networks/blocks/regunet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/segresnet_block.py b/monai/networks/blocks/segresnet_block.py index ded270ab52..1ed6c08daa 100644 --- a/monai/networks/blocks/segresnet_block.py +++ b/monai/networks/blocks/segresnet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/selfattention.py b/monai/networks/blocks/selfattention.py index 4a86cd84bc..932475b06c 100644 --- a/monai/networks/blocks/selfattention.py +++ b/monai/networks/blocks/selfattention.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/squeeze_and_excitation.py b/monai/networks/blocks/squeeze_and_excitation.py index a9ac57aa4f..46cd48d6aa 100644 --- a/monai/networks/blocks/squeeze_and_excitation.py +++ b/monai/networks/blocks/squeeze_and_excitation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/transformerblock.py b/monai/networks/blocks/transformerblock.py index 616d84e067..5ccc2090b4 100644 --- a/monai/networks/blocks/transformerblock.py +++ b/monai/networks/blocks/transformerblock.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/unetr_block.py b/monai/networks/blocks/unetr_block.py index a9d871a644..ccc055e889 100644 --- a/monai/networks/blocks/unetr_block.py +++ b/monai/networks/blocks/unetr_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/upsample.py b/monai/networks/blocks/upsample.py index 6a8498fe6f..a6aa13dde4 100644 --- a/monai/networks/blocks/upsample.py +++ b/monai/networks/blocks/upsample.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/blocks/warp.py b/monai/networks/blocks/warp.py index 2cb349f8f0..e9cc908464 100644 --- a/monai/networks/blocks/warp.py +++ b/monai/networks/blocks/warp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/__init__.py b/monai/networks/layers/__init__.py index 5115c00af3..b6c13472c4 100644 --- a/monai/networks/layers/__init__.py +++ b/monai/networks/layers/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/convutils.py b/monai/networks/layers/convutils.py index 5efb6e792f..9aa11fa7d0 100644 --- a/monai/networks/layers/convutils.py +++ b/monai/networks/layers/convutils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/factories.py b/monai/networks/layers/factories.py index 6379f49449..d4de08fc50 100644 --- a/monai/networks/layers/factories.py +++ b/monai/networks/layers/factories.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/filtering.py b/monai/networks/layers/filtering.py index bbf925eba9..3b2214d59a 100644 --- a/monai/networks/layers/filtering.py +++ b/monai/networks/layers/filtering.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/gmm.py b/monai/networks/layers/gmm.py index eb9a3f91e4..3091f95458 100644 --- a/monai/networks/layers/gmm.py +++ b/monai/networks/layers/gmm.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/simplelayers.py b/monai/networks/layers/simplelayers.py index b17eae6c5b..0f5c20953e 100644 --- a/monai/networks/layers/simplelayers.py +++ b/monai/networks/layers/simplelayers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/spatial_transforms.py b/monai/networks/layers/spatial_transforms.py index 01e45b2e67..6b5acb166a 100644 --- a/monai/networks/layers/spatial_transforms.py +++ b/monai/networks/layers/spatial_transforms.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/layers/utils.py b/monai/networks/layers/utils.py index 42fac58716..380a77552c 100644 --- a/monai/networks/layers/utils.py +++ b/monai/networks/layers/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/__init__.py b/monai/networks/nets/__init__.py index 22fcef4903..7e730da1a1 100644 --- a/monai/networks/nets/__init__.py +++ b/monai/networks/nets/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/ahnet.py b/monai/networks/nets/ahnet.py index b481374aa1..21e3c33bf3 100644 --- a/monai/networks/nets/ahnet.py +++ b/monai/networks/nets/ahnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/autoencoder.py b/monai/networks/nets/autoencoder.py index 75edde70eb..f4a0451dc7 100644 --- a/monai/networks/nets/autoencoder.py +++ b/monai/networks/nets/autoencoder.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/basic_unet.py b/monai/networks/nets/basic_unet.py index 1e46846576..4a72dcdd9a 100644 --- a/monai/networks/nets/basic_unet.py +++ b/monai/networks/nets/basic_unet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/classifier.py b/monai/networks/nets/classifier.py index 7f4e43eedb..a1f913ea23 100644 --- a/monai/networks/nets/classifier.py +++ b/monai/networks/nets/classifier.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/densenet.py b/monai/networks/nets/densenet.py index 8fb2c269ab..59576f5dd4 100644 --- a/monai/networks/nets/densenet.py +++ b/monai/networks/nets/densenet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/dints.py b/monai/networks/nets/dints.py index c024d6e0f1..eb79145fad 100644 --- a/monai/networks/nets/dints.py +++ b/monai/networks/nets/dints.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/dynunet.py b/monai/networks/nets/dynunet.py index 337a99acd8..4cd3046261 100644 --- a/monai/networks/nets/dynunet.py +++ b/monai/networks/nets/dynunet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -31,13 +31,13 @@ class DynUNetSkipLayer(nn.Module): forward passes of the network. """ - heads: Optional[List[torch.Tensor]] + heads: List[torch.Tensor] - def __init__(self, index, downsample, upsample, next_layer, heads=None, super_head=None): + def __init__(self, index, heads, downsample, upsample, super_head, next_layer): super().__init__() self.downsample = downsample - self.next_layer = next_layer self.upsample = upsample + self.next_layer = next_layer self.super_head = super_head self.heads = heads self.index = index @@ -46,8 +46,8 @@ def forward(self, x): downout = self.downsample(x) nextout = self.next_layer(downout) upout = self.upsample(nextout, downout) - if self.super_head is not None and self.heads is not None and self.index > 0: - self.heads[self.index - 1] = self.super_head(upout) + + self.heads[self.index] = self.super_head(upout) return upout @@ -79,8 +79,6 @@ class DynUNet(nn.Module): For example, if `strides=((1, 2, 4), 2, 1, 1)`, the minimal spatial size of the input is `(8, 16, 32)`, and the spatial size of the output is `(8, 8, 8)`. - For backwards compatibility with old weights, please set `strict=False` when calling `load_state_dict`. - Usage example with medical segmentation decathlon dataset is available at: https://github.com/Project-MONAI/tutorials/tree/master/modules/dynunet_pipeline. @@ -102,16 +100,18 @@ class DynUNet(nn.Module): norm_name: feature normalization type and arguments. Defaults to ``INSTANCE``. act_name: activation layer type and arguments. Defaults to ``leakyrelu``. deep_supervision: whether to add deep supervision head before output. Defaults to ``False``. - If ``True``, in training mode, the forward function will output not only the final feature map - (from `output_block`), but also the feature maps that come from the intermediate up sample layers. + If ``True``, in training mode, the forward function will output not only the last feature + map, but also the previous feature maps that come from the intermediate up sample layers. In order to unify the return type (the restriction of TorchScript), all intermediate - feature maps are interpolated into the same size as the final feature map and stacked together + feature maps are interpolated into the same size as the last feature map and stacked together (with a new dimension in the first axis)into one single tensor. - For instance, if there are two intermediate feature maps with shapes: (1, 2, 16, 12) and - (1, 2, 8, 6), and the final feature map has the shape (1, 2, 32, 24), then all intermediate feature maps - will be interpolated into (1, 2, 32, 24), and the stacked tensor will has the shape (1, 3, 2, 32, 24). + For instance, if there are three feature maps with shapes: (1, 2, 32, 24), (1, 2, 16, 12) and + (1, 2, 8, 6). The last two will be interpolated into (1, 2, 32, 24), and the stacked tensor + will has the shape (1, 3, 2, 8, 6). When calculating the loss, you can use torch.unbind to get all feature maps can compute the loss one by one with the ground truth, then do a weighted average for all losses to achieve the final loss. + (To be added: a corresponding tutorial link) + deep_supr_num: number of feature maps that will output during deep supervision head. The value should be larger than 0 and less than the number of up sample layers. Defaults to 1. @@ -160,17 +160,16 @@ def __init__( self.upsamples = self.get_upsamples() self.output_block = self.get_output_block(0) self.deep_supervision = deep_supervision + self.deep_supervision_heads = self.get_deep_supervision_heads() self.deep_supr_num = deep_supr_num - # initialize the typed list of supervision head outputs so that Torchscript can recognize what's going on - self.heads: List[torch.Tensor] = [torch.rand(1)] * self.deep_supr_num - if self.deep_supervision: - self.deep_supervision_heads = self.get_deep_supervision_heads() - self.check_deep_supr_num() - self.apply(self.initialize_weights) self.check_kernel_stride() + self.check_deep_supr_num() - def create_skips(index, downsamples, upsamples, bottleneck, superheads=None): + # initialize the typed list of supervision head outputs so that Torchscript can recognize what's going on + self.heads: List[torch.Tensor] = [torch.rand(1)] * (len(self.deep_supervision_heads) + 1) + + def create_skips(index, downsamples, upsamples, superheads, bottleneck): """ Construct the UNet topology as a sequence of skip layers terminating with the bottleneck layer. This is done recursively from the top down since a recursive nn.Module subclass is being used to be compatible @@ -181,50 +180,30 @@ def create_skips(index, downsamples, upsamples, bottleneck, superheads=None): if len(downsamples) != len(upsamples): raise ValueError(f"{len(downsamples)} != {len(upsamples)}") + if (len(downsamples) - len(superheads)) not in (1, 0): + raise ValueError(f"{len(downsamples)}-(0,1) != {len(superheads)}") if len(downsamples) == 0: # bottom of the network, pass the bottleneck block return bottleneck - - if superheads is None: - next_layer = create_skips(1 + index, downsamples[1:], upsamples[1:], bottleneck) - return DynUNetSkipLayer(index, downsample=downsamples[0], upsample=upsamples[0], next_layer=next_layer) - - super_head_flag = False if index == 0: # don't associate a supervision head with self.input_block - rest_heads = superheads + current_head, rest_heads = nn.Identity(), superheads + elif not self.deep_supervision: # bypass supervision heads by passing nn.Identity in place of a real one + current_head, rest_heads = nn.Identity(), superheads[1:] else: - if len(superheads) > 0: - super_head_flag = True - rest_heads = superheads[1:] - else: - rest_heads = nn.ModuleList() + current_head, rest_heads = superheads[0], superheads[1:] # create the next layer down, this will stop at the bottleneck layer - next_layer = create_skips(1 + index, downsamples[1:], upsamples[1:], bottleneck, superheads=rest_heads) - if super_head_flag: - return DynUNetSkipLayer( - index, - downsample=downsamples[0], - upsample=upsamples[0], - next_layer=next_layer, - heads=self.heads, - super_head=superheads[0], - ) - - return DynUNetSkipLayer(index, downsample=downsamples[0], upsample=upsamples[0], next_layer=next_layer) - - if not self.deep_supervision: - self.skip_layers = create_skips( - 0, [self.input_block] + list(self.downsamples), self.upsamples[::-1], self.bottleneck - ) - else: - self.skip_layers = create_skips( - 0, - [self.input_block] + list(self.downsamples), - self.upsamples[::-1], - self.bottleneck, - superheads=self.deep_supervision_heads, - ) + next_layer = create_skips(1 + index, downsamples[1:], upsamples[1:], rest_heads, bottleneck) + + return DynUNetSkipLayer(index, self.heads, downsamples[0], upsamples[0], current_head, next_layer) + + self.skip_layers = create_skips( + 0, + [self.input_block] + list(self.downsamples), + self.upsamples[::-1], + self.deep_supervision_heads, + self.bottleneck, + ) def check_kernel_stride(self): kernels, strides = self.kernel_size, self.strides @@ -263,7 +242,8 @@ def forward(self, x): out = self.output_block(out) if self.training and self.deep_supervision: out_all = [out] - for feature_map in self.heads: + feature_maps = self.heads[1 : self.deep_supr_num + 1] + for feature_map in feature_maps: out_all.append(interpolate(feature_map, out.shape[2:])) return torch.stack(out_all, dim=1) return out @@ -354,7 +334,7 @@ def get_module_list( return nn.ModuleList(layers) def get_deep_supervision_heads(self): - return nn.ModuleList([self.get_output_block(i + 1) for i in range(self.deep_supr_num)]) + return nn.ModuleList([self.get_output_block(i + 1) for i in range(len(self.upsamples) - 1)]) @staticmethod def initialize_weights(module): diff --git a/monai/networks/nets/efficientnet.py b/monai/networks/nets/efficientnet.py index fa5efbc4ef..c35b46fd75 100644 --- a/monai/networks/nets/efficientnet.py +++ b/monai/networks/nets/efficientnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/fullyconnectednet.py b/monai/networks/nets/fullyconnectednet.py index 810c07431b..19197bd58d 100644 --- a/monai/networks/nets/fullyconnectednet.py +++ b/monai/networks/nets/fullyconnectednet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/generator.py b/monai/networks/nets/generator.py index a69cae4d7b..434629f4e8 100644 --- a/monai/networks/nets/generator.py +++ b/monai/networks/nets/generator.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/highresnet.py b/monai/networks/nets/highresnet.py index 95c0c758af..2937cda32a 100644 --- a/monai/networks/nets/highresnet.py +++ b/monai/networks/nets/highresnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/milmodel.py b/monai/networks/nets/milmodel.py index 2f4afaffbe..75cd9cf53e 100644 --- a/monai/networks/nets/milmodel.py +++ b/monai/networks/nets/milmodel.py @@ -1,14 +1,3 @@ -# Copyright (c) MONAI Consortium -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - from typing import Dict, Optional, Union, cast import torch @@ -22,24 +11,23 @@ class MILModel(nn.Module): """ Multiple Instance Learning (MIL) model, with a backbone classification model. - Currently, it only works for 2D images, a typical use case is for classification of the + Currently, it only works for 2D images, typical use case is for classification of the digital pathology whole slide images. The expected shape of input data is `[B, N, C, H, W]`, - where `B` is the batch_size of PyTorch Dataloader and `N` is the number of instances + where `B` is the batch_size of PyTorch Dataloader and `N` is the number of the instances extracted from every original image in the batch. A tutorial example is available at: https://github.com/Project-MONAI/tutorials/tree/master/pathology/multiple_instance_learning. Args: num_classes: number of output classes. - mil_mode: MIL algorithm, available values (Defaults to ``"att"``): - - - ``"mean"`` - average features from all instances, equivalent to pure CNN (non MIL). - - ``"max"`` - retain only the instance with the max probability for loss calculation. - - ``"att"`` - attention based MIL https://arxiv.org/abs/1802.04712. - - ``"att_trans"`` - transformer MIL https://arxiv.org/abs/2111.01556. - - ``"att_trans_pyramid"`` - transformer pyramid MIL https://arxiv.org/abs/2111.01556. - + mil_mode: MIL algorithm, available values: + "mean" - average features from all instances, equivalent to pure CNN (non MIL). + "max - retain only the instance with the max probability for loss calculation. + "att" - attention based MIL https://arxiv.org/abs/1802.04712. + "att_trans" - transformer MIL https://arxiv.org/abs/2111.01556. + "att_trans_pyramid" - transformer pyramid MIL https://arxiv.org/abs/2111.01556. + Defaults to ``att``. pretrained: init backbone with pretrained weights, defaults to ``True``. - backbone: Backbone classifier CNN (either ``None``, a ``nn.Module`` that returns features, + backbone: Backbone classifier CNN (either None, nn.Module that returns features, or a string name of a torchvision model). Defaults to ``None``, in which case ResNet50 is used. backbone_num_features: Number of output features of the backbone CNN diff --git a/monai/networks/nets/netadapter.py b/monai/networks/nets/netadapter.py index 425c1d5820..68d9bbe648 100644 --- a/monai/networks/nets/netadapter.py +++ b/monai/networks/nets/netadapter.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/regressor.py b/monai/networks/nets/regressor.py index 0a1e6258a9..bc8feb7527 100644 --- a/monai/networks/nets/regressor.py +++ b/monai/networks/nets/regressor.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/regunet.py b/monai/networks/nets/regunet.py index 174431cc3c..ead12382eb 100644 --- a/monai/networks/nets/regunet.py +++ b/monai/networks/nets/regunet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/resnet.py b/monai/networks/nets/resnet.py index a263c8e8b3..fc400895df 100644 --- a/monai/networks/nets/resnet.py +++ b/monai/networks/nets/resnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -154,7 +154,6 @@ class ResNet(nn.Module): ResNet based on: `Deep Residual Learning for Image Recognition `_ and `Can Spatiotemporal 3D CNNs Retrace the History of 2D CNNs and ImageNet? `_. Adapted from ``_. - Args: block: which ResNet block to use, either Basic or Bottleneck. layers: how many layers to use. diff --git a/monai/networks/nets/segresnet.py b/monai/networks/nets/segresnet.py index d2c45dd3a3..37d47a0d31 100644 --- a/monai/networks/nets/segresnet.py +++ b/monai/networks/nets/segresnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/senet.py b/monai/networks/nets/senet.py index a85d32ba5a..a58c2adb51 100644 --- a/monai/networks/nets/senet.py +++ b/monai/networks/nets/senet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/torchvision_fc.py b/monai/networks/nets/torchvision_fc.py index e93019d050..21c6b0325a 100644 --- a/monai/networks/nets/torchvision_fc.py +++ b/monai/networks/nets/torchvision_fc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/transchex.py b/monai/networks/nets/transchex.py index 7b3afe3e5e..481ed2ec2e 100644 --- a/monai/networks/nets/transchex.py +++ b/monai/networks/nets/transchex.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py index 21259936e7..e1ebaaf6f9 100644 --- a/monai/networks/nets/unet.py +++ b/monai/networks/nets/unet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/unetr.py b/monai/networks/nets/unetr.py index b22f0584a2..b75bc15892 100644 --- a/monai/networks/nets/unetr.py +++ b/monai/networks/nets/unetr.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/varautoencoder.py b/monai/networks/nets/varautoencoder.py index 7386883124..b4ef8be93d 100644 --- a/monai/networks/nets/varautoencoder.py +++ b/monai/networks/nets/varautoencoder.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/vit.py b/monai/networks/nets/vit.py index 62e92603ab..2707e5ad1d 100644 --- a/monai/networks/nets/vit.py +++ b/monai/networks/nets/vit.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/vitautoenc.py b/monai/networks/nets/vitautoenc.py index 3ec89488ff..a08b10d00d 100644 --- a/monai/networks/nets/vitautoenc.py +++ b/monai/networks/nets/vitautoenc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/nets/vnet.py b/monai/networks/nets/vnet.py index ede5f688aa..1b1d3bfba7 100644 --- a/monai/networks/nets/vnet.py +++ b/monai/networks/nets/vnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/networks/utils.py b/monai/networks/utils.py index f7fd2e2956..ef0cff0eed 100644 --- a/monai/networks/utils.py +++ b/monai/networks/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -458,13 +458,11 @@ def convert_to_torchscript( device: target device to verify the model, if None, use CUDA if available. rtol: the relative tolerance when comparing the outputs of PyTorch model and TorchScript model. atol: the absolute tolerance when comparing the outputs of PyTorch model and TorchScript model. - kwargs: other arguments except `obj` for `torch.jit.script()` to convert model, for more details: - https://pytorch.org/docs/master/generated/torch.jit.script.html. """ model.eval() with torch.no_grad(): - script_module = torch.jit.script(model, **kwargs) + script_module = torch.jit.script(model) if filename_or_obj is not None: if not pytorch_after(1, 7): torch.jit.save(m=script_module, f=filename_or_obj) diff --git a/monai/optimizers/__init__.py b/monai/optimizers/__init__.py index 8ce5d3f925..e53aa8d468 100644 --- a/monai/optimizers/__init__.py +++ b/monai/optimizers/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -10,6 +10,5 @@ # limitations under the License. from .lr_finder import LearningRateFinder -from .lr_scheduler import ExponentialLR, LinearLR, WarmupCosineSchedule from .novograd import Novograd from .utils import generate_param_groups diff --git a/monai/optimizers/lr_finder.py b/monai/optimizers/lr_finder.py index ce092d33ab..9cd66c226d 100644 --- a/monai/optimizers/lr_finder.py +++ b/monai/optimizers/lr_finder.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -146,30 +146,30 @@ class LearningRateFinder: and what is the optimal learning rate. Example (fastai approach): - >>> lr_finder = LearningRateFinder(net, optimizer, criterion) - >>> lr_finder.range_test(data_loader, end_lr=100, num_iter=100) - >>> lr_finder.get_steepest_gradient() - >>> lr_finder.plot() # to inspect the loss-learning rate graph + >>> lr_finder = LearningRateFinder(net, optimizer, criterion) + >>> lr_finder.range_test(data_loader, end_lr=100, num_iter=100) + >>> lr_finder.get_steepest_gradient() + >>> lr_finder.plot() # to inspect the loss-learning rate graph Example (Leslie Smith's approach): - >>> lr_finder = LearningRateFinder(net, optimizer, criterion) - >>> lr_finder.range_test(train_loader, val_loader=val_loader, end_lr=1, num_iter=100, step_mode="linear") + >>> lr_finder = LearningRateFinder(net, optimizer, criterion) + >>> lr_finder.range_test(train_loader, val_loader=val_loader, end_lr=1, num_iter=100, step_mode="linear") Gradient accumulation is supported; example: - >>> train_data = ... # prepared dataset - >>> desired_bs, real_bs = 32, 4 # batch size - >>> accumulation_steps = desired_bs // real_bs # required steps for accumulation - >>> data_loader = torch.utils.data.DataLoader(train_data, batch_size=real_bs, shuffle=True) - >>> acc_lr_finder = LearningRateFinder(net, optimizer, criterion) - >>> acc_lr_finder.range_test(data_loader, end_lr=10, num_iter=100, accumulation_steps=accumulation_steps) + >>> train_data = ... # prepared dataset + >>> desired_bs, real_bs = 32, 4 # batch size + >>> accumulation_steps = desired_bs // real_bs # required steps for accumulation + >>> data_loader = torch.utils.data.DataLoader(train_data, batch_size=real_bs, shuffle=True) + >>> acc_lr_finder = LearningRateFinder(net, optimizer, criterion) + >>> acc_lr_finder.range_test(data_loader, end_lr=10, num_iter=100, accumulation_steps=accumulation_steps) By default, image will be extracted from data loader with x["image"] and x[0], depending on whether batch data is a dictionary or not (and similar behaviour for extracting the label). If your data loader returns something other than this, pass a callable function to extract it, e.g.: - >>> image_extractor = lambda x: x["input"] - >>> label_extractor = lambda x: x[100] - >>> lr_finder = LearningRateFinder(net, optimizer, criterion) - >>> lr_finder.range_test(train_loader, val_loader, image_extractor, label_extractor) + >>> image_extractor = lambda x: x["input"] + >>> label_extractor = lambda x: x[100] + >>> lr_finder = LearningRateFinder(net, optimizer, criterion) + >>> lr_finder.range_test(train_loader, val_loader, image_extractor, label_extractor) References: Modified from: https://github.com/davidtvs/pytorch-lr-finder. diff --git a/monai/optimizers/lr_scheduler.py b/monai/optimizers/lr_scheduler.py index 83412c61ea..5ad52c5286 100644 --- a/monai/optimizers/lr_scheduler.py +++ b/monai/optimizers/lr_scheduler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/optimizers/novograd.py b/monai/optimizers/novograd.py index 07a6aff90a..6d14a055fb 100644 --- a/monai/optimizers/novograd.py +++ b/monai/optimizers/novograd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -20,7 +20,7 @@ class Novograd(Optimizer): Novograd based on `Stochastic Gradient Methods with Layer-wise Adaptive Moments for Training of Deep Networks `_. The code is adapted from the implementations in `Jasper for PyTorch - `_, + `_, and `OpenSeq2Seq `_. Args: diff --git a/monai/optimizers/utils.py b/monai/optimizers/utils.py index 1a040927d8..08949912d7 100644 --- a/monai/optimizers/utils.py +++ b/monai/optimizers/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/__init__.py b/monai/transforms/__init__.py index c9cd1b4e0d..3f7e53f514 100644 --- a/monai/transforms/__init__.py +++ b/monai/transforms/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -178,9 +178,6 @@ RandStdShiftIntensityd, RandStdShiftIntensityD, RandStdShiftIntensityDict, - SavitzkyGolaySmoothd, - SavitzkyGolaySmoothD, - SavitzkyGolaySmoothDict, ScaleIntensityd, ScaleIntensityD, ScaleIntensityDict, @@ -277,14 +274,10 @@ VoteEnsembled, VoteEnsembleDict, ) -from .smooth_field.array import ( - RandSmoothDeform, - RandSmoothFieldAdjustContrast, - RandSmoothFieldAdjustIntensity, - SmoothField, -) -from .smooth_field.dictionary import RandSmoothDeformd, RandSmoothFieldAdjustContrastd, RandSmoothFieldAdjustIntensityd +from .smooth_field.array import RandSmoothFieldAdjustContrast, RandSmoothFieldAdjustIntensity, SmoothField +from .smooth_field.dictionary import RandSmoothFieldAdjustContrastd, RandSmoothFieldAdjustIntensityd from .spatial.array import ( + AddCoordinateChannels, Affine, AffineGrid, Flip, @@ -309,6 +302,9 @@ Zoom, ) from .spatial.dictionary import ( + AddCoordinateChannelsd, + AddCoordinateChannelsD, + AddCoordinateChannelsDict, Affined, AffineD, AffineDict, @@ -367,7 +363,6 @@ from .transform import MapTransform, Randomizable, RandomizableTransform, ThreadUnsafe, Transform, apply_transform from .utility.array import ( AddChannel, - AddCoordinateChannels, AddExtremePointsChannel, AsChannelFirst, AsChannelLast, @@ -403,9 +398,6 @@ AddChanneld, AddChannelD, AddChannelDict, - AddCoordinateChannelsd, - AddCoordinateChannelsD, - AddCoordinateChannelsDict, AddExtremePointsChanneld, AddExtremePointsChannelD, AddExtremePointsChannelDict, diff --git a/monai/transforms/adaptors.py b/monai/transforms/adaptors.py index 92fd11cf79..434d1f1c05 100644 --- a/monai/transforms/adaptors.py +++ b/monai/transforms/adaptors.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/compose.py b/monai/transforms/compose.py index 165d9b732f..d0d14bcc2d 100644 --- a/monai/transforms/compose.py +++ b/monai/transforms/compose.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -256,9 +256,12 @@ def inverse(self, data): # and then remove the OneOf transform self.pop_transform(data, key) if index is None: - # no invertible transforms have been applied - return data + raise RuntimeError("No invertible transforms have been applied") + # if applied transform is not InvertibleTransform, throw error _transform = self.transforms[index] + if not isinstance(_transform, InvertibleTransform): + raise RuntimeError(f"Applied OneOf transform is not invertible (applied index: {index}).") + # apply the inverse - return _transform.inverse(data) if isinstance(_transform, InvertibleTransform) else data + return _transform.inverse(data) diff --git a/monai/transforms/croppad/__init__.py b/monai/transforms/croppad/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/transforms/croppad/__init__.py +++ b/monai/transforms/croppad/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/croppad/array.py b/monai/transforms/croppad/array.py index faf5306ce0..ba503aedd1 100644 --- a/monai/transforms/croppad/array.py +++ b/monai/transforms/croppad/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/croppad/batch.py b/monai/transforms/croppad/batch.py index 6edaf4622d..0cdaa3a2d8 100644 --- a/monai/transforms/croppad/batch.py +++ b/monai/transforms/croppad/batch.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/croppad/dictionary.py b/monai/transforms/croppad/dictionary.py index 03c75705ab..fd7fabe5a1 100644 --- a/monai/transforms/croppad/dictionary.py +++ b/monai/transforms/croppad/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/intensity/__init__.py b/monai/transforms/intensity/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/transforms/intensity/__init__.py +++ b/monai/transforms/intensity/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/intensity/array.py b/monai/transforms/intensity/array.py index 33da679df5..31249d547b 100644 --- a/monai/transforms/intensity/array.py +++ b/monai/transforms/intensity/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -129,10 +129,10 @@ class RandRicianNoise(RandomizableTransform): """ Add Rician noise to image. Rician noise in MRI is the result of performing a magnitude operation on complex - data with Gaussian noise of the same variance in both channels, as described in - `Noise in Magnitude Magnetic Resonance Images `_. - This transform is adapted from `DIPY `_. - See also: `The rician distribution of noisy mri data `_. + data with Gaussian noise of the same variance in both channels, as described in `Noise in Magnitude + Magnetic Resonance Images `_. This transform is adapted from + `DIPY`_. See also: `The rician distribution of noisy mri data + `_. Args: prob: Probability to add Rician noise. @@ -443,7 +443,6 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: ValueError: When ``self.minv=None`` or ``self.maxv=None`` and ``self.factor=None``. Incompatible values. """ - ret: NdarrayOrTensor if self.minv is not None or self.maxv is not None: if self.channel_wise: out = [rescale_array(d, self.minv, self.maxv, dtype=self.dtype) for d in img] @@ -592,7 +591,7 @@ def __call__(self, img: NdarrayOrTensor, randomize: bool = True) -> NdarrayOrTen axis=0, ) img_np, *_ = convert_data_type(img, np.ndarray) - out: NdarrayOrTensor = img_np * np.exp(_bias_fields) + out = img_np * np.exp(_bias_fields) out, *_ = convert_to_dst_type(src=out, dst=img, dtype=self.dtype or img.dtype) return out @@ -609,8 +608,8 @@ class NormalizeIntensity(Transform): subtrahend: the amount to subtract by (usually the mean). divisor: the amount to divide by (usually the standard deviation). nonzero: whether only normalize non-zero values. - channel_wise: if True, calculate on each channel separately, otherwise, calculate on - the entire image directly. default to False. + channel_wise: if using calculated mean and std, calculate on each channel separately + or calculate on the entire image directly. dtype: output data type, if None, same as input image. defaults to float32. """ @@ -920,8 +919,6 @@ class ScaleIntensityRangePercentiles(Transform): b_max: intensity target range max. clip: whether to perform clip after scaling. relative: whether to scale to the corresponding percentiles of [b_min, b_max]. - channel_wise: if True, compute intensity percentile and normalize every channel separately. - default to False. dtype: output data type, if None, same as input image. defaults to float32. """ @@ -935,7 +932,6 @@ def __init__( b_max: Optional[float], clip: bool = False, relative: bool = False, - channel_wise: bool = False, dtype: DtypeLike = np.float32, ) -> None: if lower < 0.0 or lower > 100.0: @@ -948,10 +944,12 @@ def __init__( self.b_max = b_max self.clip = clip self.relative = relative - self.channel_wise = channel_wise self.dtype = dtype - def _normalize(self, img: NdarrayOrTensor) -> NdarrayOrTensor: + def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: + """ + Apply the transform to `img`. + """ a_min: float = percentile(img, self.lower) # type: ignore a_max: float = percentile(img, self.upper) # type: ignore b_min = self.b_min @@ -969,18 +967,6 @@ def _normalize(self, img: NdarrayOrTensor) -> NdarrayOrTensor: img = scalar(img) return img - def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: - """ - Apply the transform to `img`. - """ - if self.channel_wise: - for i, d in enumerate(img): - img[i] = self._normalize(img=d) # type: ignore - else: - img = self._normalize(img=img) - - return img - class MaskIntensity(Transform): """ diff --git a/monai/transforms/intensity/dictionary.py b/monai/transforms/intensity/dictionary.py index 48a259dbc5..fa2de4c7b8 100644 --- a/monai/transforms/intensity/dictionary.py +++ b/monai/transforms/intensity/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -44,7 +44,6 @@ RandScaleIntensity, RandShiftIntensity, RandStdShiftIntensity, - SavitzkyGolaySmooth, ScaleIntensity, ScaleIntensityRange, ScaleIntensityRangePercentiles, @@ -74,7 +73,6 @@ "RandAdjustContrastd", "ScaleIntensityRangePercentilesd", "MaskIntensityd", - "SavitzkyGolaySmoothd", "GaussianSmoothd", "RandGaussianSmoothd", "GaussianSharpend", @@ -117,8 +115,6 @@ "ScaleIntensityRangePercentilesDict", "MaskIntensityD", "MaskIntensityDict", - "SavitzkyGolaySmoothD", - "SavitzkyGolaySmoothDict", "GaussianSmoothD", "GaussianSmoothDict", "RandGaussianSmoothD", @@ -659,8 +655,8 @@ class NormalizeIntensityd(MapTransform): subtrahend: the amount to subtract by (usually the mean) divisor: the amount to divide by (usually the standard deviation) nonzero: whether only normalize non-zero values. - channel_wise: if True, calculate on each channel separately, otherwise, calculate on - the entire image directly. default to False. + channel_wise: if using calculated mean and std, calculate on each channel separately + or calculate on the entire image directly. dtype: output data type, if None, same as input image. defaults to float32. allow_missing_keys: don't raise exception if key is missing. """ @@ -848,8 +844,6 @@ class ScaleIntensityRangePercentilesd(MapTransform): b_max: intensity target range max. clip: whether to perform clip after scaling. relative: whether to scale to the corresponding percentiles of [b_min, b_max] - channel_wise: if True, compute intensity percentile and normalize every channel separately. - default to False. dtype: output data type, if None, same as input image. defaults to float32. allow_missing_keys: don't raise exception if key is missing. """ @@ -865,12 +859,11 @@ def __init__( b_max: Optional[float], clip: bool = False, relative: bool = False, - channel_wise: bool = False, dtype: DtypeLike = np.float32, allow_missing_keys: bool = False, ) -> None: super().__init__(keys, allow_missing_keys) - self.scaler = ScaleIntensityRangePercentiles(lower, upper, b_min, b_max, clip, relative, channel_wise, dtype) + self.scaler = ScaleIntensityRangePercentiles(lower, upper, b_min, b_max, clip, relative, dtype) def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]: d = dict(data) @@ -921,43 +914,6 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N return d -class SavitzkyGolaySmoothd(MapTransform): - """ - Dictionary-based wrapper of :py:class:`monai.transforms.SavitzkyGolaySmooth`. - - Args: - keys: keys of the corresponding items to be transformed. - See also: :py:class:`monai.transforms.compose.MapTransform` - window_length: length of the filter window, must be a positive odd integer. - order: order of the polynomial to fit to each window, must be less than ``window_length``. - axis: optional axis along which to apply the filter kernel. Default 1 (first spatial dimension). - mode: optional padding mode, passed to convolution class. ``'zeros'``, ``'reflect'``, ``'replicate'`` - or ``'circular'``. default: ``'zeros'``. See ``torch.nn.Conv1d()`` for more information. - allow_missing_keys: don't raise exception if key is missing. - - """ - - backend = SavitzkyGolaySmooth.backend - - def __init__( - self, - keys: KeysCollection, - window_length: int, - order: int, - axis: int = 1, - mode: str = "zeros", - allow_missing_keys: bool = False, - ) -> None: - super().__init__(keys, allow_missing_keys) - self.converter = SavitzkyGolaySmooth(window_length=window_length, order=order, axis=axis, mode=mode) - - def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]: - d = dict(data) - for key in self.key_iterator(d): - d[key] = self.converter(d[key]) - return d - - class GaussianSmoothd(MapTransform): """ Dictionary-based wrapper of :py:class:`monai.transforms.GaussianSmooth`. @@ -1667,7 +1623,6 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N RandAdjustContrastD = RandAdjustContrastDict = RandAdjustContrastd ScaleIntensityRangePercentilesD = ScaleIntensityRangePercentilesDict = ScaleIntensityRangePercentilesd MaskIntensityD = MaskIntensityDict = MaskIntensityd -SavitzkyGolaySmoothD = SavitzkyGolaySmoothDict = SavitzkyGolaySmoothd GaussianSmoothD = GaussianSmoothDict = GaussianSmoothd RandGaussianSmoothD = RandGaussianSmoothDict = RandGaussianSmoothd GaussianSharpenD = GaussianSharpenDict = GaussianSharpend diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index c8bfeeca05..90ceba7489 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/inverse_batch_transform.py b/monai/transforms/inverse_batch_transform.py index ae0317cea8..9d9d8c2a5d 100644 --- a/monai/transforms/inverse_batch_transform.py +++ b/monai/transforms/inverse_batch_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/io/__init__.py b/monai/transforms/io/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/transforms/io/__init__.py +++ b/monai/transforms/io/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/io/array.py b/monai/transforms/io/array.py index 19fafbcbf4..cd2d93a0c7 100644 --- a/monai/transforms/io/array.py +++ b/monai/transforms/io/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -204,10 +204,8 @@ def __call__(self, filename: Union[Sequence[PathLike], PathLike], reader: Option break if img is None or reader is None: - if isinstance(filename, tuple) and len(filename) == 1: - filename = filename[0] raise RuntimeError( - f"cannot find a suitable reader for file: {filename}.\n" + f"can not find a suitable reader for file: {filename}.\n" " Please install the reader libraries, see also the installation instructions:\n" " https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies.\n" f" The current registered: {self.readers}.\n" diff --git a/monai/transforms/io/dictionary.py b/monai/transforms/io/dictionary.py index cb73567afb..f714dd2831 100644 --- a/monai/transforms/io/dictionary.py +++ b/monai/transforms/io/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/nvtx.py b/monai/transforms/nvtx.py index f00145efbc..6dd5c3b0a3 100644 --- a/monai/transforms/nvtx.py +++ b/monai/transforms/nvtx.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/post/__init__.py b/monai/transforms/post/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/transforms/post/__init__.py +++ b/monai/transforms/post/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/post/array.py b/monai/transforms/post/array.py index c5fe05d220..5dca7df3f6 100644 --- a/monai/transforms/post/array.py +++ b/monai/transforms/post/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -405,7 +405,7 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: raise NotImplementedError(f"{self.__class__} can not handle data of type {type(img)}.") if isinstance(img, torch.Tensor): - if hasattr(torch, "isin"): # `isin` is new in torch 1.10.0 + if hasattr(torch, "isin"): appl_lbls = torch.as_tensor(self.applied_labels, device=img.device) return torch.where(torch.isin(img, appl_lbls), img, torch.tensor(0.0).to(img)) else: diff --git a/monai/transforms/post/dictionary.py b/monai/transforms/post/dictionary.py index 9d7c9652bf..9d6173ac80 100644 --- a/monai/transforms/post/dictionary.py +++ b/monai/transforms/post/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/smooth_field/__init__.py b/monai/transforms/smooth_field/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/transforms/smooth_field/__init__.py +++ b/monai/transforms/smooth_field/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/smooth_field/array.py b/monai/transforms/smooth_field/array.py index 31ce76e5b5..b8016dd3fd 100644 --- a/monai/transforms/smooth_field/array.py +++ b/monai/transforms/smooth_field/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,163 +14,90 @@ from typing import Any, Optional, Sequence, Union import numpy as np -import torch -from torch.nn.functional import grid_sample, interpolate import monai -from monai.config.type_definitions import NdarrayOrTensor -from monai.transforms.transform import Randomizable, RandomizableTransform -from monai.transforms.utils_pytorch_numpy_unification import moveaxis -from monai.utils import GridSampleMode, GridSamplePadMode, InterpolateMode +from monai.transforms.spatial.array import Resize +from monai.transforms.transform import Randomizable, RandomizableTransform, Transform +from monai.transforms.utils import rescale_array +from monai.utils import InterpolateMode, ensure_tuple from monai.utils.enums import TransformBackends -from monai.utils.module import look_up_option, pytorch_after -from monai.utils.type_conversion import convert_to_dst_type, convert_to_tensor +from monai.utils.type_conversion import convert_to_dst_type -__all__ = ["SmoothField", "RandSmoothFieldAdjustContrast", "RandSmoothFieldAdjustIntensity", "RandSmoothDeform"] +__all__ = ["SmoothField", "RandSmoothFieldAdjustContrast", "RandSmoothFieldAdjustIntensity"] class SmoothField(Randomizable): """ - Generate a smooth field array by defining a smaller randomized field and then reinterpolating to the desired size. - - This exploits interpolation to create a smoothly varying field used for other applications. An initial randomized - field is defined with `rand_size` dimensions with `pad` number of values padding it along each dimension using - `pad_val` as the value. If `spatial_size` is given this is interpolated to that size, otherwise if None the random - array is produced uninterpolated. The output is always a Pytorch tensor allocated on the specified device. + Generate a smooth field array by defining a smaller randomized field and then resizing to the desired size. This + exploits interpolation to create a smoothly varying field used for other applications. Args: + spatial_size: final output size of the array rand_size: size of the randomized field to start from - pad: number of pixels/voxels along the edges of the field to pad with `pad_val` - pad_val: value with which to pad field edges + padder: optional transform to add padding to the randomized field + mode: interpolation mode to use when upsampling + align_corners: if True align the corners when upsampling field low: low value for randomized field high: high value for randomized field channels: number of channels of final output - spatial_size: final output size of the array, None to produce original uninterpolated field - mode: interpolation mode for resizing the field - align_corners: if True align the corners when upsampling field - device: Pytorch device to define field on """ def __init__( self, - rand_size: Sequence[int], - pad: int = 0, - pad_val: float = 0, + spatial_size: Union[Sequence[int], int], + rand_size: Union[Sequence[int], int], + padder: Optional[Transform] = None, + mode: Union[InterpolateMode, str] = InterpolateMode.AREA, + align_corners: Optional[bool] = None, low: float = -1.0, high: float = 1.0, channels: int = 1, - spatial_size: Optional[Sequence[int]] = None, - mode: Union[InterpolateMode, str] = InterpolateMode.AREA, - align_corners: Optional[bool] = None, - device: Optional[torch.device] = None, ): - self.rand_size = tuple(rand_size) - self.pad = pad - self.low = low - self.high = high - self.channels = channels - self.mode = mode - self.align_corners = align_corners - self.device = device - - self.spatial_size: Optional[Sequence[int]] = None - self.spatial_zoom: Optional[Sequence[float]] = None - - if low >= high: - raise ValueError("Value for `low` must be less than `high` otherwise field will be zeros") - - self.total_rand_size = tuple(rs + self.pad * 2 for rs in self.rand_size) - - self.field = torch.ones((1, self.channels) + self.total_rand_size, device=self.device) * pad_val - - self.crand_size = (self.channels,) + self.rand_size - - pad_slice = slice(None) if self.pad == 0 else slice(self.pad, -self.pad) - self.rand_slices = (0, slice(None)) + (pad_slice,) * len(self.rand_size) - - self.set_spatial_size(spatial_size) + self.resizer: Transform = Resize(spatial_size, mode=mode, align_corners=align_corners) + self.rand_size: tuple = ensure_tuple(rand_size) + self.padder: Optional[Transform] = padder + self.field: Optional[np.ndarray] = None + self.low: float = low + self.high: float = high + self.channels: int = channels def randomize(self, data: Optional[Any] = None) -> None: - self.field[self.rand_slices] = torch.from_numpy(self.R.uniform(self.low, self.high, self.crand_size)) + self.field = self.R.uniform(self.low, self.high, (self.channels,) + self.rand_size) # type: ignore + if self.padder is not None: + self.field = self.padder(self.field) - def set_spatial_size(self, spatial_size: Optional[Sequence[int]]) -> None: - """ - Set the `spatial_size` and `spatial_zoom` attributes used for interpolating the field to the given - dimension, or not interpolate at all if None. - - Args: - spatial_size: new size to interpolate to, or None to not interpolate - """ - if spatial_size is None: - self.spatial_size = None - self.spatial_zoom = None - else: - self.spatial_size = tuple(spatial_size) - self.spatial_zoom = tuple(s / f for s, f in zip(self.spatial_size, self.total_rand_size)) - - def set_mode(self, mode: Union[monai.utils.InterpolateMode, str]) -> None: - self.mode = mode - - def __call__(self, randomize=False) -> torch.Tensor: - if randomize: - self.randomize() + def __call__(self): + resized_field = self.resizer(self.field) - field = self.field.clone() - - if self.spatial_zoom is not None: - resized_field = interpolate( # type: ignore - input=field, # type: ignore - scale_factor=self.spatial_zoom, - mode=look_up_option(self.mode, InterpolateMode).value, - align_corners=self.align_corners, - recompute_scale_factor=False, - ) - - mina = resized_field.min() - maxa = resized_field.max() - minv = self.field.min() - maxv = self.field.max() - - # faster than rescale_array, this uses in-place operations and doesn't perform unneeded range checks - norm_field = (resized_field.squeeze(0) - mina).div_(maxa - mina) - field = norm_field.mul_(maxv - minv).add_(minv) - - return field + return rescale_array(resized_field, self.field.min(), self.field.max()) class RandSmoothFieldAdjustContrast(RandomizableTransform): """ - Randomly adjust the contrast of input images by calculating a randomized smooth field for each invocation. - - This uses SmoothField internally to define the adjustment over the image. If `pad` is greater than 0 the - edges of the input volume of that width will be mostly unchanged. Contrast is changed by raising input - values by the power of the smooth field so the range of values given by `gamma` should be chosen with this - in mind. For example, a minimum value of 0 in `gamma` will produce white areas so this should be avoided. - Afte the contrast is adjusted the values of the result are rescaled to the range of the original input. + Randomly adjust the contrast of input images by calculating a randomized smooth field for each invocation. This + uses SmoothFieldAdjustContrast and SmoothField internally. Args: spatial_size: size of input array's spatial dimensions rand_size: size of the randomized field to start from - pad: number of pixels/voxels along the edges of the field to pad with 1 + padder: optional transform to add padding to the randomized field mode: interpolation mode to use when upsampling align_corners: if True align the corners when upsampling field prob: probability transform is applied gamma: (min, max) range for exponential field - device: Pytorch device to define field on """ backend = [TransformBackends.TORCH, TransformBackends.NUMPY] def __init__( self, - spatial_size: Sequence[int], - rand_size: Sequence[int], - pad: int = 0, + spatial_size: Union[Sequence[int], int], + rand_size: Union[Sequence[int], int], + padder: Optional[Transform] = None, mode: Union[InterpolateMode, str] = InterpolateMode.AREA, align_corners: Optional[bool] = None, prob: float = 0.1, gamma: Union[Sequence[float], float] = (0.5, 4.5), - device: Optional[torch.device] = None, ): super().__init__(prob) @@ -182,18 +109,7 @@ def __init__( self.gamma = (min(gamma), max(gamma)) - self.sfield = SmoothField( - rand_size=rand_size, - pad=pad, - pad_val=1, - low=self.gamma[0], - high=self.gamma[1], - channels=1, - spatial_size=spatial_size, - mode=mode, - align_corners=align_corners, - device=device, - ) + self.sfield = SmoothField(spatial_size, rand_size, padder, mode, align_corners, self.gamma[0], self.gamma[1]) def set_random_state( self, seed: Optional[int] = None, state: Optional[np.random.RandomState] = None @@ -208,10 +124,7 @@ def randomize(self, data: Optional[Any] = None) -> None: if self._do_transform: self.sfield.randomize() - def set_mode(self, mode: Union[monai.utils.InterpolateMode, str]) -> None: - self.sfield.set_mode(mode) - - def __call__(self, img: NdarrayOrTensor, randomize: bool = True) -> NdarrayOrTensor: + def __call__(self, img: np.ndarray, randomize: bool = True): """ Apply the transform to `img`, if `randomize` randomizing the smooth field otherwise reusing the previous. """ @@ -226,51 +139,44 @@ def __call__(self, img: NdarrayOrTensor, randomize: bool = True) -> NdarrayOrTen img_rng = img_max - img_min field = self.sfield() - rfield, *_ = convert_to_dst_type(field, img) - - # everything below here is to be computed using the destination type (numpy, tensor, etc.) + field, *_ = convert_to_dst_type(field, img) - img = (img - img_min) / (img_rng + 1e-10) # rescale to unit values - img = img ** rfield # contrast is changed by raising image data to a power, in this case the field + img = (img - img_min) / max(img_rng, 1e-10) # rescale to unit values + img = img ** field # contrast is changed by raising image data to a power, in this case the field out = (img * img_rng) + img_min # rescale back to the original image value range + out, *_ = convert_to_dst_type(out, img, img.dtype) + return out class RandSmoothFieldAdjustIntensity(RandomizableTransform): """ - Randomly adjust the intensity of input images by calculating a randomized smooth field for each invocation. - - This uses SmoothField internally to define the adjustment over the image. If `pad` is greater than 0 the - edges of the input volume of that width will be mostly unchanged. Intensity is changed by multiplying the - inputs by the smooth field, so the values of `gamma` should be chosen with this in mind. The default values - of `(0.1, 1.0)` are sensible in that values will not be zeroed out by the field nor multiplied greater than - the original value range. + Randomly adjust the intensity of input images by calculating a randomized smooth field for each invocation. This + uses SmoothField internally. Args: spatial_size: size of input array rand_size: size of the randomized field to start from - pad: number of pixels/voxels along the edges of the field to pad with 1 + padder: optional transform to add padding to the randomized field mode: interpolation mode to use when upsampling align_corners: if True align the corners when upsampling field prob: probability transform is applied gamma: (min, max) range of intensity multipliers - device: Pytorch device to define field on """ backend = [TransformBackends.TORCH, TransformBackends.NUMPY] def __init__( self, - spatial_size: Sequence[int], - rand_size: Sequence[int], - pad: int = 0, - mode: Union[InterpolateMode, str] = InterpolateMode.AREA, + spatial_size: Union[Sequence[int], int], + rand_size: Union[Sequence[int], int], + padder: Optional[Transform] = None, + mode: Union[monai.utils.InterpolateMode, str] = monai.utils.InterpolateMode.AREA, align_corners: Optional[bool] = None, prob: float = 0.1, gamma: Union[Sequence[float], float] = (0.1, 1.0), - device: Optional[torch.device] = None, ): super().__init__(prob) @@ -282,18 +188,7 @@ def __init__( self.gamma = (min(gamma), max(gamma)) - self.sfield = SmoothField( - rand_size=rand_size, - pad=pad, - pad_val=1, - low=self.gamma[0], - high=self.gamma[1], - channels=1, - spatial_size=spatial_size, - mode=mode, - align_corners=align_corners, - device=device, - ) + self.sfield = SmoothField(spatial_size, rand_size, padder, mode, align_corners, self.gamma[0], self.gamma[1]) def set_random_state( self, seed: Optional[int] = None, state: Optional[np.random.RandomState] = None @@ -308,10 +203,7 @@ def randomize(self, data: Optional[Any] = None) -> None: if self._do_transform: self.sfield.randomize() - def set_mode(self, mode: Union[InterpolateMode, str]) -> None: - self.sfield.set_mode(mode) - - def __call__(self, img: NdarrayOrTensor, randomize: bool = True) -> NdarrayOrTensor: + def __call__(self, img: np.ndarray, randomize: bool = True): """ Apply the transform to `img`, if `randomize` randomizing the smooth field otherwise reusing the previous. """ @@ -322,140 +214,13 @@ def __call__(self, img: NdarrayOrTensor, randomize: bool = True) -> NdarrayOrTen if not self._do_transform: return img + img_min = img.min() + img_max = img.max() + field = self.sfield() rfield, *_ = convert_to_dst_type(field, img) - # everything below here is to be computed using the destination type (numpy, tensor, etc.) - out = img * rfield + out, *_ = convert_to_dst_type(out, img, img.dtype) return out - - -class RandSmoothDeform(RandomizableTransform): - """ - Deform an image using a random smooth field and Pytorch's grid_sample. - - The amount of deformation is given by `def_range` in fractions of the size of the image. The size of each dimension - of the input image is always defined as 2 regardless of actual image voxel dimensions, that is the coordinates in - every dimension range from -1 to 1. A value of 0.1 means pixels/voxels can be moved by up to 5% of the image's size. - - Args: - spatial_size: input array size to which deformation grid is interpolated - rand_size: size of the randomized field to start from - pad: number of pixels/voxels along the edges of the field to pad with 0 - field_mode: interpolation mode to use when upsampling the deformation field - align_corners: if True align the corners when upsampling field - prob: probability transform is applied - def_range: value of the deformation range in image size fractions, single min/max value or min/max pair - grid_dtype: type for the deformation grid calculated from the field - grid_mode: interpolation mode used for sampling input using deformation grid - grid_padding_mode: padding mode used for sampling input using deformation grid - grid_align_corners: if True align the corners when sampling the deformation grid - device: Pytorch device to define field on - """ - - backend = [TransformBackends.TORCH] - - def __init__( - self, - spatial_size: Sequence[int], - rand_size: Sequence[int], - pad: int = 0, - field_mode: Union[InterpolateMode, str] = InterpolateMode.AREA, - align_corners: Optional[bool] = None, - prob: float = 0.1, - def_range: Union[Sequence[float], float] = 1.0, - grid_dtype=torch.float32, - grid_mode: Union[GridSampleMode, str] = GridSampleMode.NEAREST, - grid_padding_mode: Union[GridSamplePadMode, str] = GridSamplePadMode.BORDER, - grid_align_corners: Optional[bool] = False, - device: Optional[torch.device] = None, - ): - super().__init__(prob) - - self.grid_dtype = grid_dtype - self.grid_mode = grid_mode - self.def_range = def_range - self.device = device - self.grid_align_corners = grid_align_corners - self.grid_padding_mode = grid_padding_mode - - if isinstance(def_range, (int, float)): - self.def_range = (-def_range, def_range) - else: - if len(def_range) != 2: - raise ValueError("Argument `def_range` should be a number or pair of numbers.") - - self.def_range = (min(def_range), max(def_range)) - - self.sfield = SmoothField( - spatial_size=spatial_size, - rand_size=rand_size, - pad=pad, - low=self.def_range[0], - high=self.def_range[1], - channels=len(rand_size), - mode=field_mode, - align_corners=align_corners, - device=device, - ) - - grid_space = spatial_size if spatial_size is not None else self.sfield.field.shape[2:] - grid_ranges = [torch.linspace(-1, 1, d) for d in grid_space] - - if pytorch_after(1, 10): - grid = torch.meshgrid(*grid_ranges, indexing="ij") - else: - grid = torch.meshgrid(*grid_ranges) - - self.grid = torch.stack(grid).unsqueeze(0).to(self.device, self.grid_dtype) - - def set_random_state( - self, seed: Optional[int] = None, state: Optional[np.random.RandomState] = None - ) -> "Randomizable": - super().set_random_state(seed, state) - self.sfield.set_random_state(seed, state) - return self - - def randomize(self, data: Optional[Any] = None) -> None: - super().randomize(None) - - if self._do_transform: - self.sfield.randomize() - - def set_field_mode(self, mode: Union[monai.utils.InterpolateMode, str]) -> None: - self.sfield.set_mode(mode) - - def set_grid_mode(self, mode: Union[monai.utils.GridSampleMode, str]) -> None: - self.grid_mode = mode - - def __call__( - self, img: NdarrayOrTensor, randomize: bool = True, device: Optional[torch.device] = None - ) -> NdarrayOrTensor: - if randomize: - self.randomize() - - if not self._do_transform: - return img - - device = device if device is not None else self.device - - field = self.sfield() - - dgrid = self.grid + field.to(self.grid_dtype) - dgrid = moveaxis(dgrid, 1, -1) # type: ignore - - img_t = convert_to_tensor(img[None], torch.float32, device) - - out = grid_sample( - input=img_t, - grid=dgrid, - mode=look_up_option(self.grid_mode, GridSampleMode).value, - align_corners=self.grid_align_corners, - padding_mode=look_up_option(self.grid_padding_mode, GridSamplePadMode).value, - ) - - out_t, *_ = convert_to_dst_type(out.squeeze(0), img) - - return out_t diff --git a/monai/transforms/smooth_field/dictionary.py b/monai/transforms/smooth_field/dictionary.py index c129d14f32..43663930ad 100644 --- a/monai/transforms/smooth_field/dictionary.py +++ b/monai/transforms/smooth_field/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -13,44 +13,31 @@ from typing import Any, Hashable, Mapping, Optional, Sequence, Union import numpy as np -import torch from monai.config import KeysCollection -from monai.config.type_definitions import NdarrayOrTensor -from monai.transforms.smooth_field.array import ( - RandSmoothDeform, - RandSmoothFieldAdjustContrast, - RandSmoothFieldAdjustIntensity, -) -from monai.transforms.transform import MapTransform, RandomizableTransform -from monai.utils import GridSampleMode, GridSamplePadMode, InterpolateMode, ensure_tuple_rep +from monai.transforms.smooth_field.array import RandSmoothFieldAdjustContrast, RandSmoothFieldAdjustIntensity +from monai.transforms.transform import MapTransform, RandomizableTransform, Transform +from monai.utils import InterpolateMode from monai.utils.enums import TransformBackends -__all__ = ["RandSmoothFieldAdjustContrastd", "RandSmoothFieldAdjustIntensityd", "RandSmoothDeformd"] - - -InterpolateModeType = Union[InterpolateMode, str] -GridSampleModeType = Union[GridSampleMode, str] +__all__ = ["RandSmoothFieldAdjustContrastd", "RandSmoothFieldAdjustIntensityd"] class RandSmoothFieldAdjustContrastd(RandomizableTransform, MapTransform): """ - Dictionary version of RandSmoothFieldAdjustContrast. - - The field is randomized once per invocation by default so the same field is applied to every selected key. The - `mode` parameter specifying interpolation mode for the field can be a single value or a sequence of values with - one for each key in `keys`. + Dictionary version of RandSmoothFieldAdjustContrast. The field is randomized once per invocation by default so the + same field is applied to every selected key. Args: keys: key names to apply the augment to spatial_size: size of input arrays, all arrays stated in `keys` must have same dimensions rand_size: size of the randomized field to start from - pad: number of pixels/voxels along the edges of the field to pad with 0 + padder: optional transform to add padding to the randomized field mode: interpolation mode to use when upsampling align_corners: if True align the corners when upsampling field prob: probability transform is applied gamma: (min, max) range for exponential field - device: Pytorch device to define field on + apply_same_field: if True, apply the same field to each key, otherwise randomize individually """ backend = [TransformBackends.TORCH, TransformBackends.NUMPY] @@ -58,30 +45,28 @@ class RandSmoothFieldAdjustContrastd(RandomizableTransform, MapTransform): def __init__( self, keys: KeysCollection, - spatial_size: Sequence[int], - rand_size: Sequence[int], - pad: int = 0, - mode: Union[InterpolateModeType, Sequence[InterpolateModeType]] = InterpolateMode.AREA, + spatial_size: Union[Sequence[int], int], + rand_size: Union[Sequence[int], int], + padder: Optional[Transform] = None, + mode: Union[InterpolateMode, str] = InterpolateMode.AREA, align_corners: Optional[bool] = None, prob: float = 0.1, gamma: Union[Sequence[float], float] = (0.5, 4.5), - device: Optional[torch.device] = None, + apply_same_field: bool = True, ): RandomizableTransform.__init__(self, prob) MapTransform.__init__(self, keys) - self.mode = ensure_tuple_rep(mode, len(self.keys)) - self.trans = RandSmoothFieldAdjustContrast( spatial_size=spatial_size, rand_size=rand_size, - pad=pad, - mode=self.mode[0], + padder=padder, + mode=mode, align_corners=align_corners, prob=1.0, gamma=gamma, - device=device, ) + self.apply_same_field = apply_same_field def set_random_state( self, seed: Optional[int] = None, state: Optional[np.random.RandomState] = None @@ -96,7 +81,7 @@ def randomize(self, data: Optional[Any] = None) -> None: if self._do_transform: self.trans.randomize() - def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Mapping[Hashable, NdarrayOrTensor]: + def __call__(self, data: Mapping[Hashable, np.ndarray]) -> Mapping[Hashable, np.ndarray]: self.randomize() if not self._do_transform: @@ -104,8 +89,10 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Mapping[Hashable d = dict(data) - for idx, key in enumerate(self.key_iterator(d)): - self.trans.set_mode(self.mode[idx % len(self.mode)]) + for key in self.key_iterator(d): + if not self.apply_same_field: + self.randomize() # new field for every key + d[key] = self.trans(d[key], False) return d @@ -113,22 +100,19 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Mapping[Hashable class RandSmoothFieldAdjustIntensityd(RandomizableTransform, MapTransform): """ - Dictionary version of RandSmoothFieldAdjustIntensity. - - The field is randomized once per invocation by default so the same field is applied to every selected key. The - `mode` parameter specifying interpolation mode for the field can be a single value or a sequence of values with - one for each key in `keys`. + Dictionary version of RandSmoothFieldAdjustIntensity. The field is randomized once per invocation by default so + the same field is applied to every selected key. Args: keys: key names to apply the augment to spatial_size: size of input arrays, all arrays stated in `keys` must have same dimensions rand_size: size of the randomized field to start from - pad: number of pixels/voxels along the edges of the field to pad with 0 + padder: optional transform to add padding to the randomized field mode: interpolation mode to use when upsampling align_corners: if True align the corners when upsampling field prob: probability transform is applied gamma: (min, max) range of intensity multipliers - device: Pytorch device to define field on + apply_same_field: if True, apply the same field to each key, otherwise randomize individually """ backend = [TransformBackends.TORCH, TransformBackends.NUMPY] @@ -136,30 +120,28 @@ class RandSmoothFieldAdjustIntensityd(RandomizableTransform, MapTransform): def __init__( self, keys: KeysCollection, - spatial_size: Sequence[int], - rand_size: Sequence[int], - pad: int = 0, - mode: Union[InterpolateModeType, Sequence[InterpolateModeType]] = InterpolateMode.AREA, + spatial_size: Union[Sequence[int], int], + rand_size: Union[Sequence[int], int], + padder: Optional[Transform] = None, + mode: Union[InterpolateMode, str] = InterpolateMode.AREA, align_corners: Optional[bool] = None, prob: float = 0.1, gamma: Union[Sequence[float], float] = (0.1, 1.0), - device: Optional[torch.device] = None, + apply_same_field: bool = True, ): RandomizableTransform.__init__(self, prob) MapTransform.__init__(self, keys) - self.mode = ensure_tuple_rep(mode, len(self.keys)) - self.trans = RandSmoothFieldAdjustIntensity( spatial_size=spatial_size, rand_size=rand_size, - pad=pad, - mode=self.mode[0], + padder=padder, + mode=mode, align_corners=align_corners, prob=1.0, gamma=gamma, - device=device, ) + self.apply_same_field = apply_same_field def set_random_state( self, seed: Optional[int] = None, state: Optional[np.random.RandomState] = None @@ -172,96 +154,7 @@ def randomize(self, data: Optional[Any] = None) -> None: super().randomize(None) self.trans.randomize() - def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Mapping[Hashable, NdarrayOrTensor]: - self.randomize() - - if not self._do_transform: - return data - - d = dict(data) - - for idx, key in enumerate(self.key_iterator(d)): - self.trans.set_mode(self.mode[idx % len(self.mode)]) - d[key] = self.trans(d[key], False) - - return d - - -class RandSmoothDeformd(RandomizableTransform, MapTransform): - """ - Dictionary version of RandSmoothDeform. - - The field is randomized once per invocation by default so the same field is applied to every selected key. The - `field_mode` parameter specifying interpolation mode for the field can be a single value or a sequence of values - with one for each key in `keys`. Similarly the `grid_mode` parameter can be one value or one per key. - - Args: - keys: key names to apply the augment to - spatial_size: input array size to which deformation grid is interpolated - rand_size: size of the randomized field to start from - pad: number of pixels/voxels along the edges of the field to pad with 0 - field_mode: interpolation mode to use when upsampling the deformation field - align_corners: if True align the corners when upsampling field - prob: probability transform is applied - def_range: value of the deformation range in image size fractions - grid_dtype: type for the deformation grid calculated from the field - grid_mode: interpolation mode used for sampling input using deformation grid - grid_padding_mode: padding mode used for sampling input using deformation grid - grid_align_corners: if True align the corners when sampling the deformation grid - device: Pytorch device to define field on - """ - - backend = [TransformBackends.TORCH, TransformBackends.NUMPY] - - def __init__( - self, - keys: KeysCollection, - spatial_size: Sequence[int], - rand_size: Sequence[int], - pad: int = 0, - field_mode: Union[InterpolateModeType, Sequence[InterpolateModeType]] = InterpolateMode.AREA, - align_corners: Optional[bool] = None, - prob: float = 0.1, - def_range: Union[Sequence[float], float] = 1.0, - grid_dtype=torch.float32, - grid_mode: Union[GridSampleModeType, Sequence[GridSampleModeType]] = GridSampleMode.NEAREST, - grid_padding_mode: Union[GridSamplePadMode, str] = GridSamplePadMode.BORDER, - grid_align_corners: Optional[bool] = False, - device: Optional[torch.device] = None, - ): - RandomizableTransform.__init__(self, prob) - MapTransform.__init__(self, keys) - - self.field_mode = ensure_tuple_rep(field_mode, len(self.keys)) - self.grid_mode = ensure_tuple_rep(grid_mode, len(self.keys)) - - self.trans = RandSmoothDeform( - rand_size=rand_size, - spatial_size=spatial_size, - pad=pad, - field_mode=self.field_mode[0], - align_corners=align_corners, - prob=1.0, - def_range=def_range, - grid_dtype=grid_dtype, - grid_mode=self.grid_mode[0], - grid_padding_mode=grid_padding_mode, - grid_align_corners=grid_align_corners, - device=device, - ) - - def set_random_state( - self, seed: Optional[int] = None, state: Optional[np.random.RandomState] = None - ) -> "RandSmoothDeformd": - super().set_random_state(seed, state) - self.trans.set_random_state(seed, state) - return self - - def randomize(self, data: Optional[Any] = None) -> None: - super().randomize(None) - self.trans.randomize() - - def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Mapping[Hashable, NdarrayOrTensor]: + def __call__(self, data: Mapping[Hashable, np.ndarray]) -> Mapping[Hashable, np.ndarray]: self.randomize() if not self._do_transform: @@ -269,10 +162,10 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Mapping[Hashable d = dict(data) - for idx, key in enumerate(self.key_iterator(d)): - self.trans.set_field_mode(self.field_mode[idx % len(self.field_mode)]) - self.trans.set_grid_mode(self.grid_mode[idx % len(self.grid_mode)]) + for key in self.key_iterator(d): + if not self.apply_same_field: + self.randomize() # new field for every key - d[key] = self.trans(d[key], False, self.trans.device) + d[key] = self.trans(d[key], False) return d diff --git a/monai/transforms/spatial/__init__.py b/monai/transforms/spatial/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/transforms/spatial/__init__.py +++ b/monai/transforms/spatial/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index 4e5cac2c85..8d1558c230 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -13,7 +13,7 @@ https://github.com/Project-MONAI/MONAI/wiki/MONAI_Design """ import warnings -from typing import Any, Callable, List, Optional, Sequence, Tuple, Union +from typing import Any, List, Optional, Sequence, Tuple, Union import numpy as np import torch @@ -33,6 +33,7 @@ create_translate, map_spatial_axes, ) +from monai.transforms.utils_pytorch_numpy_unification import concatenate from monai.utils import ( GridSampleMode, GridSamplePadMode, @@ -76,6 +77,7 @@ "RandAffine", "Rand2DElastic", "Rand3DElastic", + "AddCoordinateChannels", ] RandRange = Optional[Union[Sequence[Union[Tuple[float, float], float]], float]] @@ -700,7 +702,7 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: Args: img: channel first array, must have shape: (num_channels, H[, W, ..., ]), """ - rot90: Callable = torch.rot90 if isinstance(img, torch.Tensor) else np.rot90 # type: ignore + rot90 = torch.rot90 if isinstance(img, torch.Tensor) else np.rot90 out: NdarrayOrTensor = rot90(img, self.k, map_spatial_axes(img.ndim, self.spatial_axes)) out, *_ = convert_data_type(out, dtype=img.dtype) return out @@ -1373,15 +1375,14 @@ def __call__( raise ValueError("Unknown grid.") _device = img.device if isinstance(img, torch.Tensor) else self.device img_t: torch.Tensor - grid_t: torch.Tensor img_t, *_ = convert_data_type(img, torch.Tensor, device=_device, dtype=torch.float32) # type: ignore - grid_t, *_ = convert_to_dst_type(grid, img_t) # type: ignore + grid, *_ = convert_to_dst_type(grid, img_t) if USE_COMPILED: for i, dim in enumerate(img_t.shape[1:]): - grid_t[i] += (dim - 1.0) / 2.0 - grid_t = grid_t[:-1] / grid_t[-1:] - grid_t = grid_t.permute(list(range(grid_t.ndimension()))[1:] + [0]) + grid[i] += (dim - 1.0) / 2.0 + grid = grid[:-1] / grid[-1:] + grid = grid.permute(list(range(grid.ndimension()))[1:] + [0]) _padding_mode = look_up_option( self.padding_mode if padding_mode is None else padding_mode, GridSamplePadMode ).value @@ -1394,21 +1395,21 @@ def __call__( _interp_mode = look_up_option(self.mode if mode is None else mode, GridSampleMode).value out = grid_pull( img_t.unsqueeze(0), - grid_t.unsqueeze(0), + grid.unsqueeze(0), bound=bound, extrapolate=True, interpolation=1 if _interp_mode == "bilinear" else _interp_mode, )[0] else: for i, dim in enumerate(img_t.shape[1:]): - grid_t[i] = 2.0 * grid_t[i] / (dim - 1.0) - grid_t = grid_t[:-1] / grid_t[-1:] + grid[i] = 2.0 * grid[i] / (dim - 1.0) + grid = grid[:-1] / grid[-1:] index_ordering: List[int] = list(range(img_t.ndimension() - 2, -1, -1)) - grid_t = grid_t[index_ordering] - grid_t = grid_t.permute(list(range(grid_t.ndimension()))[1:] + [0]) + grid = grid[index_ordering] + grid = grid.permute(list(range(grid.ndimension()))[1:] + [0]) out = torch.nn.functional.grid_sample( img_t.unsqueeze(0), - grid_t.unsqueeze(0), + grid.unsqueeze(0), mode=self.mode.value if mode is None else GridSampleMode(mode).value, padding_mode=self.padding_mode.value if padding_mode is None else GridSamplePadMode(padding_mode).value, align_corners=True, @@ -2023,6 +2024,49 @@ def __call__( return out +class AddCoordinateChannels(Transform): + """ + Appends additional channels encoding coordinates of the input. Useful when e.g. training using patch-based sampling, + to allow feeding of the patch's location into the network. + + This can be seen as a input-only version of CoordConv: + + Liu, R. et al. An Intriguing Failing of Convolutional Neural Networks and the CoordConv Solution, NeurIPS 2018. + """ + + backend = [TransformBackends.TORCH, TransformBackends.NUMPY] + + def __init__(self, spatial_channels: Sequence[int]) -> None: + """ + Args: + spatial_channels: the spatial dimensions that are to have their coordinates encoded in a channel and + appended to the input. E.g., `(1,2,3)` will append three channels to the input, encoding the + coordinates of the input's three spatial dimensions (0 is reserved for the channel dimension). + """ + self.spatial_channels = spatial_channels + + def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: + """ + Args: + img: data to be transformed, assuming `img` is channel first. + """ + if max(self.spatial_channels) > img.ndim - 1: + raise ValueError( + f"input has {img.ndim-1} spatial dimensions, cannot add AddCoordinateChannels channel for " + f"dim {max(self.spatial_channels)}." + ) + if 0 in self.spatial_channels: + raise ValueError("cannot add AddCoordinateChannels channel for dimension 0, as 0 is channel dim.") + + spatial_dims = img.shape[1:] + coord_channels = np.array(np.meshgrid(*tuple(np.linspace(-0.5, 0.5, s) for s in spatial_dims), indexing="ij")) + coord_channels, *_ = convert_to_dst_type(coord_channels, img) # type: ignore + # only keep required dimensions. need to subtract 1 since im will be 0-based + # but user input is 1-based (because channel dim is 0) + coord_channels = coord_channels[[s - 1 for s in self.spatial_channels]] + return concatenate((img, coord_channels), axis=0) + + class GridDistortion(Transform): backend = [TransformBackends.TORCH] diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index d1cf70f92c..e4fc4cf3a9 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -29,6 +29,7 @@ from monai.transforms.croppad.array import CenterSpatialCrop, SpatialPad from monai.transforms.inverse import InvertibleTransform from monai.transforms.spatial.array import ( + AddCoordinateChannels, Affine, AffineGrid, Flip, @@ -122,6 +123,9 @@ "ZoomDict", "RandZoomD", "RandZoomDict", + "AddCoordinateChannelsd", + "AddCoordinateChannelsD", + "AddCoordinateChannelsDict", ] GridSampleModeSequence = Union[Sequence[Union[GridSampleMode, str]], GridSampleMode, str] @@ -1752,6 +1756,34 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd return d +class AddCoordinateChannelsd(MapTransform): + """ + Dictionary-based wrapper of :py:class:`monai.transforms.AddCoordinateChannels`. + """ + + backend = AddCoordinateChannels.backend + + def __init__(self, keys: KeysCollection, spatial_channels: Sequence[int], allow_missing_keys: bool = False) -> None: + """ + Args: + keys: keys of the corresponding items to be transformed. + See also: :py:class:`monai.transforms.compose.MapTransform` + allow_missing_keys: don't raise exception if key is missing. + spatial_channels: the spatial dimensions that are to have their coordinates encoded in a channel and + appended to the input. E.g., `(1,2,3)` will append three channels to the input, encoding the + coordinates of the input's three spatial dimensions. It is assumed dimension 0 is the channel. + + """ + super().__init__(keys, allow_missing_keys) + self.add_coordinate_channels = AddCoordinateChannels(spatial_channels) + + def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]: + d = dict(data) + for key in self.key_iterator(d): + d[key] = self.add_coordinate_channels(d[key]) + return d + + class GridDistortiond(MapTransform): """ Dictionary-based wrapper of :py:class:`monai.transforms.GridDistortion`. @@ -1887,3 +1919,4 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N RandRotateD = RandRotateDict = RandRotated ZoomD = ZoomDict = Zoomd RandZoomD = RandZoomDict = RandZoomd +AddCoordinateChannelsD = AddCoordinateChannelsDict = AddCoordinateChannelsd diff --git a/monai/transforms/transform.py b/monai/transforms/transform.py index 430e659c95..3b62fc0a31 100644 --- a/monai/transforms/transform.py +++ b/monai/transforms/transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/utility/__init__.py b/monai/transforms/utility/__init__.py index 1e97f89407..14ae193634 100644 --- a/monai/transforms/utility/__init__.py +++ b/monai/transforms/utility/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/transforms/utility/array.py b/monai/transforms/utility/array.py index a107cf1cb1..84fdc0a78d 100644 --- a/monai/transforms/utility/array.py +++ b/monai/transforms/utility/array.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -37,7 +37,6 @@ convert_to_cupy, convert_to_numpy, convert_to_tensor, - deprecated_arg, ensure_tuple, look_up_option, min_version, @@ -57,7 +56,6 @@ "AsChannelFirst", "AsChannelLast", "AddChannel", - "AddCoordinateChannels", "EnsureChannelFirst", "EnsureType", "RepeatChannel", @@ -448,8 +446,6 @@ class ToCupy(Transform): Args: dtype: data type specifier. It is inferred from the input by default. - if not None, must be an argument of `numpy.dtype`, for more details: - https://docs.cupy.dev/en/stable/reference/generated/cupy.array.html. wrap_sequence: if `False`, then lists will recursively call this function, default to `True`. E.g., if `False`, `[1, 2]` -> `[array(1), array(2)]`, if `True`, then `[1, 2]` -> `array([1, 2])`. @@ -457,7 +453,7 @@ class ToCupy(Transform): backend = [TransformBackends.TORCH, TransformBackends.NUMPY] - def __init__(self, dtype: Optional[np.dtype] = None, wrap_sequence: bool = True) -> None: + def __init__(self, dtype=None, wrap_sequence: bool = True) -> None: super().__init__() self.dtype = dtype self.wrap_sequence = wrap_sequence @@ -570,7 +566,7 @@ def __init__( a typical example is to print some properties of Nifti image: affine, pixdim, etc. additional_info: user can define callable function to extract additional info from input data. logger_handler: add additional handler to output data: save to file, etc. - all the existing python logging handlers: https://docs.python.org/3/library/logging.handlers.html. + add existing python logging handlers: https://docs.python.org/3/library/logging.handlers.html the handler should have a logging level of at least `INFO`. Raises: @@ -789,7 +785,7 @@ def __call__( if img.shape[0] > 1: data = img[[*select_labels]] else: - where: Callable = np.where if isinstance(img, np.ndarray) else torch.where # type: ignore + where = np.where if isinstance(img, np.ndarray) else torch.where if isinstance(img, np.ndarray) or is_module_ver_at_least(torch, (1, 8, 0)): data = where(in1d(img, select_labels), True, False).reshape(img.shape) # pre pytorch 1.8.0, need to use 1/0 instead of True/False @@ -1010,7 +1006,6 @@ def __init__(self, name: str, *args, **kwargs) -> None: """ super().__init__() - self.name = name transform, _ = optional_import("torchvision.transforms", "0.8.0", min_version, name=name) self.trans = transform(*args, **kwargs) @@ -1199,7 +1194,6 @@ class CuCIM(Transform): def __init__(self, name: str, *args, **kwargs) -> None: super().__init__() - self.name = name self.transform, _ = optional_import("cucim.core.operations.expose.transform", name=name) self.args = args self.kwargs = kwargs @@ -1256,45 +1250,3 @@ def __call__(self, data): if not self._do_transform: return data return super().__call__(data) - - -class AddCoordinateChannels(Transform): - """ - Appends additional channels encoding coordinates of the input. Useful when e.g. training using patch-based sampling, - to allow feeding of the patch's location into the network. - - This can be seen as a input-only version of CoordConv: - - Liu, R. et al. An Intriguing Failing of Convolutional Neural Networks and the CoordConv Solution, NeurIPS 2018. - - Args: - spatial_dims: the spatial dimensions that are to have their coordinates encoded in a channel and - appended to the input image. E.g., `(0, 1, 2)` represents `H, W, D` dims and append three channels - to the input image, encoding the coordinates of the input's three spatial dimensions. - - .. deprecated:: 0.8.0 - ``spatial_channels`` is deprecated, use ``spatial_dims`` instead. - - """ - - backend = [TransformBackends.TORCH, TransformBackends.NUMPY] - - @deprecated_arg( - name="spatial_channels", new_name="spatial_dims", since="0.8", msg_suffix="please use `spatial_dims` instead." - ) - def __init__(self, spatial_dims: Sequence[int]) -> None: - self.spatial_dims = spatial_dims - - def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: - """ - Args: - img: data to be transformed, assuming `img` is channel first. - """ - if max(self.spatial_dims) > img.ndim - 2 or min(self.spatial_dims) < 0: - raise ValueError(f"`spatial_dims` values must be within [0, {img.ndim - 2}]") - - spatial_size = img.shape[1:] - coord_channels = np.array(np.meshgrid(*tuple(np.linspace(-0.5, 0.5, s) for s in spatial_size), indexing="ij")) - coord_channels, *_ = convert_to_dst_type(coord_channels, img) # type: ignore - coord_channels = coord_channels[list(self.spatial_dims)] - return concatenate((img, coord_channels), axis=0) diff --git a/monai/transforms/utility/dictionary.py b/monai/transforms/utility/dictionary.py index b611d2ed30..082be8dea8 100644 --- a/monai/transforms/utility/dictionary.py +++ b/monai/transforms/utility/dictionary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -30,7 +30,6 @@ from monai.transforms.transform import MapTransform, Randomizable, RandomizableTransform from monai.transforms.utility.array import ( AddChannel, - AddCoordinateChannels, AddExtremePointsChannel, AsChannelFirst, AsChannelLast, @@ -62,7 +61,7 @@ ) from monai.transforms.utils import extreme_points_to_image, get_extreme_points from monai.transforms.utils_pytorch_numpy_unification import concatenate -from monai.utils import convert_to_numpy, deprecated_arg, ensure_tuple, ensure_tuple_rep +from monai.utils import convert_to_numpy, ensure_tuple, ensure_tuple_rep from monai.utils.enums import TraceKeys, TransformBackends from monai.utils.type_conversion import convert_to_dst_type @@ -70,9 +69,6 @@ "AddChannelD", "AddChannelDict", "AddChanneld", - "AddCoordinateChannelsD", - "AddCoordinateChannelsDict", - "AddCoordinateChannelsd", "AddExtremePointsChannelD", "AddExtremePointsChannelDict", "AddExtremePointsChanneld", @@ -596,8 +592,6 @@ class ToCupyd(MapTransform): keys: keys of the corresponding items to be transformed. See also: :py:class:`monai.transforms.compose.MapTransform` dtype: data type specifier. It is inferred from the input by default. - if not None, must be an argument of `numpy.dtype`, for more details: - https://docs.cupy.dev/en/stable/reference/generated/cupy.array.html. wrap_sequence: if `False`, then lists will recursively call this function, default to `True`. E.g., if `False`, `[1, 2]` -> `[array(1), array(2)]`, if `True`, then `[1, 2]` -> `array([1, 2])`. allow_missing_keys: don't raise exception if key is missing. @@ -606,11 +600,7 @@ class ToCupyd(MapTransform): backend = ToCupy.backend def __init__( - self, - keys: KeysCollection, - dtype: Optional[np.dtype] = None, - wrap_sequence: bool = True, - allow_missing_keys: bool = False, + self, keys: KeysCollection, dtype=None, wrap_sequence: bool = True, allow_missing_keys: bool = False ) -> None: super().__init__(keys, allow_missing_keys) self.converter = ToCupy(dtype=dtype, wrap_sequence=wrap_sequence) @@ -795,7 +785,7 @@ def __init__( additional info from input data. it also can be a sequence of string, each element corresponds to a key in ``keys``. logger_handler: add additional handler to output data: save to file, etc. - all the existing python logging handlers: https://docs.python.org/3/library/logging.handlers.html. + add existing python logging handlers: https://docs.python.org/3/library/logging.handlers.html the handler should have a logging level of at least `INFO`. allow_missing_keys: don't raise exception if key is missing. @@ -1329,7 +1319,6 @@ def __init__(self, keys: KeysCollection, name: str, allow_missing_keys: bool = F """ super().__init__(keys, allow_missing_keys) - self.name = name self.trans = TorchVision(name, *args, **kwargs) def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]: @@ -1369,7 +1358,6 @@ def __init__(self, keys: KeysCollection, name: str, allow_missing_keys: bool = F """ MapTransform.__init__(self, keys, allow_missing_keys) - self.name = name self.trans = TorchVision(name, *args, **kwargs) def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]: @@ -1531,7 +1519,6 @@ class CuCIMd(MapTransform): def __init__(self, keys: KeysCollection, name: str, allow_missing_keys: bool = False, *args, **kwargs) -> None: super().__init__(keys=keys, allow_missing_keys=allow_missing_keys) - self.name = name self.trans = CuCIM(name, *args, **kwargs) def __call__(self, data): @@ -1593,39 +1580,6 @@ def __call__(self, data): return super().__call__(data) -class AddCoordinateChannelsd(MapTransform): - """ - Dictionary-based wrapper of :py:class:`monai.transforms.AddCoordinateChannels`. - - Args: - keys: keys of the corresponding items to be transformed. - See also: :py:class:`monai.transforms.compose.MapTransform` - spatial_dims: the spatial dimensions that are to have their coordinates encoded in a channel and - appended to the input image. E.g., `(0, 1, 2)` represents `H, W, D` dims and append three channels - to the input image, encoding the coordinates of the input's three spatial dimensions. - allow_missing_keys: don't raise exception if key is missing. - - .. deprecated:: 0.8.0 - ``spatial_channels`` is deprecated, use ``spatial_dims`` instead. - - """ - - backend = AddCoordinateChannels.backend - - @deprecated_arg( - name="spatial_channels", new_name="spatial_dims", since="0.8", msg_suffix="please use `spatial_dims` instead." - ) - def __init__(self, keys: KeysCollection, spatial_dims: Sequence[int], allow_missing_keys: bool = False) -> None: - super().__init__(keys, allow_missing_keys) - self.add_coordinate_channels = AddCoordinateChannels(spatial_dims=spatial_dims) - - def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]: - d = dict(data) - for key in self.key_iterator(d): - d[key] = self.add_coordinate_channels(d[key]) - return d - - IdentityD = IdentityDict = Identityd AsChannelFirstD = AsChannelFirstDict = AsChannelFirstd AsChannelLastD = AsChannelLastDict = AsChannelLastd @@ -1664,4 +1618,3 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N ToDeviceD = ToDeviceDict = ToDeviced CuCIMD = CuCIMDict = CuCIMd RandCuCIMD = RandCuCIMDict = RandCuCIMd -AddCoordinateChannelsD = AddCoordinateChannelsDict = AddCoordinateChannelsd diff --git a/monai/transforms/utils.py b/monai/transforms/utils.py index 739d98e5c0..b0553ff8c7 100644 --- a/monai/transforms/utils.py +++ b/monai/transforms/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -873,7 +873,7 @@ def generate_spatial_bounding_box( margin: Union[Sequence[int], int] = 0, ) -> Tuple[List[int], List[int]]: """ - generate the spatial bounding box of foreground in the image with start-end positions (inclusive). + generate the spatial bounding box of foreground in the image with start-end positions. Users can define arbitrary function to select expected foreground from the whole image or specified channels. And it can also add margin to every dim of the bounding box. The output format of the coordinates is: @@ -1306,7 +1306,7 @@ def shift_fourier(x: NdarrayOrTensor, spatial_dims: int, n_dims: Optional[int] = dims = tuple(range(-spatial_dims, 0)) k: NdarrayOrTensor if isinstance(x, torch.Tensor): - if hasattr(torch.fft, "fftshift"): # `fftshift` is new in torch 1.8.0 + if hasattr(torch.fft, "fftshift"): k = torch.fft.fftshift(torch.fft.fftn(x, dim=dims), dim=dims) else: # if using old PyTorch, will convert to numpy array and return @@ -1339,7 +1339,7 @@ def inv_shift_fourier(k: NdarrayOrTensor, spatial_dims: int, n_dims: Optional[in dims = tuple(range(-spatial_dims, 0)) out: NdarrayOrTensor if isinstance(k, torch.Tensor): - if hasattr(torch.fft, "ifftshift"): # `ifftshift` is new in torch 1.8.0 + if hasattr(torch.fft, "ifftshift"): out = torch.fft.ifftn(torch.fft.ifftshift(k, dim=dims), dim=dims, norm="backward").real else: # if using old PyTorch, will convert to numpy array and return diff --git a/monai/transforms/utils_create_transform_ims.py b/monai/transforms/utils_create_transform_ims.py index ab282d5332..59d359639b 100644 --- a/monai/transforms/utils_create_transform_ims.py +++ b/monai/transforms/utils_create_transform_ims.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -102,11 +102,9 @@ RandGibbsNoise, RandHistogramShift, RandKSpaceSpikeNoise, - RandRicianNoise, RandScaleIntensity, RandShiftIntensity, RandStdShiftIntensity, - SavitzkyGolaySmooth, ScaleIntensityRange, ScaleIntensityRangePercentiles, ShiftIntensity, @@ -132,11 +130,9 @@ RandGibbsNoised, RandHistogramShiftd, RandKSpaceSpikeNoised, - RandRicianNoised, RandScaleIntensityd, RandShiftIntensityd, RandStdShiftIntensityd, - SavitzkyGolaySmoothd, ScaleIntensityRanged, ScaleIntensityRangePercentilesd, ShiftIntensityd, @@ -145,18 +141,7 @@ ) from monai.transforms.post.array import KeepLargestConnectedComponent, LabelFilter, LabelToContour from monai.transforms.post.dictionary import AsDiscreted, KeepLargestConnectedComponentd, LabelFilterd, LabelToContourd -from monai.transforms.smooth_field.array import ( - RandSmoothDeform, - RandSmoothFieldAdjustContrast, - RandSmoothFieldAdjustIntensity, -) -from monai.transforms.smooth_field.dictionary import ( - RandSmoothDeformd, - RandSmoothFieldAdjustContrastd, - RandSmoothFieldAdjustIntensityd, -) from monai.transforms.spatial.array import ( - GridDistortion, Rand2DElastic, RandAffine, RandAxisFlip, @@ -166,7 +151,6 @@ Spacing, ) from monai.transforms.spatial.dictionary import ( - GridDistortiond, Rand2DElasticd, RandAffined, RandAxisFlipd, @@ -536,10 +520,6 @@ def create_transform_im( dict(keys=CommonKeys.IMAGE, global_prob=1, prob=1, common_sampling=True, intensity_range=(13, 15)), data, ) - create_transform_im(RandRicianNoise, dict(prob=1.0, mean=1, std=0.5), data) - create_transform_im(RandRicianNoised, dict(keys=CommonKeys.IMAGE, prob=1.0, mean=1, std=0.5), data) - create_transform_im(SavitzkyGolaySmooth, dict(window_length=5, order=1), data) - create_transform_im(SavitzkyGolaySmoothd, dict(keys=CommonKeys.IMAGE, window_length=5, order=1), data) create_transform_im(GibbsNoise, dict(alpha=0.8), data) create_transform_im(GibbsNoised, dict(keys=CommonKeys.IMAGE, alpha=0.8), data) create_transform_im(RandGibbsNoise, dict(prob=1.0, alpha=(0.6, 0.8)), data) @@ -660,8 +640,8 @@ def create_transform_im( create_transform_im(RandScaleCropd, dict(keys=keys, roi_scale=0.4), data) create_transform_im(CenterScaleCrop, dict(roi_scale=0.4), data) create_transform_im(CenterScaleCropd, dict(keys=keys, roi_scale=0.4), data) - create_transform_im(AsDiscrete, dict(to_onehot=None, threshold=10), data, is_post=True, colorbar=True) - create_transform_im(AsDiscreted, dict(keys=CommonKeys.LABEL, to_onehot=None, threshold=10), data, is_post=True) + create_transform_im(AsDiscrete, dict(to_onehot=2, threshold=10), data, is_post=True, colorbar=True) + create_transform_im(AsDiscreted, dict(keys=CommonKeys.LABEL, to_onehot=2, threshold=10), data, is_post=True) create_transform_im(LabelFilter, dict(applied_labels=(1, 2, 3, 4, 5, 6)), data, is_post=True) create_transform_im( LabelFilterd, dict(keys=CommonKeys.LABEL, applied_labels=(1, 2, 3, 4, 5, 6)), data, is_post=True @@ -680,55 +660,9 @@ def create_transform_im( create_transform_im( KeepLargestConnectedComponentd, dict(keys=CommonKeys.LABEL, applied_labels=1), data_binary, is_post=True, ndim=2 ) - create_transform_im( - GridDistortion, dict(num_cells=3, distort_steps=[(1.5,) * 4] * 3, mode="nearest", padding_mode="zeros"), data - ) - create_transform_im( - GridDistortiond, - dict( - keys=keys, num_cells=3, distort_steps=[(1.5,) * 4] * 3, mode=["bilinear", "nearest"], padding_mode="zeros" - ), - data, - ) create_transform_im(RandGridDistortion, dict(num_cells=3, prob=1.0, distort_limit=(-0.1, 0.1)), data) create_transform_im( RandGridDistortiond, dict(keys=keys, num_cells=4, prob=1.0, distort_limit=(-0.2, 0.2), mode=["bilinear", "nearest"]), data, ) - create_transform_im( - RandSmoothFieldAdjustContrast, dict(spatial_size=(217, 217, 217), rand_size=(10, 10, 10), prob=1.0), data - ) - create_transform_im( - RandSmoothFieldAdjustContrastd, - dict(keys=keys, spatial_size=(217, 217, 217), rand_size=(10, 10, 10), prob=1.0), - data, - ) - create_transform_im( - RandSmoothFieldAdjustIntensity, - dict(spatial_size=(217, 217, 217), rand_size=(10, 10, 10), prob=1.0, gamma=(0.5, 4.5)), - data, - ) - create_transform_im( - RandSmoothFieldAdjustIntensityd, - dict(keys=keys, spatial_size=(217, 217, 217), rand_size=(10, 10, 10), prob=1.0, gamma=(0.5, 4.5)), - data, - ) - - create_transform_im( - RandSmoothDeform, - dict(spatial_size=(217, 217, 217), rand_size=(10, 10, 10), prob=1.0, def_range=0.05, grid_mode="blinear"), - data, - ) - create_transform_im( - RandSmoothDeformd, - dict( - keys=keys, - spatial_size=(217, 217, 217), - rand_size=(10, 10, 10), - prob=1.0, - def_range=0.05, - grid_mode="blinear", - ), - data, - ) diff --git a/monai/transforms/utils_pytorch_numpy_unification.py b/monai/transforms/utils_pytorch_numpy_unification.py index 25d59ac89a..9754981560 100644 --- a/monai/transforms/utils_pytorch_numpy_unification.py +++ b/monai/transforms/utils_pytorch_numpy_unification.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -42,7 +42,7 @@ def moveaxis(x: NdarrayOrTensor, src: int, dst: int) -> NdarrayOrTensor: """`moveaxis` for pytorch and numpy, using `permute` for pytorch ver < 1.8""" if isinstance(x, torch.Tensor): - if hasattr(torch, "moveaxis"): # `moveaxis` is new in torch 1.8.0 + if hasattr(torch, "moveaxis"): return torch.moveaxis(x, src, dst) return _moveaxis_with_permute(x, src, dst) # type: ignore if isinstance(x, np.ndarray): @@ -81,37 +81,32 @@ def clip(a: NdarrayOrTensor, a_min, a_max) -> NdarrayOrTensor: return result -def percentile(x: NdarrayOrTensor, q, dim: Optional[int] = None) -> Union[NdarrayOrTensor, float, int]: +def percentile(x: NdarrayOrTensor, q) -> Union[NdarrayOrTensor, float, int]: """`np.percentile` with equivalent implementation for torch. Pytorch uses `quantile`, but this functionality is only available from v1.7. For earlier methods, we calculate it ourselves. This doesn't do interpolation, so is the equivalent of ``numpy.percentile(..., interpolation="nearest")``. - For more details, please refer to: - https://pytorch.org/docs/stable/generated/torch.quantile.html. - https://numpy.org/doc/stable/reference/generated/numpy.percentile.html. Args: x: input data q: percentile to compute (should in range 0 <= q <= 100) - dim: the dim along which the percentiles are computed. default is to compute the percentile - along a flattened version of the array. only work for numpy array or Tensor with PyTorch >= 1.7.0. Returns: Resulting value (scalar) """ if np.isscalar(q): - if not 0 <= q <= 100: # type: ignore + if not 0 <= q <= 100: raise ValueError elif any(q < 0) or any(q > 100): raise ValueError result: Union[NdarrayOrTensor, float, int] if isinstance(x, np.ndarray): - result = np.percentile(x, q, axis=dim) + result = np.percentile(x, q) else: q = torch.tensor(q, device=x.device) - if hasattr(torch, "quantile"): # `quantile` is new in torch 1.7.0 - result = torch.quantile(x, q / 100.0, dim=dim) + if hasattr(torch, "quantile"): + result = torch.quantile(x, q / 100.0) else: # Note that ``kthvalue()`` works one-based, i.e., the first sorted value # corresponds to k=1, not k=0. Thus, we need the `1 +`. @@ -134,7 +129,7 @@ def where(condition: NdarrayOrTensor, x=None, y=None) -> NdarrayOrTensor: if x is not None: result = np.where(condition, x, y) else: - result = np.where(condition) # type: ignore + result = np.where(condition) else: if x is not None: x = torch.as_tensor(x, device=condition.device) @@ -222,7 +217,7 @@ def ravel(x: NdarrayOrTensor): Return a contiguous flattened array/tensor. """ if isinstance(x, torch.Tensor): - if hasattr(torch, "ravel"): # `ravel` is new in torch 1.8.0 + if hasattr(torch, "ravel"): return x.ravel() return x.flatten().contiguous() return np.ravel(x) @@ -268,7 +263,7 @@ def maximum(a: NdarrayOrTensor, b: NdarrayOrTensor) -> NdarrayOrTensor: """ if isinstance(a, torch.Tensor) and isinstance(b, torch.Tensor): # is torch and has torch.maximum (pt>1.6) - if hasattr(torch, "maximum"): # `maximum` is new in torch 1.7.0 + if hasattr(torch, "maximum"): return torch.maximum(a, b) return torch.stack((a, b)).max(dim=0)[0] return np.maximum(a, b) diff --git a/monai/utils/__init__.py b/monai/utils/__init__.py index 0c04680234..d58fcca32d 100644 --- a/monai/utils/__init__.py +++ b/monai/utils/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -24,7 +24,6 @@ GridSamplePadMode, InterpolateMode, InverseKeys, - JITMetadataKeys, LossReduction, Method, MetricReduction, diff --git a/monai/utils/aliases.py b/monai/utils/aliases.py index 0ae79e26ff..a08dab4f95 100644 --- a/monai/utils/aliases.py +++ b/monai/utils/aliases.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/utils/decorators.py b/monai/utils/decorators.py index 0856c0fc1a..1931d703c9 100644 --- a/monai/utils/decorators.py +++ b/monai/utils/decorators.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/utils/deprecate_utils.py b/monai/utils/deprecate_utils.py index a6092c1b63..4ae5991d9f 100644 --- a/monai/utils/deprecate_utils.py +++ b/monai/utils/deprecate_utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -10,7 +10,6 @@ # limitations under the License. import inspect -import sys import warnings from functools import wraps from types import FunctionType @@ -63,7 +62,7 @@ def deprecated( # if version_val.startswith("0+"): # # version unknown, set version_val to a large value (assuming the latest version) - # version_val = f"{sys.maxsize}" + # version_val = "100" if since is not None and removed is not None and not version_leq(since, removed): raise ValueError(f"since must be less or equal to removed, got since={since}, removed={removed}.") is_not_yet_deprecated = since is not None and version_val != since and version_leq(version_val, since) @@ -145,8 +144,6 @@ def deprecated_arg( msg_suffix: message appended to warning/exception detailing reasons for deprecation and what to use instead. version_val: (used for testing) version to compare since and removed against, default is MONAI version. new_name: name of position or keyword argument to replace the deprecated argument. - if it is specified and the signature of the decorated function has a `kwargs`, the value to the - deprecated argument `name` will be removed. Returns: Decorated callable which warns or raises exception when deprecated argument used. @@ -154,7 +151,7 @@ def deprecated_arg( if version_val.startswith("0+") or not f"{version_val}".strip()[0].isdigit(): # version unknown, set version_val to a large value (assuming the latest version) - version_val = f"{sys.maxsize}" + version_val = "100" if since is not None and removed is not None and not version_leq(since, removed): raise ValueError(f"since must be less or equal to removed, got since={since}, removed={removed}.") is_not_yet_deprecated = since is not None and version_val != since and version_leq(version_val, since) @@ -200,13 +197,9 @@ def _wrapper(*args, **kwargs): # multiple values for new_name using both args and kwargs kwargs.pop(new_name, None) binding = sig.bind(*args, **kwargs).arguments + positional_found = name in binding - kw_found = False - for k, param in sig.parameters.items(): - if param.kind == inspect.Parameter.VAR_KEYWORD and k in binding and name in binding[k]: - kw_found = True - # if the deprecated arg is found in the **kwargs, it should be removed - kwargs.pop(name, None) + kw_found = "kwargs" in binding and name in binding["kwargs"] if positional_found or kw_found: if is_removed: diff --git a/monai/utils/dist.py b/monai/utils/dist.py index 37536bfe83..beb958a5c8 100644 --- a/monai/utils/dist.py +++ b/monai/utils/dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/utils/enums.py b/monai/utils/enums.py index 08a59c598c..c059a4a5e2 100644 --- a/monai/utils/enums.py +++ b/monai/utils/enums.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -266,15 +266,3 @@ class TransformBackends(Enum): TORCH = "torch" NUMPY = "numpy" - - -class JITMetadataKeys(Enum): - """ - Keys stored in the metadata file for saved Torchscript models. Some of these are generated by the routines - and others are optionally provided by users. - """ - - NAME = "name" - TIMESTAMP = "timestamp" - VERSION = "version" - DESCRIPTION = "description" diff --git a/monai/utils/jupyter_utils.py b/monai/utils/jupyter_utils.py index 366d11ebd8..1f55f2fa61 100644 --- a/monai/utils/jupyter_utils.py +++ b/monai/utils/jupyter_utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/utils/misc.py b/monai/utils/misc.py index eae0580696..1cb5c90244 100644 --- a/monai/utils/misc.py +++ b/monai/utils/misc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -89,7 +89,7 @@ def ensure_tuple(vals: Any) -> Tuple[Any, ...]: Returns a tuple of `vals`. """ if not issequenceiterable(vals): - return (vals,) + vals = (vals,) return tuple(vals) @@ -98,8 +98,8 @@ def ensure_tuple_size(tup: Any, dim: int, pad_val: Any = 0) -> Tuple[Any, ...]: """ Returns a copy of `tup` with `dim` values by either shortened or padded with `pad_val` as necessary. """ - new_tup = ensure_tuple(tup) + (pad_val,) * dim - return new_tup[:dim] + tup = ensure_tuple(tup) + (pad_val,) * dim + return tuple(tup[:dim]) def ensure_tuple_rep(tup: Any, dim: int) -> Tuple[Any, ...]: @@ -251,10 +251,6 @@ def set_determinism( for func in additional_settings: func(seed) - if torch.backends.flags_frozen(): - warnings.warn("PyTorch global flag support of backends is disabled, enable it to set global `cudnn` flags.") - torch.backends.__allow_nonbracketed_mutation_flag = True - if seed is not None: torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False @@ -262,9 +258,9 @@ def set_determinism( torch.backends.cudnn.deterministic = _flag_deterministic torch.backends.cudnn.benchmark = _flag_cudnn_benchmark if use_deterministic_algorithms is not None: - if hasattr(torch, "use_deterministic_algorithms"): # `use_deterministic_algorithms` is new in torch 1.8.0 + if hasattr(torch, "use_deterministic_algorithms"): torch.use_deterministic_algorithms(use_deterministic_algorithms) - elif hasattr(torch, "set_deterministic"): # `set_deterministic` is new in torch 1.7.0 + elif hasattr(torch, "set_deterministic"): torch.set_deterministic(use_deterministic_algorithms) # type: ignore else: warnings.warn("use_deterministic_algorithms=True, but PyTorch version is too old to set the mode.") diff --git a/monai/utils/module.py b/monai/utils/module.py index c0fc10a7c0..e475ae1957 100644 --- a/monai/utils/module.py +++ b/monai/utils/module.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/utils/nvtx.py b/monai/utils/nvtx.py index 691f900c7d..0693d6fe5b 100644 --- a/monai/utils/nvtx.py +++ b/monai/utils/nvtx.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -62,15 +62,8 @@ def __call__(self, obj: Any): # Define the name to be associated to the range if not provided if self.name is None: name = type(obj).__name__ - # If CuCIM or TorchVision transform wrappers are being used, - # append the underlying transform to the name for more clarity - if "CuCIM" in name or "TorchVision" in name: - name = f"{name}_{obj.name}" self.name_counter[name] += 1 - if self.name_counter[name] > 1: - self.name = f"{name}_{self.name_counter[name]}" - else: - self.name = name + self.name = f"{name}_{self.name_counter[name]}" # Define the methods to be wrapped if not provided if self.methods is None: diff --git a/monai/utils/profiling.py b/monai/utils/profiling.py index 8e0742268f..d7459885fb 100644 --- a/monai/utils/profiling.py +++ b/monai/utils/profiling.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/utils/state_cacher.py b/monai/utils/state_cacher.py index 3e392ab979..2cf0271db2 100644 --- a/monai/utils/state_cacher.py +++ b/monai/utils/state_cacher.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/utils/type_conversion.py b/monai/utils/type_conversion.py index 8686557176..6a90d21a09 100644 --- a/monai/utils/type_conversion.py +++ b/monai/utils/type_conversion.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -59,7 +59,7 @@ def dtype_torch_to_numpy(dtype): def dtype_numpy_to_torch(dtype): """Convert a numpy dtype to its torch equivalent.""" # np dtypes can be given as np.float32 and np.dtype(np.float32) so unify them - dtype = np.dtype(dtype) if isinstance(dtype, (type, str)) else dtype + dtype = np.dtype(dtype) if isinstance(dtype, type) else dtype return look_up_option(dtype, _np_to_torch_dtype) @@ -151,8 +151,8 @@ def convert_to_numpy(data, dtype: DtypeLike = None, wrap_sequence: bool = False) will convert Tensor, Numpy array, float, int, bool to numpy arrays, strings and objects keep the original. for dictionary, list or tuple, convert every item to a numpy array if applicable. dtype: target data type when converting to numpy array. - wrap_sequence: if `False`, then lists will recursively call this function. - E.g., `[1, 2]` -> `[array(1), array(2)]`. If `True`, then `[1, 2]` -> `array([1, 2])`. + wrap_sequence: if `False`, then lists will recursively call this function. E.g., `[1, 2]` -> `[array(1), array(2)]`. + If `True`, then `[1, 2]` -> `array([1, 2])`. """ if isinstance(data, torch.Tensor): data = data.detach().to(dtype=get_equivalent_dtype(dtype, torch.Tensor), device="cpu").numpy() @@ -175,19 +175,19 @@ def convert_to_numpy(data, dtype: DtypeLike = None, wrap_sequence: bool = False) return data -def convert_to_cupy(data, dtype: Optional[np.dtype] = None, wrap_sequence: bool = False): +def convert_to_cupy(data, dtype, wrap_sequence: bool = False): """ Utility to convert the input data to a cupy array. If passing a dictionary, list or tuple, recursively check every item and convert it to cupy array. Args: data: input data can be PyTorch Tensor, numpy array, cupy array, list, dictionary, int, float, bool, str, etc. - Tensor, numpy array, cupy array, float, int, bool are converted to cupy arrays, + Tensor, numpy array, cupy array, float, int, bool are converted to cupy arrays + for dictionary, list or tuple, convert every item to a numpy array if applicable. - dtype: target data type when converting to Cupy array, tt must be an argument of `numpy.dtype`, - for more details: https://docs.cupy.dev/en/stable/reference/generated/cupy.array.html. - wrap_sequence: if `False`, then lists will recursively call this function. - E.g., `[1, 2]` -> `[array(1), array(2)]`. If `True`, then `[1, 2]` -> `array([1, 2])`. + dtype: target data type when converting to Cupy array. + wrap_sequence: if `False`, then lists will recursively call this function. E.g., `[1, 2]` -> `[array(1), array(2)]`. + If `True`, then `[1, 2]` -> `array([1, 2])`. """ # direct calls @@ -227,8 +227,8 @@ def convert_data_type( dtype: dtype of output data. Converted to correct library type (e.g., `np.float32` is converted to `torch.float32` if output type is `torch.Tensor`). If left blank, it remains unchanged. - wrap_sequence: if `False`, then lists will recursively call this function. - E.g., `[1, 2]` -> `[array(1), array(2)]`. If `True`, then `[1, 2]` -> `array([1, 2])`. + wrap_sequence: if `False`, then lists will recursively call this function. E.g., `[1, 2]` -> `[array(1), array(2)]`. + If `True`, then `[1, 2]` -> `array([1, 2])`. Returns: modified data, orig_type, orig_device diff --git a/monai/visualize/__init__.py b/monai/visualize/__init__.py index cd980846b3..1e3140d3a4 100644 --- a/monai/visualize/__init__.py +++ b/monai/visualize/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/visualize/class_activation_maps.py b/monai/visualize/class_activation_maps.py index b7e433d6fa..cddd0b1270 100644 --- a/monai/visualize/class_activation_maps.py +++ b/monai/visualize/class_activation_maps.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/visualize/img2tensorboard.py b/monai/visualize/img2tensorboard.py index 4d4e91c6fd..619c65f79d 100644 --- a/monai/visualize/img2tensorboard.py +++ b/monai/visualize/img2tensorboard.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/visualize/occlusion_sensitivity.py b/monai/visualize/occlusion_sensitivity.py index 184fa50e61..bc2ecc3787 100644 --- a/monai/visualize/occlusion_sensitivity.py +++ b/monai/visualize/occlusion_sensitivity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/visualize/utils.py b/monai/visualize/utils.py index 63cac7ea35..abdfd5c4b5 100644 --- a/monai/visualize/utils.py +++ b/monai/visualize/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/monai/visualize/visualizer.py b/monai/visualize/visualizer.py index 5f19e4f63f..bbb01f5c5e 100644 --- a/monai/visualize/visualizer.py +++ b/monai/visualize/visualizer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/pyproject.toml b/pyproject.toml index 03e9f49ab5..b53a7640b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ requires = [ [tool.black] line-length = 120 -target-version = ['py37', 'py38', 'py39'] +target-version = ['py36', 'py37', 'py38'] include = '\.pyi?$' exclude = ''' ( diff --git a/requirements-dev.txt b/requirements-dev.txt index fc752a7627..f47eb14bbd 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ # Full requirements for developments -r requirements-min.txt -pytorch-ignite==0.4.7 +pytorch-ignite==0.4.6 gdown>=3.6.4 scipy itk>=5.2 diff --git a/requirements-min.txt b/requirements-min.txt index 195f6f49f4..5db219c840 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -1,5 +1,5 @@ # Requirements for minimal tests -r requirements.txt -setuptools>=50.3.0,!=60.0.0 +setuptools>=50.3.0 coverage>=5.5 parameterized diff --git a/runtests.sh b/runtests.sh index 70ca8df5c2..a77f9decd5 100755 --- a/runtests.sh +++ b/runtests.sh @@ -1,6 +1,6 @@ #! /bin/bash -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -38,14 +38,12 @@ doNetTests=false doDryRun=false doZooTests=false doUnitTests=false -doBuild=false doBlackFormat=false doBlackFix=false doIsortFormat=false doIsortFix=false doFlake8Format=false doClangFormat=false -doCopyRight=false doPytypeFormat=false doMypyFormat=false doCleanup=false @@ -57,8 +55,7 @@ PY_EXE=${MONAI_PY_EXE:-$(which python)} function print_usage { echo "runtests.sh [--codeformat] [--autofix] [--black] [--isort] [--flake8] [--clangformat] [--pytype] [--mypy]" - echo " [--unittests] [--disttests] [--coverage] [--quick] [--min] [--net] [--dryrun] [-j number] [--list_tests]" - echo " [--copyright] [--build] [--clean] [--help] [--version]" + echo " [--unittests] [--disttests] [--coverage] [--quick] [--min] [--net] [--dryrun] [-j number] [--clean] [--help] [--version]" echo "" echo "MONAI unit testing utilities." echo "" @@ -89,12 +86,10 @@ function print_usage { echo " -q, --quick : skip long running unit tests and integration tests" echo " -m, --min : only run minimal unit tests which do not require optional packages" echo " --net : perform integration testing" - echo " -b, --build : compile and install the source code folder an editable release." echo " --list_tests : list unit tests and exit" echo "" echo "Misc. options:" echo " --dryrun : display the commands to the screen without running" - echo " --copyright : check whether every source code has a copyright header" echo " -f, --codeformat : shorthand to run all code style and static analysis tests" echo " -c, --clean : clean temporary files from tests and exit" echo " -h, --help : show this help message and exit" @@ -108,7 +103,7 @@ function print_usage { } function check_import { - echo "Python: ${PY_EXE}" + echo "python: ${PY_EXE}" ${cmdPrefix}${PY_EXE} -c "import monai" } @@ -243,7 +238,6 @@ do doFlake8Format=true doPytypeFormat=true doMypyFormat=true - doCopyRight=true ;; --disttests) doDistTests=true @@ -256,7 +250,6 @@ do doBlackFix=true doIsortFormat=true doBlackFormat=true - doCopyRight=true ;; --clangformat) doClangFormat=true @@ -277,12 +270,6 @@ do NUM_PARALLEL=$2 shift ;; - --copyright) - doCopyRight=true - ;; - -b|--build) - doBuild=true - ;; -c|--clean) doCleanup=true ;; @@ -327,14 +314,6 @@ else check_import fi -if [ $doBuild = true ] -then - echo "${separator}${blue}compile and install${noColor}" - # try to compile MONAI cpp - compile_cpp - - echo "${green}done! (to uninstall and clean up, please use \"./runtests.sh --clean\")${noColor}" -fi if [ $doCleanup = true ] then @@ -356,33 +335,12 @@ then exit fi +# try to compile MONAI cpp +compile_cpp + # unconditionally report on the state of monai print_version -if [ $doCopyRight = true ] -then - # check copyright headers - copyright_bad=0 - copyright_all=0 - while read -r fname; do - copyright_all=$((copyright_all + 1)) - if ! grep "http://www.apache.org/licenses/LICENSE-2.0" "$fname" > /dev/null; then - print_error_msg "Missing the license header in file: $fname" - copyright_bad=$((copyright_bad + 1)) - fi - done <<< "$(find "$(pwd)/monai" "$(pwd)/tests" -type f \ - ! -wholename "*_version.py" -and -name "*.py" -or -name "*.cpp" -or -name "*.cu" -or -name "*.h")" - if [[ ${copyright_bad} -eq 0 ]]; - then - echo "${green}Source code copyright headers checked ($copyright_all).${noColor}" - else - echo "Please add the licensing header to the file ($copyright_bad of $copyright_all files)." - echo " See also: https://github.com/Project-MONAI/MONAI/blob/dev/CONTRIBUTING.md#checking-the-coding-style" - echo "" - exit 1 - fi -fi - if [ $doIsortFormat = true ] then @@ -577,7 +535,7 @@ if [ $doUnitTests = true ] then echo "${separator}${blue}unittests${noColor}" torch_validate - ${cmdPrefix}${cmd} ./tests/runner.py -p "^(?!test_integration).*(?= 3.7 +python_requires = >= 3.6 # for compiling and develop setup only # no need to specify the versions so that we could # compile for multiple targeted versions. @@ -34,7 +34,7 @@ all = pillow tensorboard gdown>=3.6.4 - pytorch-ignite==0.4.7 + pytorch-ignite==0.4.6 torchvision itk>=5.2 tqdm>=4.47.0 @@ -61,7 +61,7 @@ tensorboard = gdown = gdown>=3.6.4 ignite = - pytorch-ignite==0.4.7 + pytorch-ignite==0.4.6 torchvision = torchvision itk = diff --git a/setup.py b/setup.py index 83a60129e6..95087ce06f 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/__init__.py b/tests/__init__.py index 4639a58496..5093d1f72d 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/clang_format_utils.py b/tests/clang_format_utils.py index 1b13ce0ac3..22f86c50b9 100644 --- a/tests/clang_format_utils.py +++ b/tests/clang_format_utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/hvd_evenly_divisible_all_gather.py b/tests/hvd_evenly_divisible_all_gather.py index f4c39e4e73..42b2e9530d 100644 --- a/tests/hvd_evenly_divisible_all_gather.py +++ b/tests/hvd_evenly_divisible_all_gather.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/min_tests.py b/tests/min_tests.py index 00f3e49850..f8e4743244 100644 --- a/tests/min_tests.py +++ b/tests/min_tests.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -101,7 +101,6 @@ def run_testsuit(): "test_label_filter", "test_lltm", "test_lmdbdataset", - "test_lmdbdataset_dist", "test_load_image", "test_load_imaged", "test_load_spacing_orientation", diff --git a/tests/ngc_mmar_loading.py b/tests/ngc_mmar_loading.py index a371917e59..c1ed22de5d 100644 --- a/tests/ngc_mmar_loading.py +++ b/tests/ngc_mmar_loading.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/runner.py b/tests/runner.py index 7356581365..b340d60719 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_acn_block.py b/tests/test_acn_block.py index 4c12155fd8..5e2467a565 100644 --- a/tests/test_acn_block.py +++ b/tests/test_acn_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_activations.py b/tests/test_activations.py index a67e6f8cb6..92b1e1d945 100644 --- a/tests/test_activations.py +++ b/tests/test_activations.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_activationsd.py b/tests/test_activationsd.py index 557d68de90..2c522d36ed 100644 --- a/tests/test_activationsd.py +++ b/tests/test_activationsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_adaptors.py b/tests/test_adaptors.py index 3c351d9e20..9bcd01feb7 100644 --- a/tests/test_adaptors.py +++ b/tests/test_adaptors.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_add_channeld.py b/tests/test_add_channeld.py index 9dc984aff3..8bdd89a4ae 100644 --- a/tests/test_add_channeld.py +++ b/tests/test_add_channeld.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_add_coordinate_channels.py b/tests/test_add_coordinate_channels.py index 5a483e25b9..4d779cffff 100644 --- a/tests/test_add_coordinate_channels.py +++ b/tests/test_add_coordinate_channels.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -20,10 +20,10 @@ TESTS, TEST_CASES_ERROR_1, TEST_CASES_ERROR_2 = [], [], [] for p in TEST_NDARRAYS: - TESTS.append([{"spatial_dims": (0, 1, 2)}, p(np.random.randint(0, 2, size=(1, 3, 3, 3))), (4, 3, 3, 3)]) - TESTS.append([{"spatial_dims": (0,)}, p(np.random.randint(0, 2, size=(1, 3, 3, 3))), (2, 3, 3, 3)]) - TEST_CASES_ERROR_1.append([{"spatial_dims": (2,)}, p(np.random.randint(0, 2, size=(1, 3, 3)))]) - TEST_CASES_ERROR_2.append([{"spatial_dims": (-1, 0, 1)}, p(np.random.randint(0, 2, size=(1, 3, 3)))]) + TESTS.append([{"spatial_channels": (1, 2, 3)}, p(np.random.randint(0, 2, size=(1, 3, 3, 3))), (4, 3, 3, 3)]) + TESTS.append([{"spatial_channels": (1,)}, p(np.random.randint(0, 2, size=(1, 3, 3, 3))), (2, 3, 3, 3)]) + TEST_CASES_ERROR_1.append([{"spatial_channels": (3,)}, p(np.random.randint(0, 2, size=(1, 3, 3)))]) + TEST_CASES_ERROR_2.append([{"spatial_channels": (0, 1, 2)}, p(np.random.randint(0, 2, size=(1, 3, 3)))]) class TestAddCoordinateChannels(unittest.TestCase): diff --git a/tests/test_add_coordinate_channelsd.py b/tests/test_add_coordinate_channelsd.py index c14ff0ba64..08d9e62468 100644 --- a/tests/test_add_coordinate_channelsd.py +++ b/tests/test_add_coordinate_channelsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -22,20 +22,24 @@ for p in TEST_NDARRAYS: TESTS.append( [ - {"spatial_dims": (0, 1, 2), "keys": ["img"]}, + {"spatial_channels": (1, 2, 3), "keys": ["img"]}, {"img": p(np.random.randint(0, 2, size=(1, 3, 3, 3)))}, (4, 3, 3, 3), ] ) TESTS.append( - [{"spatial_dims": (0,), "keys": ["img"]}, {"img": p(np.random.randint(0, 2, size=(1, 3, 3, 3)))}, (2, 3, 3, 3)] + [ + {"spatial_channels": (1,), "keys": ["img"]}, + {"img": p(np.random.randint(0, 2, size=(1, 3, 3, 3)))}, + (2, 3, 3, 3), + ] ) TEST_CASES_ERROR_1.append( - [{"spatial_dims": (2,), "keys": ["img"]}, {"img": p(np.random.randint(0, 2, size=(1, 3, 3)))}] + [{"spatial_channels": (3,), "keys": ["img"]}, {"img": p(np.random.randint(0, 2, size=(1, 3, 3)))}] ) TEST_CASES_ERROR_2.append( - [{"spatial_dims": (-1, 0, 1), "keys": ["img"]}, {"img": p(np.random.randint(0, 2, size=(1, 3, 3)))}] + [{"spatial_channels": (0, 1, 2), "keys": ["img"]}, {"img": p(np.random.randint(0, 2, size=(1, 3, 3)))}] ) diff --git a/tests/test_add_extreme_points_channel.py b/tests/test_add_extreme_points_channel.py index d2c8a627b6..06d26dfdfc 100644 --- a/tests/test_add_extreme_points_channel.py +++ b/tests/test_add_extreme_points_channel.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_add_extreme_points_channeld.py b/tests/test_add_extreme_points_channeld.py index 39d221596f..acd0ce69ce 100644 --- a/tests/test_add_extreme_points_channeld.py +++ b/tests/test_add_extreme_points_channeld.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_adjust_contrast.py b/tests/test_adjust_contrast.py index 2f6c4e2259..80ac61cfea 100644 --- a/tests/test_adjust_contrast.py +++ b/tests/test_adjust_contrast.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_adjust_contrastd.py b/tests/test_adjust_contrastd.py index a7224b643b..1e1c2cf8bc 100644 --- a/tests/test_adjust_contrastd.py +++ b/tests/test_adjust_contrastd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_adn.py b/tests/test_adn.py index 2352f5c1e2..2130ebc005 100644 --- a/tests/test_adn.py +++ b/tests/test_adn.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_affine.py b/tests/test_affine.py index d681d2941b..e5d11e2a82 100644 --- a/tests/test_affine.py +++ b/tests/test_affine.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_affine_grid.py b/tests/test_affine_grid.py index 6f6364feda..27e049843c 100644 --- a/tests/test_affine_grid.py +++ b/tests/test_affine_grid.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_affine_transform.py b/tests/test_affine_transform.py index 5170ab4260..ef39c297ce 100644 --- a/tests/test_affine_transform.py +++ b/tests/test_affine_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_affined.py b/tests/test_affined.py index 355833b858..a7c818fe65 100644 --- a/tests/test_affined.py +++ b/tests/test_affined.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_ahnet.py b/tests/test_ahnet.py index dba8eaf72b..f4bfa555fc 100644 --- a/tests/test_ahnet.py +++ b/tests/test_ahnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_alias.py b/tests/test_alias.py index 49f9fa56fe..0895da5743 100644 --- a/tests/test_alias.py +++ b/tests/test_alias.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_apply_filter.py b/tests/test_apply_filter.py index ff8480a02f..6bddfb5cf2 100644 --- a/tests/test_apply_filter.py +++ b/tests/test_apply_filter.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_arraydataset.py b/tests/test_arraydataset.py index ee1a92cf97..f6459cc88c 100644 --- a/tests/test_arraydataset.py +++ b/tests/test_arraydataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_as_channel_first.py b/tests/test_as_channel_first.py index a2d56295b8..918e576011 100644 --- a/tests/test_as_channel_first.py +++ b/tests/test_as_channel_first.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_as_channel_firstd.py b/tests/test_as_channel_firstd.py index 91086f9299..68d33434c1 100644 --- a/tests/test_as_channel_firstd.py +++ b/tests/test_as_channel_firstd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_as_channel_last.py b/tests/test_as_channel_last.py index e6446ab7a6..55a7a08676 100644 --- a/tests/test_as_channel_last.py +++ b/tests/test_as_channel_last.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_as_channel_lastd.py b/tests/test_as_channel_lastd.py index a6d94d216a..350f639f3f 100644 --- a/tests/test_as_channel_lastd.py +++ b/tests/test_as_channel_lastd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_as_discrete.py b/tests/test_as_discrete.py index a68e6431ec..8cbefbac39 100644 --- a/tests/test_as_discrete.py +++ b/tests/test_as_discrete.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_as_discreted.py b/tests/test_as_discreted.py index 21825c2d6c..7c7cfdf6e5 100644 --- a/tests/test_as_discreted.py +++ b/tests/test_as_discreted.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_autoencoder.py b/tests/test_autoencoder.py index bed5a198ff..451a93dc01 100644 --- a/tests/test_autoencoder.py +++ b/tests/test_autoencoder.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_basic_unet.py b/tests/test_basic_unet.py index a4f88367dd..1de37b316a 100644 --- a/tests/test_basic_unet.py +++ b/tests/test_basic_unet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_bending_energy.py b/tests/test_bending_energy.py index 318b1905df..f254b9624c 100644 --- a/tests/test_bending_energy.py +++ b/tests/test_bending_energy.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -22,28 +22,9 @@ TEST_CASES = [ [{}, {"pred": torch.ones((1, 3, 5, 5, 5), device=device)}, 0.0], [{}, {"pred": torch.arange(0, 5, device=device)[None, None, None, None, :].expand(1, 3, 5, 5, 5)}, 0.0], - [ - {"normalize": False}, - {"pred": torch.arange(0, 5, device=device)[None, None, None, None, :].expand(1, 3, 5, 5, 5) ** 2}, - 4.0, - ], - [ - {"normalize": False}, - {"pred": torch.arange(0, 5, device=device)[None, None, None, :].expand(1, 2, 5, 5) ** 2}, - 4.0, - ], - [{"normalize": False}, {"pred": torch.arange(0, 5, device=device)[None, None, :].expand(1, 1, 5) ** 2}, 4.0], - [ - {"normalize": True}, - {"pred": torch.arange(0, 5, device=device)[None, None, None, None, :].expand(1, 3, 5, 5, 5) ** 2}, - 100.0, - ], - [ - {"normalize": True}, - {"pred": torch.arange(0, 5, device=device)[None, None, None, :].expand(1, 2, 5, 5) ** 2}, - 100.0, - ], - [{"normalize": True}, {"pred": torch.arange(0, 5, device=device)[None, None, :].expand(1, 1, 5) ** 2}, 100.0], + [{}, {"pred": torch.arange(0, 5, device=device)[None, None, None, None, :].expand(1, 3, 5, 5, 5) ** 2}, 4.0], + [{}, {"pred": torch.arange(0, 5, device=device)[None, None, None, :].expand(1, 3, 5, 5) ** 2}, 4.0], + [{}, {"pred": torch.arange(0, 5, device=device)[None, None, :].expand(1, 3, 5) ** 2}, 4.0], ] @@ -56,24 +37,18 @@ def test_shape(self, input_param, input_data, expected_val): def test_ill_shape(self): loss = BendingEnergyLoss() # not in 3-d, 4-d, 5-d - with self.assertRaisesRegex(ValueError, "Expecting 3-d, 4-d or 5-d"): + with self.assertRaisesRegex(ValueError, ""): loss.forward(torch.ones((1, 3), device=device)) - with self.assertRaisesRegex(ValueError, "Expecting 3-d, 4-d or 5-d"): - loss.forward(torch.ones((1, 4, 5, 5, 5, 5), device=device)) + with self.assertRaisesRegex(ValueError, ""): + loss.forward(torch.ones((1, 3, 5, 5, 5, 5), device=device)) # spatial_dim < 5 - with self.assertRaisesRegex(ValueError, "All spatial dimensions"): + with self.assertRaisesRegex(ValueError, ""): loss.forward(torch.ones((1, 3, 4, 5, 5), device=device)) - with self.assertRaisesRegex(ValueError, "All spatial dimensions"): + with self.assertRaisesRegex(ValueError, ""): loss.forward(torch.ones((1, 3, 5, 4, 5))) - with self.assertRaisesRegex(ValueError, "All spatial dimensions"): + with self.assertRaisesRegex(ValueError, ""): loss.forward(torch.ones((1, 3, 5, 5, 4))) - # number of vector components unequal to number of spatial dims - with self.assertRaisesRegex(ValueError, "Number of vector components"): - loss.forward(torch.ones((1, 2, 5, 5, 5))) - with self.assertRaisesRegex(ValueError, "Number of vector components"): - loss.forward(torch.ones((1, 2, 5, 5, 5))) - def test_ill_opts(self): pred = torch.rand(1, 3, 5, 5, 5).to(device=device) with self.assertRaisesRegex(ValueError, ""): diff --git a/tests/test_bilateral_approx_cpu.py b/tests/test_bilateral_approx_cpu.py index b3f4f5c3be..d55a6ff5b3 100644 --- a/tests/test_bilateral_approx_cpu.py +++ b/tests/test_bilateral_approx_cpu.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_bilateral_approx_cuda.py b/tests/test_bilateral_approx_cuda.py index db34b0ff71..bc7defdc4e 100644 --- a/tests/test_bilateral_approx_cuda.py +++ b/tests/test_bilateral_approx_cuda.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_bilateral_precise.py b/tests/test_bilateral_precise.py index b19369d758..3b8f6194cf 100644 --- a/tests/test_bilateral_precise.py +++ b/tests/test_bilateral_precise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_blend_images.py b/tests/test_blend_images.py index 6fea53ac30..67e967b89d 100644 --- a/tests/test_blend_images.py +++ b/tests/test_blend_images.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_border_pad.py b/tests/test_border_pad.py index b632ff831f..7bd3f36c20 100644 --- a/tests/test_border_pad.py +++ b/tests/test_border_pad.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_border_padd.py b/tests/test_border_padd.py index e4b8dd20ea..b48629fc98 100644 --- a/tests/test_border_padd.py +++ b/tests/test_border_padd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_bounding_rect.py b/tests/test_bounding_rect.py index a7c2648f1e..eef8ebec50 100644 --- a/tests/test_bounding_rect.py +++ b/tests/test_bounding_rect.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_bounding_rectd.py b/tests/test_bounding_rectd.py index 47ed854263..4b0e132ca3 100644 --- a/tests/test_bounding_rectd.py +++ b/tests/test_bounding_rectd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cachedataset.py b/tests/test_cachedataset.py index 9d85c711fd..7f35b99ad5 100644 --- a/tests/test_cachedataset.py +++ b/tests/test_cachedataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cachedataset_parallel.py b/tests/test_cachedataset_parallel.py index f409e17787..96aadd9614 100644 --- a/tests/test_cachedataset_parallel.py +++ b/tests/test_cachedataset_parallel.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cachedataset_persistent_workers.py b/tests/test_cachedataset_persistent_workers.py index 4bea0486bc..6cdd0ada99 100644 --- a/tests/test_cachedataset_persistent_workers.py +++ b/tests/test_cachedataset_persistent_workers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cachentransdataset.py b/tests/test_cachentransdataset.py index 99ca0e0c3d..13c1e1c68e 100644 --- a/tests/test_cachentransdataset.py +++ b/tests/test_cachentransdataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cast_to_type.py b/tests/test_cast_to_type.py index 82daabc4e7..d06efb17b5 100644 --- a/tests/test_cast_to_type.py +++ b/tests/test_cast_to_type.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -18,9 +18,9 @@ from monai.transforms import CastToType from monai.utils import optional_import from monai.utils.type_conversion import get_equivalent_dtype -from tests.utils import HAS_CUPY, TEST_NDARRAYS +from tests.utils import TEST_NDARRAYS -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") TESTS = [] for p in TEST_NDARRAYS: @@ -45,7 +45,7 @@ def test_type(self, out_dtype, input_data, expected_type): self.assertEqual(result.dtype, get_equivalent_dtype(expected_type, type(result))) @parameterized.expand(TESTS_CUPY) - @unittest.skipUnless(HAS_CUPY, "Requires CuPy") + @unittest.skipUnless(has_cp, "Requires CuPy") def test_type_cupy(self, out_dtype, input_data, expected_type): input_data = cp.asarray(input_data) diff --git a/tests/test_cast_to_typed.py b/tests/test_cast_to_typed.py index 4c7623a9e0..007598c200 100644 --- a/tests/test_cast_to_typed.py +++ b/tests/test_cast_to_typed.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,9 +17,8 @@ from monai.transforms import CastToTyped from monai.utils import optional_import -from tests.utils import HAS_CUPY -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") TEST_CASE_1 = [ {"keys": ["img"], "dtype": np.float64}, @@ -59,7 +58,7 @@ def test_type(self, input_param, input_data, expected_type): self.assertEqual(v.dtype, expected_type[k]) @parameterized.expand(TESTS_CUPY) - @unittest.skipUnless(HAS_CUPY, "Requires CuPy") + @unittest.skipUnless(has_cp, "Requires CuPy") def test_type_cupy(self, input_param, input_data, expected_type): input_data = {k: cp.asarray(v) for k, v in input_data.items()} diff --git a/tests/test_center_scale_crop.py b/tests/test_center_scale_crop.py index f22651e3e0..4c5bfc4fac 100644 --- a/tests/test_center_scale_crop.py +++ b/tests/test_center_scale_crop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_center_scale_cropd.py b/tests/test_center_scale_cropd.py index 8aef2dbe5b..a827d611e6 100644 --- a/tests/test_center_scale_cropd.py +++ b/tests/test_center_scale_cropd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_center_spatial_crop.py b/tests/test_center_spatial_crop.py index 09f61be2f1..d6a7edb305 100644 --- a/tests/test_center_spatial_crop.py +++ b/tests/test_center_spatial_crop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_center_spatial_cropd.py b/tests/test_center_spatial_cropd.py index bdbc1a5031..be44468987 100644 --- a/tests/test_center_spatial_cropd.py +++ b/tests/test_center_spatial_cropd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_channel_pad.py b/tests/test_channel_pad.py index bde0f18d83..ebc731c321 100644 --- a/tests/test_channel_pad.py +++ b/tests/test_channel_pad.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_check_hash.py b/tests/test_check_hash.py index 5297021540..8009302ad0 100644 --- a/tests/test_check_hash.py +++ b/tests/test_check_hash.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_check_missing_files.py b/tests/test_check_missing_files.py index ecd0b52a63..1134409a66 100644 --- a/tests/test_check_missing_files.py +++ b/tests/test_check_missing_files.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_classes_to_indices.py b/tests/test_classes_to_indices.py index 1f39e0f480..7c89e3179d 100644 --- a/tests/test_classes_to_indices.py +++ b/tests/test_classes_to_indices.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_classes_to_indicesd.py b/tests/test_classes_to_indicesd.py index 398620d304..0df7490ec5 100644 --- a/tests/test_classes_to_indicesd.py +++ b/tests/test_classes_to_indicesd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_compose.py b/tests/test_compose.py index e0913f59e1..28783cad23 100644 --- a/tests/test_compose.py +++ b/tests/test_compose.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_compose_get_number_conversions.py b/tests/test_compose_get_number_conversions.py index fca5bc727d..eb10c7d5ef 100644 --- a/tests/test_compose_get_number_conversions.py +++ b/tests/test_compose_get_number_conversions.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_compute_confusion_matrix.py b/tests/test_compute_confusion_matrix.py index 1212715548..ef65c474c8 100644 --- a/tests/test_compute_confusion_matrix.py +++ b/tests/test_compute_confusion_matrix.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_compute_froc.py b/tests/test_compute_froc.py index d68f3f7fb4..70de836dd9 100644 --- a/tests/test_compute_froc.py +++ b/tests/test_compute_froc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_compute_meandice.py b/tests/test_compute_meandice.py index ad66ed672a..f96563e22e 100644 --- a/tests/test_compute_meandice.py +++ b/tests/test_compute_meandice.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_compute_regression_metrics.py b/tests/test_compute_regression_metrics.py index 65ca73a4ec..126eab3f07 100644 --- a/tests/test_compute_regression_metrics.py +++ b/tests/test_compute_regression_metrics.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_compute_roc_auc.py b/tests/test_compute_roc_auc.py index d06eed8740..02e2f2b24f 100644 --- a/tests/test_compute_roc_auc.py +++ b/tests/test_compute_roc_auc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_concat_itemsd.py b/tests/test_concat_itemsd.py index 2f98738233..9c51e1efea 100644 --- a/tests/test_concat_itemsd.py +++ b/tests/test_concat_itemsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_contrastive_loss.py b/tests/test_contrastive_loss.py index 5dce860486..b9caecce65 100644 --- a/tests/test_contrastive_loss.py +++ b/tests/test_contrastive_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -61,7 +61,7 @@ def test_result(self, input_param, input_data, expected_val): def test_ill_shape(self): loss = ContrastiveLoss(temperature=0.5, batch_size=1) - with self.assertRaisesRegex(ValueError, ""): + with self.assertRaisesRegex(AssertionError, ""): loss(torch.ones((1, 2, 3)), torch.ones((1, 1, 2, 3))) def test_with_cuda(self): diff --git a/tests/test_convert_data_type.py b/tests/test_convert_data_type.py index 1818f500f9..28f9fbd1bd 100644 --- a/tests/test_convert_data_type.py +++ b/tests/test_convert_data_type.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_convert_to_multi_channel.py b/tests/test_convert_to_multi_channel.py index b606fee04f..4892eae809 100644 --- a/tests/test_convert_to_multi_channel.py +++ b/tests/test_convert_to_multi_channel.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_convert_to_multi_channeld.py b/tests/test_convert_to_multi_channeld.py index 7525f8d7e2..945e07e1cd 100644 --- a/tests/test_convert_to_multi_channeld.py +++ b/tests/test_convert_to_multi_channeld.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_convert_to_torchscript.py b/tests/test_convert_to_torchscript.py index a1c1471463..a772610a04 100644 --- a/tests/test_convert_to_torchscript.py +++ b/tests/test_convert_to_torchscript.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -34,7 +34,6 @@ def test_value(self): device="cuda" if torch.cuda.is_available() else "cpu", rtol=1e-3, atol=1e-4, - optimize=None, ) self.assertTrue(isinstance(torchscript_model, torch.nn.Module)) diff --git a/tests/test_convolutions.py b/tests/test_convolutions.py index 5c1681ad71..97c01dd659 100644 --- a/tests/test_convolutions.py +++ b/tests/test_convolutions.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_copy_itemsd.py b/tests/test_copy_itemsd.py index 375991cbcc..a0a1ad412b 100644 --- a/tests/test_copy_itemsd.py +++ b/tests/test_copy_itemsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_copy_model_state.py b/tests/test_copy_model_state.py index bc7b116e1f..438c521479 100644 --- a/tests/test_copy_model_state.py +++ b/tests/test_copy_model_state.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_correct_crop_centers.py b/tests/test_correct_crop_centers.py index 50478c7d5d..dba71f6e8d 100644 --- a/tests/test_correct_crop_centers.py +++ b/tests/test_correct_crop_centers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_create_cross_validation_datalist.py b/tests/test_create_cross_validation_datalist.py index 3a3e8481ea..e1dc2e522e 100644 --- a/tests/test_create_cross_validation_datalist.py +++ b/tests/test_create_cross_validation_datalist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_create_grid_and_affine.py b/tests/test_create_grid_and_affine.py index d70db45468..cd8d75f63e 100644 --- a/tests/test_create_grid_and_affine.py +++ b/tests/test_create_grid_and_affine.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_crf_cpu.py b/tests/test_crf_cpu.py index 46da3298bc..6f9864e934 100644 --- a/tests/test_crf_cpu.py +++ b/tests/test_crf_cpu.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_crf_cuda.py b/tests/test_crf_cuda.py index ca25fe2de9..8881b9aec5 100644 --- a/tests/test_crf_cuda.py +++ b/tests/test_crf_cuda.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_crop_foreground.py b/tests/test_crop_foreground.py index a9c473a4c6..0bae1f90f3 100644 --- a/tests/test_crop_foreground.py +++ b/tests/test_crop_foreground.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_crop_foregroundd.py b/tests/test_crop_foregroundd.py index 7f1842197c..5fa474d6ac 100644 --- a/tests/test_crop_foregroundd.py +++ b/tests/test_crop_foregroundd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cross_validation.py b/tests/test_cross_validation.py index 017fd0243c..ee4cb444b2 100644 --- a/tests/test_cross_validation.py +++ b/tests/test_cross_validation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_csv_dataset.py b/tests/test_csv_dataset.py index f288ac4b95..d187f4e64d 100644 --- a/tests/test_csv_dataset.py +++ b/tests/test_csv_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,7 +14,6 @@ import unittest import numpy as np -import pandas as pd from monai.data import CSVDataset from monai.transforms import ToNumpyd @@ -58,7 +57,6 @@ def prepare_csv_file(data, filepath): filepath1 = os.path.join(tempdir, "test_data1.csv") filepath2 = os.path.join(tempdir, "test_data2.csv") filepath3 = os.path.join(tempdir, "test_data3.csv") - filepaths = [filepath1, filepath2, filepath3] prepare_csv_file(test_data1, filepath1) prepare_csv_file(test_data2, filepath2) prepare_csv_file(test_data3, filepath3) @@ -78,7 +76,7 @@ def prepare_csv_file(data, filepath): ) # test multiple CSV files, join tables with kwargs - dataset = CSVDataset(filepaths, on="subject_id") + dataset = CSVDataset([filepath1, filepath2, filepath3], on="subject_id") self.assertDictEqual( {k: round(v, 4) if not isinstance(v, (str, np.bool_)) else v for k, v in dataset[3].items()}, { @@ -104,7 +102,7 @@ def prepare_csv_file(data, filepath): # test selected rows and columns dataset = CSVDataset( - src=filepaths, + filename=[filepath1, filepath2, filepath3], row_indices=[[0, 2], 3], # load row: 0, 1, 3 col_names=["subject_id", "image", "ehr_1", "ehr_7", "meta_1"], ) @@ -122,7 +120,7 @@ def prepare_csv_file(data, filepath): # test group columns dataset = CSVDataset( - src=filepaths, + filename=[filepath1, filepath2, filepath3], row_indices=[1, 3], # load row: 1, 3 col_names=["subject_id", "image", *[f"ehr_{i}" for i in range(11)], "meta_0", "meta_1", "meta_2"], col_groups={"ehr": [f"ehr_{i}" for i in range(11)], "meta12": ["meta_1", "meta_2"]}, @@ -135,7 +133,9 @@ def prepare_csv_file(data, filepath): # test transform dataset = CSVDataset( - src=filepaths, col_groups={"ehr": [f"ehr_{i}" for i in range(5)]}, transform=ToNumpyd(keys="ehr") + filename=[filepath1, filepath2, filepath3], + col_groups={"ehr": [f"ehr_{i}" for i in range(5)]}, + transform=ToNumpyd(keys="ehr"), ) self.assertEqual(len(dataset), 5) expected = [ @@ -151,7 +151,7 @@ def prepare_csv_file(data, filepath): # test default values and dtype dataset = CSVDataset( - src=filepaths, + filename=[filepath1, filepath2, filepath3], col_names=["subject_id", "image", "ehr_1", "ehr_9", "meta_1"], col_types={"image": {"type": str, "default": "No image"}, "ehr_1": {"type": int, "default": 0}}, how="outer", # generate NaN values in this merge mode @@ -161,29 +161,6 @@ def prepare_csv_file(data, filepath): self.assertEqual(type(dataset[-1]["ehr_1"]), int) np.testing.assert_allclose(dataset[-1]["ehr_9"], 3.3537, rtol=1e-2) - # test pre-loaded DataFrame - df = pd.read_csv(filepath1) - dataset = CSVDataset(src=df) - self.assertDictEqual( - {k: round(v, 4) if not isinstance(v, str) else v for k, v in dataset[2].items()}, - { - "subject_id": "s000002", - "label": 4, - "image": "./imgs/s000002.png", - "ehr_0": 3.7725, - "ehr_1": 4.2118, - "ehr_2": 4.6353, - }, - ) - - # test pre-loaded multiple DataFrames, join tables with kwargs - dfs = [pd.read_csv(i) for i in filepaths] - dataset = CSVDataset(src=dfs, on="subject_id") - self.assertEqual(dataset[3]["subject_id"], "s000003") - self.assertEqual(dataset[3]["label"], 1) - self.assertEqual(round(dataset[3]["ehr_0"], 4), 3.3333) - self.assertEqual(dataset[3]["meta_0"], False) - if __name__ == "__main__": unittest.main() diff --git a/tests/test_csv_iterable_dataset.py b/tests/test_csv_iterable_dataset.py index d6b84074ba..fae8e0ba8d 100644 --- a/tests/test_csv_iterable_dataset.py +++ b/tests/test_csv_iterable_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -15,7 +15,6 @@ import unittest import numpy as np -import pandas as pd from monai.data import CSVIterableDataset, DataLoader from monai.transforms import ToNumpyd @@ -59,7 +58,6 @@ def prepare_csv_file(data, filepath): filepath1 = os.path.join(tempdir, "test_data1.csv") filepath2 = os.path.join(tempdir, "test_data2.csv") filepath3 = os.path.join(tempdir, "test_data3.csv") - filepaths = [filepath1, filepath2, filepath3] prepare_csv_file(test_data1, filepath1) prepare_csv_file(test_data2, filepath2) prepare_csv_file(test_data3, filepath3) @@ -83,20 +81,18 @@ def prepare_csv_file(data, filepath): ) break self.assertEqual(count, 3) - dataset.close() # test reset iterables - dataset.reset(src=filepath3) + dataset.reset(filename=filepath3) count = 0 for i, item in enumerate(dataset): count += 1 if i == 4: self.assertEqual(item["meta_0"], False) self.assertEqual(count, 5) - dataset.close() # test multiple CSV files, join tables with kwargs - dataset = CSVIterableDataset(filepaths, on="subject_id", shuffle=False) + dataset = CSVIterableDataset([filepath1, filepath2, filepath3], on="subject_id", shuffle=False) count = 0 for item in dataset: count += 1 @@ -124,11 +120,13 @@ def prepare_csv_file(data, filepath): }, ) self.assertEqual(count, 5) - dataset.close() # test selected columns and chunk size dataset = CSVIterableDataset( - src=filepaths, chunksize=2, col_names=["subject_id", "image", "ehr_1", "ehr_7", "meta_1"], shuffle=False + filename=[filepath1, filepath2, filepath3], + chunksize=2, + col_names=["subject_id", "image", "ehr_1", "ehr_7", "meta_1"], + shuffle=False, ) count = 0 for item in dataset: @@ -145,11 +143,10 @@ def prepare_csv_file(data, filepath): }, ) self.assertEqual(count, 5) - dataset.close() # test group columns dataset = CSVIterableDataset( - src=filepaths, + filename=[filepath1, filepath2, filepath3], col_names=["subject_id", "image", *[f"ehr_{i}" for i in range(11)], "meta_0", "meta_1", "meta_2"], col_groups={"ehr": [f"ehr_{i}" for i in range(11)], "meta12": ["meta_1", "meta_2"]}, shuffle=False, @@ -164,13 +161,12 @@ def prepare_csv_file(data, filepath): ) np.testing.assert_allclose(item["meta12"], [False, True]) self.assertEqual(count, 5) - dataset.close() # test transform dataset = CSVIterableDataset( chunksize=2, buffer_size=4, - src=filepaths, + filename=[filepath1, filepath2, filepath3], col_groups={"ehr": [f"ehr_{i}" for i in range(5)]}, transform=ToNumpyd(keys="ehr"), shuffle=True, @@ -189,7 +185,6 @@ def prepare_csv_file(data, filepath): self.assertTrue(isinstance(item["ehr"], np.ndarray)) np.testing.assert_allclose(np.around(item["ehr"], 4), exp) self.assertEqual(count, 5) - dataset.close() # test multiple processes loading dataset = CSVIterableDataset(filepath1, transform=ToNumpyd(keys="label"), shuffle=False) @@ -205,45 +200,6 @@ def prepare_csv_file(data, filepath): np.testing.assert_allclose(item["label"], [4]) self.assertListEqual(item["image"], ["./imgs/s000002.png"]) self.assertEqual(count, 3) - dataset.close() - - # test iterable stream - iters = pd.read_csv(filepath1, chunksize=1000) - dataset = CSVIterableDataset(src=iters, shuffle=False) - count = 0 - for item in dataset: - count += 1 - if count == 3: - self.assertDictEqual( - {k: round(v, 4) if not isinstance(v, str) else v for k, v in item.items()}, - { - "subject_id": "s000002", - "label": 4, - "image": "./imgs/s000002.png", - "ehr_0": 3.7725, - "ehr_1": 4.2118, - "ehr_2": 4.6353, - }, - ) - break - self.assertEqual(count, 3) - dataset.close() - - # test multiple iterable streams, join tables with kwargs - iters = [pd.read_csv(i, chunksize=1000) for i in filepaths] - dataset = CSVIterableDataset(src=iters, on="subject_id", shuffle=False) - count = 0 - for item in dataset: - count += 1 - if count == 4: - self.assertEqual(item["subject_id"], "s000003") - self.assertEqual(item["label"], 1) - self.assertEqual(round(item["ehr_0"], 4), 3.3333) - self.assertEqual(item["meta_0"], False) - self.assertEqual(count, 5) - # manually close the pre-loaded iterables instead of `dataset.close()` - for i in iters: - i.close() if __name__ == "__main__": diff --git a/tests/test_csv_saver.py b/tests/test_csv_saver.py index 6b60de4b0c..a279599463 100644 --- a/tests/test_csv_saver.py +++ b/tests/test_csv_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cucim_dict_transform.py b/tests/test_cucim_dict_transform.py index f8b54c3147..4936375142 100644 --- a/tests/test_cucim_dict_transform.py +++ b/tests/test_cucim_dict_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,10 +16,10 @@ from monai.transforms import CuCIMd from monai.utils import optional_import, set_determinism -from tests.utils import HAS_CUPY, skip_if_no_cuda +from tests.utils import skip_if_no_cuda _, has_cut = optional_import("cucim.core.operations.expose.transform") -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") set_determinism(seed=0) @@ -62,7 +62,7 @@ @skip_if_no_cuda -@unittest.skipUnless(HAS_CUPY, "CuPy is required.") +@unittest.skipUnless(has_cp, "CuPy is required.") @unittest.skipUnless(has_cut, "cuCIM transforms are required.") class TestCuCIMDict(unittest.TestCase): @parameterized.expand( diff --git a/tests/test_cucim_transform.py b/tests/test_cucim_transform.py index 2bf9791bce..a6c0084c99 100644 --- a/tests/test_cucim_transform.py +++ b/tests/test_cucim_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,10 +16,10 @@ from monai.transforms import CuCIM from monai.utils import optional_import, set_determinism -from tests.utils import HAS_CUPY, skip_if_no_cuda +from tests.utils import skip_if_no_cuda _, has_cut = optional_import("cucim.core.operations.expose.transform") -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") set_determinism(seed=0) @@ -62,7 +62,7 @@ @skip_if_no_cuda -@unittest.skipUnless(HAS_CUPY, "CuPy is required.") +@unittest.skipUnless(has_cp, "CuPy is required.") @unittest.skipUnless(has_cut, "cuCIM transforms are required.") class TestCuCIM(unittest.TestCase): @parameterized.expand( diff --git a/tests/test_cumulative.py b/tests/test_cumulative.py index 12a6a5e5e7..90719a936e 100644 --- a/tests/test_cumulative.py +++ b/tests/test_cumulative.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cumulative_average.py b/tests/test_cumulative_average.py index 4e7e4ff5d9..90f21fc8c4 100644 --- a/tests/test_cumulative_average.py +++ b/tests/test_cumulative_average.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_cumulative_average_dist.py b/tests/test_cumulative_average_dist.py index 5de139e9ac..d58864df44 100644 --- a/tests/test_cumulative_average_dist.py +++ b/tests/test_cumulative_average_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_data_stats.py b/tests/test_data_stats.py index 65a61ce7ec..535b28bcf1 100644 --- a/tests/test_data_stats.py +++ b/tests/test_data_stats.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_data_statsd.py b/tests/test_data_statsd.py index 1f38db2b05..4c33a82b67 100644 --- a/tests/test_data_statsd.py +++ b/tests/test_data_statsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dataloader.py b/tests/test_dataloader.py index 79126b2dbb..035f145c9a 100644 --- a/tests/test_dataloader.py +++ b/tests/test_dataloader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dataset.py b/tests/test_dataset.py index f8d4ed2104..491b777550 100644 --- a/tests/test_dataset.py +++ b/tests/test_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dataset_func.py b/tests/test_dataset_func.py deleted file mode 100644 index b5871d7de1..0000000000 --- a/tests/test_dataset_func.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) MONAI Consortium -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import os -import tempfile -import unittest - -from monai.data import Dataset, DatasetFunc, load_decathlon_datalist, partition_dataset - - -class TestDatasetFunc(unittest.TestCase): - def test_seg_values(self): - with tempfile.TemporaryDirectory() as tempdir: - # prepare test datalist file - test_data = { - "name": "Spleen", - "description": "Spleen Segmentation", - "labels": {"0": "background", "1": "spleen"}, - "training": [ - {"image": "spleen_19.nii.gz", "label": "spleen_19.nii.gz"}, - {"image": "spleen_31.nii.gz", "label": "spleen_31.nii.gz"}, - ], - "test": ["spleen_15.nii.gz", "spleen_23.nii.gz"], - } - json_str = json.dumps(test_data) - file_path = os.path.join(tempdir, "test_data.json") - with open(file_path, "w") as json_file: - json_file.write(json_str) - - data_list = DatasetFunc( - data=file_path, func=load_decathlon_datalist, data_list_key="training", base_dir=tempdir - ) - # partition dataset for train / validation - data_partition = DatasetFunc( - data=data_list, func=lambda x, **kwargs: partition_dataset(x, **kwargs)[0], num_partitions=2 - ) - dataset = Dataset(data=data_partition, transform=None) - self.assertEqual(dataset[0]["image"], os.path.join(tempdir, "spleen_19.nii.gz")) - self.assertEqual(dataset[0]["label"], os.path.join(tempdir, "spleen_19.nii.gz")) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_dataset_summary.py b/tests/test_dataset_summary.py index 5569c51a0c..172d4980dd 100644 --- a/tests/test_dataset_summary.py +++ b/tests/test_dataset_summary.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -22,15 +22,6 @@ from monai.utils import set_determinism -def test_collate(batch): - elem = batch[0] - elem_type = type(elem) - if isinstance(elem, np.ndarray): - return np.stack(batch, 0) - elif isinstance(elem, dict): - return elem_type({key: test_collate([d[key] for d in batch]) for key in elem}) - - class TestDatasetSummary(unittest.TestCase): def test_spacing_intensity(self): set_determinism(seed=0) @@ -49,12 +40,9 @@ def test_spacing_intensity(self): {"image": image_name, "label": label_name} for image_name, label_name in zip(train_images, train_labels) ] - dataset = Dataset( - data=data_dicts, transform=LoadImaged(keys=["image", "label"], meta_keys=["test1", "test2"]) - ) + dataset = Dataset(data=data_dicts, transform=LoadImaged(keys=["image", "label"])) - # test **kwargs of `DatasetSummary` for `DataLoader` - calculator = DatasetSummary(dataset, num_workers=4, meta_key="test1", collate_fn=test_collate) + calculator = DatasetSummary(dataset, num_workers=4) target_spacing = calculator.get_target_spacing() self.assertEqual(target_spacing, (1.0, 1.0, 1.0)) @@ -86,7 +74,7 @@ def test_anisotropic_spacing(self): dataset = Dataset(data=data_dicts, transform=LoadImaged(keys=["image", "label"])) - calculator = DatasetSummary(dataset, num_workers=4, meta_key_postfix="meta_dict") + calculator = DatasetSummary(dataset, num_workers=4) target_spacing = calculator.get_target_spacing(anisotropic_threshold=4.0, percentile=20.0) np.testing.assert_allclose(target_spacing, (1.0, 1.0, 1.8)) diff --git a/tests/test_decathlondataset.py b/tests/test_decathlondataset.py index 9a785668ac..0756902385 100644 --- a/tests/test_decathlondataset.py +++ b/tests/test_decathlondataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -47,7 +47,6 @@ def _test_dataset(dataset): transform=transform, section="validation", download=True, - copy_cache=False, ) except (ContentTooShortError, HTTPError, RuntimeError) as e: print(str(e)) diff --git a/tests/test_decollate.py b/tests/test_decollate.py index dc43cfc422..fc0622c8f0 100644 --- a/tests/test_decollate.py +++ b/tests/test_decollate.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_deepedit_transforms.py b/tests/test_deepedit_transforms.py index aa0a73183d..391b724da9 100644 --- a/tests/test_deepedit_transforms.py +++ b/tests/test_deepedit_transforms.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_deepgrow_dataset.py b/tests/test_deepgrow_dataset.py index ff8de87b81..147d8e7099 100644 --- a/tests/test_deepgrow_dataset.py +++ b/tests/test_deepgrow_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index b040348b62..016ba17251 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_deepgrow_transforms.py b/tests/test_deepgrow_transforms.py index 5a3f55be60..3085309bdc 100644 --- a/tests/test_deepgrow_transforms.py +++ b/tests/test_deepgrow_transforms.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_delete_itemsd.py b/tests/test_delete_itemsd.py index 18138119b5..b7cd104c46 100644 --- a/tests/test_delete_itemsd.py +++ b/tests/test_delete_itemsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_densenet.py b/tests/test_densenet.py index 47f584297e..ba4b7afcb4 100644 --- a/tests/test_densenet.py +++ b/tests/test_densenet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index 545031321b..9c7fe4f632 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -29,7 +29,7 @@ def test_warning(self): def foo2(): pass - foo2() # should not raise any warnings + print(foo2()) def test_warning_milestone(self): """Test deprecated decorator with `since` and `removed` set for a milestone version""" @@ -172,7 +172,7 @@ def test_arg_warn2(self): """Test deprecated_arg decorator with just `since` set.""" @deprecated_arg("b", since=self.prev_version, version_val=self.test_version) - def afoo2(a, **kw): + def afoo2(a, **kwargs): pass afoo2(1) # ok when no b provided @@ -235,19 +235,6 @@ def afoo4(a, b=None): self.assertRaises(DeprecatedError, lambda: afoo4(1, b=2)) - def test_arg_except3_unknown(self): - """ - Test deprecated_arg decorator raises exception with `removed` set in the past. - with unknown version and kwargs - """ - - @deprecated_arg("b", removed=self.prev_version, version_val="0+untagged.1.g3131155") - def afoo4(a, b=None, **kwargs): - pass - - self.assertRaises(DeprecatedError, lambda: afoo4(1, b=2)) - self.assertRaises(DeprecatedError, lambda: afoo4(1, b=2, c=3)) - def test_replacement_arg(self): """ Test deprecated arg being replaced. @@ -258,36 +245,10 @@ def afoo4(a, b=None): return a self.assertEqual(afoo4(b=2), 2) + # self.assertRaises(DeprecatedError, lambda: afoo4(1, b=2)) self.assertEqual(afoo4(1, b=2), 1) # new name is in use self.assertEqual(afoo4(a=1, b=2), 1) # prefers the new arg - def test_replacement_arg1(self): - """ - Test deprecated arg being replaced with kwargs. - """ - - @deprecated_arg("b", new_name="a", since=self.prev_version, version_val=self.test_version) - def afoo4(a, *args, **kwargs): - return a - - self.assertEqual(afoo4(b=2), 2) - self.assertEqual(afoo4(1, b=2, c=3), 1) # new name is in use - self.assertEqual(afoo4(a=1, b=2, c=3), 1) # prefers the new arg - - def test_replacement_arg2(self): - """ - Test deprecated arg (with a default value) being replaced. - """ - - @deprecated_arg("b", new_name="a", since=self.prev_version, version_val=self.test_version) - def afoo4(a, b=None, **kwargs): - return a, kwargs - - self.assertEqual(afoo4(b=2, c=3), (2, {"c": 3})) - self.assertEqual(afoo4(1, b=2, c=3), (1, {"c": 3})) # new name is in use - self.assertEqual(afoo4(a=1, b=2, c=3), (1, {"c": 3})) # prefers the new arg - self.assertEqual(afoo4(1, 2, c=3), (1, {"c": 3})) # prefers the new positional arg - if __name__ == "__main__": unittest.main() diff --git a/tests/test_detect_envelope.py b/tests/test_detect_envelope.py index f1b9c7ad1a..30d6d889eb 100644 --- a/tests/test_detect_envelope.py +++ b/tests/test_detect_envelope.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dice_ce_loss.py b/tests/test_dice_ce_loss.py index b11165ca9c..66cfb36e99 100644 --- a/tests/test_dice_ce_loss.py +++ b/tests/test_dice_ce_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dice_focal_loss.py b/tests/test_dice_focal_loss.py index c611fe4160..a69df21693 100644 --- a/tests/test_dice_focal_loss.py +++ b/tests/test_dice_focal_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dice_loss.py b/tests/test_dice_loss.py index 4e45393de6..a6d4c987c7 100644 --- a/tests/test_dice_loss.py +++ b/tests/test_dice_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dints_cell.py b/tests/test_dints_cell.py index d480235b70..e89bb06998 100644 --- a/tests/test_dints_cell.py +++ b/tests/test_dints_cell.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dints_mixop.py b/tests/test_dints_mixop.py index b686069173..a827fc3207 100644 --- a/tests/test_dints_mixop.py +++ b/tests/test_dints_mixop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dints_network.py b/tests/test_dints_network.py index 8be5eb7ccd..bbdaadbcc4 100644 --- a/tests/test_dints_network.py +++ b/tests/test_dints_network.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_discriminator.py b/tests/test_discriminator.py index aa9b9720c4..52b9a10dd5 100644 --- a/tests/test_discriminator.py +++ b/tests/test_discriminator.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_call_dist.py b/tests/test_distcall.py similarity index 96% rename from tests/test_call_dist.py rename to tests/test_distcall.py index bed8289506..1830a85654 100644 --- a/tests/test_call_dist.py +++ b/tests/test_distcall.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_sampler_dist.py b/tests/test_distributed_sampler.py similarity index 97% rename from tests/test_sampler_dist.py rename to tests/test_distributed_sampler.py index 8b140f3ff8..0a439874bd 100644 --- a/tests/test_sampler_dist.py +++ b/tests/test_distributed_sampler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_weighted_random_sampler_dist.py b/tests/test_distributed_weighted_random_sampler.py similarity index 98% rename from tests/test_weighted_random_sampler_dist.py rename to tests/test_distributed_weighted_random_sampler.py index 13404a8acb..23574e5121 100644 --- a/tests/test_weighted_random_sampler_dist.py +++ b/tests/test_distributed_weighted_random_sampler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_divisible_pad.py b/tests/test_divisible_pad.py index f940636fa8..bb58668908 100644 --- a/tests/test_divisible_pad.py +++ b/tests/test_divisible_pad.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_divisible_padd.py b/tests/test_divisible_padd.py index 61fe917421..44faeced7b 100644 --- a/tests/test_divisible_padd.py +++ b/tests/test_divisible_padd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_download_and_extract.py b/tests/test_download_and_extract.py index f896d4ae93..164fcd723d 100644 --- a/tests/test_download_and_extract.py +++ b/tests/test_download_and_extract.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_downsample_block.py b/tests/test_downsample_block.py index ac2acb0845..d35218c6d7 100644 --- a/tests/test_downsample_block.py +++ b/tests/test_downsample_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dvf2ddf.py b/tests/test_dvf2ddf.py index d061cca7ff..cc3323cf13 100644 --- a/tests/test_dvf2ddf.py +++ b/tests/test_dvf2ddf.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dynunet.py b/tests/test_dynunet.py index 36ac9d0309..ca19ea2b47 100644 --- a/tests/test_dynunet.py +++ b/tests/test_dynunet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_dynunet_block.py b/tests/test_dynunet_block.py index 1c83552766..de3c018d78 100644 --- a/tests/test_dynunet_block.py +++ b/tests/test_dynunet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_efficientnet.py b/tests/test_efficientnet.py index 0ab383fd56..d36157e6fa 100644 --- a/tests/test_efficientnet.py +++ b/tests/test_efficientnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -13,7 +13,6 @@ import unittest from typing import TYPE_CHECKING from unittest import skipUnless -from urllib.error import ContentTooShortError, HTTPError import torch from parameterized import parameterized diff --git a/tests/test_ensemble_evaluator.py b/tests/test_ensemble_evaluator.py index c7554e9421..7f63cb6401 100644 --- a/tests/test_ensemble_evaluator.py +++ b/tests/test_ensemble_evaluator.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_ensure_channel_first.py b/tests/test_ensure_channel_first.py index dd6168ec75..0fb7759219 100644 --- a/tests/test_ensure_channel_first.py +++ b/tests/test_ensure_channel_first.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_ensure_channel_firstd.py b/tests/test_ensure_channel_firstd.py index 9b9043e4ad..b5e1abe4ca 100644 --- a/tests/test_ensure_channel_firstd.py +++ b/tests/test_ensure_channel_firstd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_ensure_type.py b/tests/test_ensure_type.py index f8a6ee30ff..80a6204325 100644 --- a/tests/test_ensure_type.py +++ b/tests/test_ensure_type.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_ensure_typed.py b/tests/test_ensure_typed.py index cadab9bd56..4a6582f9d0 100644 --- a/tests/test_ensure_typed.py +++ b/tests/test_ensure_typed.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_enum_bound_interp.py b/tests/test_enum_bound_interp.py index 7607619e7a..f788f8ba17 100644 --- a/tests/test_enum_bound_interp.py +++ b/tests/test_enum_bound_interp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_eval_mode.py b/tests/test_eval_mode.py index bc9c97d238..45c551c209 100644 --- a/tests/test_eval_mode.py +++ b/tests/test_eval_mode.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_evenly_divisible_all_gather_dist.py b/tests/test_evenly_divisible_all_gather_dist.py index 1bb3d887a0..bf3bd1bacc 100644 --- a/tests/test_evenly_divisible_all_gather_dist.py +++ b/tests/test_evenly_divisible_all_gather_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_factorized_increase.py b/tests/test_factorized_increase.py index a86f5a2db9..6ef3bb465d 100644 --- a/tests/test_factorized_increase.py +++ b/tests/test_factorized_increase.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_factorized_reduce.py b/tests/test_factorized_reduce.py index d14418233e..9ed1e8f6ca 100644 --- a/tests/test_factorized_reduce.py +++ b/tests/test_factorized_reduce.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_fg_bg_to_indices.py b/tests/test_fg_bg_to_indices.py index 03eb770d6d..0d35dd23f8 100644 --- a/tests/test_fg_bg_to_indices.py +++ b/tests/test_fg_bg_to_indices.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_fg_bg_to_indicesd.py b/tests/test_fg_bg_to_indicesd.py index 3be795919f..4691526d94 100644 --- a/tests/test_fg_bg_to_indicesd.py +++ b/tests/test_fg_bg_to_indicesd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_file_basename.py b/tests/test_file_basename.py index dc8b1316a2..cd1a08afb1 100644 --- a/tests/test_file_basename.py +++ b/tests/test_file_basename.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -74,11 +74,6 @@ def test_value(self): expected = os.path.join(output_tmp, "test", "test_post_8") self.assertEqual(result, expected) - def test_relative_path(self): - output = create_file_basename("", "test.txt", "output", "", makedirs=False) - expected = os.path.join("output", "test", "test") - self.assertEqual(output, expected) - if __name__ == "__main__": unittest.main() diff --git a/tests/test_fill_holes.py b/tests/test_fill_holes.py index 9f9dc1fc2e..073982e811 100644 --- a/tests/test_fill_holes.py +++ b/tests/test_fill_holes.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_fill_holesd.py b/tests/test_fill_holesd.py index f7aa9f6108..432c60ba74 100644 --- a/tests/test_fill_holesd.py +++ b/tests/test_fill_holesd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_flip.py b/tests/test_flip.py index 17cf0d2c39..8547f8aeb4 100644 --- a/tests/test_flip.py +++ b/tests/test_flip.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_flipd.py b/tests/test_flipd.py index 900779f4e0..2fa783f8ad 100644 --- a/tests/test_flipd.py +++ b/tests/test_flipd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_focal_loss.py b/tests/test_focal_loss.py index d8a9c8ab5b..bec3a6fb84 100644 --- a/tests/test_focal_loss.py +++ b/tests/test_focal_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_fourier.py b/tests/test_fourier.py index e1b5f3089d..488bf0cbf9 100644 --- a/tests/test_fourier.py +++ b/tests/test_fourier.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_fullyconnectednet.py b/tests/test_fullyconnectednet.py index 6378ec9718..ec91a99c3e 100644 --- a/tests/test_fullyconnectednet.py +++ b/tests/test_fullyconnectednet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gaussian.py b/tests/test_gaussian.py index 461b11d076..b17663652b 100644 --- a/tests/test_gaussian.py +++ b/tests/test_gaussian.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gaussian_filter.py b/tests/test_gaussian_filter.py index 9d76e44cec..62aea524b8 100644 --- a/tests/test_gaussian_filter.py +++ b/tests/test_gaussian_filter.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gaussian_sharpen.py b/tests/test_gaussian_sharpen.py index 547febdfaf..9130e33656 100644 --- a/tests/test_gaussian_sharpen.py +++ b/tests/test_gaussian_sharpen.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gaussian_sharpend.py b/tests/test_gaussian_sharpend.py index d9ef503532..4b84eb9c12 100644 --- a/tests/test_gaussian_sharpend.py +++ b/tests/test_gaussian_sharpend.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gaussian_smooth.py b/tests/test_gaussian_smooth.py index 53f2fc396b..24ecfb88e8 100644 --- a/tests/test_gaussian_smooth.py +++ b/tests/test_gaussian_smooth.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gaussian_smoothd.py b/tests/test_gaussian_smoothd.py index 839bac81fe..ae358dd59a 100644 --- a/tests/test_gaussian_smoothd.py +++ b/tests/test_gaussian_smoothd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_generalized_dice_loss.py b/tests/test_generalized_dice_loss.py index f93878a683..9611bef177 100644 --- a/tests/test_generalized_dice_loss.py +++ b/tests/test_generalized_dice_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_generalized_wasserstein_dice_loss.py b/tests/test_generalized_wasserstein_dice_loss.py index 2c33d365f4..5ad946d20d 100644 --- a/tests/test_generalized_wasserstein_dice_loss.py +++ b/tests/test_generalized_wasserstein_dice_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_generate_label_classes_crop_centers.py b/tests/test_generate_label_classes_crop_centers.py index 4f64aadc26..0e40750276 100644 --- a/tests/test_generate_label_classes_crop_centers.py +++ b/tests/test_generate_label_classes_crop_centers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_generate_param_groups.py b/tests/test_generate_param_groups.py index 0b259442ea..c718f2c729 100644 --- a/tests/test_generate_param_groups.py +++ b/tests/test_generate_param_groups.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_generate_pos_neg_label_crop_centers.py b/tests/test_generate_pos_neg_label_crop_centers.py index e1d9398fe3..b8f2840757 100644 --- a/tests/test_generate_pos_neg_label_crop_centers.py +++ b/tests/test_generate_pos_neg_label_crop_centers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_generate_spatial_bounding_box.py b/tests/test_generate_spatial_bounding_box.py index 00c9d49724..d73b9fafcc 100644 --- a/tests/test_generate_spatial_bounding_box.py +++ b/tests/test_generate_spatial_bounding_box.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_generator.py b/tests/test_generator.py index 617655f86e..b5d846febc 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_get_equivalent_dtype.py b/tests/test_get_equivalent_dtype.py index fc0867523d..de2379b15b 100644 --- a/tests/test_get_equivalent_dtype.py +++ b/tests/test_get_equivalent_dtype.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_get_extreme_points.py b/tests/test_get_extreme_points.py index 457351b98c..269cf63cce 100644 --- a/tests/test_get_extreme_points.py +++ b/tests/test_get_extreme_points.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_get_layers.py b/tests/test_get_layers.py index 6109052d1f..e6ea810a6b 100644 --- a/tests/test_get_layers.py +++ b/tests/test_get_layers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_get_package_version.py b/tests/test_get_package_version.py index c4e15c9d09..beddb340ab 100644 --- a/tests/test_get_package_version.py +++ b/tests/test_get_package_version.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gibbs_noise.py b/tests/test_gibbs_noise.py index 3fbe047944..2c5e117eaf 100644 --- a/tests/test_gibbs_noise.py +++ b/tests/test_gibbs_noise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gibbs_noised.py b/tests/test_gibbs_noised.py index 4905300703..f02052818f 100644 --- a/tests/test_gibbs_noised.py +++ b/tests/test_gibbs_noised.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_global_mutual_information_loss.py b/tests/test_global_mutual_information_loss.py index 1e97122d08..b6defb6aca 100644 --- a/tests/test_global_mutual_information_loss.py +++ b/tests/test_global_mutual_information_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_globalnet.py b/tests/test_globalnet.py index ef0209e397..32bc58f610 100644 --- a/tests/test_globalnet.py +++ b/tests/test_globalnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_gmm.py b/tests/test_gmm.py index f085dd916c..641f6b998b 100644 --- a/tests/test_gmm.py +++ b/tests/test_gmm.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_grid_dataset.py b/tests/test_grid_dataset.py index 9c4bcc52ae..3c5c5bd4fa 100644 --- a/tests/test_grid_dataset.py +++ b/tests/test_grid_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_grid_distortion.py b/tests/test_grid_distortion.py index 5e7ccd7c32..09fcb856f3 100644 --- a/tests/test_grid_distortion.py +++ b/tests/test_grid_distortion.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_grid_distortiond.py b/tests/test_grid_distortiond.py index 662596f935..55e2e6ad1d 100644 --- a/tests/test_grid_distortiond.py +++ b/tests/test_grid_distortiond.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_grid_pull.py b/tests/test_grid_pull.py index b0f19d1a00..25e1d7c1d8 100644 --- a/tests/test_grid_pull.py +++ b/tests/test_grid_pull.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_checkpoint_loader.py b/tests/test_handler_checkpoint_loader.py index ec43ed357b..81a3cdc96d 100644 --- a/tests/test_handler_checkpoint_loader.py +++ b/tests/test_handler_checkpoint_loader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_checkpoint_saver.py b/tests/test_handler_checkpoint_saver.py index 1b746184a4..86544e5321 100644 --- a/tests/test_handler_checkpoint_saver.py +++ b/tests/test_handler_checkpoint_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_classification_saver.py b/tests/test_handler_classification_saver.py index a498fa2b5c..e06c6e95f0 100644 --- a/tests/test_handler_classification_saver.py +++ b/tests/test_handler_classification_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_classification_saver_dist.py b/tests/test_handler_classification_saver_dist.py index e92009d37f..d9bbe67ecd 100644 --- a/tests/test_handler_classification_saver_dist.py +++ b/tests/test_handler_classification_saver_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_confusion_matrix.py b/tests/test_handler_confusion_matrix.py index 5bddef26af..ce02192442 100644 --- a/tests/test_handler_confusion_matrix.py +++ b/tests/test_handler_confusion_matrix.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_confusion_matrix_dist.py b/tests/test_handler_confusion_matrix_dist.py index 325a799098..31e853cd00 100644 --- a/tests/test_handler_confusion_matrix_dist.py +++ b/tests/test_handler_confusion_matrix_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_decollate_batch.py b/tests/test_handler_decollate_batch.py index 1a43ae295b..d2282a971f 100644 --- a/tests/test_handler_decollate_batch.py +++ b/tests/test_handler_decollate_batch.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_early_stop.py b/tests/test_handler_early_stop.py index 36604e5735..4707a8b3cc 100644 --- a/tests/test_handler_early_stop.py +++ b/tests/test_handler_early_stop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_garbage_collector.py b/tests/test_handler_garbage_collector.py index 0350ba62fb..23ecfbbf37 100644 --- a/tests/test_handler_garbage_collector.py +++ b/tests/test_handler_garbage_collector.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_hausdorff_distance.py b/tests/test_handler_hausdorff_distance.py index 7e38f0ad56..038b2e5473 100644 --- a/tests/test_handler_hausdorff_distance.py +++ b/tests/test_handler_hausdorff_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_lr_scheduler.py b/tests/test_handler_lr_scheduler.py index b260686315..82a62dce21 100644 --- a/tests/test_handler_lr_scheduler.py +++ b/tests/test_handler_lr_scheduler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -10,10 +10,7 @@ # limitations under the License. import logging -import os -import re import sys -import tempfile import unittest import numpy as np @@ -27,8 +24,6 @@ class TestHandlerLrSchedule(unittest.TestCase): def test_content(self): logging.basicConfig(stream=sys.stdout, level=logging.INFO) data = [0] * 8 - test_lr = 0.1 - gamma = 0.1 # set up engine def _train_func(engine, batch): @@ -46,45 +41,24 @@ def run_validation(engine): net = torch.nn.PReLU() def _reduce_lr_on_plateau(): - optimizer = torch.optim.SGD(net.parameters(), test_lr) + optimizer = torch.optim.SGD(net.parameters(), 0.1) lr_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=1) handler = LrScheduleHandler(lr_scheduler, step_transform=lambda x: val_engine.state.metrics["val_loss"]) handler.attach(train_engine) - return handler + return lr_scheduler - with tempfile.TemporaryDirectory() as tempdir: - key_to_handler = "test_log_lr" - key_to_print = "Current learning rate" - filename = os.path.join(tempdir, "test_lr.log") - # test with additional logging handler - file_saver = logging.FileHandler(filename, mode="w") - file_saver.setLevel(logging.INFO) - - def _reduce_on_step(): - optimizer = torch.optim.SGD(net.parameters(), test_lr) - lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=2, gamma=gamma) - handler = LrScheduleHandler(lr_scheduler, name=key_to_handler, logger_handler=file_saver) - handler.attach(train_engine) - handler.logger.setLevel(logging.INFO) - return handler - - schedulers = _reduce_lr_on_plateau(), _reduce_on_step() - - train_engine.run(data, max_epochs=5) - file_saver.close() - schedulers[1].logger.removeHandler(file_saver) + def _reduce_on_step(): + optimizer = torch.optim.SGD(net.parameters(), 0.1) + lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=2, gamma=0.1) + handler = LrScheduleHandler(lr_scheduler) + handler.attach(train_engine) + return lr_scheduler - with open(filename) as f: - output_str = f.read() - has_key_word = re.compile(f".*{key_to_print}.*") - content_count = 0 - for line in output_str.split("\n"): - if has_key_word.match(line): - content_count += 1 - self.assertTrue(content_count > 0) + schedulers = _reduce_lr_on_plateau(), _reduce_on_step() + train_engine.run(data, max_epochs=5) for scheduler in schedulers: - np.testing.assert_allclose(scheduler.lr_scheduler._last_lr[0], 0.001) + np.testing.assert_allclose(scheduler._last_lr[0], 0.001) if __name__ == "__main__": diff --git a/tests/test_handler_mean_dice.py b/tests/test_handler_mean_dice.py index f309c7e693..b505502e8d 100644 --- a/tests/test_handler_mean_dice.py +++ b/tests/test_handler_mean_dice.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_metric_logger.py b/tests/test_handler_metric_logger.py index c3de866c5c..5812605cd7 100644 --- a/tests/test_handler_metric_logger.py +++ b/tests/test_handler_metric_logger.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_metrics_saver.py b/tests/test_handler_metrics_saver.py index 1f65eb46dc..17c23be274 100644 --- a/tests/test_handler_metrics_saver.py +++ b/tests/test_handler_metrics_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_metrics_saver_dist.py b/tests/test_handler_metrics_saver_dist.py index 06dcbafa28..0b65b14886 100644 --- a/tests/test_handler_metrics_saver_dist.py +++ b/tests/test_handler_metrics_saver_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_mlflow.py b/tests/test_handler_mlflow.py index 05b99b0053..808ebffe33 100644 --- a/tests/test_handler_mlflow.py +++ b/tests/test_handler_mlflow.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_nvtx.py b/tests/test_handler_nvtx.py index eeca15ea6f..6723e55892 100644 --- a/tests/test_handler_nvtx.py +++ b/tests/test_handler_nvtx.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_parameter_scheduler.py b/tests/test_handler_parameter_scheduler.py index 72742f1956..63d3f7b064 100644 --- a/tests/test_handler_parameter_scheduler.py +++ b/tests/test_handler_parameter_scheduler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_post_processing.py b/tests/test_handler_post_processing.py index 89087e1765..4b47ece063 100644 --- a/tests/test_handler_post_processing.py +++ b/tests/test_handler_post_processing.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_prob_map_producer.py b/tests/test_handler_prob_map_producer.py index b3f79cf587..316cd6f70a 100644 --- a/tests/test_handler_prob_map_producer.py +++ b/tests/test_handler_prob_map_producer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_regression_metrics.py b/tests/test_handler_regression_metrics.py index c6af76a4db..7bb72dd5d5 100644 --- a/tests/test_handler_regression_metrics.py +++ b/tests/test_handler_regression_metrics.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_regression_metrics_dist.py b/tests/test_handler_regression_metrics_dist.py index a8b644d550..c336ccf28c 100644 --- a/tests/test_handler_regression_metrics_dist.py +++ b/tests/test_handler_regression_metrics_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_rocauc.py b/tests/test_handler_rocauc.py index 6e2d6be27e..bd32922777 100644 --- a/tests/test_handler_rocauc.py +++ b/tests/test_handler_rocauc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_rocauc_dist.py b/tests/test_handler_rocauc_dist.py index 5113911d7c..0905816868 100644 --- a/tests/test_handler_rocauc_dist.py +++ b/tests/test_handler_rocauc_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_segmentation_saver.py b/tests/test_handler_segmentation_saver.py index 3632a98cfc..78dea0a68b 100644 --- a/tests/test_handler_segmentation_saver.py +++ b/tests/test_handler_segmentation_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_smartcache.py b/tests/test_handler_smartcache.py index ec96d47e3d..23a6aa7500 100644 --- a/tests/test_handler_smartcache.py +++ b/tests/test_handler_smartcache.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_stats.py b/tests/test_handler_stats.py index ee0df74002..49433195c8 100644 --- a/tests/test_handler_stats.py +++ b/tests/test_handler_stats.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -45,19 +45,18 @@ def _update_metric(engine): # set up testing handler stats_handler = StatsHandler(name=key_to_handler, logger_handler=log_handler) stats_handler.attach(engine) - stats_handler.logger.setLevel(logging.INFO) engine.run(range(3), max_epochs=2) # check logging output output_str = log_stream.getvalue() log_handler.close() + grep = re.compile(f".*{key_to_handler}.*") has_key_word = re.compile(f".*{key_to_print}.*") - content_count = 0 - for line in output_str.split("\n"): - if has_key_word.match(line): - content_count += 1 - self.assertTrue(content_count > 0) + for idx, line in enumerate(output_str.split("\n")): + if grep.match(line): + if idx in [5, 10]: + self.assertTrue(has_key_word.match(line)) def test_loss_print(self): log_stream = StringIO() @@ -75,19 +74,18 @@ def _train_func(engine, batch): # set up testing handler stats_handler = StatsHandler(name=key_to_handler, tag_name=key_to_print, logger_handler=log_handler) stats_handler.attach(engine) - stats_handler.logger.setLevel(logging.INFO) engine.run(range(3), max_epochs=2) # check logging output output_str = log_stream.getvalue() log_handler.close() + grep = re.compile(f".*{key_to_handler}.*") has_key_word = re.compile(f".*{key_to_print}.*") - content_count = 0 - for line in output_str.split("\n"): - if has_key_word.match(line): - content_count += 1 - self.assertTrue(content_count > 0) + for idx, line in enumerate(output_str.split("\n")): + if grep.match(line): + if idx in [1, 2, 3, 6, 7, 8]: + self.assertTrue(has_key_word.match(line)) def test_loss_dict(self): log_stream = StringIO() @@ -104,22 +102,21 @@ def _train_func(engine, batch): # set up testing handler stats_handler = StatsHandler( - name=key_to_handler, output_transform=lambda x: {key_to_print: x[0]}, logger_handler=log_handler + name=key_to_handler, output_transform=lambda x: {key_to_print: x}, logger_handler=log_handler ) stats_handler.attach(engine) - stats_handler.logger.setLevel(logging.INFO) engine.run(range(3), max_epochs=2) # check logging output output_str = log_stream.getvalue() log_handler.close() + grep = re.compile(f".*{key_to_handler}.*") has_key_word = re.compile(f".*{key_to_print}.*") - content_count = 0 - for line in output_str.split("\n"): - if has_key_word.match(line): - content_count += 1 - self.assertTrue(content_count > 0) + for idx, line in enumerate(output_str.split("\n")): + if grep.match(line): + if idx in [1, 2, 3, 6, 7, 8]: + self.assertTrue(has_key_word.match(line)) def test_loss_file(self): key_to_handler = "test_logging" @@ -139,19 +136,18 @@ def _train_func(engine, batch): # set up testing handler stats_handler = StatsHandler(name=key_to_handler, tag_name=key_to_print, logger_handler=handler) stats_handler.attach(engine) - stats_handler.logger.setLevel(logging.INFO) engine.run(range(3), max_epochs=2) handler.close() stats_handler.logger.removeHandler(handler) with open(filename) as f: output_str = f.read() + grep = re.compile(f".*{key_to_handler}.*") has_key_word = re.compile(f".*{key_to_print}.*") - content_count = 0 - for line in output_str.split("\n"): - if has_key_word.match(line): - content_count += 1 - self.assertTrue(content_count > 0) + for idx, line in enumerate(output_str.split("\n")): + if grep.match(line): + if idx in [1, 2, 3, 6, 7, 8]: + self.assertTrue(has_key_word.match(line)) def test_exception(self): # set up engine @@ -194,19 +190,17 @@ def _update_metric(engine): name=key_to_handler, state_attributes=["test1", "test2", "test3"], logger_handler=log_handler ) stats_handler.attach(engine) - stats_handler.logger.setLevel(logging.INFO) engine.run(range(3), max_epochs=2) # check logging output output_str = log_stream.getvalue() log_handler.close() + grep = re.compile(f".*{key_to_handler}.*") has_key_word = re.compile(".*State values.*") - content_count = 0 - for line in output_str.split("\n"): - if has_key_word.match(line): - content_count += 1 - self.assertTrue(content_count > 0) + for idx, line in enumerate(output_str.split("\n")): + if grep.match(line) and idx in [5, 10]: + self.assertTrue(has_key_word.match(line)) if __name__ == "__main__": diff --git a/tests/test_handler_surface_distance.py b/tests/test_handler_surface_distance.py index c990181998..f6ec0286a8 100644 --- a/tests/test_handler_surface_distance.py +++ b/tests/test_handler_surface_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_tb_image.py b/tests/test_handler_tb_image.py index d11bbfec59..b5d963eedf 100644 --- a/tests/test_handler_tb_image.py +++ b/tests/test_handler_tb_image.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_tb_stats.py b/tests/test_handler_tb_stats.py index eae60f9b09..f0c4d49fd0 100644 --- a/tests/test_handler_tb_stats.py +++ b/tests/test_handler_tb_stats.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_handler_validation.py b/tests/test_handler_validation.py index 42ffc8b9eb..06f400109d 100644 --- a/tests/test_handler_validation.py +++ b/tests/test_handler_validation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_hashing.py b/tests/test_hashing.py index 5a1265bd48..ca317a72e8 100644 --- a/tests/test_hashing.py +++ b/tests/test_hashing.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_hausdorff_distance.py b/tests/test_hausdorff_distance.py index 79a2c84b37..182c8cdaca 100644 --- a/tests/test_hausdorff_distance.py +++ b/tests/test_hausdorff_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_header_correct.py b/tests/test_header_correct.py index aa0a4dde08..4a8927fa80 100644 --- a/tests/test_header_correct.py +++ b/tests/test_header_correct.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_highresnet.py b/tests/test_highresnet.py index 76c2203431..61af529b63 100644 --- a/tests/test_highresnet.py +++ b/tests/test_highresnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_hilbert_transform.py b/tests/test_hilbert_transform.py index 10aa83293f..ffe5824034 100644 --- a/tests/test_hilbert_transform.py +++ b/tests/test_hilbert_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_histogram_normalize.py b/tests/test_histogram_normalize.py index 95aa37f26e..06fe7e6956 100644 --- a/tests/test_histogram_normalize.py +++ b/tests/test_histogram_normalize.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_histogram_normalized.py b/tests/test_histogram_normalized.py index 7b86a9685f..e11ee77da5 100644 --- a/tests/test_histogram_normalized.py +++ b/tests/test_histogram_normalized.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_identity.py b/tests/test_identity.py index 60134c24a4..172860668c 100644 --- a/tests/test_identity.py +++ b/tests/test_identity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_identityd.py b/tests/test_identityd.py index 2df74ba2c6..665b7d5d1c 100644 --- a/tests/test_identityd.py +++ b/tests/test_identityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_image_dataset.py b/tests/test_image_dataset.py index c478f28d13..3b3c06c87c 100644 --- a/tests/test_image_dataset.py +++ b/tests/test_image_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_img2tensorboard.py b/tests/test_img2tensorboard.py index 58c4d3cfab..5d76231356 100644 --- a/tests/test_img2tensorboard.py +++ b/tests/test_img2tensorboard.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_init_reader.py b/tests/test_init_reader.py index 03a63cc375..0017c6acee 100644 --- a/tests/test_init_reader.py +++ b/tests/test_init_reader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_classification_2d.py b/tests/test_integration_classification_2d.py index 2c0c9e1f2e..cafad9dcf0 100644 --- a/tests/test_integration_classification_2d.py +++ b/tests/test_integration_classification_2d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_determinism.py b/tests/test_integration_determinism.py index 97e510d03c..6c858b7832 100644 --- a/tests/test_integration_determinism.py +++ b/tests/test_integration_determinism.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_fast_train.py b/tests/test_integration_fast_train.py index 3522a57342..b2706dbb47 100644 --- a/tests/test_integration_fast_train.py +++ b/tests/test_integration_fast_train.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_segmentation_3d.py b/tests/test_integration_segmentation_3d.py index 97e339f5bb..8898bcdbf8 100644 --- a/tests/test_integration_segmentation_3d.py +++ b/tests/test_integration_segmentation_3d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_sliding_window.py b/tests/test_integration_sliding_window.py index af49e3db77..0522bf080e 100644 --- a/tests/test_integration_sliding_window.py +++ b/tests/test_integration_sliding_window.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_stn.py b/tests/test_integration_stn.py index ca067c4d78..ae00892159 100644 --- a/tests/test_integration_stn.py +++ b/tests/test_integration_stn.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_unet_2d.py b/tests/test_integration_unet_2d.py index e60c91968a..88e6d7e795 100644 --- a/tests/test_integration_unet_2d.py +++ b/tests/test_integration_unet_2d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_workflows.py b/tests/test_integration_workflows.py index adb6acfcdd..7018c53240 100644 --- a/tests/test_integration_workflows.py +++ b/tests/test_integration_workflows.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_integration_workflows_gan.py b/tests/test_integration_workflows_gan.py index 790b222ea0..d4b7d99b62 100644 --- a/tests/test_integration_workflows_gan.py +++ b/tests/test_integration_workflows_gan.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_intensity_stats.py b/tests/test_intensity_stats.py index 3479306180..6fe8237f00 100644 --- a/tests/test_intensity_stats.py +++ b/tests/test_intensity_stats.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_intensity_statsd.py b/tests/test_intensity_statsd.py index 97d3de80c0..596c80deb5 100644 --- a/tests/test_intensity_statsd.py +++ b/tests/test_intensity_statsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_inverse.py b/tests/test_inverse.py index 4455009658..992a919065 100644 --- a/tests/test_inverse.py +++ b/tests/test_inverse.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_inverse_collation.py b/tests/test_inverse_collation.py index 3c293070bb..d04360a95d 100644 --- a/tests/test_inverse_collation.py +++ b/tests/test_inverse_collation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_invertd.py b/tests/test_invertd.py index 1dd4e2eecf..c0a949dd9a 100644 --- a/tests/test_invertd.py +++ b/tests/test_invertd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_is_supported_format.py b/tests/test_is_supported_format.py index 71a44bd190..0008712f96 100644 --- a/tests/test_is_supported_format.py +++ b/tests/test_is_supported_format.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_iterable_dataset.py b/tests/test_iterable_dataset.py index 2c47a2181e..74d0f79a3c 100644 --- a/tests/test_iterable_dataset.py +++ b/tests/test_iterable_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_k_space_spike_noise.py b/tests/test_k_space_spike_noise.py index 43717aa214..66763f286f 100644 --- a/tests/test_k_space_spike_noise.py +++ b/tests/test_k_space_spike_noise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_k_space_spike_noised.py b/tests/test_k_space_spike_noised.py index 0230f40b15..3fa6a394f3 100644 --- a/tests/test_k_space_spike_noised.py +++ b/tests/test_k_space_spike_noised.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_keep_largest_connected_component.py b/tests/test_keep_largest_connected_component.py index 5307830cd3..5a7fc80e2e 100644 --- a/tests/test_keep_largest_connected_component.py +++ b/tests/test_keep_largest_connected_component.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_keep_largest_connected_componentd.py b/tests/test_keep_largest_connected_componentd.py index 94a36feed0..097787bd3f 100644 --- a/tests/test_keep_largest_connected_componentd.py +++ b/tests/test_keep_largest_connected_componentd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_label_filter.py b/tests/test_label_filter.py index b782f90441..b004511265 100644 --- a/tests/test_label_filter.py +++ b/tests/test_label_filter.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_label_filterd.py b/tests/test_label_filterd.py index d53dc21faf..19e6f94a0f 100644 --- a/tests/test_label_filterd.py +++ b/tests/test_label_filterd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_label_to_contour.py b/tests/test_label_to_contour.py index fef40af08d..e63b581e27 100644 --- a/tests/test_label_to_contour.py +++ b/tests/test_label_to_contour.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_label_to_contourd.py b/tests/test_label_to_contourd.py index 6481e803ba..922362f1d9 100644 --- a/tests/test_label_to_contourd.py +++ b/tests/test_label_to_contourd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_label_to_mask.py b/tests/test_label_to_mask.py index 8f81a8da1a..6c8f935fbc 100644 --- a/tests/test_label_to_mask.py +++ b/tests/test_label_to_mask.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_label_to_maskd.py b/tests/test_label_to_maskd.py index e67b857502..b2073e8ac3 100644 --- a/tests/test_label_to_maskd.py +++ b/tests/test_label_to_maskd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lambda.py b/tests/test_lambda.py index c187cc979b..738c81130d 100644 --- a/tests/test_lambda.py +++ b/tests/test_lambda.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lambdad.py b/tests/test_lambdad.py index 30d70f40fb..05ba0ff6bc 100644 --- a/tests/test_lambdad.py +++ b/tests/test_lambdad.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lesion_froc.py b/tests/test_lesion_froc.py index 6b4989a9d5..4a67c8d0b3 100644 --- a/tests/test_lesion_froc.py +++ b/tests/test_lesion_froc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_list_data_collate.py b/tests/test_list_data_collate.py index 93b06cc187..eebac69fcf 100644 --- a/tests/test_list_data_collate.py +++ b/tests/test_list_data_collate.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_list_to_dict.py b/tests/test_list_to_dict.py index ec81310c9f..c366e8f3bd 100644 --- a/tests/test_list_to_dict.py +++ b/tests/test_list_to_dict.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lltm.py b/tests/test_lltm.py index 7633c2fe34..4186c91246 100644 --- a/tests/test_lltm.py +++ b/tests/test_lltm.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lmdbdataset.py b/tests/test_lmdbdataset.py index b624e5c4e3..fbdb651297 100644 --- a/tests/test_lmdbdataset.py +++ b/tests/test_lmdbdataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lmdbdataset_dist.py b/tests/test_lmdbdataset_dist.py deleted file mode 100644 index cad2949dde..0000000000 --- a/tests/test_lmdbdataset_dist.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) MONAI Consortium -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import shutil -import tempfile -import unittest - -import numpy as np - -from monai.data import LMDBDataset, json_hashing -from monai.transforms import Transform -from tests.utils import DistCall, DistTestCase, skip_if_windows - - -class _InplaceXform(Transform): - def __call__(self, data): - if data: - data[0] = data[0] + np.pi - else: - data.append(1) - return data - - -@skip_if_windows -class TestMPLMDBDataset(DistTestCase): - def setUp(self): - self.tempdir = tempfile.mkdtemp() - - def tearDown(self): - shutil.rmtree(self.tempdir) - - @DistCall(nnodes=1, nproc_per_node=1) - def test_mp_cache(self): - items = [[list(range(i))] for i in range(5)] - - ds = LMDBDataset(items, transform=_InplaceXform(), cache_dir=self.tempdir, lmdb_kwargs={"map_size": 10 * 1024}) - self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]]) - ds1 = LMDBDataset(items, transform=_InplaceXform(), cache_dir=self.tempdir, lmdb_kwargs={"map_size": 10 * 1024}) - self.assertEqual(list(ds1), list(ds)) - self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]]) - - ds = LMDBDataset( - items, - transform=_InplaceXform(), - cache_dir=self.tempdir, - lmdb_kwargs={"map_size": 10 * 1024}, - hash_func=json_hashing, - ) - self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]]) - ds1 = LMDBDataset( - items, - transform=_InplaceXform(), - cache_dir=self.tempdir, - lmdb_kwargs={"map_size": 10 * 1024}, - hash_func=json_hashing, - ) - self.assertEqual(list(ds1), list(ds)) - self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]]) - - self.assertTrue(isinstance(ds1.info(), dict)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_load_decathlon_datalist.py b/tests/test_load_decathlon_datalist.py index 91d144d84f..d2113fccfa 100644 --- a/tests/test_load_decathlon_datalist.py +++ b/tests/test_load_decathlon_datalist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_load_image.py b/tests/test_load_image.py index 3a4d05f012..849fd9b4e1 100644 --- a/tests/test_load_image.py +++ b/tests/test_load_image.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -90,21 +90,12 @@ def get_data(self, _obj): {"image_only": False, "reader": ITKReader(pixel_type=itk.UC)}, "tests/testing_data/CT_DICOM", (16, 16, 4), - (16, 16, 4), ] TEST_CASE_11 = [ {"image_only": False, "reader": "ITKReader", "pixel_type": itk.UC}, "tests/testing_data/CT_DICOM", (16, 16, 4), - (16, 16, 4), -] - -TEST_CASE_12 = [ - {"image_only": False, "reader": "ITKReader", "pixel_type": itk.UC, "reverse_indexing": True}, - "tests/testing_data/CT_DICOM", - (16, 16, 4), - (4, 16, 16), ] @@ -147,8 +138,8 @@ def test_itk_reader(self, input_param, filenames, expected_shape): np.testing.assert_allclose(header["original_affine"], np_diag) self.assertTupleEqual(result.shape, expected_shape) - @parameterized.expand([TEST_CASE_10, TEST_CASE_11, TEST_CASE_12]) - def test_itk_dicom_series_reader(self, input_param, filenames, expected_shape, expected_np_shape): + @parameterized.expand([TEST_CASE_10, TEST_CASE_11]) + def test_itk_dicom_series_reader(self, input_param, filenames, expected_shape): result, header = LoadImage(**input_param)(filenames) self.assertTrue("affine" in header) self.assertEqual(header["filename_or_obj"], f"{Path(filenames)}") @@ -163,8 +154,8 @@ def test_itk_dicom_series_reader(self, input_param, filenames, expected_shape, e ] ), ) + self.assertTupleEqual(result.shape, expected_shape) self.assertTupleEqual(tuple(header["spatial_shape"]), expected_shape) - self.assertTupleEqual(result.shape, expected_np_shape) def test_itk_reader_multichannel(self): test_image = np.random.randint(0, 256, size=(256, 224, 3)).astype("uint8") @@ -172,14 +163,12 @@ def test_itk_reader_multichannel(self): filename = os.path.join(tempdir, "test_image.png") itk_np_view = itk.image_view_from_array(test_image, is_vector=True) itk.imwrite(itk_np_view, filename) - for flag in (False, True): - result, header = LoadImage(reader=ITKReader(reverse_indexing=flag))(Path(filename)) + result, header = LoadImage(reader=ITKReader())(Path(filename)) - self.assertTupleEqual(tuple(header["spatial_shape"]), (224, 256)) - test_image = test_image.transpose(1, 0, 2) - np.testing.assert_allclose(result[:, :, 0], test_image[:, :, 0]) - np.testing.assert_allclose(result[:, :, 1], test_image[:, :, 1]) - np.testing.assert_allclose(result[:, :, 2], test_image[:, :, 2]) + self.assertTupleEqual(tuple(header["spatial_shape"]), (224, 256)) + np.testing.assert_allclose(result[:, :, 0], test_image[:, :, 0].T) + np.testing.assert_allclose(result[:, :, 1], test_image[:, :, 1].T) + np.testing.assert_allclose(result[:, :, 2], test_image[:, :, 2].T) def test_load_nifti_multichannel(self): test_image = np.random.randint(0, 256, size=(31, 64, 16, 2)).astype(np.float32) @@ -196,8 +185,6 @@ def test_load_nifti_multichannel(self): self.assertTupleEqual(tuple(nib_header["spatial_shape"]), (16, 64, 31)) self.assertTupleEqual(tuple(nib_image.shape), (16, 64, 31, 2)) - np.testing.assert_allclose(itk_img, nib_image, atol=1e-3, rtol=1e-3) - def test_load_png(self): spatial_size = (256, 224) test_image = np.random.randint(0, 256, size=spatial_size) @@ -254,15 +241,6 @@ def test_my_reader(self): out = LoadImage()("test", reader=_MiniReader(is_compatible=False)) self.assertEqual(out[1]["name"], "my test") - def test_itk_meta(self): - """test metadata from a directory""" - out, meta = LoadImage(reader="ITKReader", pixel_type=itk.UC, series_meta=True)("tests/testing_data/CT_DICOM") - idx = "0008|103e" - label = itk.GDCMImageIO.GetLabelFromTag(idx, "")[1] - val = meta[idx] - expected = "Series Description=Routine Brain " - self.assertEqual(f"{label}={val}", expected) - if __name__ == "__main__": unittest.main() diff --git a/tests/test_load_imaged.py b/tests/test_load_imaged.py index 39885a2cae..cfe85c7c9c 100644 --- a/tests/test_load_imaged.py +++ b/tests/test_load_imaged.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_load_spacing_orientation.py b/tests/test_load_spacing_orientation.py index 7690adf284..48aac7ec56 100644 --- a/tests/test_load_spacing_orientation.py +++ b/tests/test_load_spacing_orientation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_loader_semaphore.py b/tests/test_loader_semaphore.py index bbb2d4eef6..85c6d54f35 100644 --- a/tests/test_loader_semaphore.py +++ b/tests/test_loader_semaphore.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_local_normalized_cross_correlation_loss.py b/tests/test_local_normalized_cross_correlation_loss.py index 8070c27f90..31954e727b 100644 --- a/tests/test_local_normalized_cross_correlation_loss.py +++ b/tests/test_local_normalized_cross_correlation_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_localnet.py b/tests/test_localnet.py index 1a288fb447..dc680f15f9 100644 --- a/tests/test_localnet.py +++ b/tests/test_localnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_localnet_block.py b/tests/test_localnet_block.py index d85509344e..f4e857a0fa 100644 --- a/tests/test_localnet_block.py +++ b/tests/test_localnet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_look_up_option.py b/tests/test_look_up_option.py index 89fec1b575..60786f2fc5 100644 --- a/tests/test_look_up_option.py +++ b/tests/test_look_up_option.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lr_finder.py b/tests/test_lr_finder.py index 78c94d4e41..c3a7c83448 100644 --- a/tests/test_lr_finder.py +++ b/tests/test_lr_finder.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_lr_scheduler.py b/tests/test_lr_scheduler.py index a3e1ea9dd6..acafc87131 100644 --- a/tests/test_lr_scheduler.py +++ b/tests/test_lr_scheduler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_map_binary_to_indices.py b/tests/test_map_binary_to_indices.py index bc96231160..2d29aa7c0d 100644 --- a/tests/test_map_binary_to_indices.py +++ b/tests/test_map_binary_to_indices.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_map_classes_to_indices.py b/tests/test_map_classes_to_indices.py index 2f32382f6b..ae75b90c16 100644 --- a/tests/test_map_classes_to_indices.py +++ b/tests/test_map_classes_to_indices.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_map_label_value.py b/tests/test_map_label_value.py index 0416858a74..5705074c06 100644 --- a/tests/test_map_label_value.py +++ b/tests/test_map_label_value.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_map_label_valued.py b/tests/test_map_label_valued.py index cf8ca6c8e2..426ac28836 100644 --- a/tests/test_map_label_valued.py +++ b/tests/test_map_label_valued.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_map_transform.py b/tests/test_map_transform.py index dd77ccb099..803e699a7d 100644 --- a/tests/test_map_transform.py +++ b/tests/test_map_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_mask_intensity.py b/tests/test_mask_intensity.py index b6cfe0e10c..c2f7d661d6 100644 --- a/tests/test_mask_intensity.py +++ b/tests/test_mask_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_mask_intensityd.py b/tests/test_mask_intensityd.py index fe61e7be04..c21e26eba6 100644 --- a/tests/test_mask_intensityd.py +++ b/tests/test_mask_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_masked_dice_loss.py b/tests/test_masked_dice_loss.py index 317da3a316..ce74215023 100644 --- a/tests/test_masked_dice_loss.py +++ b/tests/test_masked_dice_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_masked_inference_wsi_dataset.py b/tests/test_masked_inference_wsi_dataset.py index 6cec5b4304..576b4c85f4 100644 --- a/tests/test_masked_inference_wsi_dataset.py +++ b/tests/test_masked_inference_wsi_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_masked_loss.py b/tests/test_masked_loss.py index 9f28d51aa4..b56fcbbcdb 100644 --- a/tests/test_masked_loss.py +++ b/tests/test_masked_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_matshow3d.py b/tests/test_matshow3d.py index 83984d1556..d720c18806 100644 --- a/tests/test_matshow3d.py +++ b/tests/test_matshow3d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_mean_ensemble.py b/tests/test_mean_ensemble.py index b14f6f01d3..9136f3a963 100644 --- a/tests/test_mean_ensemble.py +++ b/tests/test_mean_ensemble.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_mean_ensembled.py b/tests/test_mean_ensembled.py index b5e1569d65..b3148fce6d 100644 --- a/tests/test_mean_ensembled.py +++ b/tests/test_mean_ensembled.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_mednistdataset.py b/tests/test_mednistdataset.py index 54fb11135a..a833ab75f3 100644 --- a/tests/test_mednistdataset.py +++ b/tests/test_mednistdataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -43,9 +43,7 @@ def _test_dataset(dataset): self.assertTupleEqual(dataset[0]["image"].shape, (1, 64, 64)) try: # will start downloading if testing_dir doesn't have the MedNIST files - data = MedNISTDataset( - root_dir=testing_dir, transform=transform, section="test", download=True, copy_cache=False - ) + data = MedNISTDataset(root_dir=testing_dir, transform=transform, section="test", download=True) except (ContentTooShortError, HTTPError, RuntimeError) as e: print(str(e)) if isinstance(e, RuntimeError): diff --git a/tests/test_milmodel.py b/tests/test_milmodel.py index ad04e96c60..9b21d4e2d1 100644 --- a/tests/test_milmodel.py +++ b/tests/test_milmodel.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_mlp.py b/tests/test_mlp.py index 6fec5b6854..b6e78c9a66 100644 --- a/tests/test_mlp.py +++ b/tests/test_mlp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_mmar_download.py b/tests/test_mmar_download.py index 2cae5969db..7e778fa334 100644 --- a/tests/test_mmar_download.py +++ b/tests/test_mmar_download.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -22,7 +22,7 @@ from monai.apps import RemoteMMARKeys, download_mmar, get_model_spec, load_from_mmar from monai.apps.mmars import MODEL_DESC from monai.apps.mmars.mmars import _get_val -from tests.utils import skip_if_quick +from tests.utils import SkipIfBeforePyTorchVersion, skip_if_quick TEST_CASES = [["clara_pt_prostate_mri_segmentation_1"], ["clara_pt_covid19_ct_lesion_segmentation_1"]] TEST_EXTRACT_CASES = [ @@ -104,6 +104,7 @@ class TestMMMARDownload(unittest.TestCase): @parameterized.expand(TEST_CASES) @skip_if_quick + @SkipIfBeforePyTorchVersion((1, 6)) def test_download(self, idx): try: # test model specification diff --git a/tests/test_module_list.py b/tests/test_module_list.py index 5ec4aa9ff1..3aefaf5e0c 100644 --- a/tests/test_module_list.py +++ b/tests/test_module_list.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_multi_scale.py b/tests/test_multi_scale.py index 963824f25e..01a760db72 100644 --- a/tests/test_multi_scale.py +++ b/tests/test_multi_scale.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_net_adapter.py b/tests/test_net_adapter.py index 0d73499a6d..198de8d142 100644 --- a/tests/test_net_adapter.py +++ b/tests/test_net_adapter.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_network_consistency.py b/tests/test_network_consistency.py index 419e1202d0..ccccd9e7f0 100644 --- a/tests/test_network_consistency.py +++ b/tests/test_network_consistency.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -22,7 +22,7 @@ import monai.networks.nets as nets from monai.utils import set_determinism -extra_test_data_dir = os.environ.get("MONAI_EXTRA_TEST_DATA") +extra_test_data_dir = os.environ.get("MONAI_EXTRA_TEST_DATA", None) TESTS = [] if extra_test_data_dir is not None: @@ -60,8 +60,8 @@ def test_network_consistency(self, net_name, data_path, json_path): json_file.close() # Create model - model = getattr(nets, net_name)(**model_params) - model.load_state_dict(loaded_data["model"], strict=False) + model = nets.__dict__[net_name](**model_params) + model.load_state_dict(loaded_data["model"]) model.eval() in_data = loaded_data["in_data"] diff --git a/tests/test_nifti_endianness.py b/tests/test_nifti_endianness.py index 06b2d803d8..bf0f27b9ca 100644 --- a/tests/test_nifti_endianness.py +++ b/tests/test_nifti_endianness.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_nifti_header_revise.py b/tests/test_nifti_header_revise.py index 7f917cb0e9..8d9a1d4f3a 100644 --- a/tests/test_nifti_header_revise.py +++ b/tests/test_nifti_header_revise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_nifti_rw.py b/tests/test_nifti_rw.py index 1322fa6a45..ff7f11e47f 100644 --- a/tests/test_nifti_rw.py +++ b/tests/test_nifti_rw.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_nifti_saver.py b/tests/test_nifti_saver.py index 6855a59041..3cbb24c69e 100644 --- a/tests/test_nifti_saver.py +++ b/tests/test_nifti_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_normalize_intensity.py b/tests/test_normalize_intensity.py index 5bcee1263b..41c6b053ec 100644 --- a/tests/test_normalize_intensity.py +++ b/tests/test_normalize_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -41,7 +41,7 @@ TESTS.append( [ p, - {"nonzero": False, "channel_wise": True, "subtrahend": [1, 2, 3], "dtype": np.float32}, + {"nonzero": False, "channel_wise": True, "subtrahend": [1, 2, 3]}, p(np.ones((3, 2, 2))), p(np.array([[[0.0, 0.0], [0.0, 0.0]], [[-1.0, -1.0], [-1.0, -1.0]], [[-2.0, -2.0], [-2.0, -2.0]]])), ] @@ -49,7 +49,7 @@ TESTS.append( [ p, - {"nonzero": True, "channel_wise": True, "subtrahend": [1, 2, 3], "divisor": [0, 0, 2], "dtype": "float32"}, + {"nonzero": True, "channel_wise": True, "subtrahend": [1, 2, 3], "divisor": [0, 0, 2]}, p(np.ones((3, 2, 2))), p(np.array([[[0.0, 0.0], [0.0, 0.0]], [[-1.0, -1.0], [-1.0, -1.0]], [[-1.0, -1.0], [-1.0, -1.0]]])), ] @@ -57,7 +57,7 @@ TESTS.append( [ p, - {"nonzero": True, "channel_wise": False, "subtrahend": 2, "divisor": 0, "dtype": torch.float32}, + {"nonzero": True, "channel_wise": False, "subtrahend": 2, "divisor": 0}, p(np.ones((3, 2, 2))), p(np.ones((3, 2, 2)) * -1.0), ] diff --git a/tests/test_normalize_intensityd.py b/tests/test_normalize_intensityd.py index 12a39b1b5b..60b1d05456 100644 --- a/tests/test_normalize_intensityd.py +++ b/tests/test_normalize_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_npzdictitemdataset.py b/tests/test_npzdictitemdataset.py index e24a2cfc1f..2e86ef29d0 100644 --- a/tests/test_npzdictitemdataset.py +++ b/tests/test_npzdictitemdataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_numpy_reader.py b/tests/test_numpy_reader.py index 662d22afde..d84f339e3d 100644 --- a/tests/test_numpy_reader.py +++ b/tests/test_numpy_reader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_nvtx_decorator.py b/tests/test_nvtx_decorator.py index e81c72efcf..0955fbb712 100644 --- a/tests/test_nvtx_decorator.py +++ b/tests/test_nvtx_decorator.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,25 +17,18 @@ from monai.transforms import ( Compose, - CuCIM, Flip, FlipD, RandAdjustContrast, - RandCuCIM, RandFlip, Randomizable, Rotate90, - ToCupy, - TorchVision, ToTensor, ToTensorD, ) from monai.utils import Range, optional_import -from tests.utils import HAS_CUPY _, has_nvtx = optional_import("torch._C._nvtx", descriptor="NVTX is not installed. Are you sure you have a CUDA build?") -_, has_tvt = optional_import("torchvision.transforms") -_, has_cut = optional_import("cucim.core.operations.expose.transform") TEST_CASE_ARRAY_0 = [np.random.randn(3, 3)] @@ -47,12 +40,10 @@ TEST_CASE_TORCH_0 = [torch.randn(3, 3)] TEST_CASE_TORCH_1 = [torch.randn(3, 10, 10)] -TEST_CASE_WRAPPER = [np.random.randn(3, 10, 10)] - -@unittest.skipUnless(has_nvtx, "CUDA is required for NVTX Range!") class TestNVTXRangeDecorator(unittest.TestCase): @parameterized.expand([TEST_CASE_ARRAY_0, TEST_CASE_ARRAY_1]) + @unittest.skipUnless(has_nvtx, "CUDA is required for NVTX Range!") def test_tranform_array(self, input): transforms = Compose([Range("random flip")(Flip()), Range()(ToTensor())]) # Apply transforms @@ -74,10 +65,11 @@ def test_tranform_array(self, input): self.assertIsInstance(output2, torch.Tensor) self.assertIsInstance(output3, torch.Tensor) np.testing.assert_equal(output.numpy(), output1.numpy()) - np.testing.assert_equal(output.numpy(), output2.numpy()) + np.testing.assert_equal(output.numpy(), output1.numpy()) np.testing.assert_equal(output.numpy(), output3.numpy()) @parameterized.expand([TEST_CASE_DICT_0, TEST_CASE_DICT_1]) + @unittest.skipUnless(has_nvtx, "CUDA is required for NVTX Range!") def test_tranform_dict(self, input): transforms = Compose([Range("random flip dict")(FlipD(keys="image")), Range()(ToTensorD("image"))]) # Apply transforms @@ -102,32 +94,8 @@ def test_tranform_dict(self, input): np.testing.assert_equal(output.numpy(), output2.numpy()) np.testing.assert_equal(output.numpy(), output3.numpy()) - @parameterized.expand([TEST_CASE_WRAPPER]) - @unittest.skipUnless(HAS_CUPY, "Requires CuPy.") - @unittest.skipUnless(has_cut, "Requires cuCIM transforms.") - @unittest.skipUnless(has_tvt, "Requires torchvision transforms.") - def test_wrapper_tranforms(self, input): - transform_list = [ - ToTensor(), - TorchVision(name="RandomHorizontalFlip", p=1.0), - ToCupy(), - CuCIM(name="image_flip", spatial_axis=-1), - RandCuCIM(name="rand_image_rotate_90", prob=1.0, max_k=1, spatial_axis=(-2, -1)), - ] - - transforms = Compose(transform_list) - transforms_range = Compose([Range()(t) for t in transform_list]) - - # Apply transforms - output = transforms(input) - - # Apply transforms with Range - output_r = transforms_range(input) - - # Check the outputs - np.testing.assert_equal(output.get(), output_r.get()) - @parameterized.expand([TEST_CASE_ARRAY_1]) + @unittest.skipUnless(has_nvtx, "CUDA is required for NVTX Range!") def test_tranform_randomized(self, input): # Compose deterministic and randomized transforms transforms = Compose( @@ -168,6 +136,7 @@ def test_tranform_randomized(self, input): break @parameterized.expand([TEST_CASE_TORCH_0, TEST_CASE_TORCH_1]) + @unittest.skipUnless(has_nvtx, "CUDA is required for NVTX Range!") def test_network(self, input): # Create a network model = torch.nn.Sequential(torch.nn.ReLU(), torch.nn.Sigmoid()) @@ -195,6 +164,7 @@ def test_network(self, input): np.testing.assert_equal(output.numpy(), output3.numpy()) @parameterized.expand([TEST_CASE_TORCH_0, TEST_CASE_TORCH_1]) + @unittest.skipUnless(has_nvtx, "CUDA is required for NVTX Range!") def test_loss(self, input): # Create a network and loss model = torch.nn.Sigmoid() @@ -224,6 +194,7 @@ def test_loss(self, input): np.testing.assert_equal(output.numpy(), output2.numpy()) np.testing.assert_equal(output.numpy(), output3.numpy()) + @unittest.skipUnless(has_nvtx, "CUDA is required for NVTX Range!") def test_context_manager(self): model = torch.nn.Sigmoid() loss = torch.nn.BCELoss() diff --git a/tests/test_nvtx_transform.py b/tests/test_nvtx_transform.py index 01a069ed8a..36a924dd1c 100644 --- a/tests/test_nvtx_transform.py +++ b/tests/test_nvtx_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_occlusion_sensitivity.py b/tests/test_occlusion_sensitivity.py index ff32f747d4..18da4057ab 100644 --- a/tests/test_occlusion_sensitivity.py +++ b/tests/test_occlusion_sensitivity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_one_of.py b/tests/test_one_of.py index 29d13d7d0c..7537062569 100644 --- a/tests/test_one_of.py +++ b/tests/test_one_of.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -12,18 +12,9 @@ import unittest from copy import deepcopy -import numpy as np from parameterized import parameterized -from monai.transforms import ( - InvertibleTransform, - OneOf, - RandScaleIntensityd, - RandShiftIntensityd, - Resized, - TraceableTransform, - Transform, -) +from monai.transforms import InvertibleTransform, OneOf, TraceableTransform, Transform from monai.transforms.compose import Compose from monai.transforms.transform import MapTransform from monai.utils.enums import TraceKeys @@ -148,52 +139,32 @@ def _match(a, b): _match(p, f) @parameterized.expand(TEST_INVERSES) - def test_inverse(self, transform, invertible): + def test_inverse(self, transform, should_be_ok): data = {k: (i + 1) * 10.0 for i, k in enumerate(KEYS)} fwd_data = transform(data) - - if invertible: - for k in KEYS: - t = fwd_data[TraceableTransform.trace_key(k)][-1] - # make sure the OneOf index was stored - self.assertEqual(t[TraceKeys.CLASS_NAME], OneOf.__name__) - # make sure index exists and is in bounds - self.assertTrue(0 <= t[TraceKeys.EXTRA_INFO]["index"] < len(transform)) + if not should_be_ok: + with self.assertRaises(RuntimeError): + transform.inverse(fwd_data) + return + + for k in KEYS: + t = fwd_data[TraceableTransform.trace_key(k)][-1] + # make sure the OneOf index was stored + self.assertEqual(t[TraceKeys.CLASS_NAME], OneOf.__name__) + # make sure index exists and is in bounds + self.assertTrue(0 <= t[TraceKeys.EXTRA_INFO]["index"] < len(transform)) # call the inverse fwd_inv_data = transform.inverse(fwd_data) - if invertible: - for k in KEYS: - # check transform was removed - self.assertTrue( - len(fwd_inv_data[TraceableTransform.trace_key(k)]) < len(fwd_data[TraceableTransform.trace_key(k)]) - ) - # check data is same as original (and different from forward) - self.assertEqual(fwd_inv_data[k], data[k]) - self.assertNotEqual(fwd_inv_data[k], fwd_data[k]) - else: - # if not invertible, should not change the data - self.assertDictEqual(fwd_data, fwd_inv_data) - - def test_inverse_compose(self): - transform = Compose( - [ - Resized(keys="img", spatial_size=[100, 100, 100]), - OneOf( - [ - RandScaleIntensityd(keys="img", factors=0.5, prob=1.0), - RandShiftIntensityd(keys="img", offsets=0.5, prob=1.0), - ] - ), - ] - ) - transform.set_random_state(seed=0) - result = transform({"img": np.ones((1, 101, 102, 103))}) - - result = transform.inverse(result) - # invert to the original spatial shape - self.assertTupleEqual(result["img"].shape, (1, 101, 102, 103)) + for k in KEYS: + # check transform was removed + self.assertTrue( + len(fwd_inv_data[TraceableTransform.trace_key(k)]) < len(fwd_data[TraceableTransform.trace_key(k)]) + ) + # check data is same as original (and different from forward) + self.assertEqual(fwd_inv_data[k], data[k]) + self.assertNotEqual(fwd_inv_data[k], fwd_data[k]) def test_one_of(self): p = OneOf((A(), B(), C()), (1, 2, 1)) diff --git a/tests/test_optim_novograd.py b/tests/test_optim_novograd.py index 0cf4c35cb6..35f54d67ae 100644 --- a/tests/test_optim_novograd.py +++ b/tests/test_optim_novograd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_optional_import.py b/tests/test_optional_import.py index b87ebf8909..05584f9f9c 100644 --- a/tests/test_optional_import.py +++ b/tests/test_optional_import.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_orientation.py b/tests/test_orientation.py index 685c977f36..aa7f33a469 100644 --- a/tests/test_orientation.py +++ b/tests/test_orientation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_orientationd.py b/tests/test_orientationd.py index 89ecd07b0a..452172ce9b 100644 --- a/tests/test_orientationd.py +++ b/tests/test_orientationd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_p3d_block.py b/tests/test_p3d_block.py index 62b7098dcd..b9237cba01 100644 --- a/tests/test_p3d_block.py +++ b/tests/test_p3d_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_pad_collation.py b/tests/test_pad_collation.py index a070fc760f..eda36f4761 100644 --- a/tests/test_pad_collation.py +++ b/tests/test_pad_collation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_parallel_execution.py b/tests/test_parallel_execution.py index 6186e73f68..c4115d21ef 100644 --- a/tests/test_parallel_execution.py +++ b/tests/test_parallel_execution.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_partition_dataset.py b/tests/test_partition_dataset.py index 687cf8df34..b036cd6827 100644 --- a/tests/test_partition_dataset.py +++ b/tests/test_partition_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_partition_dataset_classes.py b/tests/test_partition_dataset_classes.py index 4ed283bdd7..3aef47107a 100644 --- a/tests/test_partition_dataset_classes.py +++ b/tests/test_partition_dataset_classes.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_patch_dataset.py b/tests/test_patch_dataset.py index 1796ad4f23..40e8bbb20a 100644 --- a/tests/test_patch_dataset.py +++ b/tests/test_patch_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_patch_wsi_dataset.py b/tests/test_patch_wsi_dataset.py index 79165df36d..ca54332ad5 100644 --- a/tests/test_patch_wsi_dataset.py +++ b/tests/test_patch_wsi_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_patchembedding.py b/tests/test_patchembedding.py index 4af2b47ba5..6c9ac78a99 100644 --- a/tests/test_patchembedding.py +++ b/tests/test_patchembedding.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_pathology_he_stain.py b/tests/test_pathology_he_stain.py index 7b884315fc..7f76c3f03e 100644 --- a/tests/test_pathology_he_stain.py +++ b/tests/test_pathology_he_stain.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_pathology_he_stain_dict.py b/tests/test_pathology_he_stain_dict.py index 7d6c3ffb75..2ba2c3f71b 100644 --- a/tests/test_pathology_he_stain_dict.py +++ b/tests/test_pathology_he_stain_dict.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_pathology_prob_nms.py b/tests/test_pathology_prob_nms.py index 3399e33afa..879ca88821 100644 --- a/tests/test_pathology_prob_nms.py +++ b/tests/test_pathology_prob_nms.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_persistentdataset.py b/tests/test_persistentdataset.py index 17575c79f7..9c66d3d10c 100644 --- a/tests/test_persistentdataset.py +++ b/tests/test_persistentdataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_persistentdataset_dist.py b/tests/test_persistentdataset_dist.py index 20dcb2c264..d45bba03e5 100644 --- a/tests/test_persistentdataset_dist.py +++ b/tests/test_persistentdataset_dist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_phl_cpu.py b/tests/test_phl_cpu.py index d479f554b4..3583c4e996 100644 --- a/tests/test_phl_cpu.py +++ b/tests/test_phl_cpu.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_phl_cuda.py b/tests/test_phl_cuda.py index d49a60ecd9..4ba47e4fca 100644 --- a/tests/test_phl_cuda.py +++ b/tests/test_phl_cuda.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_pil_reader.py b/tests/test_pil_reader.py index 0f7792a56c..0a076b581e 100644 --- a/tests/test_pil_reader.py +++ b/tests/test_pil_reader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_plot_2d_or_3d_image.py b/tests/test_plot_2d_or_3d_image.py index 2e4adb93e3..cfcb145503 100644 --- a/tests/test_plot_2d_or_3d_image.py +++ b/tests/test_plot_2d_or_3d_image.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_png_rw.py b/tests/test_png_rw.py index 84251b391f..265b31b83b 100644 --- a/tests/test_png_rw.py +++ b/tests/test_png_rw.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_png_saver.py b/tests/test_png_saver.py index d832718643..e807cf2927 100644 --- a/tests/test_png_saver.py +++ b/tests/test_png_saver.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_polyval.py b/tests/test_polyval.py index db3bcaca53..4ff05bc817 100644 --- a/tests/test_polyval.py +++ b/tests/test_polyval.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_prepare_batch_default.py b/tests/test_prepare_batch_default.py index 8aabb4e9ce..c0d75b1263 100644 --- a/tests/test_prepare_batch_default.py +++ b/tests/test_prepare_batch_default.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_prepare_batch_extra_input.py b/tests/test_prepare_batch_extra_input.py index 79c9a13679..8feb1f9569 100644 --- a/tests/test_prepare_batch_extra_input.py +++ b/tests/test_prepare_batch_extra_input.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_print_info.py b/tests/test_print_info.py index 591316884c..64f0b66949 100644 --- a/tests/test_print_info.py +++ b/tests/test_print_info.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_print_transform_backends.py b/tests/test_print_transform_backends.py index 2db00fea39..4164687f01 100644 --- a/tests/test_print_transform_backends.py +++ b/tests/test_print_transform_backends.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_probnms.py b/tests/test_probnms.py index aab312c1db..1f1afff5db 100644 --- a/tests/test_probnms.py +++ b/tests/test_probnms.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_probnmsd.py b/tests/test_probnmsd.py index bb2315487b..dc6e6f8211 100644 --- a/tests/test_probnmsd.py +++ b/tests/test_probnmsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_pytorch_version_after.py b/tests/test_pytorch_version_after.py index 68abb9571f..6b5ca6fdb0 100644 --- a/tests/test_pytorch_version_after.py +++ b/tests/test_pytorch_version_after.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_query_memory.py b/tests/test_query_memory.py index cdb44d3eb1..22c29598fc 100644 --- a/tests/test_query_memory.py +++ b/tests/test_query_memory.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_adjust_contrast.py b/tests/test_rand_adjust_contrast.py index eaeff70d51..db408dda42 100644 --- a/tests/test_rand_adjust_contrast.py +++ b/tests/test_rand_adjust_contrast.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_adjust_contrastd.py b/tests/test_rand_adjust_contrastd.py index e5f1f6099a..87a3752b26 100644 --- a/tests/test_rand_adjust_contrastd.py +++ b/tests/test_rand_adjust_contrastd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_affine.py b/tests/test_rand_affine.py index 8de408ab84..4cef6b4d44 100644 --- a/tests/test_rand_affine.py +++ b/tests/test_rand_affine.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_affine_grid.py b/tests/test_rand_affine_grid.py index 60ac40f468..ade615cd65 100644 --- a/tests/test_rand_affine_grid.py +++ b/tests/test_rand_affine_grid.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_affined.py b/tests/test_rand_affined.py index 882b5554e6..e59a345d0d 100644 --- a/tests/test_rand_affined.py +++ b/tests/test_rand_affined.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_axis_flip.py b/tests/test_rand_axis_flip.py index b7c504557f..1772ef4987 100644 --- a/tests/test_rand_axis_flip.py +++ b/tests/test_rand_axis_flip.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_axis_flipd.py b/tests/test_rand_axis_flipd.py index ff97d5dc1e..8ccc9b35d7 100644 --- a/tests/test_rand_axis_flipd.py +++ b/tests/test_rand_axis_flipd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_bias_field.py b/tests/test_rand_bias_field.py index b3aa8e9174..ba755337d4 100644 --- a/tests/test_rand_bias_field.py +++ b/tests/test_rand_bias_field.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_bias_fieldd.py b/tests/test_rand_bias_fieldd.py index da08cfe053..b82d435f40 100644 --- a/tests/test_rand_bias_fieldd.py +++ b/tests/test_rand_bias_fieldd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_coarse_dropout.py b/tests/test_rand_coarse_dropout.py index a05d323277..db26ea3c7a 100644 --- a/tests/test_rand_coarse_dropout.py +++ b/tests/test_rand_coarse_dropout.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_coarse_dropoutd.py b/tests/test_rand_coarse_dropoutd.py index e54db130a5..ebb090e378 100644 --- a/tests/test_rand_coarse_dropoutd.py +++ b/tests/test_rand_coarse_dropoutd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_coarse_shuffle.py b/tests/test_rand_coarse_shuffle.py index fb7311e5a3..0262fe2b3a 100644 --- a/tests/test_rand_coarse_shuffle.py +++ b/tests/test_rand_coarse_shuffle.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_coarse_shuffled.py b/tests/test_rand_coarse_shuffled.py index fa9c17286d..ad49c8d02d 100644 --- a/tests/test_rand_coarse_shuffled.py +++ b/tests/test_rand_coarse_shuffled.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_crop_by_label_classes.py b/tests/test_rand_crop_by_label_classes.py index 11d73df74e..c987c3f0fd 100644 --- a/tests/test_rand_crop_by_label_classes.py +++ b/tests/test_rand_crop_by_label_classes.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_crop_by_label_classesd.py b/tests/test_rand_crop_by_label_classesd.py index 92780458e0..e51413a8d0 100644 --- a/tests/test_rand_crop_by_label_classesd.py +++ b/tests/test_rand_crop_by_label_classesd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_crop_by_pos_neg_label.py b/tests/test_rand_crop_by_pos_neg_label.py index f8b8a77a45..42a72ccf2b 100644 --- a/tests/test_rand_crop_by_pos_neg_label.py +++ b/tests/test_rand_crop_by_pos_neg_label.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_crop_by_pos_neg_labeld.py b/tests/test_rand_crop_by_pos_neg_labeld.py index bff5c0e7fd..c200b8acac 100644 --- a/tests/test_rand_crop_by_pos_neg_labeld.py +++ b/tests/test_rand_crop_by_pos_neg_labeld.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_cucim_dict_transform.py b/tests/test_rand_cucim_dict_transform.py index cd41b7f49a..c084331e0e 100644 --- a/tests/test_rand_cucim_dict_transform.py +++ b/tests/test_rand_cucim_dict_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,10 +16,10 @@ from monai.transforms import RandCuCIMd from monai.utils import optional_import, set_determinism -from tests.utils import HAS_CUPY, skip_if_no_cuda +from tests.utils import skip_if_no_cuda _, has_cut = optional_import("cucim.core.operations.expose.transform") -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") set_determinism(seed=0) @@ -74,7 +74,7 @@ @skip_if_no_cuda -@unittest.skipUnless(HAS_CUPY, "CuPy is required.") +@unittest.skipUnless(has_cp, "CuPy is required.") @unittest.skipUnless(has_cut, "cuCIM transforms are required.") class TestRandCuCIMDict(unittest.TestCase): @parameterized.expand( diff --git a/tests/test_rand_cucim_transform.py b/tests/test_rand_cucim_transform.py index 0950329833..907bc35e01 100644 --- a/tests/test_rand_cucim_transform.py +++ b/tests/test_rand_cucim_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,10 +16,10 @@ from monai.transforms import RandCuCIM from monai.utils import optional_import, set_determinism -from tests.utils import HAS_CUPY, skip_if_no_cuda +from tests.utils import skip_if_no_cuda _, has_cut = optional_import("cucim.core.operations.expose.transform") -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") set_determinism(seed=0) @@ -74,7 +74,7 @@ @skip_if_no_cuda -@unittest.skipUnless(HAS_CUPY, "CuPy is required.") +@unittest.skipUnless(has_cp, "CuPy is required.") @unittest.skipUnless(has_cut, "cuCIM transforms are required.") class TestRandCuCIM(unittest.TestCase): @parameterized.expand( diff --git a/tests/test_rand_deform_grid.py b/tests/test_rand_deform_grid.py index 8a2c8bf6eb..4725e28339 100644 --- a/tests/test_rand_deform_grid.py +++ b/tests/test_rand_deform_grid.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_elastic_2d.py b/tests/test_rand_elastic_2d.py index bc23a6c5cb..22920d0f35 100644 --- a/tests/test_rand_elastic_2d.py +++ b/tests/test_rand_elastic_2d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_elastic_3d.py b/tests/test_rand_elastic_3d.py index d4eed3753f..712049ec1a 100644 --- a/tests/test_rand_elastic_3d.py +++ b/tests/test_rand_elastic_3d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_elasticd_2d.py b/tests/test_rand_elasticd_2d.py index ead39e5731..77e6489d50 100644 --- a/tests/test_rand_elasticd_2d.py +++ b/tests/test_rand_elasticd_2d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_elasticd_3d.py b/tests/test_rand_elasticd_3d.py index 84bc765ab0..5f8a5f47ed 100644 --- a/tests/test_rand_elasticd_3d.py +++ b/tests/test_rand_elasticd_3d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_flip.py b/tests/test_rand_flip.py index b9e9a8c4d6..df49d60861 100644 --- a/tests/test_rand_flip.py +++ b/tests/test_rand_flip.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_flipd.py b/tests/test_rand_flipd.py index 9a92661c59..c2869537cb 100644 --- a/tests/test_rand_flipd.py +++ b/tests/test_rand_flipd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gaussian_noise.py b/tests/test_rand_gaussian_noise.py index 1f2adfb9e7..d376add460 100644 --- a/tests/test_rand_gaussian_noise.py +++ b/tests/test_rand_gaussian_noise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gaussian_noised.py b/tests/test_rand_gaussian_noised.py index be1df0f2e6..3e578075ae 100644 --- a/tests/test_rand_gaussian_noised.py +++ b/tests/test_rand_gaussian_noised.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gaussian_sharpen.py b/tests/test_rand_gaussian_sharpen.py index 06563a35b6..4804fc2422 100644 --- a/tests/test_rand_gaussian_sharpen.py +++ b/tests/test_rand_gaussian_sharpen.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gaussian_sharpend.py b/tests/test_rand_gaussian_sharpend.py index ecffa547e0..3508ebaa19 100644 --- a/tests/test_rand_gaussian_sharpend.py +++ b/tests/test_rand_gaussian_sharpend.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gaussian_smooth.py b/tests/test_rand_gaussian_smooth.py index d51618be95..b4d4304b67 100644 --- a/tests/test_rand_gaussian_smooth.py +++ b/tests/test_rand_gaussian_smooth.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gaussian_smoothd.py b/tests/test_rand_gaussian_smoothd.py index e0ef0a8bb5..2c80b978f2 100644 --- a/tests/test_rand_gaussian_smoothd.py +++ b/tests/test_rand_gaussian_smoothd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gibbs_noise.py b/tests/test_rand_gibbs_noise.py index fe928038da..15cadea0e2 100644 --- a/tests/test_rand_gibbs_noise.py +++ b/tests/test_rand_gibbs_noise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_gibbs_noised.py b/tests/test_rand_gibbs_noised.py index 8c5e045b90..ac5fc164e2 100644 --- a/tests/test_rand_gibbs_noised.py +++ b/tests/test_rand_gibbs_noised.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_grid_distortion.py b/tests/test_rand_grid_distortion.py index 80f19df0db..eabe6d34a1 100644 --- a/tests/test_rand_grid_distortion.py +++ b/tests/test_rand_grid_distortion.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_grid_distortiond.py b/tests/test_rand_grid_distortiond.py index 323848dc0b..835f38743c 100644 --- a/tests/test_rand_grid_distortiond.py +++ b/tests/test_rand_grid_distortiond.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_histogram_shift.py b/tests/test_rand_histogram_shift.py index c66f7859c6..e38e2ea5f8 100644 --- a/tests/test_rand_histogram_shift.py +++ b/tests/test_rand_histogram_shift.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_histogram_shiftd.py b/tests/test_rand_histogram_shiftd.py index fe8ddf9ffd..2191e99518 100644 --- a/tests/test_rand_histogram_shiftd.py +++ b/tests/test_rand_histogram_shiftd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_k_space_spike_noise.py b/tests/test_rand_k_space_spike_noise.py index 645e6ae1ce..1c9ca9c1d5 100644 --- a/tests/test_rand_k_space_spike_noise.py +++ b/tests/test_rand_k_space_spike_noise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_k_space_spike_noised.py b/tests/test_rand_k_space_spike_noised.py index 7a6a73b215..9036166b61 100644 --- a/tests/test_rand_k_space_spike_noised.py +++ b/tests/test_rand_k_space_spike_noised.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_lambda.py b/tests/test_rand_lambda.py index 043f44aec4..bf537883cf 100644 --- a/tests/test_rand_lambda.py +++ b/tests/test_rand_lambda.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_lambdad.py b/tests/test_rand_lambdad.py index 854fef8879..0a127839b8 100644 --- a/tests/test_rand_lambdad.py +++ b/tests/test_rand_lambdad.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_rician_noise.py b/tests/test_rand_rician_noise.py index 8e2ea1ee3a..7ec5fc4dc4 100644 --- a/tests/test_rand_rician_noise.py +++ b/tests/test_rand_rician_noise.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_rician_noised.py b/tests/test_rand_rician_noised.py index 05707059bc..bb5ebbe8c8 100644 --- a/tests/test_rand_rician_noised.py +++ b/tests/test_rand_rician_noised.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_rotate.py b/tests/test_rand_rotate.py index b453b01884..4817e81735 100644 --- a/tests/test_rand_rotate.py +++ b/tests/test_rand_rotate.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_rotate90.py b/tests/test_rand_rotate90.py index b845944062..8d4e591559 100644 --- a/tests/test_rand_rotate90.py +++ b/tests/test_rand_rotate90.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_rotate90d.py b/tests/test_rand_rotate90d.py index ded18e430a..3071aa82c8 100644 --- a/tests/test_rand_rotate90d.py +++ b/tests/test_rand_rotate90d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_rotated.py b/tests/test_rand_rotated.py index 23314720c1..fb2038e8c3 100644 --- a/tests/test_rand_rotated.py +++ b/tests/test_rand_rotated.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_scale_crop.py b/tests/test_rand_scale_crop.py index 5d6312002f..a0c5471ffb 100644 --- a/tests/test_rand_scale_crop.py +++ b/tests/test_rand_scale_crop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_scale_cropd.py b/tests/test_rand_scale_cropd.py index 5e833fef98..3dc4578f62 100644 --- a/tests/test_rand_scale_cropd.py +++ b/tests/test_rand_scale_cropd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_scale_intensity.py b/tests/test_rand_scale_intensity.py index 5aa5c7b964..c3d18330ea 100644 --- a/tests/test_rand_scale_intensity.py +++ b/tests/test_rand_scale_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_scale_intensityd.py b/tests/test_rand_scale_intensityd.py index 655bd88ee0..7c2392fded 100644 --- a/tests/test_rand_scale_intensityd.py +++ b/tests/test_rand_scale_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_shift_intensity.py b/tests/test_rand_shift_intensity.py index b4f32a385a..7f5b278fd0 100644 --- a/tests/test_rand_shift_intensity.py +++ b/tests/test_rand_shift_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_shift_intensityd.py b/tests/test_rand_shift_intensityd.py index 10bb5cd71e..5950faac26 100644 --- a/tests/test_rand_shift_intensityd.py +++ b/tests/test_rand_shift_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_spatial_crop.py b/tests/test_rand_spatial_crop.py index 8f4bb0fffa..19b1841c6d 100644 --- a/tests/test_rand_spatial_crop.py +++ b/tests/test_rand_spatial_crop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_spatial_crop_samples.py b/tests/test_rand_spatial_crop_samples.py index 18fdf38773..eefe7d0e0a 100644 --- a/tests/test_rand_spatial_crop_samples.py +++ b/tests/test_rand_spatial_crop_samples.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_spatial_crop_samplesd.py b/tests/test_rand_spatial_crop_samplesd.py index b7ceefe542..a4e8bdb2e6 100644 --- a/tests/test_rand_spatial_crop_samplesd.py +++ b/tests/test_rand_spatial_crop_samplesd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_spatial_cropd.py b/tests/test_rand_spatial_cropd.py index 9e6e86eea2..edcb61dc99 100644 --- a/tests/test_rand_spatial_cropd.py +++ b/tests/test_rand_spatial_cropd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_std_shift_intensity.py b/tests/test_rand_std_shift_intensity.py index fdf386fee4..5b0db09063 100644 --- a/tests/test_rand_std_shift_intensity.py +++ b/tests/test_rand_std_shift_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_std_shift_intensityd.py b/tests/test_rand_std_shift_intensityd.py index e98d1e3ad3..fbc71721d0 100644 --- a/tests/test_rand_std_shift_intensityd.py +++ b/tests/test_rand_std_shift_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_weighted_crop.py b/tests/test_rand_weighted_crop.py index dae7f05016..eb0e4244f7 100644 --- a/tests/test_rand_weighted_crop.py +++ b/tests/test_rand_weighted_crop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_weighted_cropd.py b/tests/test_rand_weighted_cropd.py index 93726f55bb..f53238d17c 100644 --- a/tests/test_rand_weighted_cropd.py +++ b/tests/test_rand_weighted_cropd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_zoom.py b/tests/test_rand_zoom.py index 35472024ef..da630853fe 100644 --- a/tests/test_rand_zoom.py +++ b/tests/test_rand_zoom.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rand_zoomd.py b/tests/test_rand_zoomd.py index a22f2f36f1..89a997e925 100644 --- a/tests/test_rand_zoomd.py +++ b/tests/test_rand_zoomd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_randomizable.py b/tests/test_randomizable.py index 7445287a12..9972bded0f 100644 --- a/tests/test_randomizable.py +++ b/tests/test_randomizable.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_randtorchvisiond.py b/tests/test_randtorchvisiond.py index 2e96d723ee..2dffe67994 100644 --- a/tests/test_randtorchvisiond.py +++ b/tests/test_randtorchvisiond.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_reg_loss_integration.py b/tests/test_reg_loss_integration.py index 822a056879..2949ee1519 100644 --- a/tests/test_reg_loss_integration.py +++ b/tests/test_reg_loss_integration.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -20,7 +20,7 @@ from tests.utils import SkipIfBeforePyTorchVersion TEST_CASES = [ - [BendingEnergyLoss, {}, ["pred"], 3], + [BendingEnergyLoss, {}, ["pred"]], [LocalNormalizedCrossCorrelationLoss, {"kernel_size": 7, "kernel_type": "rectangular"}, ["pred", "target"]], [LocalNormalizedCrossCorrelationLoss, {"kernel_size": 5, "kernel_type": "triangular"}, ["pred", "target"]], [LocalNormalizedCrossCorrelationLoss, {"kernel_size": 3, "kernel_type": "gaussian"}, ["pred", "target"]], @@ -42,7 +42,7 @@ def tearDown(self): @parameterized.expand(TEST_CASES) @SkipIfBeforePyTorchVersion((1, 9)) - def test_convergence(self, loss_type, loss_args, forward_args, pred_channels=1): + def test_convergence(self, loss_type, loss_args, forward_args): """ The goal of this test is to assess if the gradient of the loss function is correct by testing if we can train a one layer neural network @@ -64,7 +64,7 @@ def __init__(self): self.layer = nn.Sequential( nn.Conv3d(in_channels=1, out_channels=1, kernel_size=3, padding=1), nn.ReLU(), - nn.Conv3d(in_channels=1, out_channels=pred_channels, kernel_size=3, padding=1), + nn.Conv3d(in_channels=1, out_channels=1, kernel_size=3, padding=1), ) def forward(self, x): diff --git a/tests/test_regunet.py b/tests/test_regunet.py index e37ca49538..4dd968a1cf 100644 --- a/tests/test_regunet.py +++ b/tests/test_regunet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_regunet_block.py b/tests/test_regunet_block.py index 3be02ea377..9b96875432 100644 --- a/tests/test_regunet_block.py +++ b/tests/test_regunet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_remove_repeated_channel.py b/tests/test_remove_repeated_channel.py index 39b42cc4b0..ebbe6c730c 100644 --- a/tests/test_remove_repeated_channel.py +++ b/tests/test_remove_repeated_channel.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_remove_repeated_channeld.py b/tests/test_remove_repeated_channeld.py index 9db66a6aa0..9d4812791e 100644 --- a/tests/test_remove_repeated_channeld.py +++ b/tests/test_remove_repeated_channeld.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_repeat_channel.py b/tests/test_repeat_channel.py index 3d74b6479c..e246dd1212 100644 --- a/tests/test_repeat_channel.py +++ b/tests/test_repeat_channel.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_repeat_channeld.py b/tests/test_repeat_channeld.py index a348f3eea9..3b73962bb9 100644 --- a/tests/test_repeat_channeld.py +++ b/tests/test_repeat_channeld.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_require_pkg.py b/tests/test_require_pkg.py index dbe63fff3f..ff32a322bb 100644 --- a/tests/test_require_pkg.py +++ b/tests/test_require_pkg.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_resample_datalist.py b/tests/test_resample_datalist.py index fa120b261e..1d92e431cd 100644 --- a/tests/test_resample_datalist.py +++ b/tests/test_resample_datalist.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_resampler.py b/tests/test_resampler.py index 7dfb86a7a9..af23421ecc 100644 --- a/tests/test_resampler.py +++ b/tests/test_resampler.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_resize.py b/tests/test_resize.py index 06246b2358..65d934afe6 100644 --- a/tests/test_resize.py +++ b/tests/test_resize.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_resize_with_pad_or_crop.py b/tests/test_resize_with_pad_or_crop.py index f81e1d4b08..262cd2ffdb 100644 --- a/tests/test_resize_with_pad_or_crop.py +++ b/tests/test_resize_with_pad_or_crop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_resize_with_pad_or_cropd.py b/tests/test_resize_with_pad_or_cropd.py index 28993a2bf4..91201bba53 100644 --- a/tests/test_resize_with_pad_or_cropd.py +++ b/tests/test_resize_with_pad_or_cropd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_resized.py b/tests/test_resized.py index d7374ea930..7d09f13bad 100644 --- a/tests/test_resized.py +++ b/tests/test_resized.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_resnet.py b/tests/test_resnet.py index ffb48125a4..335a5f5869 100644 --- a/tests/test_resnet.py +++ b/tests/test_resnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rotate.py b/tests/test_rotate.py index 42947e7f72..411fed3d1d 100644 --- a/tests/test_rotate.py +++ b/tests/test_rotate.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rotate90.py b/tests/test_rotate90.py index 9865120688..9857b26fe8 100644 --- a/tests/test_rotate90.py +++ b/tests/test_rotate90.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rotate90d.py b/tests/test_rotate90d.py index ef4bad9419..a2a4a27521 100644 --- a/tests/test_rotate90d.py +++ b/tests/test_rotate90d.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_rotated.py b/tests/test_rotated.py index 1b759cfef5..91918513b8 100644 --- a/tests/test_rotated.py +++ b/tests/test_rotated.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_saliency_inferer.py b/tests/test_saliency_inferer.py index c97bcb7811..416b7170ae 100644 --- a/tests/test_saliency_inferer.py +++ b/tests/test_saliency_inferer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_save_classificationd.py b/tests/test_save_classificationd.py index c5a8b4705d..1418bf22ee 100644 --- a/tests/test_save_classificationd.py +++ b/tests/test_save_classificationd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_save_image.py b/tests/test_save_image.py index d3671cf830..be77b12b8e 100644 --- a/tests/test_save_image.py +++ b/tests/test_save_image.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_save_imaged.py b/tests/test_save_imaged.py index d84e582621..f05a83dd9a 100644 --- a/tests/test_save_imaged.py +++ b/tests/test_save_imaged.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_savitzky_golay_filter.py b/tests/test_savitzky_golay_filter.py index b410a641ea..fa38659acb 100644 --- a/tests/test_savitzky_golay_filter.py +++ b/tests/test_savitzky_golay_filter.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_savitzky_golay_smooth.py b/tests/test_savitzky_golay_smooth.py index ac42cf806e..0f398bc48f 100644 --- a/tests/test_savitzky_golay_smooth.py +++ b/tests/test_savitzky_golay_smooth.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -59,9 +59,15 @@ class TestSavitzkyGolaySmooth(unittest.TestCase): - @parameterized.expand( - [TEST_CASE_SINGLE_VALUE, TEST_CASE_2D_AXIS_2, TEST_CASE_SINE_SMOOTH, TEST_CASE_SINGLE_VALUE_REP] - ) + @parameterized.expand([TEST_CASE_SINGLE_VALUE, TEST_CASE_2D_AXIS_2, TEST_CASE_SINE_SMOOTH]) + def test_value(self, arguments, image, expected_data, atol): + for p in TEST_NDARRAYS: + result = SavitzkyGolaySmooth(**arguments)(p(image.astype(np.float32))) + torch.testing.assert_allclose(result, p(expected_data.astype(np.float32)), rtol=1e-4, atol=atol) + + +class TestSavitzkyGolaySmoothREP(unittest.TestCase): + @parameterized.expand([TEST_CASE_SINGLE_VALUE_REP]) def test_value(self, arguments, image, expected_data, atol): for p in TEST_NDARRAYS: result = SavitzkyGolaySmooth(**arguments)(p(image.astype(np.float32))) diff --git a/tests/test_savitzky_golay_smoothd.py b/tests/test_savitzky_golay_smoothd.py deleted file mode 100644 index 6f0b33f533..0000000000 --- a/tests/test_savitzky_golay_smoothd.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) MONAI Consortium -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -import numpy as np -import torch -from parameterized import parameterized - -from monai.transforms import SavitzkyGolaySmoothd -from tests.utils import TEST_NDARRAYS - -# Zero-padding trivial tests - -TEST_CASE_SINGLE_VALUE = [ - {"keys": "img", "window_length": 3, "order": 1}, - np.expand_dims(np.array([1.0]), 0), # Input data: Single value - np.expand_dims(np.array([1 / 3]), 0), # Expected output: With a window length of 3 and polyorder 1 - # output should be equal to mean of 0, 1 and 0 = 1/3 (because input will be zero-padded and a linear fit performed) - 1e-5, # absolute tolerance -] - -TEST_CASE_2D_AXIS_2 = [ - {"keys": "img", "window_length": 3, "order": 1, "axis": 2}, # along axis 2 (second spatial dim) - np.expand_dims(np.ones((2, 3)), 0), - np.expand_dims(np.array([[2 / 3, 1.0, 2 / 3], [2 / 3, 1.0, 2 / 3]]), 0), - 1e-5, # absolute tolerance -] - -# Replicated-padding trivial tests - -TEST_CASE_SINGLE_VALUE_REP = [ - {"keys": "img", "window_length": 3, "order": 1, "mode": "replicate"}, - np.expand_dims(np.array([1.0]), 0), # Input data: Single value - np.expand_dims(np.array([1.0]), 0), # Expected output: With a window length of 3 and polyorder 1 - # output will be equal to mean of [1, 1, 1] = 1 (input will be nearest-neighbour-padded and a linear fit performed) - 1e-5, # absolute tolerance -] - -# Sine smoothing - -TEST_CASE_SINE_SMOOTH = [ - {"keys": "img", "window_length": 3, "order": 1}, - # Sine wave with period equal to savgol window length (windowed to reduce edge effects). - np.expand_dims(np.sin(2 * np.pi * 1 / 3 * np.arange(100)) * np.hanning(100), 0), - # Should be smoothed out to zeros - np.expand_dims(np.zeros(100), 0), - # tolerance chosen by examining output of SciPy.signal.savgol_filter() when provided the above input - 2e-2, # absolute tolerance -] - - -class TestSavitzkyGolaySmoothd(unittest.TestCase): - @parameterized.expand( - [TEST_CASE_SINGLE_VALUE, TEST_CASE_2D_AXIS_2, TEST_CASE_SINE_SMOOTH, TEST_CASE_SINGLE_VALUE_REP] - ) - def test_value(self, arguments, image, expected_data, atol): - for p in TEST_NDARRAYS: - result = SavitzkyGolaySmoothd(**arguments)({"img": p(image.astype(np.float32))})["img"] - torch.testing.assert_allclose(result, p(expected_data.astype(np.float32)), rtol=1e-4, atol=atol) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_scale_intensity.py b/tests/test_scale_intensity.py index b81351ed2e..33f4bc759b 100644 --- a/tests/test_scale_intensity.py +++ b/tests/test_scale_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_scale_intensity_range.py b/tests/test_scale_intensity_range.py index faddf9001b..2384532776 100644 --- a/tests/test_scale_intensity_range.py +++ b/tests/test_scale_intensity_range.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_scale_intensity_range_percentiles.py b/tests/test_scale_intensity_range_percentiles.py index 6ccfaf7ba6..3556c7a8b4 100644 --- a/tests/test_scale_intensity_range_percentiles.py +++ b/tests/test_scale_intensity_range_percentiles.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -19,7 +19,7 @@ class TestScaleIntensityRangePercentiles(NumpyImageTestCase2D): def test_scaling(self): - img = self.imt[0] + img = self.imt lower = 10 upper = 99 b_min = 0 @@ -34,7 +34,7 @@ def test_scaling(self): assert_allclose(result, p(expected), rtol=1e-4) def test_relative_scaling(self): - img = self.imt[0] + img = self.imt lower = 10 upper = 99 b_min = 100 @@ -65,26 +65,6 @@ def test_invalid_instantiation(self): self.assertRaises(ValueError, ScaleIntensityRangePercentiles, lower=30, upper=-20, b_min=0, b_max=255) self.assertRaises(ValueError, ScaleIntensityRangePercentiles, lower=30, upper=900, b_min=0, b_max=255) - def test_channel_wise(self): - img = self.imt[0] - lower = 10 - upper = 99 - b_min = 0 - b_max = 255 - scaler = ScaleIntensityRangePercentiles( - lower=lower, upper=upper, b_min=b_min, b_max=b_max, channel_wise=True, dtype=np.uint8 - ) - expected = [] - for c in img: - a_min = np.percentile(c, lower) - a_max = np.percentile(c, upper) - expected.append(((c - a_min) / (a_max - a_min)) * (b_max - b_min) + b_min) - expected = np.stack(expected).astype(np.uint8) - - for p in TEST_NDARRAYS: - result = scaler(p(img)) - assert_allclose(result, p(expected), rtol=1e-4) - if __name__ == "__main__": unittest.main() diff --git a/tests/test_scale_intensity_range_percentilesd.py b/tests/test_scale_intensity_range_percentilesd.py index cd0a5f8c35..ac2118d99f 100644 --- a/tests/test_scale_intensity_range_percentilesd.py +++ b/tests/test_scale_intensity_range_percentilesd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -27,14 +27,15 @@ def test_scaling(self): a_min = np.percentile(img, lower) a_max = np.percentile(img, upper) - expected = (((img - a_min) / (a_max - a_min)) * (b_max - b_min) + b_min).astype(np.uint8) + expected = (img - a_min) / (a_max - a_min) + expected = (expected * (b_max - b_min)) + b_min for p in TEST_NDARRAYS: data = {"img": p(img)} scaler = ScaleIntensityRangePercentilesd( - keys=data.keys(), lower=lower, upper=upper, b_min=b_min, b_max=b_max, dtype=np.uint8 + keys=data.keys(), lower=lower, upper=upper, b_min=b_min, b_max=b_max ) - assert_allclose(p(expected), scaler(data)["img"], rtol=1e-4) + assert_allclose(p(expected), scaler(data)["img"]) def test_relative_scaling(self): img = self.imt @@ -74,26 +75,6 @@ def test_invalid_instantiation(self): s = ScaleIntensityRangePercentilesd(keys=["img"], lower=30, upper=90, b_min=None, b_max=20, relative=True) s(self.imt) - def test_channel_wise(self): - img = self.imt - lower = 10 - upper = 99 - b_min = 0 - b_max = 255 - scaler = ScaleIntensityRangePercentilesd( - keys="img", lower=lower, upper=upper, b_min=b_min, b_max=b_max, channel_wise=True, dtype=np.uint8 - ) - expected = [] - for c in img: - a_min = np.percentile(c, lower) - a_max = np.percentile(c, upper) - expected.append((((c - a_min) / (a_max - a_min)) * (b_max - b_min) + b_min).astype(np.uint8)) - expected = np.stack(expected) - - for p in TEST_NDARRAYS: - data = {"img": p(img)} - assert_allclose(scaler(data)["img"], p(expected), rtol=1e-4) - if __name__ == "__main__": unittest.main() diff --git a/tests/test_scale_intensity_ranged.py b/tests/test_scale_intensity_ranged.py index ffbd3e44c4..a4b7f17b04 100644 --- a/tests/test_scale_intensity_ranged.py +++ b/tests/test_scale_intensity_ranged.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_scale_intensityd.py b/tests/test_scale_intensityd.py index 42f1527490..93449b15e2 100644 --- a/tests/test_scale_intensityd.py +++ b/tests/test_scale_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_se_block.py b/tests/test_se_block.py index 88983a7746..1f515a7fb4 100644 --- a/tests/test_se_block.py +++ b/tests/test_se_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_se_blocks.py b/tests/test_se_blocks.py index 400ee85e7f..e9aed7d9d9 100644 --- a/tests/test_se_blocks.py +++ b/tests/test_se_blocks.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_seg_loss_integration.py b/tests/test_seg_loss_integration.py index f4a0f25267..98d840afea 100644 --- a/tests/test_seg_loss_integration.py +++ b/tests/test_seg_loss_integration.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_segresnet.py b/tests/test_segresnet.py index b7c37f87b9..da23997c95 100644 --- a/tests/test_segresnet.py +++ b/tests/test_segresnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_segresnet_block.py b/tests/test_segresnet_block.py index 9bb435ac1d..eb8cc9676b 100644 --- a/tests/test_segresnet_block.py +++ b/tests/test_segresnet_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_select_cross_validation_folds.py b/tests/test_select_cross_validation_folds.py index 7693baca80..6dbd004e71 100644 --- a/tests/test_select_cross_validation_folds.py +++ b/tests/test_select_cross_validation_folds.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_select_itemsd.py b/tests/test_select_itemsd.py index ba75a27cff..bf63864eb0 100644 --- a/tests/test_select_itemsd.py +++ b/tests/test_select_itemsd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_selfattention.py b/tests/test_selfattention.py index 407bee341c..559e86487b 100644 --- a/tests/test_selfattention.py +++ b/tests/test_selfattention.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_senet.py b/tests/test_senet.py index be7f571e0b..9aae5e5e54 100644 --- a/tests/test_senet.py +++ b/tests/test_senet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_separable_filter.py b/tests/test_separable_filter.py index 167add9556..0183ab9ef9 100644 --- a/tests/test_separable_filter.py +++ b/tests/test_separable_filter.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_set_determinism.py b/tests/test_set_determinism.py index 7d6c54909d..537aa36676 100644 --- a/tests/test_set_determinism.py +++ b/tests/test_set_determinism.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -40,8 +40,6 @@ def test_values(self): self.assertEqual(seed, get_seed()) a = np.random.randint(seed) b = torch.randint(seed, (1,)) - # tset when global flag support is disabled - torch.backends.disable_global_flags() set_determinism(seed=seed) c = np.random.randint(seed) d = torch.randint(seed, (1,)) diff --git a/tests/test_set_visible_devices.py b/tests/test_set_visible_devices.py index 75cbd6fb0d..b6da879f4b 100644 --- a/tests/test_set_visible_devices.py +++ b/tests/test_set_visible_devices.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_shift_intensity.py b/tests/test_shift_intensity.py index ecded268ab..b73c18b6a5 100644 --- a/tests/test_shift_intensity.py +++ b/tests/test_shift_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_shift_intensityd.py b/tests/test_shift_intensityd.py index a37aaf4a6b..66aad23b1e 100644 --- a/tests/test_shift_intensityd.py +++ b/tests/test_shift_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_simple_aspp.py b/tests/test_simple_aspp.py index 9c952bd791..fbc8cb37d1 100644 --- a/tests/test_simple_aspp.py +++ b/tests/test_simple_aspp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_simulatedelay.py b/tests/test_simulatedelay.py index abf629f5c5..3a4686218e 100644 --- a/tests/test_simulatedelay.py +++ b/tests/test_simulatedelay.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_simulatedelayd.py b/tests/test_simulatedelayd.py index cbabb68e0f..58bd3eb6b8 100644 --- a/tests/test_simulatedelayd.py +++ b/tests/test_simulatedelayd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_skip_connection.py b/tests/test_skip_connection.py index f523891084..462acd9242 100644 --- a/tests/test_skip_connection.py +++ b/tests/test_skip_connection.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_sliding_window_inference.py b/tests/test_sliding_window_inference.py index 3d4ad3151b..c5b941bf3d 100644 --- a/tests/test_sliding_window_inference.py +++ b/tests/test_sliding_window_inference.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_smartcache_patch_wsi_dataset.py b/tests/test_smartcache_patch_wsi_dataset.py index 73583b5eb1..2150ede51c 100644 --- a/tests/test_smartcache_patch_wsi_dataset.py +++ b/tests/test_smartcache_patch_wsi_dataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -45,7 +45,6 @@ "cache_num": 2, "num_init_workers": 1, "num_replace_workers": 1, - "copy_cache": False, }, [ {"image": np.array([[[239]], [[239]], [[239]]], dtype=np.uint8), "label": np.array([[[0]]])}, diff --git a/tests/test_smartcachedataset.py b/tests/test_smartcachedataset.py index e7d51be63a..f390a9127e 100644 --- a/tests/test_smartcachedataset.py +++ b/tests/test_smartcachedataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_smooth_field.py b/tests/test_smooth_field.py index 5849b96167..761cc9e5fa 100644 --- a/tests/test_smooth_field.py +++ b/tests/test_smooth_field.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -10,72 +10,47 @@ # limitations under the License. import unittest -from itertools import product import numpy as np -import torch from parameterized import parameterized -from monai.transforms import RandSmoothDeformd, RandSmoothFieldAdjustContrastd, RandSmoothFieldAdjustIntensityd +from monai.transforms import RandSmoothFieldAdjustContrastd, RandSmoothFieldAdjustIntensityd from tests.utils import TEST_NDARRAYS, assert_allclose, is_tf32_env _rtol = 5e-3 if is_tf32_env() else 1e-4 -INPUT_SHAPES = ((1, 8, 8), (2, 8, 8), (1, 8, 8, 8)) +INPUT_SHAPE1 = (1, 8, 8) +INPUT_SHAPE2 = (2, 8, 8) TESTS_CONTRAST = [] TESTS_INTENSITY = [] -TESTS_DEFORM = [] -KEY = "test" - -for arr_type, shape in product(TEST_NDARRAYS, INPUT_SHAPES): - in_arr = arr_type(np.ones(shape, np.float32)) - exp_arr = arr_type(np.ones(shape, np.float32)) - rand_size = (4,) * (len(shape) - 1) - - device = torch.device("cpu") - - if isinstance(in_arr, torch.Tensor) and in_arr.get_device() >= 0: - device = torch.device(in_arr.get_device()) - - TESTS_CONTRAST.append( +for p in TEST_NDARRAYS: + TESTS_CONTRAST += [ ( - {"keys": (KEY,), "spatial_size": shape[1:], "rand_size": rand_size, "prob": 1.0, "device": device}, - {KEY: in_arr}, - {KEY: exp_arr}, - ) - ) - - TESTS_INTENSITY.append( + {"keys": ("test",), "spatial_size": INPUT_SHAPE1[1:], "rand_size": (4, 4), "prob": 1.0}, + {"test": p(np.ones(INPUT_SHAPE1, np.float32))}, + {"test": p(np.ones(INPUT_SHAPE1, np.float32))}, + ), ( - { - "keys": (KEY,), - "spatial_size": shape[1:], - "rand_size": rand_size, - "prob": 1.0, - "device": device, - "gamma": (0.9, 1), - }, - {KEY: in_arr}, - {KEY: exp_arr}, - ) - ) + {"keys": ("test",), "spatial_size": INPUT_SHAPE2[1:], "rand_size": (4, 4), "prob": 1.0}, + {"test": p(np.ones(INPUT_SHAPE2, np.float32))}, + {"test": p(np.ones(INPUT_SHAPE2, np.float32))}, + ), + ] - TESTS_DEFORM.append( + TESTS_INTENSITY += [ ( - { - "keys": (KEY,), - "spatial_size": shape[1:], - "rand_size": rand_size, - "prob": 1.0, - "device": device, - "def_range": 0.1, - }, - {KEY: in_arr}, - {KEY: exp_arr}, - ) - ) + {"keys": ("test",), "spatial_size": INPUT_SHAPE1[1:], "rand_size": (4, 4), "prob": 1.0, "gamma": (1, 1)}, + {"test": p(np.ones(INPUT_SHAPE1, np.float32))}, + {"test": p(np.ones(INPUT_SHAPE1, np.float32))}, + ), + ( + {"keys": ("test",), "spatial_size": INPUT_SHAPE2[1:], "rand_size": (4, 4), "prob": 1.0, "gamma": (1, 1)}, + {"test": p(np.ones(INPUT_SHAPE2, np.float32))}, + {"test": p(np.ones(INPUT_SHAPE2, np.float32))}, + ), + ] class TestSmoothField(unittest.TestCase): @@ -87,18 +62,7 @@ def test_rand_smooth_field_adjust_contrastd(self, input_param, input_data, expec res = g(input_data) for key, result in res.items(): expected = expected_val[key] - assert_allclose(result, expected, rtol=_rtol, atol=1e-1) - - def test_rand_smooth_field_adjust_contrastd_pad(self): - input_param, input_data, expected_val = TESTS_CONTRAST[0] - - g = RandSmoothFieldAdjustContrastd(pad=1, **input_param) - g.set_random_state(123) - - res = g(input_data) - for key, result in res.items(): - expected = expected_val[key] - assert_allclose(result, expected, rtol=_rtol, atol=1e-1) + assert_allclose(result, expected, rtol=_rtol, atol=5e-3) @parameterized.expand(TESTS_INTENSITY) def test_rand_smooth_field_adjust_intensityd(self, input_param, input_data, expected_val): @@ -108,36 +72,4 @@ def test_rand_smooth_field_adjust_intensityd(self, input_param, input_data, expe res = g(input_data) for key, result in res.items(): expected = expected_val[key] - assert_allclose(result, expected, rtol=_rtol, atol=1e-1) - - def test_rand_smooth_field_adjust_intensityd_pad(self): - input_param, input_data, expected_val = TESTS_INTENSITY[0] - - g = RandSmoothFieldAdjustIntensityd(pad=1, **input_param) - g.set_random_state(123) - - res = g(input_data) - for key, result in res.items(): - expected = expected_val[key] - assert_allclose(result, expected, rtol=_rtol, atol=1e-1) - - @parameterized.expand(TESTS_DEFORM) - def test_rand_smooth_deformd(self, input_param, input_data, expected_val): - g = RandSmoothDeformd(**input_param) - g.set_random_state(123) - - res = g(input_data) - for key, result in res.items(): - expected = expected_val[key] - assert_allclose(result, expected, rtol=_rtol, atol=1e-1) - - def test_rand_smooth_deformd_pad(self): - input_param, input_data, expected_val = TESTS_DEFORM[0] - - g = RandSmoothDeformd(pad=1, **input_param) - g.set_random_state(123) - - res = g(input_data) - for key, result in res.items(): - expected = expected_val[key] - assert_allclose(result, expected, rtol=_rtol, atol=1e-1) + assert_allclose(result, expected, rtol=_rtol, atol=5e-3) diff --git a/tests/test_spacing.py b/tests/test_spacing.py index ebff25712d..cd362bccea 100644 --- a/tests/test_spacing.py +++ b/tests/test_spacing.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_spacingd.py b/tests/test_spacingd.py index 79e759082a..355706f65a 100644 --- a/tests/test_spacingd.py +++ b/tests/test_spacingd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_spatial_crop.py b/tests/test_spatial_crop.py index bf1eb11491..84e65d07fb 100644 --- a/tests/test_spatial_crop.py +++ b/tests/test_spatial_crop.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_spatial_cropd.py b/tests/test_spatial_cropd.py index 5b16f460fd..17743124e0 100644 --- a/tests/test_spatial_cropd.py +++ b/tests/test_spatial_cropd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_spatial_pad.py b/tests/test_spatial_pad.py index 4cdeb6d64e..83a261138e 100644 --- a/tests/test_spatial_pad.py +++ b/tests/test_spatial_pad.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_spatial_padd.py b/tests/test_spatial_padd.py index 762a1145f5..8400bb82cc 100644 --- a/tests/test_spatial_padd.py +++ b/tests/test_spatial_padd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_split_channel.py b/tests/test_split_channel.py index 75216227e4..38315a102c 100644 --- a/tests/test_split_channel.py +++ b/tests/test_split_channel.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_split_channeld.py b/tests/test_split_channeld.py index 7a34855676..344f206c86 100644 --- a/tests/test_split_channeld.py +++ b/tests/test_split_channeld.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_split_on_grid.py b/tests/test_split_on_grid.py index b1d4cd93c5..8017fcccbd 100644 --- a/tests/test_split_on_grid.py +++ b/tests/test_split_on_grid.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_split_on_grid_dict.py b/tests/test_split_on_grid_dict.py index 778a38da34..7b96fc4190 100644 --- a/tests/test_split_on_grid_dict.py +++ b/tests/test_split_on_grid_dict.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_squeezedim.py b/tests/test_squeezedim.py index 8403efe836..15ff7e94d6 100644 --- a/tests/test_squeezedim.py +++ b/tests/test_squeezedim.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_squeezedimd.py b/tests/test_squeezedimd.py index 6baf4696a5..35e7cd5d74 100644 --- a/tests/test_squeezedimd.py +++ b/tests/test_squeezedimd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_state_cacher.py b/tests/test_state_cacher.py index e4164be272..9d7926c0d8 100644 --- a/tests/test_state_cacher.py +++ b/tests/test_state_cacher.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_std_shift_intensity.py b/tests/test_std_shift_intensity.py index 55750161ec..5c16e14c45 100644 --- a/tests/test_std_shift_intensity.py +++ b/tests/test_std_shift_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_std_shift_intensityd.py b/tests/test_std_shift_intensityd.py index 595da5cbc2..4eb256f1e5 100644 --- a/tests/test_std_shift_intensityd.py +++ b/tests/test_std_shift_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_subpixel_upsample.py b/tests/test_subpixel_upsample.py index 0216f164c3..05390d231a 100644 --- a/tests/test_subpixel_upsample.py +++ b/tests/test_subpixel_upsample.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_surface_distance.py b/tests/test_surface_distance.py index 781c71c23a..8f09218f57 100644 --- a/tests/test_surface_distance.py +++ b/tests/test_surface_distance.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_synthetic.py b/tests/test_synthetic.py index fadf6255ff..6b08df8b00 100644 --- a/tests/test_synthetic.py +++ b/tests/test_synthetic.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_testtimeaugmentation.py b/tests/test_testtimeaugmentation.py index cf4772e8bc..09a7f1c2ed 100644 --- a/tests/test_testtimeaugmentation.py +++ b/tests/test_testtimeaugmentation.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_thread_buffer.py b/tests/test_thread_buffer.py index 04511220f8..4efc6ee419 100644 --- a/tests/test_thread_buffer.py +++ b/tests/test_thread_buffer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_threadcontainer.py b/tests/test_threadcontainer.py index 2419b390fd..c33261710a 100644 --- a/tests/test_threadcontainer.py +++ b/tests/test_threadcontainer.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_threshold_intensity.py b/tests/test_threshold_intensity.py index 01321f1b0b..075a650ec0 100644 --- a/tests/test_threshold_intensity.py +++ b/tests/test_threshold_intensity.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_threshold_intensityd.py b/tests/test_threshold_intensityd.py index e0610ebb5b..a2a9fdcf2b 100644 --- a/tests/test_threshold_intensityd.py +++ b/tests/test_threshold_intensityd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_tile_on_grid.py b/tests/test_tile_on_grid.py index 08fb5d96fe..1a3fc8d44d 100644 --- a/tests/test_tile_on_grid.py +++ b/tests/test_tile_on_grid.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_tile_on_grid_dict.py b/tests/test_tile_on_grid_dict.py index 9f1d67ac29..78b7907805 100644 --- a/tests/test_tile_on_grid_dict.py +++ b/tests/test_tile_on_grid_dict.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_timedcall_dist.py b/tests/test_timedcall.py similarity index 95% rename from tests/test_timedcall_dist.py rename to tests/test_timedcall.py index a2b3ae585a..de10abb8f7 100644 --- a/tests/test_timedcall_dist.py +++ b/tests/test_timedcall.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,7 +17,7 @@ from tests.utils import TimedCall -@TimedCall(seconds=20 if sys.platform == "linux" else 60, force_quit=False) +@TimedCall(seconds=10 if sys.platform == "linux" else 60, force_quit=False) def case_1_seconds(arg=None): time.sleep(1) return "good" if not arg else arg diff --git a/tests/test_to_cupy.py b/tests/test_to_cupy.py index 36edf24f3f..4235be0580 100644 --- a/tests/test_to_cupy.py +++ b/tests/test_to_cupy.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,12 +17,12 @@ from monai.transforms import ToCupy from monai.utils import optional_import -from tests.utils import HAS_CUPY, skip_if_no_cuda +from tests.utils import skip_if_no_cuda -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") -@skipUnless(HAS_CUPY, "CuPy is required.") +@skipUnless(has_cp, "CuPy is required.") class TestToCupy(unittest.TestCase): def test_cupy_input(self): test_data = cp.array([[1, 2], [3, 4]], dtype=cp.float32) diff --git a/tests/test_to_cupyd.py b/tests/test_to_cupyd.py index 3e778ae269..58ff1571b0 100644 --- a/tests/test_to_cupyd.py +++ b/tests/test_to_cupyd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,13 +17,13 @@ from monai.transforms import ToCupyd from monai.utils import optional_import -from tests.utils import HAS_CUPY, skip_if_no_cuda +from tests.utils import skip_if_no_cuda -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") -@skipUnless(HAS_CUPY, "CuPy is required.") class TestToCupyd(unittest.TestCase): + @skipUnless(has_cp, "CuPy is required.") def test_cupy_input(self): test_data = cp.array([[1, 2], [3, 4]]) test_data = cp.rot90(test_data) @@ -33,6 +33,7 @@ def test_cupy_input(self): self.assertTrue(result.flags["C_CONTIGUOUS"]) cp.testing.assert_allclose(result, test_data) + @skipUnless(has_cp, "CuPy is required.") def test_numpy_input(self): test_data = np.array([[1, 2], [3, 4]]) test_data = np.rot90(test_data) @@ -42,6 +43,7 @@ def test_numpy_input(self): self.assertTrue(result.flags["C_CONTIGUOUS"]) cp.testing.assert_allclose(result, test_data) + @skipUnless(has_cp, "CuPy is required.") def test_tensor_input(self): test_data = torch.tensor([[1, 2], [3, 4]]) test_data = test_data.rot90() @@ -51,6 +53,7 @@ def test_tensor_input(self): self.assertTrue(result.flags["C_CONTIGUOUS"]) cp.testing.assert_allclose(result, test_data.numpy()) + @skipUnless(has_cp, "CuPy is required.") @skip_if_no_cuda def test_tensor_cuda_input(self): test_data = torch.tensor([[1, 2], [3, 4]]).cuda() @@ -61,6 +64,7 @@ def test_tensor_cuda_input(self): self.assertTrue(result.flags["C_CONTIGUOUS"]) cp.testing.assert_allclose(result, test_data.cpu().numpy()) + @skipUnless(has_cp, "CuPy is required.") def test_list_tuple(self): test_data = [[1, 2], [3, 4]] result = ToCupyd(keys="img", wrap_sequence=True)({"img": test_data})["img"] diff --git a/tests/test_to_device.py b/tests/test_to_device.py index 70f1ea8828..9855a353f0 100644 --- a/tests/test_to_device.py +++ b/tests/test_to_device.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_to_deviced.py b/tests/test_to_deviced.py index 7d075ad365..3b3a7a2e8f 100644 --- a/tests/test_to_deviced.py +++ b/tests/test_to_deviced.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_to_numpy.py b/tests/test_to_numpy.py index e1f135a289..983e29647c 100644 --- a/tests/test_to_numpy.py +++ b/tests/test_to_numpy.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,13 +17,13 @@ from monai.transforms import ToNumpy from monai.utils import optional_import -from tests.utils import HAS_CUPY, assert_allclose, skip_if_no_cuda +from tests.utils import assert_allclose, skip_if_no_cuda -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") class TestToNumpy(unittest.TestCase): - @skipUnless(HAS_CUPY, "CuPy is required.") + @skipUnless(has_cp, "CuPy is required.") def test_cupy_input(self): test_data = cp.array([[1, 2], [3, 4]]) test_data = cp.rot90(test_data) @@ -47,7 +47,7 @@ def test_tensor_input(self): test_data = torch.tensor([[1, 2], [3, 4]]) test_data = test_data.rot90() self.assertFalse(test_data.is_contiguous()) - result = ToNumpy(dtype=torch.uint8)(test_data) + result = ToNumpy()(test_data) self.assertTrue(isinstance(result, np.ndarray)) self.assertTrue(result.flags["C_CONTIGUOUS"]) assert_allclose(result, test_data, type_test=False) @@ -73,7 +73,7 @@ def test_list_tuple(self): def test_single_value(self): for test_data in [5, np.array(5), torch.tensor(5)]: - result = ToNumpy(dtype=np.uint8)(test_data) + result = ToNumpy()(test_data) self.assertTrue(isinstance(result, np.ndarray)) assert_allclose(result, np.asarray(test_data), type_test=False) self.assertEqual(result.ndim, 0) diff --git a/tests/test_to_numpyd.py b/tests/test_to_numpyd.py index ba7cf798ef..0b0b032ef2 100644 --- a/tests/test_to_numpyd.py +++ b/tests/test_to_numpyd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -17,13 +17,13 @@ from monai.transforms import ToNumpyd from monai.utils import optional_import -from tests.utils import HAS_CUPY, assert_allclose, skip_if_no_cuda +from tests.utils import assert_allclose, skip_if_no_cuda -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") class TestToNumpyd(unittest.TestCase): - @skipUnless(HAS_CUPY, "CuPy is required.") + @skipUnless(has_cp, "CuPy is required.") def test_cupy_input(self): test_data = cp.array([[1, 2], [3, 4]]) test_data = cp.rot90(test_data) diff --git a/tests/test_to_onehot.py b/tests/test_to_onehot.py index c08672bfb2..c3e373955d 100644 --- a/tests/test_to_onehot.py +++ b/tests/test_to_onehot.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_to_pil.py b/tests/test_to_pil.py index 0a1351028c..b4581053c0 100644 --- a/tests/test_to_pil.py +++ b/tests/test_to_pil.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_to_pild.py b/tests/test_to_pild.py index d00ecf13d4..3b83fa5258 100644 --- a/tests/test_to_pild.py +++ b/tests/test_to_pild.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_to_tensor.py b/tests/test_to_tensor.py index bfc61cdb19..18129bc5de 100644 --- a/tests/test_to_tensor.py +++ b/tests/test_to_tensor.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -15,9 +15,9 @@ from parameterized import parameterized from monai.transforms import ToTensor -from tests.utils import HAS_CUPY, TEST_NDARRAYS, assert_allclose, optional_import +from tests.utils import TEST_NDARRAYS, assert_allclose, optional_import -cp, _ = optional_import("cupy") +cp, has_cp = optional_import("cupy") im = [[1, 2], [3, 4]] @@ -47,7 +47,7 @@ def test_single_input(self, test_data): assert_allclose(result, test_data, type_test=False) self.assertEqual(result.ndim, 0) - @unittest.skipUnless(HAS_CUPY, "CuPy is required.") + @unittest.skipUnless(has_cp, "CuPy is required.") def test_cupy(self): test_data = [[1, 2], [3, 4]] cupy_array = cp.ascontiguousarray(cp.asarray(test_data)) diff --git a/tests/test_torchscript_utils.py b/tests/test_torchscript_utils.py deleted file mode 100644 index b26d41345a..0000000000 --- a/tests/test_torchscript_utils.py +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright (c) MONAI Consortium -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import tempfile -import unittest - -import torch - -from monai.config import get_config_values -from monai.data import load_net_with_metadata, save_net_with_metadata -from monai.utils import JITMetadataKeys -from monai.utils.module import pytorch_after - - -class TestModule(torch.nn.Module): - def forward(self, x): - return x + 10 - - -class TestTorchscript(unittest.TestCase): - def test_save_net_with_metadata(self): - """Save a network without metadata to a file.""" - m = torch.jit.script(TestModule()) - - with tempfile.TemporaryDirectory() as tempdir: - save_net_with_metadata(m, f"{tempdir}/test") - - self.assertTrue(os.path.isfile(f"{tempdir}/test.pt")) - - def test_save_net_with_metadata_ext(self): - """Save a network without metadata to a file.""" - m = torch.jit.script(TestModule()) - - with tempfile.TemporaryDirectory() as tempdir: - save_net_with_metadata(m, f"{tempdir}/test.zip") - - self.assertTrue(os.path.isfile(f"{tempdir}/test.zip")) - - def test_save_net_with_metadata_with_extra(self): - """Save a network with simple metadata to a file.""" - m = torch.jit.script(TestModule()) - - test_metadata = {"foo": [1, 2], "bar": "string"} - - with tempfile.TemporaryDirectory() as tempdir: - save_net_with_metadata(m, f"{tempdir}/test", meta_values=test_metadata) - - self.assertTrue(os.path.isfile(f"{tempdir}/test.pt")) - - def test_load_net_with_metadata(self): - """Save then load a network with no metadata or other extra files.""" - m = torch.jit.script(TestModule()) - - with tempfile.TemporaryDirectory() as tempdir: - save_net_with_metadata(m, f"{tempdir}/test") - _, meta, extra_files = load_net_with_metadata(f"{tempdir}/test.pt") - - del meta[JITMetadataKeys.TIMESTAMP.value] # no way of knowing precisely what this value would be - - self.assertEqual(meta, get_config_values()) - self.assertEqual(extra_files, {}) - - def test_load_net_with_metadata_with_extra(self): - """Save then load a network with basic metadata.""" - m = torch.jit.script(TestModule()) - - test_metadata = {"foo": [1, 2], "bar": "string"} - - with tempfile.TemporaryDirectory() as tempdir: - save_net_with_metadata(m, f"{tempdir}/test", meta_values=test_metadata) - _, meta, extra_files = load_net_with_metadata(f"{tempdir}/test.pt") - - del meta[JITMetadataKeys.TIMESTAMP.value] # no way of knowing precisely what this value would be - - test_compare = get_config_values() - test_compare.update(test_metadata) - - self.assertEqual(meta, test_compare) - self.assertEqual(extra_files, {}) - - def test_save_load_more_extra_files(self): - """Save then load extra file data from a torchscript file.""" - m = torch.jit.script(TestModule()) - - test_metadata = {"foo": [1, 2], "bar": "string"} - - more_extra_files = {"test.txt": b"This is test data"} - - with tempfile.TemporaryDirectory() as tempdir: - save_net_with_metadata(m, f"{tempdir}/test", meta_values=test_metadata, more_extra_files=more_extra_files) - - self.assertTrue(os.path.isfile(f"{tempdir}/test.pt")) - - _, _, loaded_extra_files = load_net_with_metadata(f"{tempdir}/test.pt", more_extra_files=("test.txt",)) - - if pytorch_after(1, 7): - self.assertEqual(more_extra_files["test.txt"], loaded_extra_files["test.txt"]) - else: - self.assertEqual(more_extra_files["test.txt"].decode(), loaded_extra_files["test.txt"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_torchvision.py b/tests/test_torchvision.py index e0844eb4b9..8973ad523f 100644 --- a/tests/test_torchvision.py +++ b/tests/test_torchvision.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_torchvision_fc_model.py b/tests/test_torchvision_fc_model.py index 98b300eeac..cc603e2585 100644 --- a/tests/test_torchvision_fc_model.py +++ b/tests/test_torchvision_fc_model.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_torchvision_fully_conv_model.py b/tests/test_torchvision_fully_conv_model.py index 34a61ce9fa..444e871c45 100644 --- a/tests/test_torchvision_fully_conv_model.py +++ b/tests/test_torchvision_fully_conv_model.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_torchvisiond.py b/tests/test_torchvisiond.py index 4c62c6e41a..1530691824 100644 --- a/tests/test_torchvisiond.py +++ b/tests/test_torchvisiond.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_traceable_transform.py b/tests/test_traceable_transform.py index bc6aad3a62..b4e9c509f7 100644 --- a/tests/test_traceable_transform.py +++ b/tests/test_traceable_transform.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_train_mode.py b/tests/test_train_mode.py index 231e3854f0..1acb443041 100644 --- a/tests/test_train_mode.py +++ b/tests/test_train_mode.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_transchex.py b/tests/test_transchex.py index 462ce64fd6..e178cb5184 100644 --- a/tests/test_transchex.py +++ b/tests/test_transchex.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_transformerblock.py b/tests/test_transformerblock.py index d6131d010c..616e3e7ec9 100644 --- a/tests/test_transformerblock.py +++ b/tests/test_transformerblock.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_transpose.py b/tests/test_transpose.py index 94a5b49c3a..176fa6f10e 100644 --- a/tests/test_transpose.py +++ b/tests/test_transpose.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_transposed.py b/tests/test_transposed.py index 14e62eb9da..719efea4c3 100644 --- a/tests/test_transposed.py +++ b/tests/test_transposed.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_tversky_loss.py b/tests/test_tversky_loss.py index 2bb2409360..57e887d3f0 100644 --- a/tests/test_tversky_loss.py +++ b/tests/test_tversky_loss.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_unet.py b/tests/test_unet.py index 1ae0094d55..e1dabc4ed0 100644 --- a/tests/test_unet.py +++ b/tests/test_unet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_unetr.py b/tests/test_unetr.py index a8c7b7bf88..d19ed2ca59 100644 --- a/tests/test_unetr.py +++ b/tests/test_unetr.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_unetr_block.py b/tests/test_unetr_block.py index c0f14c829d..7546918a2c 100644 --- a/tests/test_unetr_block.py +++ b/tests/test_unetr_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_upsample_block.py b/tests/test_upsample_block.py index aa4141aabc..02dbaacdc6 100644 --- a/tests/test_upsample_block.py +++ b/tests/test_upsample_block.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_utils_pytorch_numpy_unification.py b/tests/test_utils_pytorch_numpy_unification.py index 4db3056b7b..c3b1bc259b 100644 --- a/tests/test_utils_pytorch_numpy_unification.py +++ b/tests/test_utils_pytorch_numpy_unification.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -16,7 +16,7 @@ from monai.transforms.utils_pytorch_numpy_unification import percentile from monai.utils import set_determinism -from tests.utils import TEST_NDARRAYS, SkipIfBeforePyTorchVersion, assert_allclose +from tests.utils import TEST_NDARRAYS, assert_allclose class TestPytorchNumpyUnification(unittest.TestCase): @@ -42,18 +42,6 @@ def test_fails(self): with self.assertRaises(ValueError): percentile(arr, q) - @SkipIfBeforePyTorchVersion((1, 7)) - def test_dim(self): - q = np.random.randint(0, 100, size=50) - results = [] - for p in TEST_NDARRAYS: - arr = p(np.arange(6).reshape(1, 2, 3).astype(np.float32)) - results.append(percentile(arr, q, dim=1)) - # pre torch 1.7, no `quantile`. Our own method doesn't interpolate, - # so we can only be accurate to 0.5 - atol = 0.5 if not hasattr(torch, "quantile") else 1e-4 - assert_allclose(results[0], results[-1], type_test=False, atol=atol) - if __name__ == "__main__": unittest.main() diff --git a/tests/test_varautoencoder.py b/tests/test_varautoencoder.py index 95fea8afcb..e22a017fc6 100644 --- a/tests/test_varautoencoder.py +++ b/tests/test_varautoencoder.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_version_leq.py b/tests/test_version_leq.py index 86fccca9fb..042a561a90 100644 --- a/tests/test_version_leq.py +++ b/tests/test_version_leq.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vis_cam.py b/tests/test_vis_cam.py index 2137926424..47c116cd5d 100644 --- a/tests/test_vis_cam.py +++ b/tests/test_vis_cam.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vis_gradcam.py b/tests/test_vis_gradcam.py index acca06d405..72385a37a7 100644 --- a/tests/test_vis_gradcam.py +++ b/tests/test_vis_gradcam.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vis_gradcampp.py b/tests/test_vis_gradcampp.py index a261b6055b..5f801dce45 100644 --- a/tests/test_vis_gradcampp.py +++ b/tests/test_vis_gradcampp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vit.py b/tests/test_vit.py index 870e4010ec..cdf0888222 100644 --- a/tests/test_vit.py +++ b/tests/test_vit.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vitautoenc.py b/tests/test_vitautoenc.py index c45cde68c2..9e4af61b0a 100644 --- a/tests/test_vitautoenc.py +++ b/tests/test_vitautoenc.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vnet.py b/tests/test_vnet.py index add0396bd8..4eba5396b2 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vote_ensemble.py b/tests/test_vote_ensemble.py index 79868d4706..08c375d568 100644 --- a/tests/test_vote_ensemble.py +++ b/tests/test_vote_ensemble.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_vote_ensembled.py b/tests/test_vote_ensembled.py index e42a57f3b7..6059f40bee 100644 --- a/tests/test_vote_ensembled.py +++ b/tests/test_vote_ensembled.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_warp.py b/tests/test_warp.py index fde1048bf7..c6c79a369a 100644 --- a/tests/test_warp.py +++ b/tests/test_warp.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_with_allow_missing_keys.py b/tests/test_with_allow_missing_keys.py index 36d5c0c843..68c5ad30c4 100644 --- a/tests/test_with_allow_missing_keys.py +++ b/tests/test_with_allow_missing_keys.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_write_metrics_reports.py b/tests/test_write_metrics_reports.py index 101e1137b6..3c93f20144 100644 --- a/tests/test_write_metrics_reports.py +++ b/tests/test_write_metrics_reports.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_wsireader.py b/tests/test_wsireader.py index 416a0c11a1..61eb2d82ce 100644 --- a/tests/test_wsireader.py +++ b/tests/test_wsireader.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -28,8 +28,6 @@ has_cucim = has_cucim and hasattr(cucim, "CuImage") _, has_osl = optional_import("openslide") imsave, has_tiff = optional_import("tifffile", name="imsave") -_, has_codec = optional_import("imagecodecs") -has_tiff = has_tiff and has_codec FILE_URL = "https://drive.google.com/uc?id=1sGTKZlJBIz53pfqTxoTqiIQzIoEzHLAe" base_name, extension = FILE_URL.split("id=")[1], ".tiff" @@ -71,13 +69,6 @@ np.array([[[[239]], [[239]], [[239]]], [[[243]], [[243]], [[243]]]]), ] -TEST_CASE_5 = [ - FILE_PATH, - {"location": (HEIGHT - 2, WIDTH - 2), "level": 0, "grid_shape": (1, 1)}, - np.array([[[239, 239], [239, 239]], [[239, 239], [239, 239]], [[237, 237], [237, 237]]]), -] - - TEST_CASE_RGB_0 = [np.ones((3, 2, 2), dtype=np.uint8)] # CHW TEST_CASE_RGB_1 = [np.ones((3, 100, 100), dtype=np.uint8)] # CHW @@ -101,7 +92,7 @@ def save_rgba_tiff(array: np.ndarray, filename: str, mode: str): return filename -@skipUnless(has_cucim or has_osl or has_tiff, "Requires cucim, openslide, or tifffile!") +@skipUnless(has_cucim or has_osl, "Requires cucim or openslide!") def setUpModule(): # noqa: N802 download_url(FILE_URL, FILE_PATH, "5a3cfd4fd725c50578ddb80b517b759f") @@ -113,37 +104,27 @@ class Tests(unittest.TestCase): @parameterized.expand([TEST_CASE_0]) def test_read_whole_image(self, file_path, level, expected_shape): reader = WSIReader(self.backend, level=level) - with reader.read(file_path) as img_obj: - img = reader.get_data(img_obj)[0] + img_obj = reader.read(file_path) + img = reader.get_data(img_obj)[0] self.assertTupleEqual(img.shape, expected_shape) - @parameterized.expand([TEST_CASE_1, TEST_CASE_2, TEST_CASE_5]) + @parameterized.expand([TEST_CASE_1, TEST_CASE_2]) def test_read_region(self, file_path, patch_info, expected_img): reader = WSIReader(self.backend) - with reader.read(file_path) as img_obj: - if self.backend == "tifffile": - with self.assertRaises(ValueError): - reader.get_data(img_obj, **patch_info)[0] - else: - # Read twice to check multiple calls - img = reader.get_data(img_obj, **patch_info)[0] - img2 = reader.get_data(img_obj, **patch_info)[0] - self.assertTupleEqual(img.shape, img2.shape) - self.assertIsNone(assert_array_equal(img, img2)) - self.assertTupleEqual(img.shape, expected_img.shape) - self.assertIsNone(assert_array_equal(img, expected_img)) + img_obj = reader.read(file_path) + # Read twice to check multiple calls + img = reader.get_data(img_obj, **patch_info)[0] + img = reader.get_data(img_obj, **patch_info)[0] + self.assertTupleEqual(img.shape, expected_img.shape) + self.assertIsNone(assert_array_equal(img, expected_img)) @parameterized.expand([TEST_CASE_3, TEST_CASE_4]) def test_read_patches(self, file_path, patch_info, expected_img): reader = WSIReader(self.backend) - with reader.read(file_path) as img_obj: - if self.backend == "tifffile": - with self.assertRaises(ValueError): - reader.get_data(img_obj, **patch_info)[0] - else: - img = reader.get_data(img_obj, **patch_info)[0] - self.assertTupleEqual(img.shape, expected_img.shape) - self.assertIsNone(assert_array_equal(img, expected_img)) + img_obj = reader.read(file_path) + img = reader.get_data(img_obj, **patch_info)[0] + self.assertTupleEqual(img.shape, expected_img.shape) + self.assertIsNone(assert_array_equal(img, expected_img)) @parameterized.expand([TEST_CASE_RGB_0, TEST_CASE_RGB_1]) @skipUnless(has_tiff, "Requires tifffile.") @@ -159,8 +140,8 @@ def test_read_rgba(self, img_expected): os.path.join(os.path.dirname(__file__), "testing_data", f"temp_tiff_image_{mode}.tiff"), mode=mode, ) - with reader.read(file_path) as img_obj: - image[mode], _ = reader.get_data(img_obj) + img_obj = reader.read(file_path) + image[mode], _ = reader.get_data(img_obj) self.assertIsNone(assert_array_equal(image["RGB"], img_expected)) self.assertIsNone(assert_array_equal(image["RGBA"], img_expected)) @@ -168,10 +149,7 @@ def test_read_rgba(self, img_expected): @parameterized.expand([TEST_CASE_TRANSFORM_0]) def test_with_dataloader(self, file_path, level, expected_spatial_shape, expected_shape): train_transform = Compose( - [ - LoadImaged(keys=["image"], reader=WSIReader, backend=self.backend, level=level), - ToTensord(keys=["image"]), - ] + [LoadImaged(keys=["image"], reader=WSIReader, backend="cuCIM", level=level), ToTensord(keys=["image"])] ) dataset = Dataset([{"image": file_path}], transform=train_transform) data_loader = DataLoader(dataset) diff --git a/tests/test_zipdataset.py b/tests/test_zipdataset.py index f381e0a453..710ca71fc2 100644 --- a/tests/test_zipdataset.py +++ b/tests/test_zipdataset.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_zoom.py b/tests/test_zoom.py index 1a7694072e..9411988a7e 100644 --- a/tests/test_zoom.py +++ b/tests/test_zoom.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_zoom_affine.py b/tests/test_zoom_affine.py index 3c4bcd302c..49c3c0dcac 100644 --- a/tests/test_zoom_affine.py +++ b/tests/test_zoom_affine.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/test_zoomd.py b/tests/test_zoomd.py index 87a5cec22b..6231978ca7 100644 --- a/tests/test_zoomd.py +++ b/tests/test_zoomd.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/testing_data/cpp_resample_answers.py b/tests/testing_data/cpp_resample_answers.py index 93f596619e..67af152059 100644 --- a/tests/testing_data/cpp_resample_answers.py +++ b/tests/testing_data/cpp_resample_answers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/testing_data/integration_answers.py b/tests/testing_data/integration_answers.py index 99765a2b33..c5d99bf1ed 100644 --- a/tests/testing_data/integration_answers.py +++ b/tests/testing_data/integration_answers.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/tests/utils.py b/tests/utils.py index 7e36b289e6..7ed4ba1745 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) MONAI Consortium +# Copyright 2020 - 2021 MONAI Consortium # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -97,10 +97,6 @@ def test_pretrained_networks(network, input_param, device): return network(**input_param).to(device) except (URLError, HTTPError) as e: raise unittest.SkipTest(e) from e - except RuntimeError as r_error: - if "unexpected EOF" in f"{r_error}": # The file might be corrupted. - raise unittest.SkipTest(f"{r_error}") from r_error - raise def test_is_quick(): @@ -218,27 +214,6 @@ def __call__(self, obj): )(obj) -def has_cupy(): - """ - Returns True if the user has installed a version of cupy. - """ - cp, has_cp = optional_import("cupy") - if not has_cp: - return False - try: # test cupy installation with a basic example - x = cp.arange(6, dtype="f").reshape(2, 3) - y = cp.arange(3, dtype="f") - kernel = cp.ElementwiseKernel( - "float32 x, float32 y", "float32 z", """ if (x - 2 > y) { z = x * y; } else { z = x + y; } """, "my_kernel" - ) - return kernel(x, y)[0, 0] == 0 - except Exception: - return False - - -HAS_CUPY = has_cupy() - - def make_nifti_image(array: NdarrayOrTensor, affine=None): """ Create a temporary nifti image on the disk and return the image name. @@ -375,7 +350,8 @@ def run_process(self, func, local_rank, args, kwargs, results): os.environ["RANK"] = str(self.nproc_per_node * self.node_rank + local_rank) if torch.cuda.is_available(): - torch.cuda.set_device(int(local_rank)) # using device ids from CUDA_VISIBILE_DEVICES + os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" + torch.cuda.set_device(int(local_rank)) dist.init_process_group( backend=self.backend, @@ -430,7 +406,6 @@ def _wrapper(*args, **kwargs): for p in processes: p.join() assert results.get(), "Distributed call failed." - _del_original_func(obj) return _wrapper @@ -512,7 +487,6 @@ def _wrapper(*args, **kwargs): finally: p.join() - _del_original_func(obj) res = None try: res = results.get(block=False) @@ -538,15 +512,6 @@ def _cache_original_func(obj) -> None: _original_funcs[obj.__name__] = obj -def _del_original_func(obj): - """pop the original function from cache.""" - global _original_funcs - _original_funcs.pop(obj.__name__, None) - if torch.cuda.is_available(): # clean up the cached function - torch.cuda.synchronize() - torch.cuda.empty_cache() - - def _call_original_func(name, module, *args, **kwargs): if name not in _original_funcs: _original_module = importlib.import_module(module) # reimport, refresh _original_funcs @@ -635,7 +600,7 @@ def test_script_save(net, *inputs, device=None, rtol=1e-4, atol=0.0): def query_memory(n=2): """ - Find best n idle devices and return a string of device ids using the `nvidia-smi` command. + Find best n idle devices and return a string of device ids. """ bash_string = "nvidia-smi --query-gpu=power.draw,temperature.gpu,memory.used --format=csv,noheader,nounits"