Skip to content
Merged
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
97 changes: 71 additions & 26 deletions metazarr/demo/detail-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,90 @@ function createNodeInfo(node) {
addInfoRow(dl, "Fill Value", formatFillValue(meta.fill_value));
}

if (node.chunks) addInfoRow(dl, "Chunks", formatChunks(node.chunks));

// Computed: chunk count, chunk size, uncompressed size
if (node.shape) {
// Chunk and shard info
{
const shardingCodec =
meta?.zarr_format === 3 &&
meta?.codecs?.find((c) => c.name === "sharding_indexed");
const innerChunkShape = shardingCodec?.configuration?.chunk_shape;
// Use chunk_grid from raw metadata for the shard (outer) shape, since
// node.chunks may come from zarrita which resolves to inner chunk shape.
const shardShape = shardingCodec
? meta?.chunk_grid?.configuration?.chunk_shape
: null;
const chunkShape = getChunkShape(node);
const byteSize = dtypeByteSize(node.dtype);

if (chunkShape) {
const numChunks = node.shape.map((s, i) => Math.ceil(s / chunkShape[i]));
const totalChunks = numChunks.reduce((a, b) => a * b, 1);
if (shardingCodec && innerChunkShape && shardShape && node.shape) {
// --- Sharded array: chunks then shards ---
addInfoRow(dl, "Chunk Shape", `[${innerChunkShape.join(", ")}]`);

const chunkCount = node.shape.map((s, i) =>
Math.ceil(s / innerChunkShape[i]),
);
const totalChunks = chunkCount.reduce((a, b) => a * b, 1);
addInfoRow(
dl,
"Chunk Count",
`${totalChunks.toLocaleString()}` +
(numChunks.length > 1 ? ` [${numChunks.join(" \u00d7 ")}]` : ""),
`${totalChunks.toLocaleString()} [${chunkCount.join(" \u00d7 ")}]`,
);

if (byteSize) {
const chunkElements = chunkShape.reduce((a, b) => a * b, 1);
const chunkElements = innerChunkShape.reduce((a, b) => a * b, 1);
addInfoRow(dl, "Chunk Size", formatBytes(chunkElements * byteSize));
}

const chunksPerShard = shardShape.map((s, i) =>
Math.ceil(s / innerChunkShape[i]),
);
addInfoRow(
dl,
"Chunks per Shard",
`[${chunksPerShard.join(", ")}]`,
);

addInfoRow(dl, "Shard Shape", `[${shardShape.join(", ")}]`);

const shardCount = node.shape.map((s, i) =>
Math.ceil(s / shardShape[i]),
);
const totalShards = shardCount.reduce((a, b) => a * b, 1);
addInfoRow(
dl,
"Shard Count",
`${totalShards.toLocaleString()} [${shardCount.join(" \u00d7 ")}]`,
);

if (byteSize) {
const shardElements = shardShape.reduce((a, b) => a * b, 1);
addInfoRow(dl, "Shard Size", formatBytes(shardElements * byteSize));
}
} else {
// --- Non-sharded array ---
if (node.chunks) addInfoRow(dl, "Chunks", formatChunks(node.chunks));

if (node.shape && chunkShape) {
const numChunks = node.shape.map((s, i) =>
Math.ceil(s / chunkShape[i]),
);
const totalChunks = numChunks.reduce((a, b) => a * b, 1);
addInfoRow(
dl,
"Chunk Count",
`${totalChunks.toLocaleString()}` +
(numChunks.length > 1
? ` [${numChunks.join(" \u00d7 ")}]`
: ""),
);

if (byteSize) {
const chunkElements = chunkShape.reduce((a, b) => a * b, 1);
addInfoRow(dl, "Chunk Size", formatBytes(chunkElements * byteSize));
}
}
}

if (byteSize) {
if (node.shape && byteSize) {
const totalElements = node.shape.reduce((a, b) => a * b, 1);
addInfoRow(dl, "Uncompressed", formatBytes(totalElements * byteSize));
}
Expand All @@ -99,21 +159,6 @@ function createNodeInfo(node) {
// Codecs (v3) or Compressor + Filters (v2)
if (meta?.zarr_format === 3 && meta?.codecs) {
addInfoRow(dl, "Codecs", formatCodecs(meta.codecs));

// Sharding detection
const shardingCodec = meta.codecs.find(
(c) => c.name === "sharding_indexed",
);
if (shardingCodec?.configuration?.chunk_shape) {
const subShape = shardingCodec.configuration.chunk_shape;
const subByteSize = dtypeByteSize(node.dtype);
let shardLabel = `Sub-chunks: [${subShape.join(", ")}]`;
if (subByteSize) {
const subElements = subShape.reduce((a, b) => a * b, 1);
shardLabel += ` (${formatBytes(subElements * subByteSize)})`;
}
addInfoRow(dl, "Sharding", shardLabel);
}
} else if (meta?.zarr_format === 2) {
if (meta.compressor) {
addInfoRow(dl, "Compressor", formatV2Codec(meta.compressor));
Expand Down
1 change: 1 addition & 0 deletions metazarr/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ <h1>metazarr</h1>
<span class="examples-label">Examples:</span>
<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>
<button class="example-chip" data-url="s3://us-west-2.opendata.source.coop/pangeo/geozarr-examples/TCI.zarr">Sentinel-2</button>
<button class="example-chip" data-url="s3://us-west-2.opendata.source.coop/tge-labs/aef-mosaic">AEF Mosaic (sharded)</button>
</div>
<div id="status"></div>
<a href="https://github.com/zarr-developers/geozarr-toolkit" target="_blank" rel="noopener noreferrer" class="github-link" aria-label="GitHub repository">
Expand Down
Loading