Open haesleinhuepf opened 2 years ago
I'll have my hand at it :)
Hi @haesleinhuepf ,
I've tried to formulate this similarly as in the linked repos (Thanks for the hints), and the result would look something like this - is this what you had in mind?
from functools import wraps
from toolz import curry
import inspect
from napari.layers import Surface, Points
@curry
def convert_annotation(function) -> callable:
@wraps(function)
def wrapper(*args, **kwargs):
# From https://github.com/haesleinhuepf/napari-simpleitk-image-processing/blob/main/src/napari_simpleitk_image_processing/_simpleitk_image_processing.py
sig = inspect.signature(function)
# create mapping from position and keyword arguments to parameters
# will raise a TypeError if the provided arguments do not match the signature
# https://docs.python.org/3/library/inspect.html#inspect.Signature.bind
bound = sig.bind(*args, **kwargs)
# set default values for missing arguments
# https://docs.python.org/3/library/inspect.html#inspect.BoundArguments.apply_defaults
bound.apply_defaults()
# copy images to napari.types
for key, value in bound.arguments.items():
arg = None
if isinstance(value, Surface):
arg = (value.data[0], value.data[1])
if isinstance(value, Points):
arg = (value.data)
if arg is not None:
bound.arguments[key] = arg
# call the decorated function
return function(*bound.args, **bound.kwargs)
return wrapper
Hi Johannes @jo-mueller ,
the code looks interesting. Have you tried to run it? Does it exist as repo/branch somewhere? That would make it easier to discuss about it ;-)
The next challenge might then be to modify the signature of the function to achieve that magicgui works. It should ask the user for a Surface layer, even though the function specifies SurfaceData as type. Hence, I would try to replace SurfaceData annotations with SurfaceLayer annotations.
Best, Robert
Hey @haesleinhuepf ,
the code for this lives here. I added the decorator to two functions to test the behavior and it seems to work (e.g., passes a simple test function). I haven't tried it from the viewer, yet.
It should ask the user for a Surface layer, even though the function specifies SurfaceData as type.
So...I would have to add a Surface-annotated argument in the outer function? Or replace the respective argument annotation in the wrapped function?
I think you want to modifiy the signature of wrapper
in your code.
It should be possible to formulate a function decorator that takes functions like this:
make appear them like that to the outside:
By implementing this
plugin_function
we could also solve #6 (withoutif-else
blocks in every function) and multiply the surfaceData and pointsData with the layer's scaling. Theplugin_function
could also convert back pointsData and surfaceData to layers.There are other examples where similar stuff is done:
Johannes @jo-mueller , if you're interested in implementing this, let me know! Otherwise I can also do it.