Skip to main content

TmapSlide

Pure Python reader for UNIC TMAP whole-slide images — no SDK, no native deps.

以纯 Python 读取联影 TMAP 全切片图像,开箱即用

PyPI Version PyPI Downloads Python Version License GitHub Stars

📖 English · 中文说明


TmapSlide — UNIC TMAP whole-slide images in pure Python

⚡ Quick Start

1. Install:

pip install tmapslide

2. Read a slide:

import tmapslide

slide = tmapslide.OpenSlide("sample.TMAP")

print(slide.dimensions)          # (71424, 72704)
print(slide.level_count)         # 10
print(slide.level_downsamples)   # (1.0, 2.0, 4.0, ...)

region = slide.read_region((512, 512), 0, (1024, 1024))  # RGBA PIL image
thumb = slide.get_thumbnail((512, 512))
macro = slide.associated_images["macro"]

✨ Features

  • Pure Python — no vendor SDK, no native dependencies; only Pillow
  • OpenSlide-compatible API — drop-in for code written against openslide / kfbslide: read_region, get_thumbnail, dimensions, level_count, level_dimensions, level_downsamples, properties, associated_images
  • Both known TMAP variants — TMAP06 (3-level pyramid) and TMAP07 (up to 10 levels)
  • Multi-file slides — TMAP06 slides that spill tiles into .DT1 sidecar files are read transparently
  • Trusted pixel size — several TMAP06 and TMAP07 headers carry an impossible pixel_size (e.g. 6.88e-05 mm at 40x, implying ~2 µm nuclei); tmapslide cross-checks it against the objective power and falls back to 10 µm / magnification, exposing the result via openslide.mpp-x / openslide.mpp-y (the raw header value stays in tmap.pixel_size_mm, the decision in tmap.mpp_source)
  • Fork-safe file handles — safe with PyTorch DataLoader workers
  • LRU decoded-tile cache — fast repeated reads
  • Thread-safe reads — concurrent read_region from worker threads

🏎️ Performance

Benchmark vs ASlide's pure-Python TMAP backend (median of 5 runs, same files, same machine):

Scenario TMAP07 TMAP06
Open slide 68 ms vs 46 ms 80 ms vs 220 ms (2.8×)
Cold 1024² region @L0 3.6 ms vs 15.7 ms (4.4×) 2.8 ms vs 12.3 ms (4.4×)
Random 512² region @L0 1.0 ms vs 5.2 ms (5.0×) 1.0 ms vs 5.6 ms (5.6×)
Warm 512² region ×50 45 ms vs 242 ms (5.4×) 55 ms vs 373 ms (6.8×)

The two libraries pay for indexing in opposite places. tmapslide builds a validated tile index (grid + lazy tile tables) once at open; ASlide defers that work into every read, re-decoding tiles per call. That is why TMAP07 open runs ~20 ms slower while every read is 4–7× faster — for any workload that reads more than a handful of regions, tmapslide comes out far ahead. Slide open is a once-per-process cost.

📖 API

tmapslide.OpenSlide(filename)

Member Description
dimensions (width, height) at level 0
level_count number of pyramid levels
level_dimensions (w, h) per level
level_downsamples downsample factor per level
properties read-only metadata mapping (openslide.vendor=unic, openslide.mpp-x/y, tmap.*)
associated_images lazy mapping, typically macro / label / thumbnail
read_region(loc, level, size) PIL.Image (RGBA) of the region
get_thumbnail(size) stored thumbnail when available, else lowest level
get_best_level_for_downsample(ds) best level for a downsample factor
iter_tiles(level=0) yields (x, y, load) per stored tile
close() / context manager release resources

tmapslide.open_slide(filename)

Alias of OpenSlide(filename).

📦 Supported Formats

Format Extension Vendor Backend
TMAP 06 .TMAP (+ optional .DT1 sidecars) UNIC (United Imaging) Pure Python
TMAP 07 .TMAP UNIC (United Imaging) Pure Python

🧪 Testing

Tests run against real TMAP samples when the scce_external_center data directory (or TAPSLIDE_TEST_DATA) is present next to the repo; synthetic fixtures keep the core parser covered everywhere else.

pip install -e .[dev]
pytest

📄 Format Notes (reverse-engineered)

TMAP is an undocumented proprietary format. This reader is built from binary analysis of real scanner output, cross-validated against ASlide. Both variants store plain JPEG tiles with a small binary header and index tables; there is no encryption.

  • TMAP06 stores 3 pyramid levels (40x / 10x / 2.5x); TMAP07 stores up to 10 levels (40x down to 0.078x, halving each level).
  • TMAP06 level-2 previews come from pre-rendered ShrinkTile entries and are JPEG-compressed at that scale.
  • iter_tiles() exposes the stored tile grid directly — useful for tile-based ML pipelines.
  • Metadata caveat: the header pixel_size field cannot be trusted. Measured on real slides (cell-nucleus diameters, canvas physical size, cross-checked with ASlide), both the Henan TMAP06 batch (6.88e-05 mm) and the Shanxi TMAP07 batch (1.01e-04 mm) carry corrupt values at 40x; the true resolution is 0.25 µm/px. tmapslide keeps the raw value in tmap.pixel_size_mm, exposes the corrected one via openslide.mpp-x/y, and records the decision in tmap.mpp_source (header / derived).

📄 License

MIT

🙏 Acknowledgments

  • kfbslide — the KFB reader this project is modelled after
  • OpenSlide — the API this library mimics
  • ASlide — its independent reverse-engineering of the TMAP06 layer/block structures (from decompiled vendor SDK) was used to cross-validate this implementation. tmapslide is an independent MIT-licensed implementation and ships no ASlide code

Release files for tmapslide 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tmapslide 0.2.3
File Size Uploaded
tmapslide-0.2.3.tar.gz 26.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tmapslide 0.2.3
File Interpreter ABI Platform
tmapslide-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 47.5 kB

Release files / tmapslide-0.2.3.tar.gz

Download URL tmapslide-0.2.3.tar.gz
Size 26.0 kB
Tags Source
SHA-256 checksum
How to use checksums
10c0c91517f2e0133eae63cdb8960fa66c467bce366959f845d7831892c588bb
BLAKE2b-256 checksum
How to use checksums
afaec72144848e35ecbfd4d24e9625ff2968e7014b98f6e93e637fef36ca9812
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / tmapslide-0.2.3-py3-none-any.whl

Download URL tmapslide-0.2.3-py3-none-any.whl
Size 21.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
111077b51baea87defcc0f92970ce62971a9109bd88b96c2aa64b35bc9aa144d
BLAKE2b-256 checksum
How to use checksums
9e7fc4a76ebeb8cd6b86b4927772fbe496065ae5ae33c609ed86fd8950da07ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page