Skip to content
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

Merged
merged 6 commits into from
Jul 5, 2024
Merged

Feature/zarr thumbnails #143

merged 6 commits into from
Jul 5, 2024

Conversation

BrianWhitneyAI
Copy link
Contributor

@BrianWhitneyAI BrianWhitneyAI commented Jun 25, 2024

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.

return await renderZarrThumbnailURL(this.path);
} catch (error) {
console.error("Error generating Zarr thumbnail:", error);
throw new Error("Unable to generate Zarr thumbnail");
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

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

Copy link
Contributor

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

Copy link
Contributor Author

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;
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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

@SeanLeRoy
Copy link
Contributor

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined is implicit

Suggested change
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(undefined);
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved in 552170f552170f552170f

@@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined is implicit

Suggested change
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>(undefined);
const [thumbnailPath, setThumbnailPath] = React.useState<string | undefined>();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved in 552170f552170f552170f

@@ -0,0 +1,101 @@
import * as zarr from "@zarrita/core";
import { FetchStore } from "@zarrita/storage";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

Copy link
Contributor Author

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")) {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved in 552170f552170f552170f

}));
}

export async function renderZarrThumbnailURL(zarrUrl: string): Promise<string> {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BrianWhitneyAI
Copy link
Contributor Author

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

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
download

Copy link
Contributor

@SeanLeRoy SeanLeRoy left a 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

Copy link
Contributor

@aswallace aswallace left a 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:
Screenshot 2024-07-03 at 5 07 51 PM

Copy link
Contributor

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);
Copy link
Contributor

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
Copy link
Contributor

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

@BrianWhitneyAI BrianWhitneyAI merged commit cdff2cb into main Jul 5, 2024
3 checks passed
@BrianWhitneyAI BrianWhitneyAI deleted the feature/zarr-thumbnails branch July 5, 2024 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatically detect OME ZARR thumbnail location
3 participants