filippocastelli / pyometiff Goto Github PK
View Code? Open in Web Editor NEWOME-TIFF IO in python
License: GNU General Public License v3.0
OME-TIFF IO in python
License: GNU General Public License v3.0
Hi, I was wondering if it would be possible to implement writing multi-series OME-TIFFs?
The underlying tifffile.TiffWriter class actually supports this natively (example here), and it would be really nice to have this alongside the XML validation that the OMETIFFWriter
class does.
Happy to make a PR that does this, if that would help!
setup.py is dated, just use pyproject.toml
I try to parse an OME XML string read outside the OMETIFFReader object, using the OMETIFFReader.parse_metadata(s) function. However, this function always parses the internal attribute "self.omexml_string" instead of the argument string ("omexml_string"). I suggest modifying line 54 from pyometiff/omereader.py by dropping "self." from "self.omexml_string".
Thanks a lot for this nice package!
Hello,
I am currently trying to save an ome.tiff image pyramidalized with scikit image. Currently I have it as an array of multiple images, this is how scikit image returns it.
Is there a way to do it with pyometiff ? I cannot find it in the documentation.
Thank you !
version string direct import from package no longer supported and raises metadata-generation-failed
Possible workaround: read data from file instead of import.
Hello,
Thank you for this really nice package.
I was trying to read one of my files and I get a "list index out of range error".
These data have been saved in TIFF using ImSpector Pro 7.0.
Thank you for your help.
Arnaud
PS: I can also share some data if needed.
img_array, metadata, xml_metadata = reader.read()
Key not found: list index out of range
Key not found: list index out of range
key not found list index out of range
Key not found: list index out of range
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[8], line 1
----> 1 img_array, metadata, xml_metadata = reader.read()
File ~/.virtualenvs/microscopy/lib/python3.10/site-packages/pyometiff/omereader.py:40, in OMETIFFReader.read(self)
38 def read(self) -> (np.ndarray, dict, str):
39 self.array, self.omexml_string = self._open_tiff(self.fpath)
---> 40 self.metadata = self.parse_metadata(self.omexml_string)
41 return self.array, self.metadata, self.omexml_string
File ~/.virtualenvs/microscopy/lib/python3.10/site-packages/pyometiff/omereader.py:166, in OMETIFFReader.parse_metadata(self, omexml_string)
163 metadata["ObjMag"] = None
165 # get channel names
--> 166 metadata["Channels"] = self._parse_channels(metadata["SizeC"], self.ox, self.imageseries)
167 # for c in range(metadata["SizeC"]):
168 # channel_names.append(
169 # self.ox.image(self.imageseries).Pixels.Channel(c).Name
170 # )
171
172 # self.ox.image(self.imageseries).Pixels.Channel(c).
173 metadata = self._remove_none_or_empty_dict(metadata)
File ~/.virtualenvs/microscopy/lib/python3.10/site-packages/pyometiff/omereader.py:180, in OMETIFFReader._parse_channels(cls, sizeC, ox, imageseries)
178 channels_dict = {}
179 for c in range(sizeC):
--> 180 channel_obj = ox.image(imageseries).Pixels.Channel(c)
181 channel_name = channel_obj.Name
182 channel_dict = {}
File ~/.virtualenvs/microscopy/lib/python3.10/site-packages/pyometiff/omexml.py:1032, in OMEXML.Pixels.Channel(self, index)
1030 def Channel(self, index=0):
1031 """Get the indexed channel from the Pixels element"""
-> 1032 channel = self.node.findall(qn(self.ns['ome'], "Channel"))[index]
1033 return OMEXML.Channel(channel)
IndexError: list index out of range
Hello,
Thank you very much for providing a smooth interface to open OME TIF.
When I try and open the .OME.TIFF file that I have, I get the following error:
TiffFrame 1: missing required tags
OME series: expected 1 frames, got 2
import pathlib
from pyometiff import OMETIFFReader
img_fpath = pathlib.Path("/path_to_file/file.ome.tiff")
reader = OMETIFFReader(fpath=img_fpath)
img_array, metadata, xml_metadata = reader.read()
Your thoughts on this would be greatly appreciated!
Best,
I have an RGB image with shape (15840, 28800, 3)
(i.e. axis order YXS
) - I'm attempting to generate the ome-xml
for this file by passing in the following parameters - note that this is after reshaping the array to be in dimension order SYX
(as anything else raises an error with OMETIFFWriter
):
metadata = {
'Pixels BigEndian': False,
'DimensionOrdering': 'SYX',
'SizeY': 15840,
'SizeX': 28800,
'SizeC': 1,
'SizeZ': 1,
'SizeT': 1,
'PlaneCount': 1,
'PhysicalSizeX': 4.991469905942555e-05,
'PhysicalSizeXUnit': 'cm',
'PhysicalSizeY': 4.991469905942555e-05,
'PhysicalSizeYUnit': 'cm',
'Name': 'WholeSlideHnE',
'Type': 'uint8',
'Interleaved': True,
'Channels': {
'RGB': {
'SamplesPerPixel': 3,
'BitsPerSample': (8, 8, 8)
}
}
}
params = {
"fpath" : destination,
"dimension_order" : metadata['DimensionOrdering'],
"array" : pixels,
"metadata" : metadata,
"explicit_tiffdata" : False,
"photometric" : "RGB"
}
xml = OMETIFFWriter(**params)._xml
This outputs the following XML:
<OME xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openmicroscopy.org/Schemas/OME/2016-06 http://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd">
<Image ID="Image:0" Name="WholeSlideHnE">
<AcquisitionDate>2022-07-08T16:01:50.130775</AcquisitionDate>
<Pixels BigEndian="false"
DimensionOrder="XYS"
ID="Pixels:0"
Interleaved="false"
PhysicalSizeX="4.991469905942555e-05"
PhysicalSizeXUnit="cm"
PhysicalSizeY="4.991469905942555e-05"
PhysicalSizeYUnit="cm"
SizeC="1"
SizeT="1"
SizeX="3"
SizeY="1"
SizeZ="1"
Type="uint8">
<Channel ID="Channel:00" Name="RGB" SamplesPerPixel="3">
<LightPath/>
</Channel>
<TiffData IFD="0" PlaneCount="1"/></Pixels>
</Image>\n</OME>
Questions:
SizeX
, SizeY
and Interleaved
parameters not properly parsed?Interleaved = True
even a correct value to be passing in when trying to write out an RGB image as one single channel? I understand it affects the order in which the bytes representing each pixel are stored in memory, but I'm unclear as to whether or not this makes any other difference (say with trying to load the written image into viewers, etc).Any help would be much appreciated. Thank you!
EDIT:
It seems like it might not actually be possible to generate OME-XML compliant metadata for RGB images with this package - as seen here, the OMETIFFWriter
object expects the Channels
key within the passed in metadata dictionary to contain as many keys as there are channels (inferred from the shape of the image) - however, in the case of RGB images, we only want 1 channel with a SamplesPerPixel
value of 3, rather than wanting each channel to be parsed as its own channel with SamplesPerPixel = 1
.
Hello again,
I want to write OME-TIFF from big arrays (23000 X 23000 for example). Following the example in the README, this is how I generate an OME-TIFF with random values:
import pyometiff
import numpy as np
data = np.random.randn(1, 1, 3, 23000, 23000).astype('uint8')
metadata_dict = {
"PhysicalSizeX" : "0.88",
"PhysicalSizeXUnit" : "µm",
"PhysicalSizeY" : "0.88",
"PhysicalSizeYUnit" : "µm",
"PhysicalSizeZ" : "3.3",
"PhysicalSizeZUnit" : "µm",
"Channels" : {
"405" : {
"Name" : "405nm",
"SamplesPerPixel": 1,
"ExcitationWavelength": 405.,
"ExcitationWavelengthUnit": "nm"
},
"488" : {
"Name" : "488nm",
"SamplesPerPixel": 1,
"ExcitationWavelength": 488.,
"ExcitationWavelengthUnit": "nm"
},
"638" : {
"Name" : "638nm",
"SamplesPerPixel": 1,
"ExcitationWavelength": 638.,
"ExcitationWavelengthUnit": "nm"
},
}
}
writer = pyometiff.OMETIFFWriter("test_out.ome.tiff", dimension_order="ZTCYX", array=data, metadata=metadata_dict)
writer.write()
It works, but the output file is 1.47 GB big. Is there a way to compress it, in JPEG, for example?
Thanks for your help,
Etienne
Hello,
I'm trying to read 2D OME-TIFF sample files that I found on the OME website (https://downloads.openmicroscopy.org/images/OME-TIFF/2016-06/tubhiswt-2D/) with the package pyometiff. Here is my code:
import pyometiff
reader = pyometiff.OMETIFFReader('tubhiswt_C0.ome.tif')
img_array, metadata, xml_metadata = reader.read()
When I run it, I get this error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-bd3614b76a8e> in <module>
1 reader = pyometiff.OMETIFFReader('tubhiswt_C0.ome.tif')
----> 2 img_array, metadata, xml_metadata = reader.read()
~\miniconda3\envs\tpGBM\lib\site-packages\pyometiff\omereader.py in read(self)
37 def read(self) -> (np.ndarray, dict, str):
38 self.array, self.omexml_string = self._open_tiff(self.fpath)
---> 39 self.metadata = self.parse_metadata(self.omexml_string)
40 return self.array, self.metadata, self.omexml_string
41
~\miniconda3\envs\tpGBM\lib\site-packages\pyometiff\omereader.py in parse_metadata(self, omexml_string)
131 self.imageseries
132 ).Detector.get_ID()
--> 133 metadata["DetectorType"] = self.ox.instrument(
134 self.imageseries
135 ).Detector.get_Type()
~\miniconda3\envs\tpGBM\lib\site-packages\pyometiff\omexml.py in get_Type(self)
1172
1173 def get_Type(self):
-> 1174 return get_int_attr(self.node, "Type")
1175 def set_Type(self, value):
1176 self.node.set("Type", str(value))
~\miniconda3\envs\tpGBM\lib\site-packages\pyometiff\omexml.py in get_int_attr(node, attribute)
294 '''Cast an element attribute to an int or return None if not present'''
295 attr = node.get(attribute)
--> 296 return None if attr is None else int(attr)
297
298 def make_text_node(parent, namespace, tag_name, text):
ValueError: invalid literal for int() with base 10: 'PMT'
I also tried with another OME-TIFF file from https://docs.openmicroscopy.org/ome-model/5.6.3/ome-tiff/data.html, for example 00001_01.ome.tiff, and the reading works just fine.
Do you know why the first ones can't be read?
Thanks for your help,
Etienne
Dear all,
Could you clarify a bit exact meaning of Sizes BF, DimOrder BF, DimOrder BF Array, DimOrder fields in metadata?
Thank you for any input.
The example dataset at https://docs.openmicroscopy.org/ome-model/6.0.0/ome-tiff/data.html#plate contains multiple (thousands of) scenes (think "plate positions"). aicsimageio allows accessing them via the scenes
and current_scene
attributes and set_scene
method on the AICSImage
object. On the other hand, AFAICT (but I may be wrong), pyometiff only lets one access the first scene. (My guess is that accessing the other scenes requires passing the series
kwarg to TiffFile.asarray(...)
.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.