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

Decorators for helping with the multichannel->channel_axis transition #5228

Merged
merged 8 commits into from
Mar 9, 2021

Conversation

grlee77
Copy link
Contributor

@grlee77 grlee77 commented Feb 10, 2021

This PR is related to #4294. It introduces two new decorators to help with the proposed transition from multichannel to channel_axis:

1.) deprecate_multichannel_kwarg is a decorated based on deprecate_kwarg, but additionally takes care of converting values from:
multichannel=False -> channel_axis=None
multichannel=True -> channel_axis=(-1,)

2.) channel_as_last_axis can be used to help automate shuffling of axes to/from the last position. This will not be needed for functdions capable of handling arbitrary channel positions, but is a quick way to adapt many existing functions that all assume channels correspond to the last axis.

For now I just applied these to the existing montage function as a concrete example. I want to get initial feedback before extending the approach further. Right now only a single channel axis is supported, but the channel_as_last_axis decorator could also be adapted to handle more general cases.

@grlee77 grlee77 added the 📜 type: API Involves API change(s) label Feb 10, 2021
@grlee77 grlee77 added this to the 1.0 milestone Feb 10, 2021
@pep8speaks
Copy link

pep8speaks commented Feb 10, 2021

Hello @grlee77! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

Line 66:12: E201 whitespace after '['
Line 66:15: E241 multiple spaces after ','
Line 67:12: E201 whitespace after '['
Line 67:15: E241 multiple spaces after ','
Line 68:12: E201 whitespace after '['
Line 68:15: E241 multiple spaces after ','
Line 70:12: E201 whitespace after '['
Line 70:15: E241 multiple spaces after ','
Line 71:12: E201 whitespace after '['
Line 71:15: E241 multiple spaces after ','
Line 74:12: E201 whitespace after '['
Line 74:15: E241 multiple spaces after ','
Line 75:12: E201 whitespace after '['
Line 75:15: E241 multiple spaces after ','
Line 76:12: E201 whitespace after '['
Line 76:15: E241 multiple spaces after ','
Line 77:12: E201 whitespace after '['
Line 77:15: E241 multiple spaces after ','
Line 78:12: E201 whitespace after '['
Line 78:15: E241 multiple spaces after ','
Line 79:12: E201 whitespace after '['
Line 79:15: E241 multiple spaces after ','
Line 80:12: E201 whitespace after '['
Line 80:15: E241 multiple spaces after ','
Line 81:12: E201 whitespace after '['
Line 81:15: E241 multiple spaces after ','
Line 125:11: E201 whitespace after '['
Line 125:16: E241 multiple spaces after ','
Line 125:22: E241 multiple spaces after ','
Line 125:28: E241 multiple spaces after ','

Comment last updated at 2021-03-05 13:21:09 UTC

…tion

deprecate_multichannel_kwarg handles deprecation of the multichannel argument and conversion to the new channel_axis form

channel_as_last_axis helps automatically move channels to the end for compatibility with existing code
channels in the output will be restored back to their original position

Apply the channel_axis change to montage and test with different channel axes
@grlee77 grlee77 added this to In progress in skimage2 API Feb 10, 2021
Base automatically changed from master to main February 18, 2021 18:23
@@ -21,15 +21,16 @@ def test_montage_simple_gray():
assert_array_equal(arr_out, arr_ref)


def test_montage_simple_rgb():
def test_montage_simple_rgb(channel_pos=-1):
Copy link
Member

Choose a reason for hiding this comment

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

not sure what channel_pos is used for here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should not be there. I originally started modifying this test class, but later decided to leave this one using multichannel and add a new test_montage_simple_rgb_channel_axes test case instead to test the channel_axis argument.

@emmanuelle
Copy link
Member

Thanks @grlee77 the approach looks sound to me. So deprecate_multichannel_kwarg would be used just during the transition to 1.0 but the channel_as_last_axis decorator could stay for a longer time? With the latter decorator and the use of np.moveaxis, do I understand correctly that for an array with channels corresponding to the leading axis, channel_axis=0 + this decorator would lead to memory-contiguous arrays being used in functions such as denoise_tv_bregman etc. which do

channel_in = np.ascontiguousarray(image[..., c:c+1])

?

silence whitespace errors E201, E202, E203 in test_*.py and colorconv.py where small arrays
are defined using spacing favorable for reading by humans
@grlee77
Copy link
Contributor Author

grlee77 commented Mar 4, 2021

So deprecate_multichannel_kwarg would be used just during the transition to 1.0 but the channel_as_last_axis decorator could stay for a longer time?

Yes, this way we don't have to make solutions for every functions individually to support alternative channel positions. If there are cases where it makes sense to handle the channels in a different manner, then those functions can implement that internally and stop using the channel_as_last_axis decorator.

do I understand correctly that for an array with channels corresponding to the leading axis, channel_axis=0 + this decorator would lead to memory-contiguous arrays being used in functions such as denoise_tv_bregman etc. which do

Yes, If the input array is C-contiguous with channels as the first axis then after np.moveaxis to the last position the overall array is no longer C-contiguous, but the values for a specific channel will still be C-contiguous. Minimal example

import numpy as np

a = np.ones((3, 256, 256))
a_reordered = np.moveaxis(a, 0, -1)
# overall array is now no longer C-contiguous
print(a_reordered.flags)
# but invidual channels are C-contiguous
print(a_reordered[..., 0].flags)

Also a_reordered.flags.owndata is False indicating that a_reordered is a view of a, not a copy.

Copy link
Member

@emmanuelle emmanuelle left a comment

Choose a reason for hiding this comment

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

Thanks @grlee77 the PR is ready as far as I'm concerned. @scikit-image/core we need another review please :-)

@stefanv
Copy link
Member

stefanv commented Mar 4, 2021

Looks good to me; I guess we'll know more once we start using this in practice.

@grlee77 grlee77 changed the title WIP: Decorators for helping with the multichannel->channel_axis transition Decorators for helping with the multichannel->channel_axis transition Mar 4, 2021
@grlee77
Copy link
Contributor Author

grlee77 commented Mar 4, 2021

I added a couple of additional functions to illustrate additional arguments for the channel_as_last_axis decorator

match_histograms : this one swaps channels for the first two positional arguments
apply_parallel: this one swaps channels for only the second positional argument

This PR now covers all multichannel use in skimage.util and skimage.exposure. To keep the number of changes relatively small, I would like to address other modules in subsequent PRs.

Copy link
Member

@jni jni left a comment

Choose a reason for hiding this comment

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

@grlee77 I've left a minor suggestion. It'd be great if the docstrings were PEP257 compliant (first line must be a one-liner), but it's in private classes so 🤷 I really don't mind. =)

skimage/exposure/histogram_matching.py Outdated Show resolved Hide resolved
@grlee77
Copy link
Contributor Author

grlee77 commented Mar 5, 2021

Thanks @jni, I made the requested modifications.

@jni jni merged commit d4e2a31 into scikit-image:main Mar 9, 2021
@jni
Copy link
Member

jni commented Mar 9, 2021

Thank you @grlee77! The failed checks appeared to be due to a stalled VM.

@grlee77 grlee77 moved this from In progress to Done in skimage2 API Mar 23, 2021
@grlee77 grlee77 deleted the channel_axis_decorator branch July 8, 2021 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📜 type: API Involves API change(s)
Projects
Development

Successfully merging this pull request may close these issues.

None yet

6 participants