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

Refactor segmentation_to_objects #304

Merged
merged 14 commits into from
Apr 20, 2023
Merged

Refactor segmentation_to_objects #304

merged 14 commits into from
Apr 20, 2023

Conversation

quantumjot
Copy link
Owner

@quantumjot quantumjot commented Apr 19, 2023

This PR refactors a critical function segmentation_to_objects:

  • cleans up code to remove duplications, adds modern typing
  • adds an (optional) progress bar if tqdm is installed, to provide feedback
  • add support for a multiprocessing Pool for more performant detection
  • allows user defined image analysis functions by exposing extra_properties
  • updates the example notebook to demonstrate some of the changes
  • a few small changes to documentation
  • adds some tests for the new functionality

@quantumjot
Copy link
Owner Author

These changes are to enable @ania-m-b to do some "advanced" analysis.

@deprecated-napari-hub-preview-bot
Copy link

deprecated-napari-hub-preview-bot bot commented Apr 19, 2023

Preview page for your plugin is ready here:
https://preview.napari-hub.org/quantumjot/btrack/304
Updated: 2023-04-20T11:30:19.635085

@quantumjot quantumjot marked this pull request as ready for review April 20, 2023 08:50
@quantumjot
Copy link
Owner Author

@paddyroddy and @p-j-smith - this should also help with some aspects of running this from the napari plugin

@quantumjot quantumjot requested a review from paddyroddy April 20, 2023 09:57
Copy link
Collaborator

@paddyroddy paddyroddy left a comment

Choose a reason for hiding this comment

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

Have added some thoughts

def extra_prop(_mask) -> float:
return np.sum(_mask)

extra_properties = (extra_prop,)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not just something like this?

Suggested change
extra_properties = (extra_prop,)
extra_properties = (np.sum(_mask),)

Copy link
Owner Author

Choose a reason for hiding this comment

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

Happy to do it this way, but I was trying to emulate how an end user would actually use this. Probably doesn't matter in the tests

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah I see. I couldn't really make sense of it.

Copy link
Owner Author

Choose a reason for hiding this comment

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

The idea is that you can now provide functions that work on the image data and return properties that become part of the PyTrackObject properties - it's much cleaner to use and makes end-use much more powerful

Comment on lines 24 to 27
# this provides a dummy progress bar in case `tqdm` is not installed.
def tqdm(iterator, *args, **kwargs):
logger.info("Try installing ``tqdm`` for progress bar rendering.")
return iterator
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why wouldn't tqdm be installed?

Copy link
Owner Author

Choose a reason for hiding this comment

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

I just left it optional, we could add to the requirements

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see any harm in that?

Copy link
Collaborator

Choose a reason for hiding this comment

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

If we want it optional could add something similar to optional-dependencies.docs

Copy link
Owner Author

Choose a reason for hiding this comment

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

I've added it as a requirement. I think it could be useful in other parts of the codebase too

def _next_array(self) -> Tuple[npt.NDArray, Optional[npt.NDArray]]:
"""__next__ method for an array-like input."""
if self._iter >= len(self):
raise StopIteration
Copy link
Collaborator

Choose a reason for hiding this comment

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

What happens when this is raised? Should we have some sort of logging?

Copy link
Owner Author

Choose a reason for hiding this comment

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

This StopIteration just allows the iterator to stop when it get's to the end of the data. It doesn't interrupt execution of the code

Copy link
Collaborator

Choose a reason for hiding this comment

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

Cool

centroid_type: str = "centroid"
intensity_image: Optional[npt.NDArray] = None
scale: Optional[Tuple[float]] = None
assign_class_ID: bool = False # noqa: N815
Copy link
Collaborator

Choose a reason for hiding this comment

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

Once python=3.10 is the min we support, we can use dataclasses.KW_ONLY to avoid the noqa here

Copy link
Owner Author

Choose a reason for hiding this comment

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

Nice! I think this is actually because of the mixed case here

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oops, I should have checked what the error is for

import logging
from typing import Generator, List, Optional, Tuple, Union
from multiprocessing.pool import ThreadPool as Pool
Copy link
Collaborator

Choose a reason for hiding this comment

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

Have you considered concurrent.futures.ThreadPoolExecutor?

Copy link
Owner Author

Choose a reason for hiding this comment

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

Oops - this is a good catch, it's actually supposed to be just a Pool

Copy link
Owner Author

Choose a reason for hiding this comment

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

I feel like this is something we can take a look at when this is integrated into the napari plugin - I'm not sure what the best way to play with that is yet

btrack/io/_localization.py Outdated Show resolved Hide resolved
btrack/io/_localization.py Outdated Show resolved Hide resolved
btrack/io/_localization.py Outdated Show resolved Hide resolved
quantumjot and others added 3 commits April 20, 2023 12:01
Co-authored-by: Patrick Roddy <patrickjamesroddy@gmail.com>
Co-authored-by: Patrick Roddy <patrickjamesroddy@gmail.com>
Co-authored-by: Patrick Roddy <patrickjamesroddy@gmail.com>
@codecov-commenter
Copy link

codecov-commenter commented Apr 20, 2023

Codecov Report

Patch coverage: 95.74% and project coverage change: +0.37 🎉

Comparison is base (146419f) 84.09% compared to head (07721e5) 84.47%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #304      +/-   ##
==========================================
+ Coverage   84.09%   84.47%   +0.37%     
==========================================
  Files          30       30              
  Lines        1905     1932      +27     
  Branches      295      295              
==========================================
+ Hits         1602     1632      +30     
+ Misses        216      215       -1     
+ Partials       87       85       -2     
Impacted Files Coverage Δ
btrack/io/_localization.py 91.89% <95.74%> (+6.17%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@quantumjot quantumjot requested a review from paddyroddy April 20, 2023 11:39
@quantumjot
Copy link
Owner Author

Thanks for the review @paddyroddy - I think I took care of everything.

@quantumjot quantumjot merged commit 69fc3a8 into main Apr 20, 2023
@quantumjot quantumjot deleted the regionprops-extra branch April 20, 2023 11:56
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.

3 participants