feat: generate viewer links dynamically for Zarr datasets#307
feat: generate viewer links dynamically for Zarr datasets#307allison-truhlar wants to merge 72 commits intomainfrom
Conversation
- Custom viewers (validator, vol-e) now check for multiscales - Ensures viewers only display for OME-Zarr datasets, not plain Zarr arrays - Update DataToolLinks alt text to use displayName for E2E test compatibility
Add useCallback to memoize the getCompatibleViewers function in ViewersContext to prevent unnecessary recalculations and improve performance when filtering compatible viewers based on metadata.
Add more detailed error logging and ensure graceful degradation when: - Capability manifests fail to load - Viewer configuration parsing fails - No valid viewers are configured The application will continue with an empty viewer list and clear console messages to help users troubleshoot configuration issues.
neomorphic
left a comment
There was a problem hiding this comment.
Looks good to me. I was able to enable and disable a viewer using the viewers.config.yaml. I added a few comments about some the code I wasn't sure on.
- previously, if a logo path wasn't found, a 404 URL was still created, so it was never falling through to the fallback_logo.
- includes checking that a fallback_logo is used when no logo is found for a viewer
…to mimic intended setup
docs/Development.md
Outdated
|
|
||
| **Quick Setup:** | ||
|
|
||
| 1. Edit the configuration file at `frontend/src/config/viewers.config.yaml` to enable/disable viewers or customize URLs |
There was a problem hiding this comment.
It's best not to edit committed source code to change configuration. If users change version controlled code then they will have problems staying up to date with upstream changes. One alternative pattern for this would be to allow users to copy this file into the main directory with their own changes, and then during the build use it to override the default config.
| openWithToolUrls.avivator = null; | ||
| // Convert our metadata to OmeZarrMetadata format for capability checking | ||
| const omeZarrMetadata = { | ||
| version: effectiveZarrVersion === 3 ? '0.5' : '0.4', |
There was a problem hiding this comment.
This is extremely fragile code from my original vibe-coded prototype. We need a better way to get the NGFF version.
Starting in NGFF 0.5, there is an attribute that specifies the version (https://ngff.openmicroscopy.org/specifications/0.5/index.html#ome-zarr-metadata).
I'm not sure if there's a reliable way to tell for versions prior to 0.5. @mkitti do you know? We could take a look at the OME-NGFF Validator, which somehow prints the version.
There was a problem hiding this comment.
There are some hints here:
https://www.openmicroscopy.org/2021/12/16/ome-ngff.html
There was a problem hiding this comment.
I think we should not put too much effort into identifying pre-0.4 OME-NGFF. At best, it might provide some degradation path if axes or other elements are missing: if axes are missing, assume XYZCT.
If necessary, we comb through the old specs:
https://ngff.openmicroscopy.org/specifications/0.1/index.html
What I am more concerned about in the above code is future compatibility. OME-NGFF 0.6 is coming soon. If we do see Zarr v3, we should look for and parse the attributes.ome.version key.
There was a problem hiding this comment.
OME-NGFF Validator has a straightforward function to determine the version number that I could borrow: https://github.com/ome/ome-ngff-validator/blob/01ca6c8dae499914114acd136353ac452f93bce4/src/utils.js#L138
If no version metadata is found, since version wasn't required metadata in 0.4 and earlier, it defaults to 0.4.
There was a problem hiding this comment.
Yep, that makes sense for now. In the long term it would be nice if there was a single library that we relied on for all OME-Zarr parsing, ideally something that integrates with a thumbnail library like ome-zarr.js. I started an issue over there.
There was a problem hiding this comment.
A related question - should I be switching all my version numbers in the app from the Zarr versions (2, 3) to using OME-Zarr version numbers when possible - i.e., only using Zarr version numbers when there isn't OME metadata available?
There was a problem hiding this comment.
Zarr version is distinct from OME-Zarr version. Those are two separate version numbers. However, OME-Zarr 0.5+ is only defined on Zarr version 3 at the moment.
There was a problem hiding this comment.
Here's what this looks like now: https://github.com/JaneliaSciComp/fileglancer/pull/307/changes#diff-472127167cec0c0cf8f508d637d7736126efccafdbf76cc0513fa01a494f7b16R49
See commits 10ab39e, 5b91435, da940a1
How does this look?
Add a gitignored frontend/viewers.config.yaml that, when present, is bundled instead of the committed default. Uses a Vite regex alias to correctly handle the ?raw query suffix. Includes a template file users can copy and customize without touching committed source.
- necessary for supporting unit test of how vite resolves the viewers.config.yaml file path at startup
- includes mock viewers.config.yaml file for CI
…EffectiveZarrStorageVersion utilities - also splits availableVersions in the ZarrMetadataResult type into availableZarrVersions (number[]) and availableOmeZarrVersions (string[])
… and read versions from content
- copy icon had changed from img to svg - i saved the vizarr/avivator logo under avivator.png, so needed to update vizarr -> avivator
Clickup id: 86advt10e
This PR implements dynamic viewer configuration for Zarr datasets via a build-time viewers.config.yaml file and integration of the @bioimagetools/capability-manifest library for automatic dataset-viewer compatibility detection.
Changes
Created viewers.config.yaml with documentation for customizing viewer configuration. This file specifies available viewers for a Fileglancer deployment. The default configuration is our current viewers: Neuroglancer, Avivator, Vol-E, and OME-Zarr Validator. Configuration is bundled at build time.
Added ViewersContext for managing viewer configuration. This context:
/publicfolder bundled into the application during the build (this is currently the case since the manifests are not present on our main branch, only in this PR branch)getCompatibleViewers()function to determine dataset-viewer compatibility using the capability-manifest library for compatibility detectionRefactored useZarrMetadata to dynamically generate
openWithToolUrlsusing ViewersContext. URLs are generated only for compatible viewers based on thegetCompatibleViewersfunction.Updated DataToolLinks to render viewer buttons dynamically by mapping over valid viewers from ViewersContext. The "Copy URL" tool is always available when a data link is available.
Added logo management system with convention-based naming (
{name}.png), custom logo override support, and fallback logo for missing assets.Added unit tests for config parsing and component tests for DataToolLinks.
Updated documentation with a ViewersConfiguration.md guide and updated CLAUDE.md with viewer configuration instructions.