Skip to content

Overlay format V2: generated geometry and explicit rasters ​

V2 extends the V1 index without changing slide/annotation/project formats. Same microscope-overlays document, workspace/project checks, pixel coordinates, appearance, and index-last commit protocol; version: 2 permits new sources below. Readers accept V1 and V2; V1 sources stay valid. Writers preserve source bytes, appearance/order, and independent revision/conflict semantics. See V1.

Source kinds ​

  • points: unchanged N×3 float32 NPY, (x,y,score); Scatterplot/Heatmap/Grid/Contour.
  • raster: H×W float32 NPY; Bitmap/Tile. Optional mode: score|mask|labels defaults to score, optional bounds: [x,y,width,height] defaults to the whole slide. score is finite 0–1 and uses index raster: score; mask is 0/1 and labels is exact nonnegative integer 0–16,777,215, both use index raster: mask. Zero is transparent for mask/labels. Bounds must be finite, positive, and inside the slide.
  • polygons: MPOLY001 binary; PolygonLayer. shape: [polygonCount,vertexCount], not a matrix shape. Float32 XY level-0 positions, uint32 ring/polygon offsets, per-polygon float32 scores. Asset extension .mpoly.
  • geojson: UTF-8 FeatureCollection with finite JSON properties. shape: [featureCount,1]; GeoJsonLayer. Point/MultiPoint, LineString/MultiLineString, Polygon/MultiPolygon. No GeometryCollection, null geometry, geography, or executable accessors. Asset extension .geojson.
  • synthetic: unchanged browser recipe; not measured data.

All real sources retain name, path: assets/<sha256>.<extension>, sha256, byteLength, and shape. Paths are canonical content addresses, never arbitrary references. NumPy/geometry parsers do not execute pickle or code. Asset and stack budgets remain ~32 MiB per asset, 128 MiB total, 64 layers/256 KiB index. Points: 1m; array values: 8,388,608. Packed polygons: 1m polygons, 2m vertices (including closure), ≤500k rings. Ordinary GeoJSON: 50k features/2m vertices. Asset bytes are verified against the source descriptor before use/commit.

MPOLY001 layout ​

All numeric fields use little-endian 32-bit values. Exact byte count is checked; trailing bytes are invalid.

Offset / orderData
0, 8 bytesASCII MPOLY001
8, 16 bytesuint32 polygon count P, ring count R, vertex count V, flags (must be 0)
nextuint32 polygon ring offsets, P+1 entries
nextuint32 ring vertex offsets, R+1 entries
nextfloat32 XY positions, 2V entries
nextfloat32 scores, P entries

Offsets start at 0 and end at R/V. Polygon ring offsets increase strictly; every polygon has an outer ring followed by holes. Each ring has at least four positions and is explicitly closed, with nonzero signed area. Scores are 0–1; coordinates finite and inside slide dimensions. Validate complete geometry/topology before producing the asset; readers do not repair self-intersections, overlapping holes, or multipolygon relationships. Float32 can lose fine coordinate precision on very large slides.

Browser decoding produces typed buffers; triangulation uses earcut for concavity/holes. Filled faces use binary SolidPolygonLayer (the internal PolygonLayer fill primitive); outlines use binary PathLayer, retaining polygon picking through ring-to-polygon mapping. There is no per-polygon GeoJSON Feature construction. Preparation still runs in the browser and is measured separately; no spatial indexing/out-of-core loading is implemented.

Raster labels use a deterministic repeating display palette, not a semantic class mapping. Scalar palette and zero/background interpretation are shared with static Python output. GeoJSON features remain ordinary objects for convenience; generated geometry stays separate from editable ROI annotations.