Skip to content

Commit d53f61a

Browse files
authored
fix: improve sharding information display (#13)
1 parent 31f240b commit d53f61a

2 files changed

Lines changed: 72 additions & 26 deletions

File tree

metazarr/demo/detail-panel.js

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -67,30 +67,90 @@ function createNodeInfo(node) {
6767
addInfoRow(dl, "Fill Value", formatFillValue(meta.fill_value));
6868
}
6969

70-
if (node.chunks) addInfoRow(dl, "Chunks", formatChunks(node.chunks));
71-
72-
// Computed: chunk count, chunk size, uncompressed size
73-
if (node.shape) {
70+
// Chunk and shard info
71+
{
72+
const shardingCodec =
73+
meta?.zarr_format === 3 &&
74+
meta?.codecs?.find((c) => c.name === "sharding_indexed");
75+
const innerChunkShape = shardingCodec?.configuration?.chunk_shape;
76+
// Use chunk_grid from raw metadata for the shard (outer) shape, since
77+
// node.chunks may come from zarrita which resolves to inner chunk shape.
78+
const shardShape = shardingCodec
79+
? meta?.chunk_grid?.configuration?.chunk_shape
80+
: null;
7481
const chunkShape = getChunkShape(node);
7582
const byteSize = dtypeByteSize(node.dtype);
7683

77-
if (chunkShape) {
78-
const numChunks = node.shape.map((s, i) => Math.ceil(s / chunkShape[i]));
79-
const totalChunks = numChunks.reduce((a, b) => a * b, 1);
84+
if (shardingCodec && innerChunkShape && shardShape && node.shape) {
85+
// --- Sharded array: chunks then shards ---
86+
addInfoRow(dl, "Chunk Shape", `[${innerChunkShape.join(", ")}]`);
87+
88+
const chunkCount = node.shape.map((s, i) =>
89+
Math.ceil(s / innerChunkShape[i]),
90+
);
91+
const totalChunks = chunkCount.reduce((a, b) => a * b, 1);
8092
addInfoRow(
8193
dl,
8294
"Chunk Count",
83-
`${totalChunks.toLocaleString()}` +
84-
(numChunks.length > 1 ? ` [${numChunks.join(" \u00d7 ")}]` : ""),
95+
`${totalChunks.toLocaleString()} [${chunkCount.join(" \u00d7 ")}]`,
8596
);
8697

8798
if (byteSize) {
88-
const chunkElements = chunkShape.reduce((a, b) => a * b, 1);
99+
const chunkElements = innerChunkShape.reduce((a, b) => a * b, 1);
89100
addInfoRow(dl, "Chunk Size", formatBytes(chunkElements * byteSize));
90101
}
102+
103+
const chunksPerShard = shardShape.map((s, i) =>
104+
Math.ceil(s / innerChunkShape[i]),
105+
);
106+
addInfoRow(
107+
dl,
108+
"Chunks per Shard",
109+
`[${chunksPerShard.join(", ")}]`,
110+
);
111+
112+
addInfoRow(dl, "Shard Shape", `[${shardShape.join(", ")}]`);
113+
114+
const shardCount = node.shape.map((s, i) =>
115+
Math.ceil(s / shardShape[i]),
116+
);
117+
const totalShards = shardCount.reduce((a, b) => a * b, 1);
118+
addInfoRow(
119+
dl,
120+
"Shard Count",
121+
`${totalShards.toLocaleString()} [${shardCount.join(" \u00d7 ")}]`,
122+
);
123+
124+
if (byteSize) {
125+
const shardElements = shardShape.reduce((a, b) => a * b, 1);
126+
addInfoRow(dl, "Shard Size", formatBytes(shardElements * byteSize));
127+
}
128+
} else {
129+
// --- Non-sharded array ---
130+
if (node.chunks) addInfoRow(dl, "Chunks", formatChunks(node.chunks));
131+
132+
if (node.shape && chunkShape) {
133+
const numChunks = node.shape.map((s, i) =>
134+
Math.ceil(s / chunkShape[i]),
135+
);
136+
const totalChunks = numChunks.reduce((a, b) => a * b, 1);
137+
addInfoRow(
138+
dl,
139+
"Chunk Count",
140+
`${totalChunks.toLocaleString()}` +
141+
(numChunks.length > 1
142+
? ` [${numChunks.join(" \u00d7 ")}]`
143+
: ""),
144+
);
145+
146+
if (byteSize) {
147+
const chunkElements = chunkShape.reduce((a, b) => a * b, 1);
148+
addInfoRow(dl, "Chunk Size", formatBytes(chunkElements * byteSize));
149+
}
150+
}
91151
}
92152

93-
if (byteSize) {
153+
if (node.shape && byteSize) {
94154
const totalElements = node.shape.reduce((a, b) => a * b, 1);
95155
addInfoRow(dl, "Uncompressed", formatBytes(totalElements * byteSize));
96156
}
@@ -99,21 +159,6 @@ function createNodeInfo(node) {
99159
// Codecs (v3) or Compressor + Filters (v2)
100160
if (meta?.zarr_format === 3 && meta?.codecs) {
101161
addInfoRow(dl, "Codecs", formatCodecs(meta.codecs));
102-
103-
// Sharding detection
104-
const shardingCodec = meta.codecs.find(
105-
(c) => c.name === "sharding_indexed",
106-
);
107-
if (shardingCodec?.configuration?.chunk_shape) {
108-
const subShape = shardingCodec.configuration.chunk_shape;
109-
const subByteSize = dtypeByteSize(node.dtype);
110-
let shardLabel = `Sub-chunks: [${subShape.join(", ")}]`;
111-
if (subByteSize) {
112-
const subElements = subShape.reduce((a, b) => a * b, 1);
113-
shardLabel += ` (${formatBytes(subElements * subByteSize)})`;
114-
}
115-
addInfoRow(dl, "Sharding", shardLabel);
116-
}
117162
} else if (meta?.zarr_format === 2) {
118163
if (meta.compressor) {
119164
addInfoRow(dl, "Compressor", formatV2Codec(meta.compressor));

metazarr/demo/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ <h1>metazarr</h1>
1818
<span class="examples-label">Examples:</span>
1919
<button class="example-chip" data-url="https://s3.explorer.eopf.copernicus.eu/esa-zarr-sentinel-explorer-fra/tests-output/sentinel-2-l2a/S2B_MSIL2A_20260216T142149_N0512_R096_T25WFV_20260216T165051.zarr">EOPF</button>
2020
<button class="example-chip" data-url="s3://us-west-2.opendata.source.coop/pangeo/geozarr-examples/TCI.zarr">Sentinel-2</button>
21+
<button class="example-chip" data-url="s3://us-west-2.opendata.source.coop/tge-labs/aef-mosaic">AEF Mosaic (sharded)</button>
2122
</div>
2223
<div id="status"></div>
2324
<a href="https://github.com/zarr-developers/geozarr-toolkit" target="_blank" rel="noopener noreferrer" class="github-link" aria-label="GitHub repository">

0 commit comments

Comments
 (0)