Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Fill missing chunks by williamsnell · Pull Request #3748 · zarr-developers/zarr-python · GitHub
Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fill missing chunks by williamsnell · Pull Request #3748 · zarr-developers/zarr-python · GitHub
Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fill missing chunks by williamsnell · Pull Request #3748 · zarr-developers/zarr-python · GitHub
Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Fill missing chunks by williamsnell · Pull Request #3748 · zarr-developers/zarr-python · GitHub
Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fill missing chunks by williamsnell · Pull Request #3748 · zarr-developers/zarr-python · GitHub
Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fill missing chunks by williamsnell · Pull Request #3748 · zarr-developers/zarr-python · GitHub
Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Fill missing chunks by williamsnell · Pull Request #3748 · zarr-developers/zarr-python · GitHub
Skip to content

Fill missing chunks - #3748

Merged
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks
Apr 2, 2026
Merged

Fill missing chunks#3748
d-v-b merged 31 commits into
zarr-developers:mainfrom
williamsnell:fill-missing-chunks

Conversation

@williamsnell

@williamsnellwilliamsnell commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Add config options for whether a missing chunk should:

  • appear as a chunk filled with fill_value (current behaviour; retained as default)
  • raise a MissingChunkError

This PR is entirely based on the work of @tomwhite in this issue. I've started this PR as this an important feature that I'd like to see merged.
I've added a test (based on the demo in the issue) and a minor docs tweak.

Questions:

  • I've added an example to config.md - is this the right place?

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

@github-actionsgithub-actionsBot added needs release notes Automatically applied to PRs which haven't added release notes and removed needs release notes Automatically applied to PRs which haven't added release notes labels Mar 5, 2026
@tomwhite

Copy link
Copy Markdown
Member

Thanks for doing this @williamsnell!

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

this is great @williamsnell! I'm wondering if this be exposed as part of the general array configuration, which is where write_empty_chunks currently sits.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

@d-v-b I've pushed a new commit moving this to ArrayConfig so we can look into the ergonomics. It does feel like a more natural fit, especially since users probably want to set write_empty_chunks and fill_missing_chunks as a pair.

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

@d-v-b

d-v-b commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

One note: I'm not sure how this interacts with Sharding now - following the existing code I hardcoded fill_missing_chunks=Truehere - does this imply there's no way to use fill_missing_chunks alongside sharding? If so, I can update the docs.

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

@williamsnell

williamsnell commented Mar 6, 2026

Copy link
Copy Markdown
ContributorAuthor

I don't think we want this new configuration option to change the behavior of the sharding codec. A missing subchunk inside a shard is conveyed explicitly via the shard index, so from the sharding codec's POV you can't have a subchunk appear missing due to a network error.

If I've understood correctly, we'll want to make this tweak to ShardingCodec._get_chunk_spec:

def _get_chunk_spec(self, shard_spec: ArraySpec) -> ArraySpec:
+ # Because the shard index and inner chunks should be stored+ # together, we detect missing data via the shard index.+ # The inner chunks defined here are thus allowed to return+ # None, even if fill_missing_chunks=False at the array level.+ config = replace(shard_spec.config, fill_missing_chunks=True)
return ArraySpec(
shape=self.chunk_shape,
dtype=shard_spec.dtype,
fill_value=shard_spec.fill_value,
- config=shard_spec.config,+ config=config,
prototype=shard_spec.prototype,
)

With this change, I think my previous point was wrong - we would be able to use fill_missing_chunk=False with sharding, and we would only raise an error if an entire shard (specifically its shard index) was missing.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

I've committed the change to _get_chunk_spec and rebased onto main.

I've also made two more changes:

  • Added some tests to check/codify expected behaviour around:
    • when a sharded array should or shouldn't raise MissingChunkError
    • how fill_missing_chunks is expected to interact with write_empty_chunks
  • Simplified the branching in codec_pipeline into if/elif/else.

@williamsnell

Copy link
Copy Markdown
ContributorAuthor

Is there a way to run coverage on this PR? I assumed it would pop up automatically, but apparently not.

Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/errors.py Outdated
Comment threadsrc/zarr/core/codec_pipeline.py Outdated
@d-v-b

Copy link
Copy Markdown
Contributor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

@williamsnell

williamsnell commented Mar 11, 2026

Copy link
Copy Markdown
ContributorAuthor

a few suggestions about the error class, if it's OK with you @williamsnell I'd be happy pushing those changes to this branch?

Go for it @d-v-b - thank you!

@d-v-bd-v-b added the benchmark Code will be benchmarked in a CI job. label Mar 11, 2026
@d-v-b

d-v-b commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

it's going in, thanks @williamsnell

@d-v-b
d-v-b merged commit 1bbc826 into zarr-developers:mainApr 2, 2026
26 checks passed
@williamsnell

williamsnell commented Apr 2, 2026

Copy link
Copy Markdown
ContributorAuthor

Thank you all!! Great to have this merged 😁

(As a small aside, I was scrolling through PRs and noticed we might be able to close the oldest open PR in the repo: #489Allow disabling filling of missing chunks. Just thought this was cool - in any case, great to have this feature now!)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@williamsnell@tomwhite@d-v-b@maxrjones@ilan-gold