Accessing Bio-Format Importer Metadata from ImageJ Script

I’m using ImageJ to convert a multichannel OME-TIFF 3D image file into a new directory with one NIfTI (.nii) file for each channel in the OME-TIFF file. I would like to use the OME Metadata “channel name” as the file name for each of the newly created .nii files.

Here is what the metadata from Bio-Formats looks like:

I can’t figure out how to access the OME/Image/Pixels/Channel:Name field from ImageJ.

Any pointers or code examples would be much appreciated.

Thanks

Dear @tskillman ,
I think a good start is to read the metadata. In my czi files the channel name is “DisplaySetting|Channel|Name”

then use Bioformat Extensions like that :

run("Bio-Formats Macro Extensions");
id = File.openDialog("Choose a file");
Ext.setId(id);
open(id);
Ext.getMetadataValue("DisplaySetting|Channel|Name", value);
print(value);

or

id = File.openDialog("Choose a file");
open(id);
infoString=getMetadata("Info");
chanPos=indexOf(infoString,"ChannelName #");
chanNum=substring(infoString,chanPos+17,chanPos+21);
print("Value = "+chanNum);

You can set a loop for all your channel

1 Like

If your channel name is visible in Show Info window then using the above solution with Ext.getMetadataValue should work and you could use something like the below using the channel key name that is used in Show Info:

run("Bio-Formats Macro Extensions");
id = File.openDialog("Choose a file");
Ext.setId(id);
Ext.getEffectiveSizeC(sizeC);

run("Bio-Formats Importer", "open=[" + id + "] autoscale color_mode=Composite rois_import=[ROI manager] split_channels view=Hyperstack stack_order=XYCZT");

for (i=0; i < sizeC; i++) {
	selectWindow("myFileName.ome.tiff - C=" + i);
	Ext.getMetadataValue("channel key name", channelName);
	run("Bio-Formats Exporter", "save=[/path/to/" + channelName + ".ome.tiff] export compression=Uncompressed");
}

If thats not possible then you can always access it directly from the Bio-Formats API using a jython script such as:

# imports
from loci.plugins import BF
from loci.formats import ImageReader

file = "/path/to/inputFile.ome.tiff"

# setup image reader 
reader = ImageReader()
omeMeta = MetadataTools.createOMEXMLMetadata()
reader.setMetadataStore(omeMeta)
reader.setId(file)
series = 0
for channel in range(omeMeta.getChannelCount(series)):
  channelName = omeMeta.getChannelName(series, channel)
1 Like

Hi @Alex.h and @dgault,

Thanks for your response. I have made no progress.

There are several issues:

  1. No, the Channel Names do not appear in the Show Info command display,
  2. My metafile structure is different than your examples and I don’t know the syntax of the “xxx|yyy|zzz” string, so I can’t figure out how to properly access my Channel Name (I tried many variations with the return value always being 0 (zero)),
  3. I tried to use the jython script but on my machine it gave an error saying it couldn’t find “loci” (not sure what libraries need to be loaded from where to resolve this).
  4. @dgault, your ijm code doesn’t work for me because you pick up the image name, not the Channel Name, as in the OME Metadata in my first post: "<Channel ID=“Chananel:0:0” Name=“cRFP (DCI: 7-9 its,…”. Those channel names (cRFP, cGFP, c405, cCy5) are what I’m after.

Below is a screen shot of my code, the image loaded, the ShowInfo display, and the Log display. Hopefully I’m missing something obvious to you. Any help appreciated.

Could you send me one file please?

Hi @tskillman, so what values are you seeing being returned for channelName = omeMeta.getChannelName(series, channel) ?

I sent you a link in a private message. Not published data.

@dgault, sorry if I wasn’t clear, but I could not get your jython script to run as I’m only familiar with the ImageJ macro language. So I don’t know what omeMeta.getChannelName(series, channel) would return.

Also, I just noticed that the ImageJ Console is showing some warnings when I run the script. As they are warnings and not errors are they important?

Sorry for the delay I can’t find a solution with a macro.

This might be a bit of an odd work around, but the following should also work:

  • Use the channel name as the image label title
    • Plugins > Bio-Formats > Bio-Formats Plugins Configuration > Set Slice Label Pattern to %w
  • Import the image using split_channels as shown in my first post
  • Read the channel name from the tile: title = getTitle();
1 Like

Dear @dgault, could we set the plugin configuration in a macro ?
It will be useful to set %w for some of my macro and %c%z%t-%n the rest of the time.

Im afraid the plugins configurations options such as the slice label aren’t available through the macro extensions.

1 Like

@dgault, Thanks for this suggestion. After a bit of struggling I got everything to work just like I wanted. Key final trick was to use getInfo(“slice.label”); instead of getTitle(); in your modified macro. Attached is a screen grab of my script associated windows. I have some extra print statements that helped me know what was going on, and I had to adjust the slice.label string to get rid of a colon (":"), which the file save command didn’t like.

Final code for others:

/*Macro to split and save multi-channel data in files, using Channel Name ("c405") for each channel's file name 
 For example a multi-channel OME-TIFF file with structure like this:

<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">
 <Experimenter FirstName="Unknown" ID="Experimenter:80c79ec6-2abf-4a1f-a2ed-c195ba4a9eb3" LastName="User"/>
  <Image ID="Image:0" Name="HBL1 GFP LC3 no stim 4 (cropped) T=1 C=c405 Z=1">
   <Pixels BigEndian="false" DimensionOrder="XYCZT" ID="Pixels:0" Interleaved="false" PhysicalSizeX="0.059" PhysicalSizeXUnit="µm" PhysicalSizeY="0.059" PhysicalSizeYUnit="µm" PhysicalSizeZ="0.5" PhysicalSizeZUnit="µm" SignificantBits="16" SizeC="6" SizeT="1" SizeX="430" SizeY="438" SizeZ="14" Type="uint16">
	<Channel ID="Channel:0:0" Name="c405" SamplesPerPixel="1">
	<LightPath/>
	<Channel ID="Channel:0:1" Name="cGFP" SamplesPerPixel="1">
	<LightPath/>
	<Channel ID="Channel:0:2" Name="cRFP" SamplesPerPixel="1">
	<LightPath/>
	...
*/


// Setup Macro Extensions
run("Bio-Formats Macro Extensions");
id = File.openDialog("Choose a file");
Ext.setId(id);
Ext.getEffectiveSizeC(sizeC);

path = File.getDirectory(id);
name = File.getName(id);

// Import file via the excellent Bio-Formats
run("Bio-Formats Importer", "open=[" + id + "] autoscale color_mode=Composite rois_import=[ROI manager] split_channels view=Hyperstack stack_order=XYCZT");

// Cycle through the slices (image windows), adjust, and save as NIfTI
for (i=0; i < sizeC; i++) {
	selectWindow(name + " - C=" + i);
	// tweak image
	run("Color Balance...");
	run("Enhance Contrast", "saturated=0.35");
	run("RGB Color");
	// use slice.label (coupled with Bio-Formats/Bio-Formats Plugins Configuration/Slice Label Pattern = %w)
	channelName = getInfo("slice.label");
	channelNameClean = channelName.replace(":","-"); 
	print("Channel name = " + channelNameClean);
	// save to NIfTI file
	run("NIfTI-1", "save=["+ path + channelNameClean + ".nii]");
}

Again, thanks to you and @Alex.h for your time in helping me. I’ve also included an image of how these auto-created file names show up in a VR visualization application.

2 Likes