Skip to content

Commit

Permalink
Use Proxy store for nested chunks (#85)
Browse files Browse the repository at this point in the history
* Use Proxy store for nested chunks

Code adapted from gzuidhof/zarr.js#88 (comment)
No Typescript types yet

* Only use nested(store) for correct version of OME-Zarr

* format fixes

* Move nested handling to io.ts

* Revert changes to ome.ts, removing isNested duplication
  • Loading branch information
will-moore authored Apr 20, 2021
1 parent 201585a commit 921d60a
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
loadMultiscales,
MAGENTA_GREEN,
MAX_CHANNELS,
nested,
open,
parseMatrix,
range,
Expand Down Expand Up @@ -115,13 +116,30 @@ function loadMultiChannel(config: MultichannelConfig, data: ZarrPixelSource<stri
};
}

function isNested(attrs: Ome.Attrs) {
let version;
if ('plate' in attrs) {
version = attrs.plate.version;
} else if ('omero' in attrs) {
version = attrs.multiscales[0].version;
} else if ('well' in attrs) {
version = attrs.well.version;
}
// OME-Zarr uses nested chunks since version 0.2
return version && version !== '0.1';
}

export async function createSourceData(config: ImageLayerConfig): Promise<SourceData> {
const node = await open(config.source);
let data: ZarrArray[];

if (node instanceof ZarrGroup) {
const attrs = (await node.attrs.asObject()) as Ome.Attrs;

if (isNested(attrs)) {
node.store = nested(node.store);
}

if ('plate' in attrs) {
return loadPlate(config, node, attrs.plate);
}
Expand Down
18 changes: 18 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ export async function loadMultiscales(grp: ZarrGroup, multiscales: Ome.Multiscal
throw Error('Multiscales metadata included a path to a group.');
}

export function nested(store: ZarrArray['store']) {
const get = (target: ZarrArray['store'], key: string | number | symbol) => {
if (key === 'getItem' || key === 'containsItem') {
return (path: string, ...args: unknown[]) => {
if (path.endsWith('.zarray') || path.endsWith('.zattrs') || path.endsWith('.zgroup')) {
return target[key](path, ...args);
}
const prefix = path.split('/');
const chunkKey = prefix.pop()!;
const newPath = [...prefix, chunkKey.replaceAll('.', '/')].join('/');
return target[key](newPath, ...args);
};
}
return Reflect.get(target, key);
};
return new Proxy(store, { get });
}

export function hexToRGB(hex: string): number[] {
if (hex.startsWith('#')) hex = hex.slice(1);
const r = parseInt(hex.slice(0, 2), 16);
Expand Down

0 comments on commit 921d60a

Please sign in to comment.