Skip to content

Commit

Permalink
fix-up attrs resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
manzt committed Jul 15, 2024
1 parent 46ab7e4 commit 938b9b4
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 33 deletions.
67 changes: 44 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
"@hms-dbmi/viv": "^0.16.0",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@zarrita/core": "^0.0.3",
"@zarrita/indexing": "^0.0.3",
"@zarrita/storage": "^0.0.2",
"deck.gl": "^8.9.34",
"imjoy-rpc": "^0.2.23",
"jotai": "^1.0.0",
"just-debounce-it": "^3.1.1",
"p-map": "^5.5.0",
"quick-lru": "^6.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"zarrita": "^0.4.0-next.14"
},
"scripts": {
"start": "vite",
Expand Down
5 changes: 3 additions & 2 deletions src/codecs/jpeg2k.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import { JpxImage } from 'https://cdn.jsdelivr.net/gh/mozilla/pdf.js@30bd5f0/src/core/jpx.js';

export default class Jpeg2k {
static codecId: 'jpeg2k';
static fromConfig(_: Record<string, any>): Jpeg2k {
kind = 'bytes_to_bytes' as const;
static codecId = 'jpeg2k';
static fromConfig(): Jpeg2k {
return new Jpeg2k();
}
encode(_: Uint8Array): never {
Expand Down
4 changes: 3 additions & 1 deletion src/io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,14 @@ function isMultiscales(attrs: zarr.Attributes): attrs is { multiscales: Ome.Mult
}

export async function createSourceData(config: ImageLayerConfig): Promise<SourceData> {
console.log('createSourceData', config);
const node = await open(config.source);
console.log('node', node);
let data: zarr.Array<zarr.DataType, Readable>[];
let axes: Ome.Axis[] | undefined;

if (node instanceof zarr.Group) {
const attrs = node.attrs;
let attrs = resolveAttrs(node.attrs);

Check failure on line 112 in src/io.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find name 'resolveAttrs'.

Check failure on line 112 in src/io.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find name 'resolveAttrs'.

if (isOmePlate(attrs)) {
return loadPlate(config, node, attrs.plate);
Expand Down
3 changes: 2 additions & 1 deletion src/ome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
loadMultiscales,
parseMatrix,
range,
resolveAttrs,
} from './utils';

export async function loadWell(
Expand Down Expand Up @@ -46,7 +47,7 @@ export async function loadWell(
// Need to get acquisitions metadata from parent Plate
const platePath = grp.path.replace(`${row}/${col}`, '');
const plate = await zarr.open(grp.resolve(platePath));
const plateAttrs = plate.attrs as { plate: Ome.Plate };
const plateAttrs = resolveAttrs(plate.attrs) as { plate: Ome.Plate };
acquisitions = plateAttrs?.plate?.acquisitions ?? [];

// filter imagePaths by acquisition
Expand Down
35 changes: 33 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,23 @@ export async function open(source: string | Readable) {
export async function getAttrsOnly<T = unknown>(location: zarr.Location<Readable>, path?: string) {
const decoder = new TextDecoder();
if (path) location = location.resolve(path);
const bytes = await location.store.get(location.resolve('.zattrs').path);
return bytes ? (JSON.parse(decoder.decode(bytes)) as T) : {};

// zarr meta and attrs are stored in the same file for v3,
// so first we can just open the node and get the attrs,
// otherwise we need to open the .zattrs file for v2.
let attrs = await zarr.open
.v3(location)
.then((node) => node.attrs)
.catch(async (err) => {
if (!(err instanceof zarr.NodeNotFoundError)) {
throw err;
}
const v2AttrsLocation = location.resolve('.zattrs');
const maybeBytes = await location.store.get(v2AttrsLocation.path);
return maybeBytes ? JSON.parse(decoder.decode(maybeBytes)) : {};
});

return resolveAttrs(attrs) as T;
}

export async function loadMultiscales(grp: zarr.Group<Readable>, multiscales: Ome.Multiscale[]) {
Expand Down Expand Up @@ -348,6 +363,9 @@ function getV2DataType(dtype: string) {

type Selection = (number | Omit<Slice, 'indices'> | null)[];

/**
* This is needed by @hms-dbmi/viv to get raw data from a Zarr.js style interface.
*/
export function createZarrArrayAdapter(arr: zarr.Array<zarr.DataType>): any {
return new Proxy(arr, {
get(target, prop) {
Expand Down Expand Up @@ -376,3 +394,16 @@ export function createZarrArrayAdapter(arr: zarr.Array<zarr.DataType>): any {
},
});
}

/**
* Extracts the OME metadata from the zarr attributes
*
* TODO: We should use zod to handle this
*/
export function resolveAttrs(attrs: zarr.Attributes): zarr.Attributes {
if ('ome' in attrs) {
// @ts-expect-error - handles v0.5
return attrs.ome;
}
return attrs;
}

0 comments on commit 938b9b4

Please sign in to comment.