-
Notifications
You must be signed in to change notification settings - Fork 27
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
[Bugfix] For layer_attributes
that are dict (like color
) do key/value comparisons
#181
[Bugfix] For layer_attributes
that are dict (like color
) do key/value comparisons
#181
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #181 +/- ##
==========================================
+ Coverage 86.25% 86.38% +0.13%
==========================================
Files 26 26
Lines 1011 1043 +32
==========================================
+ Hits 872 901 +29
- Misses 139 142 +3 ☔ View full report in Codecov by Sentry. |
@psobolewskiPhD this seems ok but I don't fully understand the issue. Perhaps there is a test that you can make for this...? |
@jni yeah a test would probably be good. It doesn't look like different layers are tested at all and they do have different attributes...
which is, for 1 label, for example:
So it's a dict with an array inside.
|
Actually, I wonder if the test issue is here: napari-animation/napari_animation/_tests/test_animation.py Lines 9 to 18 in a9ca7a7
color is not one of the attributes
|
Do you want to try adding it and see what happens to the CI? 😅 |
So having looked at it a bit more, it's a bit trickier. napari-animation/napari_animation/viewer_state.py Lines 27 to 38 in a9ca7a7
But in tests only image layers are tested: napari-animation/napari_animation/_tests/conftest.py Lines 42 to 52 in a9ca7a7
So handling of attributes like |
So an alternate way to solve this is to add Eitherway, to support other layer types, tests should test them. |
This pull request has been mentioned on Image.sc Forum. There might be relevant details there: https://forum.image.sc/t/issue-saving-animations-in-napari-animation/88868/2 |
@brisvag Took me a while to get back to this, but per our conversations at the hackathon, I added a recursive function to compare attributes: I then added tests, using napari fixtures to test all layers--I figured there was no need to reinvent the wheel when we have nice fixtures for making a buncha layers with data. The fail is that the Anyone have any insight into that? is it because it's an ENUM: |
Not 100% sure, but yes, I think evented models shoudl always end up giving nested dicts with actual objects as leaves.
Mhm... not sure I understand the error. But surely we have many other enums that are not failing? |
yeah it's odd. I tested locally by making a random Surface layer and then an animation and indeed that |
Could it just be that it has |
Yup, that would be it I think, makes them unsettable. |
layer_animation.viewer.camera.zoom *= 2 | ||
layer_animation.capture_keyframe() | ||
# advance the movie frame, simulating slider movement | ||
layer_animation.set_movie_frame_index(1) |
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.
Should this test assert something? like that an exception is not thrown? I mean if there is an exception then it's a fail--like on main with this test--so maybe this is fine?
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 it's just checking that there's no exception, yes. You could add an assert later that the viewer did indeed change, but maybe that's tested elsewhere?
JNI approved but I've changed a lot here, so lets consider that a stale review -- I can't dismiss it. |
|
||
if layer_class == Surface: | ||
layer_state["normals"]["face"].pop("mode", None) | ||
layer_state["normals"]["vertex"].pop("mode", None) |
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 confused about this — is this something users would need to do if trying to animate a Surface layer? That seems clunky. Basically, the things in the test should mirror what users would do, and if it's some weird workaround, then it might be good to e.g. push those tests to a different xfail test, so that it's obvious what needs to be fixed in the codebase going forward...
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.
So the issue is, as Lorenzo noted, that these are enums flagged as immutable, so they arn't settable. So the layer state has them, but the viewer_state
does not. The test compares the two sets of dicts, so I pop them from the layer state dict before the comparison check.
I don't think a user will ever run into this because they are immutable they can't changed during an animation anyways.
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.
Ha! Turns out I had a horrible logic bug, see:
https://forum.image.sc/t/issue-saving-animations-in-napari-animation/88868/8?u=psobolewskiphd
And with it fixed this hack isn't needed. I was setting only the states that didn't change, which would be the immutable ones.
Now when we set the changed ones, everything should be peachy!
# remove attributes that arn't captured | ||
layer_state.pop("metadata") | ||
layer_state.pop("data", None) |
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.
Can we drop these lines now, for the same reason as the surface hack? Or maybe do something like:
original_layer_state = {
k: v for k, v in layer_state.items()
if k in CAPTURED_LAYER_ATTRIBUTES
}
or something like this? I don't like that this stuff is "hardcoded" in the test...
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.
(also, arn't
is a typo. 😜)
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.
Metadata isn't captured
napari-animation/napari_animation/viewer_state.py
Lines 17 to 19 in 35e5acc
layers : dict | |
A map of layer.name -> Dict[k, v] for layer attributes for each layer in the viewer | |
(excluding metadata). |
and it's popped in viewer_state
layer_attributes.pop("metadata") |
So I think that one has to be popped.
data
doesn't get captured either:https://github.com/napari/napari-animation/blob/35e5accac9c6994b9735bc7ecb1d679e2b70bdc5/napari_animation/viewer_state.py#L30C43-L31
Only the 2 element of the tuple is used.
While it could be cool if it worked, I'm not sure how keyframes and interpolation would work with data.
So the idea in the test would be to make a NEVER_CAPTURED_ATTR variable at the top of the file and put those there?
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 it could be cool if it worked, I'm not sure how keyframes and interpolation would work with data.
I a user wants to use napari-animation to change smoothly change the contents of data
through out, there's a very good chance they actually need to add a dimension to Dims
and use that instead :P
Co-authored-by: Lorenzo Gaifas <[email protected]>
Well enough! Feel free to merge here! 😊 |
Closes: #180
Closes: #184
This adds a new function to utils.py for carrying out the comparison of layer_attribute. In particular if an attribute is a dict then the function recurses using key/value pairs.
This is needed for example for Labels layer
color
which is a dict of np.array. But other layers also have nested dicts (e.g. Surfaces)Additionally, I implement two tests that use all napari layers.
The first compares attributes between viewer_state and the actual layer and the second checks whether the animation has frames.
These tests fail in main but pass with the fix mentioned above.