-
-
Notifications
You must be signed in to change notification settings - Fork 409
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
Add tests to cover slicing behavior when changing layers and data #4819
Add tests to cover slicing behavior when changing layers and data #4819
Conversation
Codecov Report
@@ Coverage Diff @@
## main #4819 +/- ##
=======================================
Coverage 91.67% 91.67%
=======================================
Files 582 582
Lines 51073 51152 +79
=======================================
+ Hits 46819 46894 +75
- Misses 4254 4258 +4
|
This is not a real problem, and it is not a proper solution. Accepting this will make adding a bunch of layers a quadratic operation, as adding a single layer will have linear complexity. The proper solution is to update layers when the range is changed. Some signal is not emitted from the |
That's interesting, thanks @mstabrin for the report! I think the fix is not the right fix here though. (Again... 😅 I swear I am not trying to be annoying! 😂) The issue is that we update all layers based on the The reason I think this is incorrect is that a very very common use case is to add layers that occupy exactly the same space, and this fix would now make that use case much slower. |
@jni I totally agree and I think it is an inefficient solution. At first I tried to identify if the lower range changed, but could not find a way so I presented a solution with minimum changes required :) I will look into a points event, using this opportunity to learn more about events^^ I will use this PR here so jo need to close it :) |
This reverts commit 929950a.
Sooo, after some research on how the event system works I added a new event for |
This solution looks working, but But I'm not familiar with this part of the napari codebase. Calling @andy-sweet, who may better know what needs to be done. |
Ok I'm confused... It looks from the diff that there was already a
At any rate, the test failures are real... Not sure immediately what the fix is. But @Czaki @mstabrin, I think the fix to the double update is simply to remove the |
How could I miss the Yes. It is a proper solution from my point of view. |
There is a little extra magic in |
Seems like a real problem to me - the view should update when adding a new layer. But I don't understand the current solution at all.
I think the following test should work. It tests some private state, which is not ideal, but seems fine to me. Also no need for the def test_add_points_layer_with_different_range_updates_all_slices():
"""See https://github.com/napari/napari/pull/4819"""
viewer = ViewerModel()
point = viewer.add_points([[10, 5, 5]])
other_point = viewer.add_points([[8, 1, 1]])
np.testing.assert_array_equal(point._indices_view, [])
np.testing.assert_array_equal(other_point._indices_view, [0]) I think the solutions I would go to have already been tried/mentioned.
The quadratic performance of adding lots of layers with the same extent is concerning, but I believe the early return condition in |
the current problem is that adding a new layer does not cause recalculation of the slider position. So 0 in the current steep happens to be 0 in a new steep, but calculation from value to world space changes. (so current_step does not change but its implementation change). |
I see. Thanks for a different perspective. I guess the implied desired behavior is that we should try to maintain the value of In general that won't be possible because the slider has integer positions. But we could snap to the closest slider position. I think that behavior is effectively defined by |
…stabrin/napari into fix_missing_update_on_dim_range_change
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This reverts commit eafedf6.
@mstabrin : I finally picked this up again. And I have mostly good news :) I merged main into this and mostly accepted changes from main. See the diff with main on that branch for more details. The good news is that The bad news is that the other two tests ( My suggestion is to merge in the passing test ( |
@andy-sweet: Glad to hear that the first test is passing with the recent changes! :) |
We don't have many xfails in napari, but I don't think we're against them either, so that sounds good. Do you mind if I push directly to this branch? Or would you prefer if I pushed to my own and made a PR to yours? |
I don't mind :) |
Done! The two tests are marked with xfail where the reason links to the bugs. I think the bugs are slightly different, so I created separate ones, but I think they may share a solution. |
@brisvag : I added you as a reviewer because I think your recent work on dims (i.e. making it fundamentally based on |
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'm not sure I follow the difference in the succeeding and failing tests... Are all the asserts in the xfail
tests supposed to fail?
I doubt the event is not happening, that would be a pretty huge issue deep down in the evented model which would affect the whole codebase. I think the source might be that we connect to current_step
instead of point
. This is not a problem for normal use, cause we never set the point to in-between steps unless we do it manually... which we may be doing here. I fixed this connection in #5697, but you could try adding it here.
The line is:
napari/napari/components/viewer_model.py
Line 259 in 55b9a97
self.dims.events.current_step.connect(self._update_layers) |
There's a few other places where we connect to current_step
which should be changed (except for the qt module).
No, only one fails currently in each test. I think that's clarified in the reproducers in the bug write ups. Can also add comments in this PR if desired.
Oh yeah, I forgot that change is not in yet!
Even if that change comes in, I think there's still an issue (I tried the suggested change out on this branch and the new tests still fail). Here's a reproducer that shows the issue when changing from napari.components.dims import Dims
d = Dims()
d.events.range.connect(lambda: print('range change'))
d.events.point.connect(lambda: print('point change'))
print(d.range) # -> (RangeTuple(start=0.0, stop=2.0, step=1.0), RangeTuple(start=0.0, stop=2.0, step=1.0))
print(d.point) # -> (0, 0)
d.range = ((1, 2, 1), (1, 2, 1))
# -> 'range change'
# but not -> 'point change'
print(d.range) # -> (RangeTuple(start=1.0, stop=2.0, step=1.0), RangeTuple(start=1.0, stop=2.0, step=1.0))
print(d.point) # -> (1, 1) I suspect the issue is that the change to |
I was about to say that this shouldn't be an issue, but I think you're right actually... Cause when we check for equality, we only check for dependency of properties, and we don't have any concept of dependencies of fields... @Czaki, do you think we could simply manually add dependencies even if they're not properties, and get proper behaviour from our current logic? The brute force alternative is to always check equality for all values (maybe special-casing |
@mstabrin : I changed the title and description dramatically based on the new changes in the PR. Please let me know if that's not OK and/or feel free to make edits. |
I think a similar issue would arise for psygnal's EventedModel, though I haven't actually tried that yet. What do you think about writing an issue there and seeing if we can port a similar to solution to our EventedModel? |
We have a few other changes to our evented model which may not be ported there yet (like the most recent changes from @Czaki). We should definitely try to port those these and also solve this, and then use psygnal as a dependency :P |
I went ahead and merged this since the test cases are valuable and everything is green. We have the two issues to follow up on, which might share a more common general fix around Thanks again for your help and patience here @mstabrin . Hopefully we can get the remaining issues fixed soon. |
* main: (26 commits) Fix some typing in napari.components (napari#6203) Use class name for object that does not have qt name (napari#6222) test: [Automatic] Constraints upgrades: `hypothesis`, `magicgui`, `psygnal`, `tensorstore`, `tifffile`, `tqdm`, `virtualenv` (napari#6143) Replace more np.all( ... = ...) with np.array_equal (napari#6213) remove np.all(... == ...) in test_surface.py (napari#6218) Ensure pandas Series is initialized with a list as data (napari#6226) Stop using temporary directory for store array for paint test (napari#6191) Bugfix: ensure thumbnail represents canvas when multiscale (napari#6200) cleanup np.all(... == ...) from test_points.py (napari#6217) [pre-commit.ci] pre-commit autoupdate (napari#6221) use app-model for file menu (napari#4865) Add tests to cover slicing behavior when changing layers and data (napari#4819) [pre-commit.ci] pre-commit autoupdate (napari#6128) Add test coverage for async slicing of labels (napari#5325) Add collision check when set colors for labels layer (napari#6193) Update "toggle ndview" text (napari#6192) Prevent layer controls buttons changing layout while taking screenshots with flash effect on (napari#6194) Fix typing in napari.utils.perf (napari#6132) Add GUI test coverage for changes to Labels.show_selected_label (napari#5372) Fix types in 'napari.utils.colormaps.categorical_colormap' (napari#6154) ...
References and relevant issues
Related to #6198 and #6199
Description
This adds tests to cover cases when either layers are added, removed, or their data changes in ways that should trigger data to be sliced and the canvas view to be updated. Some of these cases pass due to recent changes (e.g. #5522), but some fail due to remaining issues (e.g. #6198 and #6199).