Bio-Formats accessors with ImgPlus metadata

My main goal is to get my Command plugin to retrieve channel emission wavelengths from metadata stored in an already opened Dataset. My current understanding is that a Dataset wraps an ImgPlus, and an ImgPlus holds image data and metadata. I can see that the metadata exists in a Dataset with something like this:

...

@Parameter
private Dataset img;

@Override
public void run() {
    Map<String,Object> map = img.getImgPlus().getProperties();
}

...

Bio-Formats provides a bunch of accessors, such as getChannelEmissionWavelength(int,int), but I’m not quite sure how best to use them in this scenario. Seems like I’m missing some critical piece of information that lets me connect the dots. If someone can help me figure this out, I’m happy to add a generalized example to my current maven-projects tutorials PR. Thanks!

1 Like

HI @brossetti,
You are right you are missing a step, provided you have read your image using scifio, you should be able to do the following (lifted from https://github.com/scifio/scifio/blob/master/src/main/java/io/scif/img/SCIFIOImgPlus.java#L116 )

private static final String GLOBAL_META = "scifio.metadata.global";
private static final String IMAGE_META = "scifio.metadata.image";

@Parameter
private Dataset img;

@Override
public void run() {
    Map<String,Object> map = img.getImgPlus().getProperties();
    Metadata meta = (Metadata) map.get(GLOBAL_META);
    ImageMetadata imgMeta = (ImageMetadata) map.get(IMAGE_META);
}

This provides with a lot of metadata options, depending on the type of image you have read.

5 Likes

I did some digging to see if the BioFormatsFormat of SCIFIO stashes the OMEXMLMetadata object anywhere in the ImgPlus properties table in a similar fashion. Unfortunately, looking at the source code, I don’t think it does.

If it did that, you’d have a way to make Bio-Formats-specific queries such as getChannelEmissionWavelength on any Dataset or ImgPlus which was opened using Bio-Formats.

Is this what you are looking for, @brossetti?

1 Like

I actually did some more digging inspired by your post, in KNIME Image Processing we use the metadata translator provided by scifio to get the ome metada. The following minimal example shows how you could do it:

@Parameter
TranslatorService translator;

public OMEMetadata translateToOmeXML(Metadata metadata){
    OMEMetadata omemeta = new OMEMetadata(getContext());
    translator.translate(meta, omexml, false);
    return omexml;
} 
2 Likes

Thanks @gab1one and @ctrueden!

Yes, this was my hope. Somewhere in my travels, I thought I read that the ome-xml data was stored in Datasets by default. I’ve been reading a lot of docs lately, so maybe I am just thinking of this (less definitive) comment: https://github.com/scifio/scifio-tutorials/blob/6f27d5584585cdb0bd8eb7023316499c568c721b/core/src/main/java/io/scif/tutorials/core/T3aCustomFormats.java#L123-L133 .

When I was playing around in the debugger, I noticed the following in my Dataset img:

This led me to believe that the ome-xml data is stored and should be accessible.

Thanks! Your examples were extremely helpful! I’m able to get the following to work:

...

@Parameter
private LogService log;

@Parameter
private FormatService formatService;

@Parameter
private TranslatorService translator;

@Parameter
private Dataset img;

@Parameter
private Context context;

@Override
public void run() {
    final String filePath = img.getSource();

    try {
        Format format = formatService.getFormat(filePath);
        Metadata metadata = format.createParser().parse(filePath);
        OMEMetadata omemeta = new OMEMetadata(context);
        translator.translate(metadata, omemeta, false);
        System.out.println(omemeta.getRoot().getChannelEmissionWavelength(0,0));
    }
    catch (final FormatException | IOException e) {
        log.error(e);
    }
}
...

But there is an issue when I create the Metadata object from existing ImgPlus metadata. The following code gives the error below:

...

private static final String GLOBAL_META = "scifio.metadata.global";

@Parameter
private TranslatorService translator;

@Parameter
private Dataset img;

@Parameter
private Context context;

@Override
public void run() {
    Map<String,Object> map = img.getImgPlus().getProperties();
    Metadata metadata = (Metadata) map.get(GLOBAL_META);
    OMEMetadata omemeta = new OMEMetadata(context);
    translator.translate(metadata, omemeta, false);
    System.out.println(omemeta.getRoot().getChannelEmissionWavelength(0,0));
}

...

Error: java.lang.IllegalStateException: ImageReader.getMetadataStore: Current file should not be null; call setId(String) first

I’m guessing that I’m missing something silly. I can work with the first example; however, getting the second example to work properly would scratch my mental itch. Thanks!

2 Likes