Convert Aperio SVS (compression 33007 / YUYV) to pyramidal OME-TIFF
Project description
svs-to-ometiff
Status: Experimental — single-scanner validation. This tool has been tested on ONE Aperio SVS file (AT2/GT450 scanner, lung H&E, compression 33007). Generalizability to other scanner models, firmware versions, and tissue types is not yet verified. Downstream tool compatibility is intended but not yet tested end-to-end. See Validation Status.
Convert Aperio SVS slides using proprietary compression 33007 into standard pyramidal OME-TIFF.
The Problem
Some Aperio AT2/GT450 whole-slide scanners write .svs files with TIFF
Compression tag 33007. These files are often described as JP2K-YCbCr,
ALT_JPEG, or JPEG 2000-like, but the tile payload is raw YUYV
YCbCr 4:2:2: each two-pixel pair is stored as [Y0, U, Y1, V].
Because 33007 is not a standard TIFF/JPEG/JPEG 2000 compression codec, common spatial biology tools may fail before the image can be used for Xenium or Visium registration. The failures below have been observed in the validation context described in Validation Status.
| Tool | What fails | Typical error message |
|---|---|---|
| OpenSlide | Refuses the private compression tag | Unsupported TIFF compression: 33007 |
| Bio-Formats / bfconvert | Treats tiles as JPEG-family data | Cannot read JPEG scanlines |
| QuPath | Delegates decoding through OpenSlide/Bio-Formats | Unsupported TIFF compression: 33007 |
| libvips | Cannot decode private-compression tile payloads | vips2tiff: unsupported compression 33007 |
Installation
pip install svs-to-ometiff
For the latest development version:
pip install git+https://github.com/tommy2scripts/svs-to-ometiff.git
For development (includes test/lint tools):
pip install "svs-to-ometiff[dev]"
Usage
svs-to-ometiff input.svs output.ome.tiff
Verify the output:
python - <<'PY'
import tifffile
with tifffile.TiffFile("output.ome.tiff") as tif:
print("is_ome:", tif.is_ome)
print("is_bigtiff:", tif.is_bigtiff)
print("levels:", len(tif.series[0].levels))
for index, level in enumerate(tif.series[0].levels):
print(index, level.shape)
PY
Programmatic use:
from svs_to_ometiff import convert
convert("input.svs", "output.ome.tiff", verbose=True)
How It Works
The converter does three things:
- Decodes each Aperio 33007 tile from YUYV YCbCr 4:2:2 to RGB with BT.601 full-range color conversion.
- Reassembles the full-resolution RGB image and builds a downsampled pyramid by block averaging.
- Writes a BigTIFF OME-TIFF with tiled storage and SubIFD-linked pyramid levels for downstream viewer compatibility.
Limitations
- Only Aperio compression
33007is handled. Standard JPEG, JPEG 2000, LZW, and tiled TIFF/SVS files should be opened with standard tools. - The full-resolution RGB image and generated pyramid are held in RAM. As a
rule of thumb, peak memory is about
width * height * 3 * 1.65bytes for a six-level 2x pyramid, plus TIFF writer buffers. A 40,000 x 40,000 slide typically needs 8-12 GB; very large slides can exceed 30 GB. - The CLI estimates peak RAM before decoding and prints a warning above 30 GB.
- The expected source tile width must be even because YUYV 4:2:2 shares chroma across two horizontal pixels.
- Observed in one AT2/GT450 export context. Firmware and export settings vary by site, so
verify the source TIFF Compression tag is
33007before relying on this converter.
What this does NOT do
- Does not handle JPEG-compressed SVS (compression tag
7) — use libvips or OpenSlide for those - Does not handle JPEG 2000-compressed SVS (compression tag
33003or33005) - Does not validate color fidelity against a reference scanner profile
- Has not been tested on frozen sections, IHC, or fluorescence slides
- Does not recover from malformed or truncated tiles — may crash on corrupted SVS files
Downstream Compatibility
Outputs are intended to be pyramidal OME-TIFF files for downstream workflows such as:
- Xenium Ranger and Xenium Explorer H&E registration/overlay workflows
- Space Ranger image inputs after OME-TIFF conversion
- QuPath
- napari through
tifffile - HALO and other OME-TIFF aware pathology viewers
Verification
At minimum, verify structure and a visual thumbnail before using the output in registration:
python - <<'PY'
import tifffile
path = "output.ome.tiff"
with tifffile.TiffFile(path) as tif:
assert tif.is_ome, "missing OME metadata"
assert tif.is_bigtiff, "expected BigTIFF output"
levels = tif.series[0].levels
assert len(levels) >= 2, "missing pyramid levels"
assert levels[0].shape[-1] == 3, "expected RGB output"
print("verified", path, "levels:", [level.shape for level in levels])
PY
For pixel-level validation in a pipeline, sample known tissue coordinates from
the source slide and compare RGB values after conversion. The decoder clips RGB
conversion results to 0..255, so out-of-range chroma values should not wrap
around in the output.
Validation Status
What has been tested
| Claim | Evidence | Confidence |
|---|---|---|
| YUYV decoder produces structurally correct RGB | Unit tests (grayscale, color tint, clipping); visual inspection of H&E tile | Medium |
| OME-TIFF output passes tifffile validation | is_ome=True, is_bigtiff=True, 6 pyramid levels detected |
Medium-high |
| Pyramid SubIFD linkage works in tifffile | tifffile.TiffFile.series[0].levels enumerates all 6 levels |
Medium-high |
| Synthetic 33007 SVS → valid OME-TIFF end-to-end | test_integration.py passes with known pixel values |
Medium |
| Works on real SVS file | lung SCC, post-Xenium H&E (3.2 GB, AT2/GT450, compression 33007) | Single file |
What has NOT been tested (open questions)
| Claim | Status |
|---|---|
| Other Aperio scanner models (CS2, Versa, AT Turbo) | Not tested |
| Other firmware versions of AT2/GT450 | Not tested |
| Other tissue types or stains (IHC, IF, special stains) | Not tested |
| Xenium Explorer H&E overlay workflow | Planned, not yet performed |
| STalign registration to Xenium DAPI section | Planned, not yet performed |
| Color accuracy vs. reference decoder (cross-validation) | Not performed — visual inspection only |
| Multi-file reproducibility | Only one file tested |
How to help validate
If you have access to Aperio SVS files with compression tag 33007 from different scanners or tissue types, please test the converter and report results (success or failure) via GitHub Issues. Include the scanner model, firmware version if known, and a tifffile tag dump of the source file.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file svs_to_ometiff-0.2.0.tar.gz.
File metadata
- Download URL: svs_to_ometiff-0.2.0.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17dd649193bebe483ba213b90d07983df18a90e8ff28c3179780b47759959001
|
|
| MD5 |
e6e5957cacd389b5ea7eb71d8f392461
|
|
| BLAKE2b-256 |
23d2c94539e53f399a80ddd02ab150de24f519fa797a65a520e62bb0e02c969b
|
File details
Details for the file svs_to_ometiff-0.2.0-py3-none-any.whl.
File metadata
- Download URL: svs_to_ometiff-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
601447cfe133cf1964477f3d082528f9503c60e1e7f2cc1faa1d05c214d59140
|
|
| MD5 |
ee1121fd2a9a1b42b7d1c0524dd0e32d
|
|
| BLAKE2b-256 |
c6c2e4b369ad8a3c0e4ca0c6421f4322c7b4c1e3691766827620b460f804a57e
|