-
Notifications
You must be signed in to change notification settings - Fork 7
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
Load single slices at higher resolution #163
Conversation
src/loaders/IVolumeLoader.ts
Outdated
// shape: [t, c, z, y, x] | ||
shape: number[] = [0, 0, 0, 0, 0]; | ||
// spacing: [t, c, z, y, x]; generally expect 1 for non-spatial dimensions | ||
spacing: number[] = [1, 1, 1, 1, 1]; | ||
spaceUnit = "μm"; | ||
timeUnit = "s"; | ||
canLoad = true; |
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 suggest an explanatory comment here, something like:
// dims are small enough to fit within our preferred memory footprint (see `pickLevelToLoad`)
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.
wondering if this class is even the right place to store this...
src/Volume.ts
Outdated
const minScale = this.loadSpec.multiscaleLevel ?? 0; | ||
// Loaders should cache loaded dimensions so that this call blocks no more than once per valid `LoadSpec`. | ||
const dims = await this.loader?.loadDims(this.loadSpecRequired); | ||
if (dims && currentScale > minScale && dims[currentScale - 1].canLoad) { |
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 wonder if the canLoad could be a dynamic check here? I don't think it's too slow to call a function like pickLevelToLoad if it doesn't require network fetches but I forget how frequently this gets called.
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 guess I felt like the decision of which level to load was the loader's responsibility, since pickLevelToLoad
and the MAX_ATLAS_DIMENSION
constant live in the same file as OMEZarrLoader
. I kind of agree though that this ought to be treated more like a global limit. Do we make that official by moving those items into VolumeLoaderUtils and importing/calling pickLevelToLoad
here? This is as opposed to calling it internally in loadDims
, which is what is done now.
pickLevelToLoad
itself doesn't require network fetches, it just takes dimensions and performs a bit of logic. Those dimensions, however, need to be fetched. This is the problem I referred to in the PR description and in the comment on line 251 above: loaders need to be smart enough to ensure that providing dimensions rarely requires a fetch in practice. The behavior in this PR is:
- In
OMEZarrLoader
, all dims are fetched before loader construction andloadDims
will never block - In
TiffLoader
, metadata is fetched on the first call toloadDims
orloadVolumeData
and cached (so if the volume already has data,loadVolumeData
has been called andloadDims
won't block in practice) - In
JsonImageInfoLoader
, metadata is fetched on the first call toloadDims
orloadVolumeData
per timestep and cached. In practice, if this function callsloadVolumeData
after callingloadDims
, the firstloadDims
call will have cached the metadata that theloadVolumeData
would have required so checking dims first adds no additional work.
Moving the pickLevelToLoad
call won't change these rules on when this function has to wait for the network.
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.
Yea I basically agree with everything you said here.
- pickleveltoload can be a utils-like shared function, or even a IVolumeLoader method that returns 0 by default and only does something nontrivial in omezarrloader.
- all dims could be fetched at or close to loader creation time. Then they will just be available and no call to loadDims would have to fetch anything (though they could if they wanted?)
Co-authored-by: toloudis <toloudis@users.noreply.github.com>
private async getJsonImageInfo(time: number): Promise<JsonImageInfo> { | ||
const cachedInfo = this.jsonInfo[time]; | ||
if (cachedInfo) { | ||
return cachedInfo; | ||
} | ||
|
||
const response = await fetch(this.urls[time]); |
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 like this optimization!
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.
Agree with Dan that I'm not totally sold on VolumeDims
tracking whether it can be loaded? It seems like that should be tracked by a system external to it, but I'm fine to talk about tradeoffs too.
…animated/volume-viewer into fix/load-hires-slice
I tried running this to test it, and I ran into an error? Repro:
It's possible this is related to the Vast outage today. Will check again later. |
Still getting this bug today. This is all I'm getting from the console:
|
If I have any coding time today I'll try to take a look at this error message. This is an important change to get in soon. |
The error here is indeed an uncaught promise exception that occurs when we cancel a request. You can see some hints of this by changing
Another way of saying this is: |
Co-authored-by: Peyton Lee <peyton.lee@alleninstitute.org>
Resolves #157: If a 3d volume is loaded, the user switches to z-slice mode, and a higher resolution level is available to load, reload at that higher resolution.
This is accomplished using the
loadDims
method onIVolumeLoader
(unused until now), which loads the dimensions of a volume without loading any data. I made the following changes to makeloadDims
a good solution to this issue:loadDims
returns an array ofVolumeDims
objects for each available scale level. I added the propertycanLoad: boolean
to this type to indicate whether a level can be loaded given the specifications.loadDims
isasync
,updateRequiredData
must now beasync
too. This is a bummer, so to compensate, I tried to ensure thatloadDims
rarely or never isasync
in practice.I also got rid of the
scene
property ofLoadSpec
, given that the only loader that supports scenes right now (OmeZarrLoader
) must be bound to a single scene on construction.