@biongff/vizarr 0.3.0-dev.2025-11-12.283baee9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
- package/.github/ISSUE_TEMPLATE/documentation_update.md +16 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- package/.github/ISSUE_TEMPLATE/maintenance.md +19 -0
- package/.github/ISSUE_TEMPLATE/optimisation_request.md +23 -0
- package/.github/ISSUE_TEMPLATE/support_request.md +25 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +21 -0
- package/.github/dependabot.yml +13 -0
- package/.github/workflows/build_and_deploy.yml +29 -0
- package/.github/workflows/npm-publish-dev.yml +49 -0
- package/.github/workflows/npm-publish.yml +20 -0
- package/.github/workflows/release.yml +37 -0
- package/.github/workflows/test.yml +21 -0
- package/.releaserc.json +29 -0
- package/CITATION.cff +56 -0
- package/CONTRIBUTING.md +82 -0
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/assets/favicon.ico +0 -0
- package/assets/favicon.png +0 -0
- package/assets/logo-wide.png +0 -0
- package/assets/logo-wide.svg +60 -0
- package/assets/logo.png +0 -0
- package/assets/logo.svg +36 -0
- package/assets/robots.txt +3 -0
- package/assets/screenshot.png +0 -0
- package/biome.json +34 -0
- package/index.html +24 -0
- package/main.ts +52 -0
- package/package.json +55 -0
- package/patches/@vivjs__loaders@0.17.2.patch +13 -0
- package/python/.python-version +1 -0
- package/python/README.md +14 -0
- package/python/Untitled.ipynb +40 -0
- package/python/deno.json +22 -0
- package/python/notebooks/IDR_example.ipynb +86 -0
- package/python/notebooks/README.md +35 -0
- package/python/notebooks/create_fixture.py +72 -0
- package/python/notebooks/getting_started.ipynb +217 -0
- package/python/notebooks/mandelbrot.ipynb +211 -0
- package/python/notebooks/spatial_transformations.ipynb +139 -0
- package/python/pyproject.toml +18 -0
- package/python/src/vizarr/__init__.py +10 -0
- package/python/src/vizarr/_widget.js +113 -0
- package/python/src/vizarr/_widget.py +67 -0
- package/python/uv.lock +2495 -0
- package/src/ZarrPixelSource.ts +182 -0
- package/src/codecs/jpeg2k.ts +22 -0
- package/src/codecs/register.ts +2 -0
- package/src/components/LayerController/AcquisitionController.tsx +46 -0
- package/src/components/LayerController/AddChannelButton.tsx +122 -0
- package/src/components/LayerController/AxisOptions.tsx +93 -0
- package/src/components/LayerController/AxisSlider.tsx +86 -0
- package/src/components/LayerController/AxisSliders.tsx +29 -0
- package/src/components/LayerController/ChannelController.tsx +84 -0
- package/src/components/LayerController/ChannelOptions.tsx +183 -0
- package/src/components/LayerController/ColorPalette.tsx +40 -0
- package/src/components/LayerController/Content.tsx +71 -0
- package/src/components/LayerController/Header.tsx +48 -0
- package/src/components/LayerController/Labels.tsx +73 -0
- package/src/components/LayerController/LayerFitToViewportButton.tsx +43 -0
- package/src/components/LayerController/LayerVisibilityButton.tsx +32 -0
- package/src/components/LayerController/OpacitySlider.tsx +25 -0
- package/src/components/LayerController/index.tsx +42 -0
- package/src/components/Menu.tsx +54 -0
- package/src/components/Viewer.tsx +136 -0
- package/src/hooks.ts +29 -0
- package/src/index.tsx +138 -0
- package/src/io.ts +276 -0
- package/src/layers/grid-layer.ts +214 -0
- package/src/layers/label-layer.ts +446 -0
- package/src/layers/viv-layers.ts +55 -0
- package/src/lru-store.ts +57 -0
- package/src/ome.ts +388 -0
- package/src/state.ts +202 -0
- package/src/theme.ts +80 -0
- package/src/types.ts +112 -0
- package/src/utils.ts +655 -0
- package/tsconfig.json +14 -0
- package/vite.config.js +47 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 516.22 126.13">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1, .cls-2, .cls-3, .cls-4 {
|
|
6
|
+
mix-blend-mode: multiply;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-1, .cls-2, .cls-3, .cls-5, .cls-6, .cls-7 {
|
|
10
|
+
stroke-width: 0px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.cls-1, .cls-7 {
|
|
14
|
+
fill: #ef4136;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.cls-2, .cls-5 {
|
|
18
|
+
fill: #27aae1;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.cls-3, .cls-6 {
|
|
22
|
+
fill: #39b54a;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.cls-8 {
|
|
26
|
+
isolation: isolate;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
</defs>
|
|
30
|
+
<g class="cls-8">
|
|
31
|
+
<g id="Layer_2" data-name="Layer 2">
|
|
32
|
+
<g id="Layer_1-2" data-name="Layer 1">
|
|
33
|
+
<polygon class="cls-2" points="72.82 40.61 49.38 0 7.5 0 72.82 113.14 138.15 0 96.27 0 72.82 40.61"/>
|
|
34
|
+
<polygon class="cls-1" points="102.06 12.99 72.82 63.62 43.59 12.99 15 12.99 80.32 126.13 145.65 12.99 102.06 12.99"/>
|
|
35
|
+
<polygon class="cls-3" points="72.82 63.62 43.59 12.99 0 12.99 65.32 126.13 130.65 12.99 102.06 12.99 72.82 63.62"/>
|
|
36
|
+
<g class="cls-4">
|
|
37
|
+
<path class="cls-7" d="M160.22,17.14h13.85l-20.36,92.36h-13.85l20.36-92.36Z"/>
|
|
38
|
+
<path class="cls-7" d="M172.96,98.15l63.84-68.82h-48.6l2.63-12.19h67.44l-2.35,11.35-64.11,68.82h49.85l-2.77,12.19h-68.41l2.49-11.35Z"/>
|
|
39
|
+
<path class="cls-7" d="M318.91,90.39h-45.28l-11.63,19.11h-15.92l57.05-92.36h17.31l16.34,92.36h-14.54l-3.32-19.11ZM280.41,78.07h37.25l-7.89-48.47-29.36,48.47Z"/>
|
|
40
|
+
<path class="cls-7" d="M387.58,73.92h-18.14l-7.75,35.59h-13.85l20.36-92.36h35.59c13.85,0,26.86,9.28,26.86,24.65,0,17.03-11.91,29.63-28.94,31.43l15.37,36.28h-15.23l-14.26-35.59ZM416.11,43.04c0-8.03-7.2-13.71-14.68-13.71h-22.02l-7.2,32.4h23.26c13.16,0,20.63-8.31,20.63-18.69Z"/>
|
|
41
|
+
<path class="cls-7" d="M473.16,73.92h-18.14l-7.75,35.59h-13.85l20.36-92.36h35.59c13.85,0,26.86,9.28,26.86,24.65,0,17.03-11.91,29.63-28.94,31.43l15.37,36.28h-15.23l-14.26-35.59ZM501.68,43.04c0-8.03-7.2-13.71-14.68-13.71h-22.02l-7.2,32.4h23.26c13.16,0,20.63-8.31,20.63-18.69Z"/>
|
|
42
|
+
</g>
|
|
43
|
+
<g class="cls-4">
|
|
44
|
+
<path class="cls-5" d="M160.22,17.14h13.85l-20.36,92.36h-13.85l20.36-92.36Z"/>
|
|
45
|
+
<path class="cls-5" d="M172.96,98.15l63.84-68.82h-48.6l2.63-12.19h67.44l-2.35,11.35-64.11,68.82h49.85l-2.77,12.19h-68.41l2.49-11.35Z"/>
|
|
46
|
+
<path class="cls-5" d="M318.91,90.39h-45.28l-11.63,19.11h-15.92l57.05-92.36h17.31l16.34,92.36h-14.54l-3.32-19.11ZM280.41,78.07h37.25l-7.89-48.47-29.36,48.47Z"/>
|
|
47
|
+
<path class="cls-5" d="M387.58,73.92h-18.14l-7.75,35.59h-13.85l20.36-92.36h35.59c13.85,0,26.86,9.28,26.86,24.65,0,17.03-11.91,29.63-28.94,31.43l15.37,36.28h-15.23l-14.26-35.59ZM416.11,43.04c0-8.03-7.2-13.71-14.68-13.71h-22.02l-7.2,32.4h23.26c13.16,0,20.63-8.31,20.63-18.69Z"/>
|
|
48
|
+
<path class="cls-5" d="M473.16,73.92h-18.14l-7.75,35.59h-13.85l20.36-92.36h35.59c13.85,0,26.86,9.28,26.86,24.65,0,17.03-11.91,29.63-28.94,31.43l15.37,36.28h-15.23l-14.26-35.59ZM501.68,43.04c0-8.03-7.2-13.71-14.68-13.71h-22.02l-7.2,32.4h23.26c13.16,0,20.63-8.31,20.63-18.69Z"/>
|
|
49
|
+
</g>
|
|
50
|
+
<g class="cls-4">
|
|
51
|
+
<path class="cls-6" d="M160.22,17.14h13.85l-20.36,92.36h-13.85l20.36-92.36Z"/>
|
|
52
|
+
<path class="cls-6" d="M172.96,98.15l63.84-68.82h-48.6l2.63-12.19h67.44l-2.35,11.35-64.11,68.82h49.85l-2.77,12.19h-68.41l2.49-11.35Z"/>
|
|
53
|
+
<path class="cls-6" d="M318.91,90.39h-45.28l-11.63,19.11h-15.92l57.05-92.36h17.31l16.34,92.36h-14.54l-3.32-19.11ZM280.41,78.07h37.25l-7.89-48.47-29.36,48.47Z"/>
|
|
54
|
+
<path class="cls-6" d="M387.58,73.92h-18.14l-7.75,35.59h-13.85l20.36-92.36h35.59c13.85,0,26.86,9.28,26.86,24.65,0,17.03-11.91,29.63-28.94,31.43l15.37,36.28h-15.23l-14.26-35.59ZM416.11,43.04c0-8.03-7.2-13.71-14.68-13.71h-22.02l-7.2,32.4h23.26c13.16,0,20.63-8.31,20.63-18.69Z"/>
|
|
55
|
+
<path class="cls-6" d="M473.16,73.92h-18.14l-7.75,35.59h-13.85l20.36-92.36h35.59c13.85,0,26.86,9.28,26.86,24.65,0,17.03-11.91,29.63-28.94,31.43l15.37,36.28h-15.23l-14.26-35.59ZM501.68,43.04c0-8.03-7.2-13.71-14.68-13.71h-22.02l-7.2,32.4h23.26c13.16,0,20.63-8.31,20.63-18.69Z"/>
|
|
56
|
+
</g>
|
|
57
|
+
</g>
|
|
58
|
+
</g>
|
|
59
|
+
</g>
|
|
60
|
+
</svg>
|
package/assets/logo.png
ADDED
|
Binary file
|
package/assets/logo.svg
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 145.65 126.13">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: #ef4136;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-1, .cls-2, .cls-3 {
|
|
10
|
+
mix-blend-mode: multiply;
|
|
11
|
+
stroke-width: 0px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.cls-2 {
|
|
15
|
+
fill: #27aae1;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.cls-3 {
|
|
19
|
+
fill: #39b54a;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.cls-4 {
|
|
23
|
+
isolation: isolate;
|
|
24
|
+
}
|
|
25
|
+
</style>
|
|
26
|
+
</defs>
|
|
27
|
+
<g class="cls-4">
|
|
28
|
+
<g id="Layer_2" data-name="Layer 2">
|
|
29
|
+
<g id="Layer_1-2" data-name="Layer 1">
|
|
30
|
+
<polygon class="cls-2" points="72.82 40.61 49.38 0 7.5 0 72.82 113.14 138.15 0 96.27 0 72.82 40.61"/>
|
|
31
|
+
<polygon class="cls-1" points="102.06 12.99 72.82 63.62 43.59 12.99 15 12.99 80.32 126.13 145.65 12.99 102.06 12.99"/>
|
|
32
|
+
<polygon class="cls-3" points="72.82 63.62 43.59 12.99 0 12.99 65.32 126.13 130.65 12.99 102.06 12.99 72.82 63.62"/>
|
|
33
|
+
</g>
|
|
34
|
+
</g>
|
|
35
|
+
</g>
|
|
36
|
+
</svg>
|
|
Binary file
|
package/biome.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
|
|
3
|
+
"organizeImports": {
|
|
4
|
+
"enabled": true
|
|
5
|
+
},
|
|
6
|
+
"formatter": {
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"indentStyle": "space",
|
|
9
|
+
"indentWidth": 2,
|
|
10
|
+
"lineEnding": "lf",
|
|
11
|
+
"lineWidth": 120
|
|
12
|
+
},
|
|
13
|
+
"linter": {
|
|
14
|
+
"enabled": true,
|
|
15
|
+
"rules": {
|
|
16
|
+
"recommended": true,
|
|
17
|
+
"style": {
|
|
18
|
+
"useConst": "off",
|
|
19
|
+
"noParameterAssign": "off"
|
|
20
|
+
},
|
|
21
|
+
"suspicious": {
|
|
22
|
+
"noShadowRestrictedNames": "off"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": {
|
|
27
|
+
"ignore": ["python"]
|
|
28
|
+
},
|
|
29
|
+
"vcs": {
|
|
30
|
+
"enabled": true,
|
|
31
|
+
"clientKind": "git",
|
|
32
|
+
"useIgnoreFile": true
|
|
33
|
+
}
|
|
34
|
+
}
|
package/index.html
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<link
|
|
6
|
+
rel="icon"
|
|
7
|
+
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🔬</text></svg>"
|
|
8
|
+
/>
|
|
9
|
+
<link rel="alternate icon" href="/favicon.ico" />
|
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
11
|
+
<meta name="description" content="A minimal, purely client-side program for viewing Zarr-based images." />
|
|
12
|
+
<title>vizarr</title>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<div id="root"></div>
|
|
16
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
17
|
+
<script type="module" src="/main.ts"></script>
|
|
18
|
+
<style>
|
|
19
|
+
html {
|
|
20
|
+
background-color: black;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
package/main.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import debounce from "just-debounce-it";
|
|
2
|
+
import * as vizarr from "./src/index";
|
|
3
|
+
|
|
4
|
+
async function main() {
|
|
5
|
+
console.log(`vizarr v${vizarr.version}: https://github.com/hms-dbmi/vizarr`);
|
|
6
|
+
// biome-ignore lint/style/noNonNullAssertion: We know the element exists
|
|
7
|
+
const viewer = await vizarr.createViewer(document.querySelector("#root")!);
|
|
8
|
+
const url = new URL(window.location.href);
|
|
9
|
+
|
|
10
|
+
if (!url.searchParams.has("source")) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// see if we have initial viewState
|
|
15
|
+
const viewStateString = url.searchParams.get("viewState");
|
|
16
|
+
if (viewStateString) {
|
|
17
|
+
const viewState = JSON.parse(viewStateString);
|
|
18
|
+
viewer.setViewState(viewState);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Add event listener to sync viewState as query param.
|
|
22
|
+
// Debounce to limit how quickly we are pushing to browser history
|
|
23
|
+
viewer.on(
|
|
24
|
+
"viewStateChange",
|
|
25
|
+
debounce((update: vizarr.ViewState) => {
|
|
26
|
+
const url = new URL(window.location.href);
|
|
27
|
+
url.searchParams.set("viewState", JSON.stringify(update));
|
|
28
|
+
window.history.replaceState(window.history.state, "", decodeURIComponent(url.href));
|
|
29
|
+
}, 200),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// parse image config
|
|
33
|
+
// @ts-expect-error - TODO: validate config
|
|
34
|
+
const config: vizarr.ImageLayerConfig = {};
|
|
35
|
+
|
|
36
|
+
for (const [key, value] of url.searchParams) {
|
|
37
|
+
// @ts-expect-error - TODO: validate config
|
|
38
|
+
config[key] = value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Make sure the source URL is decoded.
|
|
42
|
+
viewer.addImage(config);
|
|
43
|
+
|
|
44
|
+
const newLocation = decodeURIComponent(url.href);
|
|
45
|
+
|
|
46
|
+
// Only update history if the new location is different from the current
|
|
47
|
+
if (window.location.href !== newLocation) {
|
|
48
|
+
window.history.replaceState(window.history.state, "", newLocation);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@biongff/vizarr",
|
|
3
|
+
"version": "0.3.0-dev.2025-11-12.283baee9",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@deck.gl/core": "~9.0.0",
|
|
7
|
+
"@deck.gl/geo-layers": "~9.0.0",
|
|
8
|
+
"@deck.gl/layers": "~9.0.0",
|
|
9
|
+
"@emotion/react": "^11.14.0",
|
|
10
|
+
"@emotion/styled": "^11.14.1",
|
|
11
|
+
"@hms-dbmi/viv": "~0.17.2",
|
|
12
|
+
"@mui/icons-material": "^7.2.0",
|
|
13
|
+
"@mui/material": "^7.2.0",
|
|
14
|
+
"@vivjs/types": "~0.17.0",
|
|
15
|
+
"@zarrita/storage": "0.1.0",
|
|
16
|
+
"deck.gl": "~9.0.0",
|
|
17
|
+
"jotai": "^1.0.0",
|
|
18
|
+
"just-debounce-it": "^3.1.1",
|
|
19
|
+
"math.gl": "^4.1.0",
|
|
20
|
+
"p-map": "^7.0.3",
|
|
21
|
+
"quick-lru": "^7.0.0",
|
|
22
|
+
"react": "^18.2.0",
|
|
23
|
+
"react-dom": "^18.2.0",
|
|
24
|
+
"react-is": "18.3.1",
|
|
25
|
+
"zarrita": "0.5.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@biomejs/biome": "^1.9.4",
|
|
29
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
30
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
31
|
+
"@semantic-release/git": "^10.0.1",
|
|
32
|
+
"@semantic-release/github": "^12.0.2",
|
|
33
|
+
"@semantic-release/npm": "^13.1.1",
|
|
34
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
35
|
+
"@types/node": "^24.3.0",
|
|
36
|
+
"@types/react": "^18.3.10",
|
|
37
|
+
"@types/react-dom": "^18.2.18",
|
|
38
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
39
|
+
"semantic-release": "^25.0.2",
|
|
40
|
+
"typescript": "^5.8.2",
|
|
41
|
+
"vite": "^6.2.7"
|
|
42
|
+
},
|
|
43
|
+
"overrides": {
|
|
44
|
+
"react-is": "^18.3.1"
|
|
45
|
+
},
|
|
46
|
+
"prereleaseSha": "283baee9c93391f3d86fd39ddfce706d868be2e9",
|
|
47
|
+
"scripts": {
|
|
48
|
+
"dev": "vite",
|
|
49
|
+
"build": "npm run check && vite build",
|
|
50
|
+
"preview": "vite preview",
|
|
51
|
+
"lint": "biome ci",
|
|
52
|
+
"fix": "biome check --write",
|
|
53
|
+
"check": "tsc"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
diff --git a/dist/index.mjs b/dist/index.mjs
|
|
2
|
+
index b709ea0b4eb932f46b304b4cd8d241ac09e37a8b..37788b9807822f2d4bc257a5079f534a1d34dea7 100644
|
|
3
|
+
--- a/dist/index.mjs
|
|
4
|
+
+++ b/dist/index.mjs
|
|
5
|
+
@@ -1,8 +1,6 @@
|
|
6
|
+
import { BaseDecoder, fromBlob, fromFile, fromUrl, GeoTIFFImage, addDecoder } from 'geotiff';
|
|
7
|
+
-import { decompress } from 'lzw-tiff-decoder';
|
|
8
|
+
import quickselect from 'quickselect';
|
|
9
|
+
import * as z from 'zod';
|
|
10
|
+
-import { KeyError, openGroup, HTTPStore } from 'zarr';
|
|
11
|
+
|
|
12
|
+
var __defProp$3 = Object.defineProperty;
|
|
13
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
package/python/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "code",
|
|
5
|
+
"execution_count": null,
|
|
6
|
+
"id": "20794451-c89f-497d-aa89-3c6a432326fc",
|
|
7
|
+
"metadata": {},
|
|
8
|
+
"outputs": [],
|
|
9
|
+
"source": []
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"metadata": {
|
|
13
|
+
"kernelspec": {
|
|
14
|
+
"display_name": "Python 3 (ipykernel)",
|
|
15
|
+
"language": "python",
|
|
16
|
+
"name": "python3"
|
|
17
|
+
},
|
|
18
|
+
"language_info": {
|
|
19
|
+
"codemirror_mode": {
|
|
20
|
+
"name": "ipython",
|
|
21
|
+
"version": 3
|
|
22
|
+
},
|
|
23
|
+
"file_extension": ".py",
|
|
24
|
+
"mimetype": "text/x-python",
|
|
25
|
+
"name": "python",
|
|
26
|
+
"nbconvert_exporter": "python",
|
|
27
|
+
"pygments_lexer": "ipython3",
|
|
28
|
+
"version": "3.12.3"
|
|
29
|
+
},
|
|
30
|
+
"widgets": {
|
|
31
|
+
"application/vnd.jupyter.widget-state+json": {
|
|
32
|
+
"state": {},
|
|
33
|
+
"version_major": 2,
|
|
34
|
+
"version_minor": 0
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"nbformat": 4,
|
|
39
|
+
"nbformat_minor": 5
|
|
40
|
+
}
|
package/python/deno.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lock": false,
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"checkJs": true,
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"lib": [
|
|
7
|
+
"ES2022",
|
|
8
|
+
"DOM",
|
|
9
|
+
"DOM.Iterable"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"fmt": {
|
|
13
|
+
"useTabs": true
|
|
14
|
+
},
|
|
15
|
+
"lint": {
|
|
16
|
+
"rules": {
|
|
17
|
+
"exclude": [
|
|
18
|
+
"prefer-const"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"# Viewing an image from the IDR\n",
|
|
8
|
+
"\n",
|
|
9
|
+
"OME-NGFF is an open standard for imaging from the OME community. The Imaging Data Resource (IDR) provides serveral publically available images in this format."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"cell_type": "code",
|
|
14
|
+
"execution_count": null,
|
|
15
|
+
"metadata": {},
|
|
16
|
+
"outputs": [],
|
|
17
|
+
"source": [
|
|
18
|
+
"!pip install --quiet fsspec zarr requests aiohttp"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"cell_type": "markdown",
|
|
23
|
+
"metadata": {},
|
|
24
|
+
"source": [
|
|
25
|
+
"## Open the remote zarr"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"cell_type": "code",
|
|
30
|
+
"execution_count": null,
|
|
31
|
+
"metadata": {},
|
|
32
|
+
"outputs": [],
|
|
33
|
+
"source": [
|
|
34
|
+
"from fsspec import get_mapper\n",
|
|
35
|
+
"import zarr\n",
|
|
36
|
+
"\n",
|
|
37
|
+
"# Create a remote mapping to the data\n",
|
|
38
|
+
"url = \"https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.1/6001240.zarr/\"\n",
|
|
39
|
+
"store = get_mapper(url)\n",
|
|
40
|
+
"z_grp = zarr.open(store, mode='r')\n",
|
|
41
|
+
"z_grp"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"cell_type": "markdown",
|
|
46
|
+
"metadata": {},
|
|
47
|
+
"source": [
|
|
48
|
+
"## View with vizarr"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"cell_type": "code",
|
|
53
|
+
"execution_count": null,
|
|
54
|
+
"metadata": {},
|
|
55
|
+
"outputs": [],
|
|
56
|
+
"source": [
|
|
57
|
+
"import vizarr\n",
|
|
58
|
+
"\n",
|
|
59
|
+
"viewer = vizarr.Viewer()\n",
|
|
60
|
+
"viewer.add_image(source=z_grp)\n",
|
|
61
|
+
"viewer"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"metadata": {
|
|
66
|
+
"kernelspec": {
|
|
67
|
+
"display_name": "Python 3 (ipykernel)",
|
|
68
|
+
"language": "python",
|
|
69
|
+
"name": "python3"
|
|
70
|
+
},
|
|
71
|
+
"language_info": {
|
|
72
|
+
"codemirror_mode": {
|
|
73
|
+
"name": "ipython",
|
|
74
|
+
"version": 3
|
|
75
|
+
},
|
|
76
|
+
"file_extension": ".py",
|
|
77
|
+
"mimetype": "text/x-python",
|
|
78
|
+
"name": "python",
|
|
79
|
+
"nbconvert_exporter": "python",
|
|
80
|
+
"pygments_lexer": "ipython3",
|
|
81
|
+
"version": "3.12.3"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"nbformat": 4,
|
|
85
|
+
"nbformat_minor": 4
|
|
86
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Install Requirements
|
|
4
|
+
|
|
5
|
+
The examples require the `vizarr` [anywidget](https://github.com/manzt/anywidget). If running locally, please install the following:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install vizarr
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
This example will work in the Jupyter, JupyterLab, VS Code, and more. We recommend trying our JupyterLab.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
$ jupyter lab getting_started.ipynb
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Viewing an Image from the Imaging Data Resource
|
|
20
|
+
|
|
21
|
+
OME-NGFF is an open standard for imaging from the OME community. The [Imaging Data Resource](https://idr.openmicroscopy.org) (IDR)
|
|
22
|
+
provides serveral images in this format which are publically available.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
$ jupyter lab IDR_example.ipynb
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Display a Zoomable Mandelbrot Set
|
|
29
|
+
|
|
30
|
+
This notebook a contains a `vizarr` example visualizing a generic multiscale Zarr. The first cells create the
|
|
31
|
+
underlying generative Zarr store. It dynamically creates "chunks" at different zoom levels and associated array metadata.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
$ jupyter lab mandelbrot.ipynb
|
|
35
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import argparse
|
|
3
|
+
import zarr
|
|
4
|
+
import numpy as np
|
|
5
|
+
import os
|
|
6
|
+
import json
|
|
7
|
+
from skimage import data
|
|
8
|
+
from skimage.transform import pyramid_gaussian
|
|
9
|
+
|
|
10
|
+
# Modified from https://github.com/ome/ome-zarr-py/blob/master/tests/create_test_data.py
|
|
11
|
+
def create_ome_zarr(zarr_directory, dtype="f4"):
|
|
12
|
+
|
|
13
|
+
base = np.tile(data.astronaut(), (4, 4, 1))
|
|
14
|
+
gaussian = list(pyramid_gaussian(base, downscale=2, max_layer=3, channel_axis=-1))
|
|
15
|
+
|
|
16
|
+
pyramid = []
|
|
17
|
+
# convert each level of pyramid into 5D image (t, c, z, y, x)
|
|
18
|
+
for pixels in gaussian:
|
|
19
|
+
red = pixels[:, :, 0]
|
|
20
|
+
green = pixels[:, :, 1]
|
|
21
|
+
blue = pixels[:, :, 2]
|
|
22
|
+
# wrap to make 5D: (t, c, z, y, x)
|
|
23
|
+
pixels = np.array([np.array([red]), np.array([green]), np.array([blue])])
|
|
24
|
+
pixels = np.array([pixels]).astype(dtype)
|
|
25
|
+
pyramid.append(pixels)
|
|
26
|
+
|
|
27
|
+
store = zarr.DirectoryStore(zarr_directory)
|
|
28
|
+
grp = zarr.group(store, overwrite=True)
|
|
29
|
+
paths = []
|
|
30
|
+
for path, dataset in enumerate(pyramid):
|
|
31
|
+
grp.create_dataset(str(path), data=pyramid[path])
|
|
32
|
+
paths.append({"path": str(path)})
|
|
33
|
+
|
|
34
|
+
image_data = {
|
|
35
|
+
"id": 1,
|
|
36
|
+
"channels": [
|
|
37
|
+
{
|
|
38
|
+
"color": "FF0000",
|
|
39
|
+
"window": {"start": 0, "end": 1},
|
|
40
|
+
"label": "Red",
|
|
41
|
+
"active": True,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"color": "00FF00",
|
|
45
|
+
"window": {"start": 0, "end": 1},
|
|
46
|
+
"label": "Green",
|
|
47
|
+
"active": True,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"color": "0000FF",
|
|
51
|
+
"window": {"start": 0, "end": 1},
|
|
52
|
+
"label": "Blue",
|
|
53
|
+
"active": True,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
"rdefs": {
|
|
57
|
+
"model": "color",
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
multiscales = [
|
|
62
|
+
{
|
|
63
|
+
"version": "0.1",
|
|
64
|
+
"datasets": paths,
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
grp.attrs["multiscales"] = multiscales
|
|
68
|
+
grp.attrs["omero"] = image_data
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if __name__ == "__main__":
|
|
72
|
+
create_ome_zarr("astronaut.zarr")
|