Specify global position of a Tiff

Hi (@Alex_H @joshmoore @NicoKiaru @StephanPreibisch),

Does someone know whether it is possible to save a Tiff image file with a “global position” that is read by Bio-Formats. With global position I mean that the upper left corner of the image is not at (0,0) but at some other place in some global coordinate system. If the answer is “no”, which image file format would you recommend that can represent such information in a way that it is properly read by Bio-Formats (bdv/hdf5 or something else)?

And related to that: If one reads in a file with Bio-Formats, how would one read out such global position information?

And also related: does an ImagePlus in ImageJ have this global offset property? I could not readily see it in the API.

I just found that imagePlus.getCalibration().xOrigin and imagePlus.getCalibration().yOrigin do exist, which is nice.

But those fields do not seem to be set by Bio-Formats when, e.g., opening a czi file using the ImagePlusReader. I debugged into the ImagePlusReader code and the function public void applyCalibration(ImagePlus imp) in loci.plugins.in.Calibrator does indeed not seem to populate those fields.

Hi @Christian_Tischer,

The TIFF reference defines the X Position and Y Position. These tags should be parsed by any TIFF-based reader and accessible from the global metadata - see https://github.com/ome/bioformats/blob/6f50e4d52c9d96112635fd8b2dde737f31041cf0/components/formats-bsd/src/loci/formats/in/BaseTiffReader.java#L248-L249.

The Bio-Formats getPlanePositionX and getPlanePositionY API allow to retrieve similar information. There are a few TIFF-based readers which support this metadata it stored in the file including OME-TIFF, Micro-Manager. The caveat about the interpretation of this metadata already discussed in Bio-Formats Image Position about the semantics of this location (centre, upper left) still applies.

1 Like

Thanks @s.besson!

And what about using this information to populate the fields

imagePlus.getCalibration().xOrigin
imagePlus.getCalibration().yOrigin

in your ImagePlusReader?

Yeah we aren’t really making much use of the calibration in the ImagePlusReader unless the user sets one. Adding those fields should be possible though, there may be other similar fields which could also be populated, I will try to get a PR open to update the ImagePlusReader this week.

1 Like

Thank you @dgault this is really great :heart:

I am trying to write the information to an ome.tif.
Is this correct?

Calibration calibration = imp.getCalibration();
for ( int planeIndex = 0; planeIndex < imp.getNSlices(); planeIndex++ )
{
	meta.setPlanePositionX( FormatTools.getPhysicalSize( calibration.xOrigin, calibration.getXUnit() ), 0, planeIndex );
	meta.setPlanePositionY( FormatTools.getPhysicalSize( calibration.yOrigin, calibration.getYUnit() ), 0, planeIndex );
	meta.setPlanePositionZ( FormatTools.getPhysicalSize( calibration.zOrigin, calibration.getZUnit() ), 0, planeIndex );
}
  1. I am not sure about the planeIndex: does this refer to a z-planes or Tiff planes?
    In other words if it is a 5D image do I also need to loop over all channels and time-points?
  2. What is the imageIndex? Is that what you also call series?
  3. In fact, do you also have an ImagePlusWriter such that I would not need to implement myself?

I think I am doing something wrong. When I read in the file that I wrote using above code I get an error:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
	at java.util.ArrayList.rangeCheck(ArrayList.java:657)
	at java.util.ArrayList.get(ArrayList.java:433)
	at ome.xml.model.Pixels.getPlane(Pixels.java:740)
	at ome.xml.meta.OMEXMLMetadataImpl.getPlanePositionX(OMEXMLMetadataImpl.java:3127)
	at de.embl.cba.io.BioFormatsReader.read(BioFormatsReader.java:63)

using this code:

			// create OME-XML metadata store
			ServiceFactory factory = new ServiceFactory();
			OMEXMLService service = factory.getInstance(OMEXMLService.class);
			IMetadata meta = service.createOMEXMLMetadata();

			// create format reader
			IFormatReader reader = new ImageReader();
			reader.setMetadataStore( meta );

			// initialize file
			reader.setId( filePath );
			reader.setSeries( 0 );

			Length positionX = meta.getPlanePositionX ( 0, 0 );

Any ideas what the problem could be?

The issue must be in my writer code. I tried replacing

tiffWriter.saveBytes( i, bytes, ifd );
by
tiffWriter.savePlane( i, bytes );
but it did not help.

Here is the current code for writing: https://github.com/tischi/imagej-utils/blob/2853e5993269833037b096f1e2e599bc0bd98dcc/src/main/java/de/embl/cba/io/BioFormatsTiffWriter.java

In fact my code was working all the time :smiling_face_with_three_hearts:
I just did not save the files with the ending ome.tif but only .tif :frowning:
At least, thanks to the debugging, I know now all the guts of the bio-formats library :wink:

4 Likes

Glad to hear you got it sorted. Just to answer the questions raised either for yourself or others reading the thread later:

  1. The planeIndex will relate to all the planes in a given series, so will include the full ZCT. The index will therefore depend on the dimension ordering. There are helper methods in FormatTools.getIndex which can be used to easier calculate the correct index.
  2. Yes, imageIndex is the same as series index, it has been a point of confusion in the API for a while now. The next BF release will have some updated docs starting to try to clear this up (https://github.com/ome/bioformats/pull/3613/files)
  3. I’m afraid we don’t have a direct ImagePlusWriter
2 Likes

In fact you do have one :slight_smile:

…but it is hidden here: https://github.com/ome/bio-formats-imagej/blob/2c0205850dd9469c14a9fe777bafe71f2f10b1ff/src/main/java/loci/plugins/out/Exporter.java#L135

I would suggest a code refactoring that pulls out a ImagePlusExporter class from the plugin and then just call this from the plugin (reducing the plugin to the UI).

I could try to do this and stage a PR when I find the time (not sure when). Should I put this on my todo list?

If you are happy to refactor out an ImagePlusExporter and open a PR that would be great. I could definitely see it being useful for other developers as well.

1 Like

I can’t seem to open an issue here: https://github.com/ome/bio-formats-imagej/issues
The repo says Archived

@Christian_Tischer yes this repository was a prototype created a few years ago to extracted the ImageJ plugin which was never completed to production and hence archived.
As of today, the ImageJ plugin is still maintained in the core ome/bioformats repository - see https://github.com/ome/bioformats/blob/6f50e4d52c9d96112635fd8b2dde737f31041cf0/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java#L137.

1 Like