-
Notifications
You must be signed in to change notification settings - Fork 16
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
feat: Show path and ID of missing node when trying to find channel in… #107
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #107 +/- ##
==========================================
+ Coverage 66.18% 66.19% +0.01%
==========================================
Files 85 85
Lines 10705 10721 +16
==========================================
+ Hits 7085 7097 +12
- Misses 3620 3624 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
At first glance - I'd be surprised if there is an exception/error with the code example you gave. My initial expectation would be:
In other words - the entries for "channel 1" should be ignored. |
The behavior you are describing would also be very sensible. However, I am quite sure that we are getting an error like this. I just checked with libCZI directly (to make sure that I didn't encounter an issue on the pylibczirw side). The tests in libczi can easily be "updated" to provoke the error I described above: The image shows that I just commented the part of the test setup procedure that writes a subblock for the second channel. In that case the test fails with the "invalid path" error (the one I altered in this PR). @ptahmose do you think that this is the actual bug? I am having difficulties understading what the indended behavior actually is since both, ignoring the channel and failing, would be reasonable outcomes IMO. |
I just did some debugging and I think I was able to locate the root cause of the problem. /*static*/void libCZI::MetadataUtils::WriteDisplaySettings(libCZI::ICziMetadataBuilder* builder, const libCZI::IDisplaySettings* display_settings, const std::map<int, PixelType>* channel_pixel_type)
{
// we determine the highest channel-number that we find in the display-settings object
int max_channel_index_in_display_settings = 0;
display_settings->EnumChannels(
[&](int channel_index)->bool
{
if (channel_index > max_channel_index_in_display_settings)
{
max_channel_index_in_display_settings = channel_index;
}
return true;
});
MetadataUtils::WriteDisplaySettings(builder, display_settings, 1 + max_channel_index_in_display_settings, channel_pixel_type);
} Please note that the max_channel_index_in_display_settings varaible determines exactly what it name implies: the maximum channel index. However, subsequently, this number is interpreted as channel_count. Therefore, we are facing issues if the channel count is not the same as the maximum channel index, e.g. if the display_settings map (which is provided by the user of the library and therefore not controlled by us) features channel indices that are bigger than the actual channel count of the image (assuming the metadata at I think that there are multiple ways to approach this. One of them would be to change the WriteDisplaySettings function to accept a set of available channels instead of a channel count.
I would opt for going for this solution, but would be very open for simpler alternative solutions. |
I'd now have the following proposal:
From the libCZI-API perspective - I'd want to stick with the philosophy "we add all display-settings we are given to the metadata", but now it is straight-forward to ensure on caller-site that we only pass in display-settings for existing channels. (Note that the code in jbl/proposal_displaysettings_write requires an updated libCZI-version (including #109 ). |
Thanks for the proposal! In combination with the previous fix, I like this approach a lot! I'm closing this PR in favor of the implementation you proposed on the caller side :) |
Description
This PR proposes to add more information to some error messages that re related to missing nodes in the XML metadata.
In the context of pylibczirw it is possible to provoke undefined states where the image metadata does not match the actual subblocks. For example, consider this code snippet:
Note that the image is supposed to yield two channels (as defined in the display settings and the chanel names), but there is only written data for one channel since
test_czi.write(data=np.zeros((100, 100), dtype=np.uint8), plane={"C": 1})
is commented.Since libczi is fetching the channel ID and name from the metadata that is being written when writing the subblocks, it will, as expected, not be able to fetch the channel ID and name and rais an exception when writing the metadata. However, the error being raised is very generic and does not provide any information about what the underlying cause. This PR proposes to enable the error to show the path and index of the node such that the underlying issue is easier to understand.
Type of change
How Has This Been Tested?
Run the code snippet above with pylibczirw baced by the PR version of libczi.
Checklist: