') + ')', '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('^' + ".*" + ', '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" + ', '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('^' + ".*" + ', '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); } })(); })(); Writing multiscale element to disk fails when configuring Dask to uses "processes" · Issue #1024 · scverse/spatialdata · GitHub
Skip to content

Writing multiscale element to disk fails when configuring Dask to uses "processes" #1024

Description

@ArneDefauw

When configuring dask to use "processes" instead of "threads", writing a multiscale element to disk fails. I get the error message:

File ~/VIB/harpy/.venv_harpy/lib/python3.12/site-packages/spatialdata/_core/spatialdata.py:1177, in SpatialData.write(self, file_path, overwrite, consolidate_metadata, update_sdata_path, sdata_formats)
1174 store.close()
1176 for element_type, element_name, element in self.gen_elements():
-> 1177 self._write_element(
1178 element=element,
1179 zarr_container_path=file_path,
...
--> 120 if group.metadata.zarr_format == 3 and len(multiscales := group.metadata.attributes["ome"]["multiscales"]) != 1:
121 len_scales = len(multiscales)
122 raise ValueError(f"The length of multiscales metadata should be 1, found the length to be {len_scales}")
KeyError: 'ome'

Minimal example to reproduce:

importosfromspatialdata.modelsimportImage2DModelfromspatialdata.datasetsimportblobsimportdaskwithdask.config.set(scheduler='processes'):
sdata=blobs()
sdata=sdata.subset( element_names=[ "blobs_image" ] )
sdata.write(os.path.join( os.environ.get("TMPDIR"), "sdata.zarr" ), overwrite=True ) # this worksprint( "done" )
sdata=blobs()
sdata=sdata.subset( element_names=[ "blobs_multiscale_image" ] )
sdata.write(os.path.join( os.environ.get("TMPDIR"), "sdata.zarr" ), overwrite=True )
# this fails with#--> 120 if group.metadata.zarr_format == 3 and len(multiscales := group.metadata.attributes["ome"]["multiscales"]) != 1:# 121 len_scales = len(multiscales)# 122 raise ValueError(f"The length of multiscales metadata should be 1, found the length to be {len_scales}")#KeyError: 'ome'withdask.config.set(scheduler='threads'):
sdata=blobs()
sdata=sdata.subset( element_names=[ "blobs_image" ] )
sdata.write(os.path.join( os.environ.get("TMPDIR"), "sdata.zarr" ), overwrite=True )
print( "done" )
sdata=blobs()
sdata=sdata.subset( element_names=[ "blobs_multiscale_image" ] )
sdata.write(os.path.join( os.environ.get("TMPDIR"), "sdata.zarr" ), overwrite=True )
print("done")

I tested this on MacOS and CentOS, and got the same error message.

Working with spatialdata==0.6.0, spatial_image==1.2.3 and multiscale_spatial_image==2.0.3.

I also noticed, for images and labes, that the layer in the dask graph that starts with "from-zarr-" is no longer materialized when the spatialdata object is backed by a zarr store (zarr>=3). Probably this is unrelated to the current issue, but I found this a bit strange, since this was not the case in earlier versions of spatialdata(<0.5.0), see https://github.com/saeyslab/harpy/blob/609d639c7578a4c64c3eede4c974d4e90f982910/src/harpy/_tests/test_image/test_manager.py#L47

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions