I'm working on a Python script that processes images and saves them as TIFF files using the tifffile library. The script runs as part of a larger pipeline where I use the ashlar tool to process these TIFF files further. However, I'm encountering an issue related to ASCII encoding when saving the TIFF files.
Context:
Python Environment: I am using Python 3.9 along with the tifffile library for TIFF file handling.
Error Trigger: The error arises during the execution of the save_tiff function, which is responsible for saving TIFF files with a description.
Description Handling: The ashlar tool requires all descriptions in TIFF files to be ASCII-compliant for proper functioning in subsequent processing steps.
Python Code Snippet:
import numpy as np
import tifffile
def save_tiff(image, path, description='Generated by process_tile'):
"""
Save the image as a TIFF file with an ASCII-compliant description.
Args:
- image: The image array to save.
- path: The file path to save the TIFF file.
- description: Optional description string (default is 'Generated by process_tile').
"""
description_ascii = description.encode('ascii', 'ignore').decode('ascii')
with tifffile.TiffWriter(path, imagej=True) as tif:
tif.save(image, description=description_ascii)
Bash Script Snippet:
#!/usr/bin/env bash
module load jupyter/python_3.9
ashlar --version
# Function to check consistency of input images
check_images() {
local input_path=$1
find $input_path -name 'mask*.tif' -type f -print0 | sort -z | xargs -0 ashlar -o $OUTPUT_PATH/ashlar_output_mask.ome.tif -c 0 --stitch-alpha 0.01 --filter-sigma 1.0
}
# Function to modify TIFF descriptions to ensure ASCII compliance
modify_tiff_description() {
local input_path=$1
local temp_path=$2
find $input_path -name 'overlay*.tif' -type f -print0 | sort -z | xargs -0 ashlar -o $OUTPUT_PATH/ashlar_output_overlay.ome.tif -c 0 --stitch-alpha 0.01 --filter-sigma 1.0
}
# Create temporary directories for modified images
TEMP_PATH_MASK="${INPUT_PATH_MASK}/temp"
TEMP_PATH_OVERLAY="${INPUT_PATH_OVERLAY}/temp"
mkdir -p $TEMP_PATH_MASK $TEMP_PATH_OVERLAY # Create temp directories
# Check consistency of mask images
echo "Checking mask images..."
check_images $TEMP_PATH_MASK
# Check consistency of overlay images
echo "Checking overlay images..."
check_images $TEMP_PATH_OVERLAY
# Modify TIFF descriptions to ensure ASCII compliance
echo "Modifying TIFF descriptions for mask images..."
modify_tiff_description $INPUT_PATH_MASK $TEMP_PATH_MASK
echo "Modifying TIFF descriptions for overlay images..."
modify_tiff_description $INPUT_PATH_OVERLAY $TEMP_PATH_OVERLAY
# Clean up temporary directories
rm -rf $TEMP_PATH_MASK $TEMP_PATH_OVERLAY
Error Message:
Traceback (most recent call last):
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/tifffile/tifffile.py", line 7552, in overwrite
value = value.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\xb5' in position 552: ordinal not in range(128)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/scg/apps/software/jupyter/python_3.9/bin/ashlar", line 8, in <module>
sys.exit(main())
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/ashlar/scripts/ashlar.py", line 226, in main
return process_single(
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/ashlar/scripts/ashlar.py", line 296, in process_single
writer.run()
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/ashlar/reg.py", line 1307, in run
print()
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/tifffile/tifffile.py", line 2809, in __exit__
self.close()
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/tifffile/tifffile.py", line 2802, in close
self._write_image_description()
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/tifffile/tifffile.py", line 2791, in _write_image_description
self._descriptiontag.overwrite(self, description, erase=False)
File "/scg/apps/software/jupyter/python_3.9/lib/python3.9/site-packages/tifffile/tifffile.py", line 7554, in overwrite
raise ValueError(
ValueError: TIFF strings must be 7-bit ASCII
encodeperhaps needs - to do any encoding - to know the encoding of the stringdescription. I would expect that it either takes this information from the environment variable LANG, or uses UTF8 as default. Now let's assue that the string is supposed to be UTF8, but in reality has been encoded differently, for instance Windows-1252. In this case, the original file has a byte which isn't valid in UTF8.iconv.imagej=True. Description is ignored when writing ImageJ format, at least with recent versions of tifffile.