ZarrSource can't open an array whose GeoZarr metadata is on its parent group
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 38/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- api
Research direction
Start in packages/deck.gl-zarr/src/zarr-source.ts at ZarrSource.open, following how variable is resolved and how geoZarrMetadata reaches the parser in packages/geozarr/src/parse.ts. Read examples/aef-mosaic/src/App.tsx for the working manual call that passes the root group's attributes. Done means open(root, { variable: "embeddings" }) reads the parent group's proj:/spatial: attributes, lets array attributes override them, leaves out the group's multiscales, and still lets geoZarrMetadata replace what open reads.
Written by the indexing model from the issue text.
Description
[!NOTE]
This issue was written by Claude (Claude Code), not by @kylebarron.
From the review of #812 (comment): ZarrSource should find the aef-mosaic example's GeoZarr metadata itself, perhaps by traversing child nodes.
Problem
The AEF store keeps its GeoZarr metadata on the root group: proj:code and all the spatial: keys. The data is embeddings, an int8 array directly inside the root. Its only attribute is _zarrs.
The conventions allow this layout. A group's proj: and spatial: attributes apply to the arrays directly inside it, but not to anything deeper, and an array can override them (proj, spatial).
ZarrSource.open reads a single node's attributes, so it can't open this store by itself. The example opens the array and passes the root's attributes along (App.tsx#L52-L64):
const root = await zarr.open.v3(store, { kind: "group" });
const opened = await zarr.open.v3(root.resolve(VARIABLE), {
kind: "array",
});
if (!opened.is("int8")) {
throw new Error(`Expected AEF embeddings to be int8, got ${opened.dtype}`);
}
// The GeoZarr metadata is on the root group, not on the array
const source = await ZarrSource.open(opened, {
geoZarrMetadata: root.attrs,
});
I tried each way of calling open on an in-memory store with the same layout:
| Call | Result |
|---|---|
ZarrSource.open(root) |
NotFoundError: Not found: v2 array. Metadata without multiscales describes one level at path "." (parse.ts#L105-L112), so open tries to open the root group as an array. |
ZarrSource.open(root, { variable: "embeddings" }) |
NotFoundError: Not found: v2 group. variable must name a group (zarr-source.ts#L126-L129). |
ZarrSource.open(embeddings) |
A ZodError for the missing spatial:dimensions. |
ZarrSource.open(embeddings, { geoZarrMetadata: root.attrs }) |
Works. |
Neither zarrita error says what's wrong.
Proposal
Let variable name an array as well as a group:
const root = await zarr.open.v3(store, { kind: "group" });
const source = await ZarrSource.open(root, { variable: "embeddings" });
variablenames an array:openreads theproj:andspatial:attributes of the group the array is in.- The array's own attributes override them.
- It leaves out the group's
multiscales, which describes the group's own levels.
variablenames a group: nothing changes.geoZarrMetadatastill replaces whateveropenwould read.ZarrSource.open(group): when the group's metadata has nomultiscales, it fails with an error that asks forvariable.
dynamical-zarr-ecmwf and nldas-icechunk also open their arrays themselves. They could use variable too, but their stores have no GeoZarr metadata, so they would keep passing geoZarrMetadata.
Questions
-
How an array's attributes override its group's.
- For
proj:, the array's definition should replace the group's whole. A merge key by key could leave the group'sproj:codebeside the array'sproj:wkt2, and the parser takesproj:codefirst (parse.ts#L34-L40). - For
spatial:, the convention gives two rules. A group's properties apply to arrays "that don't define their own". Arrays can "override or supplement" them. A merge key by key fits "supplement", for example a group'sspatial:dimensionswith an array'sspatial:transform.
- For
-
Checking the data type. The example opens the array partly to check
opened.is("int8"), which makes the source aZarrSource<"int8">. Ifopenopens the array, the caller gets aZarrSource<DataType>. Two ways to keep the check:- a type guard like zarrita's,
source.is("int8"); - a
dtypeoption thatopenchecks.
Today
ZarrSource.open<"int8">(group)compiles, but nothing checks it, sinceopencasts the arrays it opens. - a type guard like zarrita's,
-
Nested paths. For
variable: "a/b/embeddings", the array's group isa/b. Shouldopenopen that group too? Without consolidated metadata, that takes one more read. The alternative is to accept only arrays directly insidenode. -
An array passed as
node. ShouldZarrSource.open(embeddings)look for the array's group too? That also takes one more read, and withvariablethe caller can pass the group instead.
🤖 Written by Claude Code
- Dominant language
- TypeScript
- Stars
- 232
- Forks
- 34
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 82
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from developmentseed/deck.gl-raster
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
developmentseed/deck.gl-raster#798 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
developmentseed/deck.gl-raster#589 ·
Maintainers usually reply within 1 day
-
Add zarr-globe examplePossibly taken @kylebarron claimed this 7 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
developmentseed/deck.gl-raster#568 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
developmentseed/deck.gl-raster#816 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
developmentseed/deck.gl-raster#814 ·
Maintainers usually reply within 1 day
All issues in developmentseed/deck.gl-raster
Similar issues
-
Replace discontinued crypto-js in the themePossibly taken @aelmanaa claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
PaloAltoNetworks/docusaurus-openapi-docs#1689 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
solana-foundation/solana-web3.js#4015 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Maintainers usually reply within 1 day
-
documentation
Difficulty 1/5 1-3 hours Newbie friendliness 90/100
ivopogace/opencode-courier#422 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
chapel-lang/chapel-vscode#158 ·
Maintainers usually reply within 1 day