Page 1 of 1

Storing OME-XML within a TIFF

PostPosted: Wed Jul 13, 2011 12:41 pm
by mmoulis
Hi !

I would like to generate an XML file and then storing it into the header of a TIFF file but i am totally lost.

For testing, i would like to store the OME-XML example file given in http://www.ome-xml.org/wiki/CompliantSpecification :

Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<OME:OME xmlns:ROI="http://www.openmicroscopy.org/Schemas/ROI/2010-04"
        xmlns:OME="http://www.openmicroscopy.org/Schemas/OME/2010-04"
        xmlns:BIN="http://www.openmicroscopy.org/Schemas/BinaryFile/2010-04"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.openmicroscopy.org/Schemas/OME/2010-04
        http://www.openmicroscopy.org/Schemas/OME/2010-04/ome.xsd">   

        <OME:Image ID="Image:0" Name="Series 1">
                <OME:AcquiredDate>2008-02-06T13:43:19</OME:AcquiredDate>
                <OME:Description>An example OME compliant file, based on Olympus.oib</OME:Description>
                <OME:Pixels DimensionOrder="XYCZT" ID="Pixels:0" PhysicalSizeX="0.207" PhysicalSizeY="0.207"
                        PhysicalSizeZ="0.0" SizeC="3" SizeT="16" SizeX="1024" SizeY="1024" SizeZ="1"
                        TimeIncrement="120.1302" Type="uint16">
                        <OME:Channel EmissionWavelength="523" ExcitationWavelength="488" ID="Channel:0:0"
                                IlluminationType="Epifluorescence" Name="CH1" SamplesPerPixel="1"
                                PinholeSize="103.5" AcquisitionMode="LaserScanningConfocalMicroscopy"/>
                        <OME:Channel EmissionWavelength="578" ExcitationWavelength="561" ID="Channel:0:1"
                                IlluminationType="Epifluorescence" Name="CH3" SamplesPerPixel="1"
                                PinholeSize="127.24" AcquisitionMode="LaserScanningConfocalMicroscopy"/>
                        <OME:Channel ExcitationWavelength="488" ID="Channel:0:2" IlluminationType="Transmitted"
                                ContrastMethod="DIC" Name="TD1" SamplesPerPixel="1" 
                                AcquisitionMode="LaserScanningConfocalMicroscopy"/>
                        <BIN:BinData BigEndian="false" Length="0"/>
                </OME:Pixels>
        </OME:Image>
       
</OME:OME>


Here is the JAVA code I wrote :

Code: Select all
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

import loci.common.services.DependencyException;
import loci.common.services.ServiceException;
import loci.common.services.ServiceFactory;
import loci.formats.FormatException;
import loci.formats.ImageReader;
import loci.formats.ome.OMEXMLMetadata;
import loci.formats.out.TiffWriter;
import loci.formats.services.OMEXMLService;

public class OMETIFFMaker {
   
   public static void main(String[] args) throws FormatException, IOException, DependencyException, ServiceException {
      final String SOURCE = "PATH_TO_THE_TIFF_FILE_TO_BE_CONVERTED";
      final String TARGET = "PATH_TO_THE_OUTPUT_OME_TIFF_FILE";
      final String XML_PATH = "PATH_TO_XML_FILE";
      
      /* ********** GETTING XML ****************** */
      System.out.print("Getting XML Content");
      BufferedReader b = new BufferedReader(new FileReader(new File(XML_PATH)));
      String xml = "";
      String tmp = b.readLine();
      while (tmp != null){
         xml = xml + tmp;
         tmp = b.readLine();
         System.out.print(".");
      }

      System.out.println("[done]");
      System.out.println("XML Content :" + xml);
      
      /* ********** MAKING NEW FILE ****************** */
      System.out.print("Copying orgininal file");
      File outFile = new File(TARGET);
      if (outFile.exists())
         outFile.delete();
      outFile.createNewFile();
      
      /* ********** COPIYNG CONTENT ***************** */
      FileInputStream in = new FileInputStream(SOURCE);
      FileOutputStream out = new FileOutputStream(outFile);
      byte buffer[] = new byte[512 * 1024];
      int readCount;
      while ((readCount = in.read(buffer)) != -1){
         out.write(buffer, 0, readCount);
         System.out.print(".");
      }
      System.out.println("[done]");
      in.close();
      out.close();
      
      /* *********** ADD XML ********************* */
      System.out.print("Converting to OME.TIFF...");
      
      OMEXMLService service = new ServiceFactory().getInstance(OMEXMLService.class);
      OMEXMLMetadata md = service.createOMEXMLMetadata();
      service.convertMetadata(xml, md);

      ImageReader ir = new ImageReader();
      ir.setMetadataStore(md);
      ir.setId(SOURCE);
      TiffWriter writer = new TiffWriter();
      writer.setMetadataRetrieve(md);
      writer.setId(TARGET);
      ir.close();
      writer.close();
      System.out.println("[done]");
   }
}

When i try to get back OME-XML Metadata using this code :
Code: Select all
import java.io.IOException;

import loci.common.services.DependencyException;
import loci.common.services.ServiceException;
import loci.common.services.ServiceFactory;
import loci.formats.FormatException;
import loci.formats.ImageReader;
import loci.formats.ome.OMEXMLMetadata;
import loci.formats.services.OMEXMLService;
import loci.formats.tiff.TiffParser;

public class ExtractMetaDatas {

   public static void main(String[] args) throws FormatException, IOException, DependencyException, ServiceException {
      final String SOURCE = "OME_TIFF_FILE_TO_BE_CHECKED";
      OMEXMLService service = new ServiceFactory().getInstance(OMEXMLService.class);
      OMEXMLMetadata md = service.createOMEXMLMetadata();
      ImageReader ir = new ImageReader();
      ir.setMetadataStore(md);
      ir.setId(SOURCE);
      System.out.println("  **** MD : ****\n" + md.dumpXML().replaceAll("><", ">\n<"));
      System.out.println("  **** Comments : ****\n" + new TiffParser(SOURCE).getComment().replaceAll("><", ">\n<"));

   }

}

I Always get these OME-XML Metadatas :
Code: Select all
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<OME xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openmicroscopy.org/Schemas/OME/2011-06 http://www.openmicroscopy.org/Schemas/OME/2011-06/ome.xsd" xmlns="http://www.openmicroscopy.org/Schemas/OME/2011-06">
<Image ID="Image:0" Name="weak3.ome.tif">
<AcquiredDate>2011-07-13T14:20:10</AcquiredDate>
<Description/>
<Pixels DimensionOrder="XYCZT" ID="Pixels:0" SizeC="1" SizeT="1" SizeX="1280" SizeY="960" SizeZ="11" Type="uint16">
<Channel ID="Channel:0:0" SamplesPerPixel="1">
<LightPath/>
</Channel>
<BinData BigEndian="true" Length="0" xmlns="http://www.openmicroscopy.org/Schemas/BinaryFile/2011-06"/>
</Pixels>
</Image>
</OME>


I must admit that i do not understand very well what the MetadataStore and MetadataRetrieve classes are and how they work. Moreover, the javadoc of these classes is quite poor :? and I am french :oops:

So what i have to do to include my xml file into a TIFF file's header ?

Kind regards,

Marius

Re: Storing OME-XML within a TIFF

PostPosted: Sun Jul 17, 2011 3:27 pm
by mmoulis
No one can help me ?

I really need an answer :)

Re: Storing OME-XML within a TIFF

PostPosted: Sun Jul 17, 2011 9:34 pm
by wmoore
Hi,

Don't worry, we haven't missed your question.

We discussed this briefly the other day - just haven't got around to responding yet.

I seem to remember using the command line was suggested (not my area of knowledge so I don't remember the details) http://www.loci.wisc.edu/bio-formats/command-line-tools

A solution is also mentioned on this post http://www.openmicroscopy.org.uk/commun ... vert#p1921 (using "convert" from ImageMagick).

Hope that helps,

Will.

Re: Storing OME-XML within a TIFF

PostPosted: Mon Jul 18, 2011 2:55 pm
by mmoulis
Thanks a lot !

The real problem was in my OME-XML structure. Moreover, I do not need to use MetadataRetrive and MetadataStore classes. I only just need the TiffSaver class.

So here is my code, hoping it will be useful for other people :

Code: Select all
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

import loci.common.RandomAccessInputStream;

import loci.formats.FormatException;
import loci.formats.tiff.TiffSaver;

public class OMETIFFMaker {
   
   public static void main(String[] args) throws IOException, FormatException {
      final String SOURCE = "PATH_TO_TIFF_FILE";
      final String TARGET = "PATH_TO_THE_GENERATED_OME_TIFF_FILE";
      final String XML_PATH = "PATH_TO_THE_OME_XML_FILE_TO_BE_INCLUDED";
      
      /* ********** GETTING XML ****************** */
      System.out.print("Getting XML Content");
      BufferedReader b = new BufferedReader(new FileReader(new File(XML_PATH)));
      String xml = "";
      String tmp = b.readLine();
      while (tmp != null){
         xml = xml + tmp;
         tmp = b.readLine();
         System.out.print(".");
      }
      b.close();
      
      System.out.println("[done]");
      //System.out.println("XML Content :" + xml);

      /* ********** MAKING NEW FILE ****************** */
      System.out.print("Copying orgininal file");
      File outFile = new File(TARGET);
      if (outFile.exists())
         outFile.delete();
      outFile.createNewFile();
      
      /* ********** COPIYNG CONTENT ***************** */
      FileInputStream in = new FileInputStream(SOURCE);
      FileOutputStream out = new FileOutputStream(outFile);
      byte buffer[] = new byte[512 * 1024];
      int readCount;
      while ((readCount = in.read(buffer)) != -1){
         out.write(buffer, 0, readCount);
         System.out.print(".");
      }
      System.out.println("[done]");
      in.close();
      out.close();
      
      /* *********** ADD XML ********************* */
      System.out.print("Converting to OME.TIFF...");
      TiffSaver saver = new TiffSaver(TARGET);
      RandomAccessInputStream input = new RandomAccessInputStream(TARGET);
      
      saver.overwriteComment(input, xml);
      input.close();

      System.out.println("[done]");
   }
}


Note : My code overwrite orginal metadatas. I am working to find out a solution :D

Re: Storing OME-XML within a TIFF

PostPosted: Tue Jul 19, 2011 1:19 pm
by mlinkert
Hi,

Note : My code overwrite orginal metadatas. I am working to find out a solution :D


Do you mean that the original TIFF comment is being overwritten?

If so, first note that that is expected behavior. If you need to preserve the original comment, the best option is to store it in the OME-XML before that is inserted into the TIFF.

In code, that would be:

Code: Select all
         // fetch the original comment from the TIFF file
          RandomAccessInputStream s = new RandomAccessInputStream(TARGET);
          TiffParser parser = new TiffParser(s);
          String originalComment = parser.getComment();
          s.close();

          // insert the original comment into the OME-XML
          OMEXMLService service = null;
          try {
            ServiceFactory factory = new ServiceFactory();
            service = factory.getInstance(OMEXMLService.class);
          }
          catch (DependencyException de) {
            throw new FormatException(de);
          }
          catch (ServiceException se) {
            throw new FormatException(se);
          }

          IMetadata meta = service.createOMEXMLMetadata();
          meta.setCommentAnnotationValue(originalComment,
            meta.getCommentAnnotationCount());
          xml = service.getOMEXML(meta);


You should be able to paste this into your code between the "COPYING CONTENTS" section and the "ADD XML" section, provided that you also import loci.common.*, loci.formats.services.OMEXMLService, and loci.formats.tiff.TiffParser.

If you don't need to preserve the original TIFF comment, then could you please explain exactly which metadata is being overwritten?

Regards,
-Melissa