-
Notifications
You must be signed in to change notification settings - Fork 43
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
Embedding widget for napari plugin #235
Embedding widget for napari plugin #235
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a closer look now and also tried to run the widget.
Two things I noticed:
- The
ndim
computation for RGB data is wrong. - We should check that the global
IMAGE_EMBEDDINGS
variable is updated.
I also checked out the branch, reinstalled (via pip install -e
) and tried to run the widget, but starting the widget from the plugins menu fails with:
RuntimeError: Failed to import command at 'micro_sam.sam_annotator._widgets:embedding_widget': /lib/x86_64-linux-gnu/libti
nfo.so.6: version `NCURSES6_TINFO_6.2.20211010' not found (required by /home/pape/software/conda/miniconda3/envs/sam/lib/p
ython3.10/site-packages/vigra/../../../././libncurses.so.6)
@GenevieveBuckley : should this work already?
I've put the widget stuff in a separate file for now. Not sure if that's the right long term choice or not, but we can always change it later.
I think that's good and makes more sense than micro_sam.sam_annotator.util
, where I put these things before.
Almost. Our biggest problem is that the global IMAGE_EMBEDDINGS variable is not accessible outside our thread worker.
How to fix the problem described by 4, above?
|
I think we have one more problem, actually. When you click the "Compute Embeddings" button a second time, nothing happens. That's ok, it checks the zarr and finds stuff already there, so it doesn't re-compute anything. That's good, even if it is a little disconcerting that there is no user feedback that the operation was sucessful (maybe we should have a "Finished" dialog box pop up or something). BUT, when you change the input image layer, but forget to update the output zarr filepath... it doesn't seem to check whether the embedding contents in the zarr directory match the input image or not. I thought PR #67 fixed this. I don't see an error or warning message anywhere, and it is returning without computing anything, just like before (except now, this is not the behaviour we want). |
Odd test failure here, something is strange. It passes locally on my machine, but on the github actions CI, we get:
"cpu" should always be available, what is going on |
there's quite a lot to follow up on, so I will structure it a bit: Running the pluginI am not sure where the error with vigra comes from, but it indeed seems to be some error in my environment(s) (tested in two now), that happens when it's imported multiple times. I can fix it for now by commenting out a few imports that we don't need for testing the plugin. Let's ignore this for now, and we can look into this more if the issue persists once we want to merge this (or even later once we have a more advanced state on dev). You can see what I had to change in the proof of concept singleton PR (see below). Global stateI played with this a bit now, and you're right this is tricky to do with the global variables. I don't think that this is a big issue going forward though, since we want to get rid of the global variables anyways! I wrote a quick proof of concept for replacing it with a singleton class and that works!
Cached embeddingsIndeed this should be addressed by #67 and you should at least see a warning when the wrong file is used. But maybe the warning is suppressed because it happens in the thread worker? Test errorThat is weird. Unfortunately I can't run the test locally right now to check it because of
Could you documented what's needed to run the tests now? Thanks! |
I implemented the singleton state in #240. This already works and if you want you can merge it here or rebase onto that PR @GenevieveBuckley. I only need to update it tomorrow for the 3d and tracking annotator, but that should not interfere with the changes here. |
This looks like you don't have We install a couple of pytest plugins (pytest-cov, pytest-qt) into our CI test environment. You're right, documenting this in a contributing guide is a good idea. |
Hi @GenevieveBuckley,
|
I think this is ready now - I'm very happy with how it has turned out!
|
Extra notes:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @GenevieveBuckley! I ran this again and it works nicely. I also tested with custom weights and it seems to work. To fully check all of this we will need to integrate with the other widgets, but we can go ahead with this now.
I found a few small things that are not related to the core logic. I will just go ahead and fix these so that we can move ahead.
And I will create a few follow-up issues for some of the things you mentioned and some things I noticed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While going through the code again I noticed an issue with the core logic. I think this is easy to fix by removing the check but won't do it myself since I may overlook some intention behind adding this check.
micro_sam/sam_annotator/_widgets.py
Outdated
raise NotADirectoryError( | ||
f"The user selected 'save_path' is not a direcotry: {save_path}" | ||
) | ||
if len(os.listdir(save_path)) > 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this defeats the purpose of caching the affinities: the idea is that a user can close the annotation tool and open it again later while pointing to the same save_path
so that the embeddings don't have to be recomputed.
This check prevents this and makes caching the embeddings not useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also relates to your comment from above:
I've put in a bit of code to make sure the save_path directory exists and is empty. It prints an error message to the terminal if the directory is not empty.
Printing the error here is not a good idea. Maybe you intended this because of the problem with the hash comparison, but I don't want to print an error for the correct behavior of using already cached affinities.
We could use a warning instead for now and remove this once we figure out the issue with the hash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's reasonable - I've changed the code to fix this problem.
Now it works in all situations:
- Creating new image embeddings,
- Returning/loading existing image embeddings if the data_signature of the save directory matches our input image, and
- Making an error popup in the napari viewer if something goes wrong (data signature does not match, save directory is not a zarr array or empty folder, anything else unexpected that raises an actual error).
…sam into embedding-widget
…o napari users will see error popup)
…beddings to exist
Codecov Report
@@ Coverage Diff @@
## dev #235 +/- ##
==========================================
+ Coverage 38.34% 39.76% +1.41%
==========================================
Files 30 33 +3
Lines 3987 4170 +183
==========================================
+ Hits 1529 1658 +129
- Misses 2458 2512 +54
📣 Codecov offers a browser extension for seamless coverage viewing on GitHub. Try it in Chrome or Firefox today! |
micro_sam/sam_annotator/_widgets.py
Outdated
save_path = str(save_path), | ||
ndim=ndim, | ||
) | ||
state.image_shape = image_data.shape |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the image_shape attribute supposed to include the RGB dimension in the case of a colour image?
Or does this need to be:
if image.rgb:
state.image_shape = image_data.shape[:-1]
else:
state.image_shape = image_data.shape
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shape is supposed to only include the spatial dimensions. So we indeed need to add the condition for rgb images. Thanks for catching this!
@@ -552,7 +579,7 @@ def precompute_image_embeddings( | |||
continue | |||
# check whether the key signature does not match or is not in the file | |||
if key not in f.attrs or f.attrs[key] != val: | |||
warnings.warn( | |||
raise RuntimeError( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upgrading this from a user warning to an actual error allows users to see a little pop up happen in the bottom of the napari viewer if an error happens. I think this is sufficient for what we need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's good! I think it's good to update this to a real error in any case, since having different embeddings will lead to non-sensical results. I think we had a warning there in the beginning because we were still testing this functionality out, and then never got around to updating it to an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes @GenevieveBuckley! This looks good now. The only thing left to do is updating how the image_shape is set.
Updated! |
3c26798
into
computational-cell-analytics:dev
Closes #203
A simple widget to compute image embeddings via the micro-sam napari plugin.
I've put the widget stuff in a separate file for now. Not sure if that's the right long term choice or not, but we can always change it later.