Code
# install.packages(c("tidyverse", "tiff", "magick", "stringr", "rstudioapi"))The Tag Image File Format (TIFF) is the standard for scientific imaging such as microscopy, astronomy, and geospatial sciences. Unlike standard photos, TIFFs can hold high bit-depths and multi-page stacks.
//
Le format TIFF (Tag Image File Format) est la norme en matière d’imagerie scientifique, notamment en microscopie, en astronomie et dans les sciences géospatiales. Contrairement aux photos classiques, les fichiers TIFF peuvent prendre en charge des profondeurs de bits élevées et des séries d’images multipages.
Validate scientific integrity and technical metadata. Detect hidden lossy compression (e.g., JPEG inside TIFF), inventory multi-page stacks, and extract embedded metadata (ImageJ tags) that are crucial for pixel-based analysis. // Vérifier l’intégrité scientifique et les métadonnées techniques. Détecter les compressions avec perte cachées (par exemple, un fichier JPEG à l’intérieur d’un fichier TIFF), recenser les piles de pages multiples et extraire les métadonnées intégrées (balises ImageJ) qui sont essentielles à l’analyse au niveau des pixels.
Hidden lossy compression and the loss of proprietary metadata during format conversion are primary risks. Scientific TIFFs often appear black or empty in standard viewers, leading to accidental deletion or incorrect processing if not properly inspected. // La compression avec perte cachée et la perte de métadonnées propriétaires lors de la conversion de format constituent les principaux risques. Les fichiers TIFF scientifiques apparaissent souvent noirs ou vides dans les visionneuses standard, ce qui peut entraîner leur suppression accidentelle ou un traitement incorrect s’ils ne sont pas correctement vérifiés.
This notebook employs a multi-strategy approach to inspection:
//
Ce cahier adopte une approche multi-stratégies pour l’inspection :
We use the ijtiff package, which is designed for scientific image handling and correctly processes multi-page and high-bit-depth files.
//
Nous utilisons le package ijtiff, conçu pour le traitement d’images scientifiques et capable de traiter correctement les fichiers multipages et ceux à grande profondeur de bits.
The following R packages are required. If you don’t have these packages, uncomment this code and run it once in your R console:
//
Les packages R suivants sont requis. Si vous ne disposez pas de ces packages, décommentez ce code et exécutez-le une fois dans votre console R :
# install.packages(c("tidyverse", "tiff", "magick", "stringr", "rstudioapi"))library(tidyverse)
library(tiff) # Raw LibTIFF
library(magick) # ImageMagick
library(stringr) # Text Mining
library(rstudioapi) # UI interactionThis block allows for interactive selection of the image directory. If running in a non-interactive environment, it defaults to the path defined in the YAML header.
//
Ce bloc permet de sélectionner de manière interactive le répertoire contenant les images. En cas d’exécution dans un environnement non interactif, le chemin par défaut est celui défini dans l’en-tête YAML.
if (interactive() && .Platform$OS.type == "windows") {
selected_dir <- rstudioapi::selectDirectory(caption = "Select TIFF Directory")
} else {
selected_dir <- NULL
}
if (!is.null(selected_dir)) {
target_dir <- selected_dir
} else {
target_dir <- params$target_dir
}
print(paste("Analyzing directory:", target_dir))[1] "Analyzing directory: data/Inspect_tiff/"
We scan for .tif and .tiff files.
//
Nous recherchons les fichiers .tif et .tiff.
tiff_files <- list.files(
path = target_dir,
pattern = "\\.tiff?$",
recursive = TRUE,
full.names = TRUE,
ignore.case = TRUE
)
print(paste("Found", length(tiff_files), "TIFF files."))[1] "Found 6 TIFF files."
This function scans all file attributes for keywords (e.g., “depth”, “compression”) to find metadata even if it uses non-standard tag names.
//
Cette fonction analyse tous les attributs des fichiers à la recherche de mots-clés (par exemple, « depth », « compression ») afin de trouver des métadonnées, même si celles-ci utilisent des noms de balises non standard.
message("Generating Deep Inspection Report...")
inspect_tiff_fuzzy <- function(fp) {
fname <- basename(fp)
tryCatch({
# Read Image Header
img <- image_read(fp)
info <- image_info(img)
attrs <- image_attributes(img)
# Fuzzy Extraction: Bit Depth
# Find ANY attribute containing "depth" or "bits" (case insensitive)
depth_check <- attrs %>%
filter(grepl("depth|bits", property, ignore.case = TRUE)) %>%
pull(value)
# Logic: Use found attribute, or fallback to info$depth, or "Unknown"
final_depth <- if(length(depth_check) > 0) {
paste(unique(depth_check), collapse = "/")
} else if ("depth" %in% names(info)) {
as.character(info$depth[1])
} else {
"Unknown"
}
# Fuzzy Extraction: Compression
# Find ANY attribute containing "compression"
comp_check <- attrs %>%
filter(grepl("compression", property, ignore.case = TRUE)) %>%
pull(value)
final_comp <- if(length(comp_check) > 0) comp_check[1] else "Unknown"
# Fuzzy Extraction: Resolution
res_check <- attrs %>%
filter(grepl("resolution|density", property, ignore.case = TRUE)) %>%
pull(value)
final_res <- if(length(res_check) > 0) paste(res_check[1], "DPI") else paste(info$density[1], "DPI")
# Build Row
tibble(
FileName = fname,
Dimensions = paste(info$width[1], "x", info$height[1]),
BitDepth = final_depth,
Compression = final_comp,
ColorSpace = info$colorspace[1],
Resolution = final_res,
FileSize_MB = round(file.size(fp) / 1024^2, 2),
Status = "Success"
)
}, error = function(e) {
# Error Handling
message(paste("Failed on:", fname, "-", e$message))
tibble(
FileName = fname, Dimensions = NA, BitDepth = NA, Compression = NA,
ColorSpace = NA, Resolution = NA, FileSize_MB = NA,
Status = paste("Error:", e$message)
)
})
}
# Execute Analysis
report <- map_dfr(tiff_files, inspect_tiff_fuzzy)
# Display
print("--- Deep Inspection Preview ---")[1] "--- Deep Inspection Preview ---"
print(head(report))# A tibble: 6 × 8
FileName Dimensions BitDepth Compression ColorSpace Resolution FileSize_MB
<chr> <chr> <chr> <chr> <chr> <chr> <dbl>
1 KL27_14D_KO… 1936 x 14… Unknown Unknown Gray 2x2 DPI 3.59
2 Td014_7D_MC… 2048 x 20… Unknown Unknown Gray 1x1 DPI 4
3 Td014_7D_MC… 2048 x 20… Unknown Unknown Gray 26x26 DPI 4
4 Td62_7D_MCA… 2048 x 20… Unknown Unknown Gray 6x6 DPI 4
5 Td63_7D_MCA… 2048 x 20… Unknown Unknown Gray 6x6 DPI 4
6 Td78_3D_MCA… 2048 x 20… Unknown Unknown Gray 6x6 DPI 4
# ℹ 1 more variable: Status <chr>
output_dir <- "Results/Inspect_tiff"
dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)
output_file <- file.path(output_dir, paste0("TIFF_DeepScan_", format(Sys.Date(), "%Y%m%d"), ".csv"))
write.csv(report, output_file, row.names = FALSE)
print(paste("Report saved to:", output_file))[1] "Report saved to: Results/Inspect_tiff/TIFF_DeepScan_20260703.csv"
Use this report to verify file integrity:
Bit Depth (16 or 32): These are true scientific images. Do not convert them to JPG or PNG, as those formats are typically limited to 8-bit and will discard data precision. If BitDepth remains “Unknown”, the file likely lacks a proper header.
Compression: Recommended (Uncompressed, LZW, Deflate, Packbits); Not recommended (JPEG, OldJPEG). If you see JPEG compression inside a TIFF, the data integrity for pixel-based analysis is compromised.
Color Space (Gray vs sRGB): Scientific microscopy data is typically Gray (intensity only). If a raw microscope file is sRGB, it may have been converted or taken from a screenshot, potentially losing its dynamic range.
//
Utilisez ce rapport pour vérifier l’intégrité des données :
Profondeur de bits (16 ou 32) : Il s’agit de véritables images scientifiques. Ne les convertissez pas au format JPG ou PNG, car ces formats sont généralement limités à 8 bits et entraîneraient une perte de précision des données. Si la profondeur de bits reste « Inconnue », le fichier ne dispose probablement pas d’un en-tête correct.
Compression : Recommandée (Non compressé, LZW, Deflate, Packbits) ; Non recommandée (JPEG, OldJPEG). Si vous constatez une compression JPEG dans un fichier TIFF, l’intégrité des données pour l’analyse au niveau des pixels est compromise.
Espace colorimétrique (Gris vs sRGB) : Les données de microscopie scientifique sont généralement en gris (intensité uniquement). Si un fichier brut de microscope est en sRGB, il a peut-être été converti ou provient d’une capture d’écran, ce qui peut entraîner une perte de sa plage dynamique.
ImageJ / Fiji: Standard open-source software for viewing and analyzing scientific TIFFs (e.g. microscopy, astronomy). It handles multi-page stacks and high-bit-depth data that confuse standard viewers (Schindelin et al. 2012).
Bio-Formats: A library specifically designed to read proprietary life sciences image formats (e.g., .czi, .lif) and convert them to standard OME-TIFF (see the Bio-Formats documentation).
ExifTool: A robust command-line tool for reading and writing embedded metadata (EXIF, IPTC, XMP) in images (see the documentation).
//
ImageJ / Fiji : logiciel libre standard destiné à la visualisation et à l’analyse de fichiers TIFF scientifiques (par exemple, en microscopie ou en astronomie). Il prend en charge les piles d’images multipages et les données à grande profondeur de bits qui posent problème aux visionneuses standard (Schindelin et al. 2012).
Bio-Formats : Une bibliothèque spécialement conçue pour lire les formats d’image propriétaires des sciences de la vie (par exemple, .czi, .lif) et les convertir au format OME-TIFF standard (voir la documentation Bio-Formats.
ExifTool : Un outil en ligne de commande robuste permettant de lire et d’écrire des métadonnées intégrées (EXIF, IPTC, XMP) dans les images (voir la [documentation](https://exiftool.org/exiftool_pod.html
For users who want to run this analysis on a server, in a batch job, or from the command line, here is a pure R script that performs the same process.
Download the R Script: Inspect_tiff_Script.R
//
Pour les utilisateurs qui souhaitent exécuter cette analyse sur un serveur, dans le cadre d’un traitement par lots ou depuis la ligne de commande, voici un script R pur qui effectue le même processus.
Télécharger le script R : Inspect_tiff_Script.R
Inspect_tiff_submit.sh
#!/bin/bash
#SBATCH --job-name=tiff_check
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --time=00:30:00
#SBATCH --mem=16G
#SBATCH --output=logs/tiff_check_%j.log
# Load R Module
# Note: ImageMagick is often a system library, but some clusters require a module.
# Check with 'module avail imagemagick' if the script fails.
module load R
module load imagemagick/7.1 # Adjust version as needed for your cluster
# Define Target Directory
# Replace with the actual path to your microscopy/image data
DATA_DIR="/scratch/user/project_data/microscopy"
# Prepare Environment
mkdir -p Results/Inspect_tiff
mkdir -p logs
# Run Analysis
echo "Starting TIFF Deep Scan on $DATA_DIR"
Rscript Inspect_tiff_Script.R "$DATA_DIR"