stack-3d/format_conversion/zeiss_to_tiff.py
2017-02-16 15:26:55 +00:00

97 lines
No EOL
3.8 KiB
Python

"""
Conversion of IMS/LSM/CZI files to OME and then Generic TIFFs
"""
import os
import logging
import math
from argparse import ArgumentParser
from functools import partial
import multiprocessing as mp
import skimage.external.tifffile
import utility
import extract_zeiss_metadata
import bftools_wrapper
def extract_pixel_values_only(input_file, working_directory, channel=0, significant_bits=8):
im = skimage.external.tifffile.imread(input_file)
pixel_vals_only = im[0, :, 0, channel, :, :] # Strip excess data
out_path = working_directory + "/" + os.path.splitext(os.path.basename(input_file))[0] + "_pixels_only.tiff"
if significant_bits==8:
skimage.external.tifffile.imsave(out_path, skimage.img_as_ubyte(pixel_vals_only))
elif significant_bits==16:
skimage.external.tifffile.imsave(out_path, skimage.img_as_uint(pixel_vals_only))
else:
# Let skiimage decide
skimage.external.tifffile.imsave(out_path, pixel_vals_only)
def do_conversion(input_file, output_file, channel = 0, series = 0):
#
# # Get the image metadata
extract_zeiss_metadata.extract_metadata(input_file, os.getcwd() + "temp_metadata.xml")
image_metadata = extract_zeiss_metadata.get_metadata_as_class(os.getcwd() + "temp_metadata.xml")
#
# # Choose the tile size
tile_x = 1024
tile_y = 1024
# Black box JVM conversion via CLI. Be skeptical of outputs,
# at least the Z-physical size is silently lost!!!
bftools_wrapper.convert(input_file, output_file, tile_x, tile_y, channel, series)
# Make versions with just XYZ pixel values for easier use in scikit-image/VTK etc.
# DANGER, now all physical size is lost. Only trust physical sizes
# in the standalone xml metadata file, obtained (and validated) using `extract_zeiss_metadata()`.
# Collect the file names
file_names = []
for eachFile in os.listdir(output_file):
if eachFile.endswith(".tiff"):
file_names.append(output_file + "/" + eachFile)
# Make a partial function for multiple arg mapping
working_directory = output_file + "/Pixel_Values_Only/"
if not os.path.exists(working_directory):
os.makedirs(working_directory)
significant_bits = int(image_metadata.Image[0].Pixels.SignificantBits)
partial_extract_pixel_values_only = partial(extract_pixel_values_only,
working_directory=working_directory,
channel=channel,
significant_bits=significant_bits)
# Limit to max 6 cpus
num_available_cpus = mp.cpu_count()
if num_available_cpus > 6:
num_available_cpus = 6
# Distribute across processes - Be conservative with available CPUs
run_cpus = int(math.floor(num_available_cpus/2))
if run_cpus == 0:
run_cpus = 1
run_cpus = 1
#pool = mp.Pool(processes = run_cpus)
pool = mp.Pool(processes = 1)
pool.map(partial_extract_pixel_values_only, file_names)
if __name__ == "__main__":
# Do setup
tool_name = "zeiss_to_tiff"
utility.do_setup(tool_name)
logger1 = logging.getLogger('format_conversion.'+tool_name)
# Suppress XML Parse warnings
pyxb_logger = logging.getLogger('pyxb')
pyxb_logger.setLevel(logging.CRITICAL)
parser = ArgumentParser()
parser.add_argument("-i", "--input_file", type=str, help='Input file in a ZEISS format.')
parser.add_argument("-o", "--output_folder", type=str, help='Output Tiff Location.')
args = parser.parse_args()
logger1.info('Start Converting Image at: ' + args.input_file)
do_conversion(args.input_file, args.output_folder, channel = 1, series = 0)
logger1.info('Completed Processing')