Read ome-xml metadata

Hi,
I would like to export to a txt file the position of the stage that is recorded in the ome-xml metadata.

I tried to use the OMEVisual plug-in but without success as I have a message saying that I need to open the images with SCIFIO (even when opening the image with SCIFIO).

I found these functions but I didn’t manage to use them. I am not sure what the variable “value” is for? also I am not sure if the functions below work on the ome-xml metadata or just the “standart” metadata

run("Bio-Formats Macro Extensions");

Ext.getMetadataValue(field, value);
-- Obtains the specified metadata field's value.
Ext.getSeriesMetadataValue(field, value)
-- Obtains the specified series metadata field's value.
Ext.getPlanePositionX(positionX, no)
-- Obtains the X coordinate of the stage for the no'th plane
-- or NaN if none.
Ext.getPlanePositionY(positionY, no)
-- Obtains the Y coordinate of the stage for the no'th plane
-- or NaN if none.

The fields i am interested in are called StagePosY and StagePosX.

Any help would be very welcome,
Thank you

Hi @LPUoO, value will be the result of metadata field being returned.
In this case I suspect what you want is to use getPlanePositionX and getPlanePositionY, here the no will be the index of the plane you are interested in. To loop over all the planes you can use the below code:

run("Bio-Formats Macro Extensions");

id = File.openDialog("Choose a file");
print("Image path: " + id);

Ext.setId(id);
Ext.getImageCount(imageCount);
print("Plane count: " + imageCount);

posX = newArray(imageCount);
posY = newArray(imageCount);
for (no=0; no<imageCount; no++) {
  Ext. getPlanePositionX(posX[no], no);
  Ext. getPlanePositionY(posY[no], no);
  print("Plane: " + no + ",PosX :" + posX[no] + ",  PosY: " + posY[no]);
}
print("Complete.");
2 Likes

Hi @dgault,
Thank you for your help.
When I run the macro you provided the output I have is:
Plane: 0,PosX :NaN, PosY: NaN.
Plane: 1 …

Does the macro you wrote retrieve the information in the metadata one would have when doing Ctrl+I or is it from the ome-XML metadata ? The reason being that only in the ome-XML metadata I see the stage position.

Also, I don’t know if it makes a difference but according to the plane count I have 200 planes but in reality I have 2 channel with 100 slices. Also each file I have is just one position, so all the planes should have the same stage position (in X and Y).

So I tried the following but as value I only get 0

run("Bio-Formats Macro Extensions");
id = File.openDialog("Choose a file");
Ext.setId(id);
field = "StagePosY";
Ext.getMetadataValue(field, value);
print("PosY :" + field);

Below is a screen shot of the actual info I would like to retrieve:
image

So right know I am a bit confused because the only output I have both ways is “0”.

Thank you very much for your help

Hi @LPUoO, the code i had used should have retrieved the value from the Plane element of the OME-XML:
<Plane PositionX="1040.32" PositionXUnit="µm" PositionY="2331.56" PositionYUnit="µm" PositionZ="1718.93" PositionZUnit="µm" TheC="1" TheT="0" TheZ="0"/>

The other call you tried (Ext.getMetadataValue(field, value);) will retrieve data from the original metadata, these are the key value pairs seen in the Show Info window.

However it seems neither of these are the correct location for your metadata. What format is it you are using? If possible would you be able to upload a sample file to: https://www.openmicroscopy.org/qa2/qa/upload/

2 Likes

I think I have a similar question (although I am using Matlab), this is why I post it here.
How can I get the microscope stage coordinates from the metadata contained in the .nd2 files?
Here are the OME Metadata I have from my file:

<OME xmlns="http://www.openmicroscopy.org/Schemas/OME/2016-06" 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">
<Instrument ID="Instrument:0">
<Detector ID="Detector:0:0" Model="Qi2_Camera_Mono_SN_751322" Type="Other"/>
<Objective Correction="Other" ID="Objective:0:0" Immersion="Other"/>
<Image ID="Image:0" Name="20190617_insituDrop_SDS10mM_002.nd2 (series 1)">
<InstrumentRef ID="Instrument:0"/>
<ObjectiveSettings ID="Objective:0:0" RefractiveIndex="1.0"/>
<Pixels BigEndian="false" DimensionOrder="XYCZT" ID="Pixels:0" Interleaved="false" PhysicalSizeX="1.833740831295843" PhysicalSizeXUnit="µm" PhysicalSizeY="1.833740831295843" PhysicalSizeYUnit="µm" SignificantBits="14" SizeC="1" SizeT="266" SizeX="1608" SizeY="1608" SizeZ="1" Type="uint16">
<Channel Color="-1" ID="Channel:0:0" Name="Mono" SamplesPerPixel="1">
<DetectorSettings Gain="1.0" ID="Detector:0:0"/>
<LightPath/>
<MetadataOnly/>
<Plane DeltaT="0.17129988263547422" DeltaTUnit="s" ExposureTime="2.0" ExposureTimeUnit="s" PositionX="-7936.8" PositionXUnit="reference frame" PositionY="-6931.900000000001" PositionYUnit="reference frame" PositionZ="3172.175" PositionZUnit="reference frame" TheC="0" TheT="0" TheZ="0"/>
<Plane DeltaT="0.2502998826354742" DeltaTUnit="s" ExposureTime="2.0" ExposureTimeUnit="s" PositionX="-7936.8" PositionXUnit="reference frame" PositionY="-6931.900000000001" PositionYUnit="reference frame" PositionZ="3172.175" PositionZUnit="reference frame" TheC="0" TheT="1" TheZ="0"/>
<Plane DeltaT="0.3122998826354742" DeltaTUnit="s" ExposureTime="2.0" ExposureTimeUnit="s" PositionX="-7936.8" PositionXUnit="reference frame" PositionY="-6931.900000000001" PositionYUnit="reference frame" PositionZ="3172.175" PositionZUnit="reference frame" TheC="0" TheT="2" TheZ="0"/>

I have tried a couple ways:

reader = bfGetReader(fname);
omeMeta = reader.getMetadataStore();
nbrIMGtot = reader.getImageCount;
hshtb=reader.getGlobalMetadata;
reader.getMetadataValue('PositionX',1)
reader.getMetadataValue(PositionX,1)
data=bfopen(fname)
data{1,4}

but nothing seems to provide my with any of the stage coordinate.
What am I doing wrong?

Thank you very much.
All the best,
LeChat
The file: https://drive.google.com/file/d/1cXVO4T4BH0q6AL2r3qpiYoSXgvFu4_LK/view?usp=sharing

Hi @LeChat, what you will want is as below:

omeMeta = data{1, 4};
// Using getPlanePositionX(int imageIndex, int planeIndex);
omeMeta.getPlanePositionX(0,0);

There are 2 types of metadata stored, OME metadata such as the above are stored in data{s, 4}, while original metadata (key value pairs which are specific to a particular file or format) are stored in data{s, 2}. See https://docs.openmicroscopy.org/bio-formats/5.9.2/developers/matlab-dev.html#retrieving-metadata for more

Amazing, thank you!
So, if I want to have get my stage position, I should:
• first, load the whole file! (do I really need to use bfopen? It take a long time, and what about the ram…?)
• second convert the output of the code you gave using ‘char’, and then a ‘str2num’ as follow:

>> alors=omeMeta.getPlanePositionX(0,10)
     alors =

ome.units.quantity.Length: value[-7936.8], unit[reference frame] stored as java.lang.Double

>> phrase=char(alors);
>> str2num(phrase(34:40))

ans =

  -7.9368e+03

Is this a good way to proceed or is there a better way?

Thank you very much for your advice and expertise.

Hi,

i once had a related task in python and I do it like this:

Look for the function get_planetable(imagefile, writecsv=False, separator=’\t’, imageID=0, showinfo=True)

It basically ready the all planedata into a pandas dataframe or saves it as CSV. I use it ti display the surface of larger samples or wellplate flatness.

Hi @LeChat, you can also use the below if you do not wish to use bfOpen:

reader = bfGetReader(fname);
omeMeta = reader.getMetadataStore();
planePosX =  omeMeta.getPlanePositionX(0,0);

To get simply the value you can use:

planePosX.value()

To get the units on their own you can use:

planePosX.unit.getSymbol()

Hi @dgault,
This sounds very nice, but it seems that I have an issue:

>> reader = bfGetReader(fname);
omeMeta = reader.getMetadataStore();
>> omeMeta

omeMeta =

loci.formats.ome.OMEPyramidStore@4567e53d

>> planePosX =  omeMeta.getPlanePositionX(0,0)

planePosX =

     []

>> planePosX =  omeMeta.getPlanePositionX(1,1)
Java exception occurred:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
	at java.util.ArrayList.rangeCheck(ArrayList.java:657)
	at java.util.ArrayList.get(ArrayList.java:433)
	at ome.xml.model.OME.getImage(OME.java:698)
	at ome.xml.meta.OMEXMLMetadataImpl.getPlanePositionX(OMEXMLMetadataImpl.java:3773)
 
>> planePosX =  omeMeta.getPlanePositionX
No method 'getPlanePositionX' with matching signature found for class 'loci.formats.ome.OMEPyramidStore'.

Is there any issue with my Java or my bf matlab toolbox?

The first call that returns an empty plane position may be because the plane position is not set on that particular plane.

The IndexOutOfBoundsException is caused when you are trying to access a plane which doesn’t exist. The 2 parameters in the getPlanePositionX call are first the index of the series you wish to access and then the second is the index of the plane.

So omeMeta.getPlanePositionX(0,0) will get data for the first plane of the first series
And omeMeta.getPlanePositionX(1,1) will get data for the second plane of the second series

To get the number of series you can use:
imageCount = omeMeta.getImageCount();

To get the number of planes in a particular series you can then use (the parameter is the index of the series you wish to get the planeCount of, in this case Im using 0 for the first series):
imageCount = omeMeta.getPlaneCount(0);

1 Like

Thank you so much for your help! So far I managed to things working :slight_smile:

(weirdly, somehow on my latest data I have not trace of the stage coordinate in the metadata (not even when I check the OME metadata on Fiji… Maybe there is something that has changed in the settings of the NIS Elements Nikon software…?)

There maybe something has changed, Im not familiar enough with the acquisition settings in NIS Elements to know what may cause this. IF you have a small sample file though I can check to confirm that the metadata isnt present - https://www.openmicroscopy.org/qa2/qa/upload/