arrayview 0.9.0__tar.gz → 0.10.1__tar.gz
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.
- {arrayview-0.9.0 → arrayview-0.10.1}/PKG-INFO +1 -1
- {arrayview-0.9.0 → arrayview-0.10.1}/pyproject.toml +1 -1
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_server.py +84 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_viewer.html +562 -116
- {arrayview-0.9.0 → arrayview-0.10.1}/uv.lock +1 -1
- {arrayview-0.9.0 → arrayview-0.10.1}/.claude/skills/invocation-consistency/SKILL.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.claude/skills/modes-consistency/SKILL.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.claude/skills/ui-consistency-audit/SKILL.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.claude/skills/viewer-ui-checklist/SKILL.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.claude/skills/visual-bug-fixing/SKILL.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.github/workflows/docs.yml +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.github/workflows/python-publish.yml +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.gitignore +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.python-version +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.tmp-vsix/extension/extension.js +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/.tmp-vsix/extension/package.json +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/AGENTS.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/LICENSE +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/README.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/comparing.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/configuration.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/display.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/index.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/loading.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/logo.png +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/measurement.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/remote.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/stylesheets/extra.css +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/docs/viewing.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/matlab/arrayview.m +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/mkdocs.yml +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/plans/webview/LOG.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/scripts/demo.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/scripts/release.sh +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/ARCHITECTURE.md +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/__init__.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/__main__.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_app.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_config.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_icon.png +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_io.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_launcher.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_platform.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_render.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_segmentation.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_session.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_shell.html +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_stdio_server.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_torch.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/_vscode.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/src/arrayview/arrayview-opener.vsix +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/conftest.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/make_vectorfield_test_arrays.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_api.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_browser.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_cli.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_config.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_interactions.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_large_arrays.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_mode_consistency.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_mode_matrix.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_rgb_pixel_art.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/test_torch.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/ui_audit.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/tests/visual_smoke.py +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/vscode-extension/LICENSE +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/vscode-extension/extension.js +0 -0
- {arrayview-0.9.0 → arrayview-0.10.1}/vscode-extension/package.json +0 -0
|
@@ -1913,6 +1913,90 @@ def get_volume_histogram(
|
|
|
1913
1913
|
return result
|
|
1914
1914
|
|
|
1915
1915
|
|
|
1916
|
+
# ── Volume Data (3-D MIP) ────────────────────────────────────────
|
|
1917
|
+
|
|
1918
|
+
|
|
1919
|
+
@app.get("/volume_data/{sid}")
|
|
1920
|
+
def get_volume_data(
|
|
1921
|
+
sid: str,
|
|
1922
|
+
dims: str = "",
|
|
1923
|
+
indices: str = "",
|
|
1924
|
+
complex_mode: int = 0,
|
|
1925
|
+
):
|
|
1926
|
+
"""Return the full 3-D sub-volume as raw float32 bytes for the WebGL MIP renderer.
|
|
1927
|
+
|
|
1928
|
+
*dims* is a comma-separated triple of the three spatial dimensions (e.g. ``"0,1,2"``).
|
|
1929
|
+
*indices* gives the current index for every dimension (comma-separated).
|
|
1930
|
+
Dimensions not in *dims* are sliced at the value given in *indices*.
|
|
1931
|
+
|
|
1932
|
+
If any axis exceeds 256, stride-based down-sampling is applied so that
|
|
1933
|
+
the returned volume fits within 256^3.
|
|
1934
|
+
|
|
1935
|
+
Response headers carry ``X-Shape`` (comma-separated), ``X-Vmin``, ``X-Vmax``.
|
|
1936
|
+
"""
|
|
1937
|
+
session = SESSIONS.get(sid)
|
|
1938
|
+
if not session:
|
|
1939
|
+
return Response(status_code=404)
|
|
1940
|
+
|
|
1941
|
+
# Parse dims and indices
|
|
1942
|
+
if not dims:
|
|
1943
|
+
return Response(status_code=400, content="dims required")
|
|
1944
|
+
dim_list = [int(d) for d in dims.split(",")]
|
|
1945
|
+
if len(dim_list) != 3:
|
|
1946
|
+
return Response(status_code=400, content="dims must be exactly 3 integers")
|
|
1947
|
+
|
|
1948
|
+
idx_list = [int(x) for x in indices.split(",")] if indices else [s // 2 for s in session.shape]
|
|
1949
|
+
|
|
1950
|
+
# Build slicer: keep the 3 spatial dims free, fix everything else
|
|
1951
|
+
slicer = []
|
|
1952
|
+
for i in range(len(session.shape)):
|
|
1953
|
+
if i in dim_list:
|
|
1954
|
+
slicer.append(slice(None))
|
|
1955
|
+
else:
|
|
1956
|
+
idx = idx_list[i] if i < len(idx_list) else session.shape[i] // 2
|
|
1957
|
+
slicer.append(min(max(idx, 0), session.shape[i] - 1))
|
|
1958
|
+
vol = np.array(session.data[tuple(slicer)])
|
|
1959
|
+
|
|
1960
|
+
# Reorder axes so dim_list order maps to (0, 1, 2) of the output
|
|
1961
|
+
# vol currently has axes at the positions corresponding to dim_list within
|
|
1962
|
+
# the free-axis subset. We need to figure out which axes of `vol` correspond
|
|
1963
|
+
# to which dim in dim_list.
|
|
1964
|
+
free_axes_sorted = sorted(dim_list)
|
|
1965
|
+
# vol axes are in the order of free_axes_sorted (numpy preserves order)
|
|
1966
|
+
perm = [free_axes_sorted.index(d) for d in dim_list]
|
|
1967
|
+
vol = np.transpose(vol, perm)
|
|
1968
|
+
|
|
1969
|
+
# Apply complex mode
|
|
1970
|
+
vol = apply_complex_mode(vol, complex_mode)
|
|
1971
|
+
|
|
1972
|
+
# Downsample any axis > 256
|
|
1973
|
+
max_dim = 256
|
|
1974
|
+
strides = []
|
|
1975
|
+
for s in vol.shape:
|
|
1976
|
+
strides.append(max(1, (s + max_dim - 1) // max_dim))
|
|
1977
|
+
if any(st > 1 for st in strides):
|
|
1978
|
+
vol = vol[::strides[0], ::strides[1], ::strides[2]]
|
|
1979
|
+
|
|
1980
|
+
vol = np.ascontiguousarray(vol, dtype=np.float32)
|
|
1981
|
+
|
|
1982
|
+
finite = vol[np.isfinite(vol)]
|
|
1983
|
+
if finite.size > 0:
|
|
1984
|
+
vmin = float(np.percentile(finite, 1))
|
|
1985
|
+
vmax = float(np.percentile(finite, 99))
|
|
1986
|
+
else:
|
|
1987
|
+
vmin, vmax = 0.0, 1.0
|
|
1988
|
+
|
|
1989
|
+
return Response(
|
|
1990
|
+
content=vol.tobytes(),
|
|
1991
|
+
media_type="application/octet-stream",
|
|
1992
|
+
headers={
|
|
1993
|
+
"X-Shape": ",".join(str(s) for s in vol.shape),
|
|
1994
|
+
"X-Vmin": str(vmin),
|
|
1995
|
+
"X-Vmax": str(vmax),
|
|
1996
|
+
},
|
|
1997
|
+
)
|
|
1998
|
+
|
|
1999
|
+
|
|
1916
2000
|
@app.get("/lebesgue/{sid}")
|
|
1917
2001
|
def get_lebesgue_slice(
|
|
1918
2002
|
sid: str,
|