-
Notifications
You must be signed in to change notification settings - Fork 1
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
Feature/zarr thumbnails #143
Conversation
return await renderZarrThumbnailURL(this.path); | ||
} catch (error) { | ||
console.error("Error generating Zarr thumbnail:", error); | ||
throw new Error("Unable to generate Zarr thumbnail"); |
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 curious if we need both the console error and the throw here
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.
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 these are a symptom of lots of iterations trying to read Zarr images and adding tries to bypass some of the errors
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.
Definitely think error handling is good move, just that having both throw & log seemed redundant
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.
What would we want to add in error handling here? Additional context that it comes from trying to render the image? The error is re-raised previously with the added console log so my thought was just let the error show if something was broken.
return canvas.toDataURL("image/png"); | ||
} catch (error) { | ||
console.error("Error reading Zarr image:", error); | ||
throw 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.
Same question here, both console and throw needed?
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.
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.
tiny nit -- feels like this .ts file name should start with lowercase?
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 this consistent in our repo? I tried to match to other files though admittedly those are .tsx files so I may be missing some rule.
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.
In general I've been seeing .tsx and class files capitalized, .ts/util files lower case, but I'm not sure how consistent that is
Were you able to test out NucMorph files? I sent you one previously via Slack - it would be cool to know it works on other ZARRs beyond those in variance |
@@ -78,14 +78,20 @@ function resizeHandleDoubleClick() { | |||
export default function FileDetails(props: Props) { | |||
const [windowState, windowDispatch] = React.useReducer(windowStateReducer, INITIAL_STATE); | |||
const [fileDetails, isLoading] = useFileDetails(); | |||
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(undefined); |
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.
undefined
is implicit
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(undefined); | |
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(); |
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.
@@ -78,14 +78,20 @@ function resizeHandleDoubleClick() { | |||
export default function FileDetails(props: Props) { | |||
const [windowState, windowDispatch] = React.useReducer(windowStateReducer, INITIAL_STATE); | |||
const [fileDetails, isLoading] = useFileDetails(); | |||
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(undefined); |
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.
undefined
is implicit
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(undefined); | |
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(); |
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.
@@ -0,0 +1,101 @@ | |||
import * as zarr from "@zarrita/core"; | |||
import { FetchStore } from "@zarrita/storage"; |
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.
Unused?
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 all of these are used. Am I missing something? zarr is used for accessing the root. FetchStore is used for accessing the store from url and zarrGet is used to create a lowest resolution view.
} | ||
if (this.cloudPath.endsWith(".zarr")) { | ||
try { | ||
if (this.path?.startsWith("/allen")) { |
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 don't think the code could ever make it here for this condition because of the return on line 168 checking for the same condition.
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.
})); | ||
} | ||
|
||
export async function renderZarrThumbnailURL(zarrUrl: string): Promise<string> { |
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.
Could you add a comment describing this function and/or more comments across the function to explain the various things going 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 tried it with this one https://allencell.s3.amazonaws.com/aics/nuc_morph_data/data_for_analysis/baseline_colonies/20200323_09_small/seg.ome.zarr and the image rendered to |
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.
LGTM I'm excited to try this out with everything else altogether
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.
Works for me locally! Below are thoughts that don't need to be addressed rn:
My only concern is that this requires a lot of network calls at once, including multiple expected non-breaking 404s per file. The main build up is on initial load, which makes sense, but also happens if you just click away from a file that's already loaded once and click back into it, so they can multiply quickly and cause some slowness. I'm wondering if there is some way we can cache...something?, but not sure if that's a realistic possibility.
Here's the network log after clicking into one file after clearing logs from initial page load:
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.
In general I've been seeing .tsx and class files capitalized, .ts/util files lower case, but I'm not sure how consistent that is
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(); | ||
React.useEffect(() => { | ||
if (file) { | ||
file.getPathToThumbnail().then(setThumbnailPath); |
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.
Since this can take some time w/ the zarr network calls, we might consider adding a loading icon specific to the thumbnail, especially since otherwise it can display the wrong thumbnail for a while
@@ -160,24 +161,26 @@ export default class FileDetail { | |||
return this.fileDetail.annotations.find((annotation) => annotation.name === annotationName); | |||
} | |||
|
|||
public getPathToThumbnail(): string | undefined { | |||
public async getPathToThumbnail(): Promise<string | undefined> { | |||
// If the thumbnail is a relative path on the allen drive then preprend it to |
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.
nit, old unrelated typo: prepend
Description
The purpose of this PR is to render thumbnails for zarr images. Resolves #89. This includes finding the lowest resolution version and taking a middle slice to ensure the highest possibility of a useful thumbnail.
Issues
This feature is heavily dependent on the access level of the file, often failing with CORS issues. I believe this is all server-side, so if we want to have this feature usable with FMS data we need to adjust those permissions.
Testing
Since we cannot test on existing data in FMS we need to import our data. I used the variance dataset to check this. I was only able to import this dataset successfully on Mac so there still might be some weird things here. If you use the variance dataset then make sure to remove the thumbnail column.