103 lines
4.1 KiB
Python
103 lines
4.1 KiB
Python
|
#!/usr/bin/env python
|
||
|
"""
|
||
|
Extract and Parse Metadata from IMS/LSM/CZI files.
|
||
|
"""
|
||
|
|
||
|
from argparse import ArgumentParser
|
||
|
import os
|
||
|
import subprocess
|
||
|
import logging
|
||
|
import utility
|
||
|
import ome_schema
|
||
|
|
||
|
def extract_metadata(input_path, output_path):
|
||
|
|
||
|
"""
|
||
|
Extract OME metadata from the input file and write it out as a nicely formatted xml using
|
||
|
bftools. (http://www.openmicroscopy.org/site/support/bio-formats5.3/users/comlinetools/display.html)
|
||
|
"""
|
||
|
|
||
|
bf_tools_dir = os.getenv('BFTOOLS_DIR', os.getcwd()) + "/"
|
||
|
command = bf_tools_dir +"showinf -omexml-only -nopix " + input_path + " | " + bf_tools_dir + "xmlindent > " + output_path
|
||
|
p = subprocess.Popen(command, shell=True)
|
||
|
p.wait()
|
||
|
|
||
|
def get_metadata_as_class(input_xml_path):
|
||
|
|
||
|
"""
|
||
|
Return the OME metadata from the input XML file as a Python class. The class is automatically generated
|
||
|
using pyxbgen (http://pyxb.sourceforge.net/pyxbgen_cli.html) and the current OME XML Schema
|
||
|
(https://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd).
|
||
|
|
||
|
If you need to use a newer schema you need to regenerate the file ome_schema.py by doing:
|
||
|
pip install pyxb
|
||
|
pyxbgen -m ome_schema -u https://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd
|
||
|
|
||
|
where the web address points to the new schema. You can then access the elements of the OME XML as
|
||
|
instance attributes etc.
|
||
|
"""
|
||
|
|
||
|
xml = open(input_xml_path).read()
|
||
|
image_metadata = ome_schema.CreateFromDocument(xml)
|
||
|
return image_metadata
|
||
|
|
||
|
def integer_color_to_rgb(color):
|
||
|
|
||
|
"""
|
||
|
Convert integer color to (r,g,b)
|
||
|
"""
|
||
|
|
||
|
return ((color >> 16) & 255, (color >> 8) & 255, color & 255)
|
||
|
|
||
|
|
||
|
def print_metadata_overview(image_metadata):
|
||
|
|
||
|
"""
|
||
|
Print a reader-friendly metadata summary
|
||
|
"""
|
||
|
|
||
|
print "Number of Images: ", len(image_metadata.Image)
|
||
|
print "Image '0' - Name: ", image_metadata.Image[0].Name
|
||
|
print "Image '0' - Num Channels: ", image_metadata.Image[0].Pixels.SizeC
|
||
|
print "Image '0' - Num Times: ", image_metadata.Image[0].Pixels.SizeT
|
||
|
pixel_size_x = image_metadata.Image[0].Pixels.PhysicalSizeX
|
||
|
pixel_size_y = image_metadata.Image[0].Pixels.PhysicalSizeY
|
||
|
pixel_size_z = image_metadata.Image[0].Pixels.PhysicalSizeZ
|
||
|
pixel_unit_x = image_metadata.Image[0].Pixels.PhysicalSizeXUnit
|
||
|
pixel_unit_y = image_metadata.Image[0].Pixels.PhysicalSizeYUnit
|
||
|
pixel_unit_z = image_metadata.Image[0].Pixels.PhysicalSizeZUnit
|
||
|
print "Image '0' - Pixel Physical Size X: ", pixel_size_x, pixel_unit_x
|
||
|
print "Image '0' - Pixel Physical Size Y: ", pixel_size_y, pixel_unit_y
|
||
|
print "Image '0' - Pixel Physical Size Z: ", pixel_size_z, pixel_unit_z
|
||
|
print "Image '0' - Pixel Size X: ", image_metadata.Image[0].Pixels.SizeX
|
||
|
print "Image '0' - Pixel Size Y:", image_metadata.Image[0].Pixels.SizeY
|
||
|
print "Image '0' - Pixel Size Z:", image_metadata.Image[0].Pixels.SizeZ
|
||
|
print "Image '0' - Pixel Dimension Order: ", image_metadata.Image[0].Pixels.DimensionOrder
|
||
|
print "Image '0' - Pixel Bits: ", image_metadata.Image[0].Pixels.SignificantBits
|
||
|
for idx, eachChannel in enumerate(image_metadata.Image[0].Pixels.Channel):
|
||
|
print "Image '0' - Channel " +str(idx) + " Color: ", integer_color_to_rgb(eachChannel.Color)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
# Do setup
|
||
|
tool_name = "extract_metadata"
|
||
|
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_file", type=str, help='Output metadata file.')
|
||
|
parser.add_argument("--verbose", type=bool, help='Output a simple metadata summary.')
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
logger1.info('Reading Metadata At: ' + args.input_file)
|
||
|
extract_metadata(args.input_file, args.output_file)
|
||
|
|
||
|
if(args.verbose):
|
||
|
image_metadata = get_metadata_as_class(args.output_file)
|
||
|
print_metadata_overview(image_metadata)
|
||
|
logger1.info('Completed Reading Metadata')
|