Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions src/ZarrPixelSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type VivPixelData = {
export class ZarrPixelSource implements viv.PixelSource<Array<string>> {
readonly labels: viv.Labels<Array<string>>;
readonly tileSize: number;
originalSizeZ: number;
readonly dtype: viv.SupportedDtype;
readonly #arr: zarr.Array<zarr.NumberDataType | zarr.BigintDataType, zarr.Readable>;
readonly #transform: (
Expand All @@ -43,6 +44,7 @@ export class ZarrPixelSource implements viv.PixelSource<Array<string>> {
this.#arr = arr;
this.labels = options.labels;
this.tileSize = options.tileSize;
this.originalSizeZ = this.shape[this.labels.indexOf("z")];
/**
* Some `zarrita` data types are not supported by Viv and require casting.
*
Expand All @@ -64,6 +66,10 @@ export class ZarrPixelSource implements viv.PixelSource<Array<string>> {
}
}

setOriginalSizeZ(sizeZ: number) {
this.originalSizeZ = sizeZ;
}

get #width() {
const lastIndex = this.shape.length - 1;
return this.shape[this.labels.indexOf("c") === lastIndex ? lastIndex - 1 : lastIndex];
Expand Down Expand Up @@ -103,14 +109,21 @@ export class ZarrPixelSource implements viv.PixelSource<Array<string>> {
signal?: AbortSignal;
}): Promise<viv.PixelData> {
const { x, y, selection, signal } = options;
let zarrSelection = buildZarrSelection(selection, {
labels: this.labels,
slices: {
x: zarr.slice(x * this.tileSize, Math.min((x + 1) * this.tileSize, this.#width)),
y: zarr.slice(y * this.tileSize, Math.min((y + 1) * this.tileSize, this.#height)),
},
});
// If we know the original sizeZ, adjust the z index of this array to account for downsampling
let zIndex = this.labels.indexOf("z");
if (this.originalSizeZ > 0 && zarrSelection[zIndex] instanceof Number) {
let z = zarrSelection[zIndex] as number;
zarrSelection[zIndex] = Math.floor((z * this.shape[zIndex]) / this.originalSizeZ);
}
return this.#fetchData({
selection: buildZarrSelection(selection, {
labels: this.labels,
slices: {
x: zarr.slice(x * this.tileSize, Math.min((x + 1) * this.tileSize, this.#width)),
y: zarr.slice(y * this.tileSize, Math.min((y + 1) * this.tileSize, this.#height)),
},
}),
selection: zarrSelection,
signal,
});
}
Expand Down
5 changes: 5 additions & 0 deletions src/ome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ export async function loadOmeMultiscales(
meta = await defaultMeta(lowresSource, axis_labels);
}
const loader = data.map((arr) => new ZarrPixelSource(arr, { labels: axis_labels, tileSize }));
// Set originalSizeZ for all ZarrPixelSource arrays so they can adjust for Z downsampling
let originalSizeZ = loader[0].shape[axis_labels.indexOf("z")];
for (const l of loader) {
l.setOriginalSizeZ(originalSizeZ);
}
const labels = await resolveOmeLabelsFromMultiscales(grp);
return {
loader: loader,
Expand Down