Skip to contents

Writes a QPTIFFImage as a multi-page 16-bit grayscale OME-TIFF (one page per channel). The first page carries an OME-XML ImageDescription (tag 270) that declares the pages as channels (SizeC = nChannels, SizeZ = SizeT = 1), so viewers such as QuPath / Bio-Formats interpret each page as a channel rather than a timepoint. Per-channel bgnorm results are embedded so the file is self-documenting and round-trips through read_qptiff.

Usage

write_qptiff(x, path)

Arguments

x

A QPTIFFImage (eager or lazy).

path

Output file path (character scalar). The directory must exist.

Value

path, invisibly.

Intensity transform

bgnorm-adjusted images

The QPTIFFImage stores background-adjusted log\(_2\)-intensities. These are inverted with \(2^x\) before writing so the output values are in a linear intensity scale.

Raw images (no bgnorm results)

Written as-is; values are assumed to be in [0, 65535].

All output values are rounded to the nearest integer and clamped to the [0, 65535] range before being written as 16-bit unsigned integers.

The native, Java-free TIFF/QPTIFF reader and writer implemented here was translated from the bioio-tifffile fork by Rafael Tubelleza.

Metadata

The first page's ImageDescription tag (TIFF tag 270) is an OME-XML document. Its <Pixels> element declares SizeC = nChannels with one <Channel Name="..."> per channel and an explicit <TiffData> page-to-channel mapping, which is what makes downstream viewers read the pages as channels. Channel 0's bgnorm metadata is appended to the OME root as no-namespace elements (ignored by OME readers but read back by read_qptiff); pages 1..n each carry a minimal PerkinElmerQPI block:


<PerkinElmerQPI>
  <Biomarker>CD20</Biomarker>
  <transform>2^x</transform>
  <bgnorm>{"level":"pixel","jsd":0.35,...}</bgnorm>
</PerkinElmerQPI>

The <Biomarker> element is the channel name; <bgnorm> holds a JSON object with GMM parameters, JSD, threshold, and normalisation flags (only present for bgnorm-adjusted images). If jsonlite is not installed, the <bgnorm> element is omitted.

Examples

path <- system.file("extdata", "PA_HNC_sample.ome.tiff", package = "bgnormR")
img  <- read_qptiff(path)
#> Reading TIFF directory structure ...
#> Reading OME-TIFF metadata ...
#> Reading IFD page layouts ...
#> Loading 5 channel(s) ...
#> Loading 5 channel(s) ...
res  <- bgnorm_pixels(img, sample_prop = 0.1)
out  <- file.path(tempdir(), "PA_HNC_bgnorm.tif")
write_qptiff(res, out)

# Round-trip: channel names and dimensions are preserved
img2 <- read_qptiff(out)
#> Reading TIFF directory structure ...
#> Reading OME-TIFF metadata ...
#> Reading IFD page layouts ...
#> Loading 5 channel(s) ...
#> Loading 5 channel(s) ...
names(img2)
#> [1] "CD20"     "CD3e"     "CD8"      "PanCK"    "Vimentin"
dim(img2)
#> [1] 550 800   5