Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature added: Get WSI at mpp #7574

Open
wants to merge 31 commits into
base: dev
Choose a base branch
from

Conversation

NikolasSchmitz
Copy link

@NikolasSchmitz NikolasSchmitz commented Mar 25, 2024

Fixes: #4980

Description

In this pull request, the feature to retrieve a whole slide image at a given mpp (microns per pixel) resolution was implemented for every WSIReader class in the function get_wsi_at_mpp.

While the implementations in the OpenslideWSIReader and CuCIMWSIReader classes were tested thoroughly, I could not find a suitable TIFF file for testing with the TiffFileWSIReader class.

For resizing, I have used PIL.Image.resize for Openslide and TiffFile, and cucim.sklearn.transform.resize for CuCIM. Originally, I used cv2.resize, but since the package isn't listed in requirements-dev.txt, I explored alternative solutions."

Types of changes

  • Non-breaking change (fix or new feature that would not break existing functionality).
  • 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.
  • In-line docstrings updated.
  • Documentation updated, tested make html command in the docs/ folder.

Please let me know what you think and how I can improve this feature.

Best
Niko

(Last PR was closed, because I changed the branch name to include the ticket id)

cxlcl and others added 6 commits March 27, 2024 01:47
…roject-MONAI#7308)

### Description

Based on the discussion topic
[here](Project-MONAI#7161 (comment)),
we implemented the Conjugate-Gradient algorithm for linear operator
inversion, and Stein's Unbiased Risk Estimator (SURE) [1] loss for
ground-truth-date free diffusion process guidance that is proposed in
[2] and illustrated in the algorithm below:

<img width="650" alt="Screenshot 2023-12-10 at 10 19 25 PM"
src="https://github.com/Project-MONAI/MONAI/assets/8581162/97069466-cbaf-44e0-b7a7-ae9deb8fd7f2">

The Conjugate-Gradient (CG) algorithm is used to solve for the inversion
of the linear operator in Line-4 in the algorithm above, where the
linear operator is too large to store explicitly as a matrix (such as
FFT/IFFT of an image) and invert directly. Instead, we can solve for the
linear inversion iteratively as in CG.

The SURE loss is applied for Line-6 above. This is a differentiable loss
function that can be used to train/giude an operator (e.g. neural
network), where the pseudo ground truth is available but the reference
ground truth is not. For example, in the MRI reconstruction, the pseudo
ground truth is the zero-filled reconstruction and the reference ground
truth is the fully sampled reconstruction. The reference ground truth is
not available due to the lack of fully sampled.

**Reference**
[1] Stein, C.M.: Estimation of the mean of a multivariate normal
distribution. Annals of Statistics 1981 [[paper
link](https://projecteuclid.org/journals/annals-of-statistics/volume-9/issue-6/Estimation-of-the-Mean-of-a-Multivariate-Normal-Distribution/10.1214/aos/1176345632.full)]
[2] B. Ozturkler et al. SMRD: SURE-based Robust MRI Reconstruction with
Diffusion Models. MICCAI 2023
[[paper link](https://arxiv.org/pdf/2310.01799.pdf)]

### Types of changes
<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [x] New tests added to cover the changes.
- [x] Integration tests passed locally by running `./runtests.sh -f -u
--net --coverage`.
- [x] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [x] In-line docstrings updated.
- [x] Documentation updated, tested `make html` command in the `docs/`
folder.

---------

Signed-off-by: chaoliu <chaoliu@nvidia.com>
Signed-off-by: cxlcl <chaoliucxl@gmail.com>
Signed-off-by: chaoliu <chaoliucxl@gmail.com>
Signed-off-by: YunLiu <55491388+KumoLiu@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: YunLiu <55491388+KumoLiu@users.noreply.github.com>
Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Nikolas Schmitz <nikolas.schmitz@rwth-aachen.de>
Signed-off-by: Nikolas Schmitz <nikolas.schmitz@rwth-aachen.de>
for more information, see https://pre-commit.ci

Signed-off-by: Nikolas Schmitz <nikolas.schmitz@rwth-aachen.de>
Signed-off-by: Nikolas Schmitz <nikolas.schmitz@rwth-aachen.de>
Signed-off-by: monai-bot <monai.miccai2019@gmail.com>

Signed-off-by: monai-bot <monai.miccai2019@gmail.com>
Signed-off-by: Nikolas Schmitz <nikolas.schmitz@rwth-aachen.de>
Signed-off-by: Nikolas Schmitz <nikolas.schmitz@rwth-aachen.de>
NikolasSchmitz and others added 3 commits March 27, 2024 02:04
Signed-off-by: Nikolas Schmitz <nikolas.schmitz@rwth-aachen.de>
…ject-MONAI#7569)

Fixes Project-MONAI#7451

### Description
Reduces the length of error messages and error messages being propagated
twice. This helps debug better when long `ConfigComponent`s are being
instantiated. Refer to issue Project-MONAI#7451 for more details

### Types of changes
<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] 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`.
- [x] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [ ] In-line docstrings updated.
- [ ] Documentation updated, tested `make html` command in the `docs/`
folder.

Signed-off-by: Suraj Pai <b.pai@maastrichtuniversity.nl>
Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Fixes Project-MONAI#2872 

### Description

Implementation of mixup, cutmix and cutout as described in the original
papers.
Current implementation support both, the dictionary-based batches and
tuples of tensors.

### Types of changes
<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [x] New tests added to cover the changes.
- [ ] Integration tests passed locally by running `./runtests.sh -f -u
--net --coverage`.
- [x] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [x] In-line docstrings updated.
- [x] Documentation updated, tested `make html` command in the `docs/`
folder.

---------

Signed-off-by: Juan Pablo de la Cruz Gutiérrez <juampatronics@gmail.com>
Signed-off-by: monai-bot <monai.miccai2019@gmail.com>
Signed-off-by: elitap <elias.tappeiner@gmx.at>
Signed-off-by: Felix Schnabel <f.schnabel@tum.de>
Signed-off-by: YanxuanLiu <yanxuanl@nvidia.com>
Signed-off-by: ytl0623 <david89062388@gmail.com>
Signed-off-by: Dženan Zukić <dzenan.zukic@kitware.com>
Signed-off-by: KumoLiu <yunl@nvidia.com>
Signed-off-by: YunLiu <55491388+KumoLiu@users.noreply.github.com>
Signed-off-by: Ishan Dutta <ishandutta0098@gmail.com>
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: kaibo <ktang@unc.edu>
Signed-off-by: heyufan1995 <heyufan1995@gmail.com>
Signed-off-by: binliu <binliu@nvidia.com>
Signed-off-by: axel.vlaminck <axel.vlaminck@gmail.com>
Signed-off-by: Ibrahim Hadzic <ibrahimhadzic45@gmail.com>
Signed-off-by: Behrooz <3968947+drbeh@users.noreply.github.com>
Signed-off-by: Timothy Baker <bakertim@umich.edu>
Signed-off-by: Mathijs de Boer <m.deboer-41@umcutrecht.nl>
Signed-off-by: Fabian Klopfer <fabian.klopfer@ieee.org>
Signed-off-by: Lucas Robinet <robinet.lucas@iuct-oncopole.fr>
Signed-off-by: Lucas Robinet <67736918+Lucas-rbnt@users.noreply.github.com>
Signed-off-by: chaoliu <chaoliu@nvidia.com>
Signed-off-by: cxlcl <chaoliucxl@gmail.com>
Signed-off-by: chaoliu <chaoliucxl@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: monai-bot <64792179+monai-bot@users.noreply.github.com>
Co-authored-by: elitap <elitap@users.noreply.github.com>
Co-authored-by: Felix Schnabel <f.schnabel@tum.de>
Co-authored-by: YanxuanLiu <104543031+YanxuanLiu@users.noreply.github.com>
Co-authored-by: ytl0623 <david89062388@gmail.com>
Co-authored-by: Dženan Zukić <dzenan.zukic@kitware.com>
Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Co-authored-by: YunLiu <55491388+KumoLiu@users.noreply.github.com>
Co-authored-by: Ishan Dutta <ishandutta0098@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Kaibo Tang <ktang@unc.edu>
Co-authored-by: Yufan He <59374597+heyufan1995@users.noreply.github.com>
Co-authored-by: binliunls <107988372+binliunls@users.noreply.github.com>
Co-authored-by: Ben Murray <ben.murray@gmail.com>
Co-authored-by: axel.vlaminck <axel.vlaminck@gmail.com>
Co-authored-by: Mingxin Zheng <18563433+mingxin-zheng@users.noreply.github.com>
Co-authored-by: Ibrahim Hadzic <ibrahimhadzic45@gmail.com>
Co-authored-by: Dr. Behrooz Hashemian <3968947+drbeh@users.noreply.github.com>
Co-authored-by: Timothy J. Baker <62781117+tim-the-baker@users.noreply.github.com>
Co-authored-by: Mathijs de Boer <8137653+MathijsdeBoer@users.noreply.github.com>
Co-authored-by: Mathijs de Boer <m.deboer-41@umcutrecht.nl>
Co-authored-by: Fabian Klopfer <fabian.klopfer@ieee.org>
Co-authored-by: Yiheng Wang <68361391+yiheng-wang-nv@users.noreply.github.com>
Co-authored-by: Lucas Robinet <67736918+Lucas-rbnt@users.noreply.github.com>
Co-authored-by: Lucas Robinet <robinet.lucas@iuct-oncopole.fr>
Co-authored-by: cxlcl <chaoliucxl@gmail.com>
Signed-off-by: Dr. Behrooz Hashemian <3968947+drbeh@users.noreply.github.com>
@drbeh
Copy link
Member

drbeh commented Apr 9, 2024

@NikolasSchmitz, I resolved the conflicts and updated the PR. Let's focus on the functionality and make this PR ready for reviewing. We can take care of any other issue once the PR is ready and please feel free to reach out to me or the working group if you still have any questions. Thanks for taking on this feature.

@NikolasSchmitz NikolasSchmitz marked this pull request as ready for review April 9, 2024 22:55
@NikolasSchmitz
Copy link
Author

Thank you @drbeh ! I now marked it as ready for review.

@ericspod ericspod requested a review from drbeh April 22, 2024 14:53
monai/data/wsi_reader.py Outdated Show resolved Hide resolved
@ericspod
Copy link
Member

@drbeh would you be able to review this? I think you're best qualified here. I made some minor comments about print and code duplication but otherwise it seems fine to me without having tested it. Thanks!

@JHancox JHancox self-assigned this May 14, 2024
Copy link
Contributor

@JHancox JHancox left a comment

Choose a reason for hiding this comment

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

Thanks for the effort @NikolasSchmitz. A welcome addition! I agree with @ericspod about the refactoring to remove duplication - that would be great.

monai/data/wsi_reader.py Outdated Show resolved Hide resolved
monai/data/wsi_reader.py Outdated Show resolved Hide resolved
@NikolasSchmitz
Copy link
Author

Thank you for the feedback, @JHancox . Unfortunately, I couldn't join the meeting because I was on my way home from ICLR.
I will review the code and provide my updates as soon as possible.

… reduce redundancy; for get_mpp of TiffFileWSIReader: added check to prevent division by zero error.
@NikolasSchmitz
Copy link
Author

I factored out the actual resizing of the image into _resize_to_mpp_res() and kept the tolerance checks in get_wsi_at_mpp(). I had some problems with specific tiff files and the TiffFile backend. Some files had zero as X/Y Resolution, which led to a division by zero error in the function get_mpp (added a check for that in the new commit).
One tiff file from a Philips scanner that I tested had unobtainable mpp values using get_mpp. In this case, the tags do exist (openslide can find them), but they must be read and parsed from the property philips_metadata as XML. I have not implemented a fix for this yet, but please let me know if this is needed. In this particular case, the best option would be to use Openslide as the backend, although there might be users who prefer Tifffile.

@ericspod
Copy link
Member

ericspod commented Aug 1, 2024

There are lines added/removed to two other files that don't need to be changed in this PR, tests/test_regularization.py is causing a conflict for example. I would remove those and we can use black here through Github to resolve formatting issues if we need to.

@NikolasSchmitz
Copy link
Author

There are lines added/removed to two other files that don't need to be changed in this PR, tests/test_regularization.py is causing a conflict for example. I would remove those and we can use black here through Github to resolve formatting issues if we need to.

Thanks for the info. Interesting though, haven't noticed that these files were changed. Perhaps through one of the coding style checks.

@ericspod
Copy link
Member

ericspod commented Aug 7, 2024

There's a few changes to do but it looks good in general. We do need tests for these new methods as well so please look at the existing WSI tests to see what needs to be added to cover new functionality. The flake8 and DCO fixes can be done at the end. Thanks!

mpp_list = [self.get_mpp(wsi, lvl) for lvl in range(wsi.resolutions["level_count"])]
closest_lvl = self._find_closest_level("mpp", mpp, mpp_list, 0, 5)

within_tolerance, closest_level_is_bigger = super()._compute_mpp_tolerances(closest_lvl, mpp_list, mpp, atol, rtol)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
within_tolerance, closest_level_is_bigger = super()._compute_mpp_tolerances(closest_lvl, mpp_list, mpp, atol, rtol)
within_tolerance, closest_level_is_bigger = self._compute_mpp_tolerances(closest_lvl, mpp_list, mpp, atol, rtol)

If you're not overriding the method in this class you can refer to it through self as it will be inherited.

Copy link
Member

Choose a reason for hiding this comment

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

Same in other places below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WSIReader support for reading by mpp or magnification
8 participants