Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a175577
Merge pull request #58 from RaredonLab/main
msraredon Aug 13, 2026
88aed76
docs: specify split-screen Phase 2, and correct stale edgeFile notes
msraredon Aug 16, 2026
ba0463b
fix: annotations belong to the panel that drew them; add frontend tests
msraredon Aug 16, 2026
dc6c47d
refactor: move display settings into panels[i].settings (split screen…
msraredon Aug 16, 2026
2299233
feat: per-panel settings with a link toggle (split screen 2b + 2d)
msraredon Aug 16, 2026
bae4fd7
feat: push settings between panels (2c), and fix edges 500ing on ever…
msraredon Aug 16, 2026
0d55f03
docs: manual describes split screen as it now works (2e)
msraredon Aug 16, 2026
23c2207
chore: v0.8.5
msraredon Aug 16, 2026
5baa6a3
Merge pull request #61 from msraredon/dev
msraredon Aug 16, 2026
a9627bc
docs: plan for issue #59 — independent sending/receiving edge filters
msraredon Aug 18, 2026
3ffdc44
docs: correct the sending_type provenance, and revise the #59 plan ar…
msraredon Aug 18, 2026
6638cc6
feat: independent sending/receiving edge filters, and unfilter the ti…
msraredon Aug 18, 2026
5e93492
chore: v0.8.6
msraredon Aug 18, 2026
54d8a9b
Merge pull request #62 from msraredon/dev
msraredon Aug 18, 2026
9137c97
feat: local neighbourhood highlighting and summaries (#60)
msraredon Aug 18, 2026
60599f8
chore: v0.8.7
msraredon Aug 18, 2026
8c6774e
Merge pull request #63 from msraredon/dev
msraredon Aug 18, 2026
cb0f86b
fix: report empty metadata columns, stop the pan re-render storm, ver…
msraredon Aug 18, 2026
67365cc
chore: v0.8.8
msraredon Aug 18, 2026
cbed10d
Merge pull request #64 from msraredon/dev
msraredon Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
242 changes: 209 additions & 33 deletions CLAUDE.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# TissuePlex

**v0.8.8**

An interactive spatial transcriptomics viewer for exploring cell-cell communication from [NICHESv2](https://github.com/RaredonLab/NICHESv2) directly on the tissue image.

![TissuePlex demo](docs/demo.gif)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from app.routers import tiles, spatial, edges, layers

APP_VERSION = "0.8.4"
APP_VERSION = "0.8.8"

app = FastAPI(title="TissuePlex API", version=APP_VERSION)

Expand Down
17 changes: 14 additions & 3 deletions backend/app/readers/base_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,18 @@ def _metadata_frame(self) -> Optional[pd.DataFrame]:

def _color_values_meta(self, field: str,
categorical: Optional[bool] = None) -> dict:
"""Per-cell values for one metadata column, typed for the frontend."""
empty = {"type": "continuous", "values": {}, "min": 0.0, "max": 0.0}
"""Per-cell values for one metadata column, typed for the frontend.

A column with no usable values is reported as ``empty: True`` rather than
as a continuous 0–0 range. Several real files ship such columns —
``fov`` and ``transcript_count`` are entirely null on the bundled MERSCOPE
dataset — and the old shape gave the UI a range slider that did nothing,
a legend with no span, and a filter that correctly matched no cells while
looking broken. ``type`` is still set so nothing switching on
categorical-vs-continuous has to learn a third case.
"""
empty = {"type": "continuous", "values": {}, "min": 0.0, "max": 0.0,
"empty": True}
df = self._metadata_frame()
if df is None or df.empty or "cell_id" not in df.columns \
or field not in df.columns:
Expand All @@ -193,6 +203,7 @@ def _color_values_meta(self, field: str,
"type": "categorical",
"values": values,
"categories": metadata_filter.sort_categories(set(values.values())),
"empty": not values,
}

# to_numeric rather than float(): a forced-continuous request can land on a
Expand All @@ -208,7 +219,7 @@ def _color_values_meta(self, field: str,
if not finite:
return empty
return {"type": "continuous", "values": values,
"min": min(finite), "max": max(finite)}
"min": min(finite), "max": max(finite), "empty": False}

def filter_cell_ids(self, spec: Optional[MetadataFilter]) -> Optional[set]:
"""Resolve a metadata filter to the set of cell ids it keeps (issue #45).
Expand Down
5 changes: 4 additions & 1 deletion backend/app/readers/duck.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ def _default_memory_limit() -> str:
return f"{mb}MB"


_MEMORY_LIMIT = os.getenv("DUCKDB_MEMORY_LIMIT") or _default_memory_limit()
# .strip() matters: an unset variable and one set to "" or " " must all fall
# through to the computed default. A whitespace value is truthy, so without it
# DuckDB receives `SET memory_limit=' '` and raises a ParserException.
_MEMORY_LIMIT = (os.getenv("DUCKDB_MEMORY_LIMIT") or "").strip() or _default_memory_limit()
_THREADS = os.getenv("DUCKDB_THREADS", "4")


Expand Down
Loading
Loading