/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Icy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.sequence;
import java.awt.Color;
import java.util.HashSet;
import java.util.Set;
import icy.image.IcyBufferedImage;
import icy.type.DataType;
import icy.util.OMEUtil;
import icy.util.StringUtil;
import icy.util.XMLUtil;
import loci.common.services.ServiceException;
import loci.formats.FormatTools;
import loci.formats.MetadataTools;
import loci.formats.meta.MetadataRetrieve;
import loci.formats.ome.OMEXMLMetadataImpl;
import ome.units.quantity.Time;
import ome.xml.meta.OMEXMLMetadata;
import ome.xml.model.Annotation;
import ome.xml.model.Channel;
import ome.xml.model.Dataset;
import ome.xml.model.Experiment;
import ome.xml.model.Experimenter;
import ome.xml.model.ExperimenterGroup;
import ome.xml.model.Image;
import ome.xml.model.Instrument;
import ome.xml.model.OME;
import ome.xml.model.Pixels;
import ome.xml.model.Plane;
import ome.xml.model.ROI;
import ome.xml.model.StructuredAnnotations;
import ome.xml.model.XMLAnnotation;
import ome.xml.model.enums.DimensionOrder;
import ome.xml.model.primitives.PositiveInteger;
/**
* Meta data utilities class.<br>
* Basically provide safe access to metadata.
*
* @author Stephane
*/
public class MetaDataUtil
{
public static final String DEFAULT_CHANNEL_NAME = "ch ";
/**
* Returns OME root element (create it if needed).
*/
public static OME getOME(OMEXMLMetadata metaData)
{
OME result = (OME) metaData.getRoot();
if (result == null)
{
metaData.createRoot();
result = (OME) metaData.getRoot();
}
return result;
}
/**
* @deprecated Use {@link #getOME(OMEXMLMetadata)} instead
*/
@Deprecated
public static OME getOME(OMEXMLMetadataImpl metaData)
{
return getOME((OMEXMLMetadata) metaData);
}
/**
* Returns the number of image serie of the specified metaData description.
*/
public static int getNumSerie(OMEXMLMetadata metaData)
{
return metaData.getImageCount();
}
/**
* @deprecated Use {@link #getNumSerie(OMEXMLMetadata)} instead
*/
@Deprecated
public static int getNumSerie(OMEXMLMetadataImpl metaData)
{
return getNumSerie((OMEXMLMetadata) metaData);
}
/**
* Return image serie object at specified index for the specified metaData description.
*/
public static Image getSerie(OMEXMLMetadata metaData, int index)
{
final OME ome = getOME(metaData);
if (index < ome.sizeOfImageList())
return ome.getImage(index);
return null;
}
/**
* @deprecated Use {@link #getSerie(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static Image getSerie(OMEXMLMetadataImpl metaData, int index)
{
return getSerie((OMEXMLMetadata) metaData, index);
}
/**
* Ensure the image serie at specified index exist for the specified metaData description.
*/
public static Image ensureSerie(OME ome, int index)
{
// create missing image
while (ome.sizeOfImageList() <= index)
{
final Image img = new Image();
ome.addImage(img);
}
final Image result = ome.getImage(index);
if (result.getPixels() == null)
{
final Pixels pix = new Pixels();
// wanted default dimension order
pix.setDimensionOrder(DimensionOrder.XYCZT);
// create default pixels object
result.setPixels(pix);
}
return result;
}
/**
* Set the number of image serie for the specified metaData description.
*/
public static void setNumSerie(OMEXMLMetadata metaData, int num)
{
final OME ome = getOME(metaData);
// keep only desired number of image
while (ome.sizeOfImageList() > num)
ome.removeImage(ome.getImage(ome.sizeOfImageList() - 1));
// create missing image
ensureSerie(ome, num - 1);
}
/**
* @deprecated Use {@link #setNumSerie(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static void setNumSerie(OMEXMLMetadataImpl metaData, int num)
{
setNumSerie((OMEXMLMetadata) metaData, num);
}
/**
* Return pixels object at specified index for the specified metaData description.
*/
public static Pixels getPixels(OME ome, int index)
{
if (ome != null)
{
if (index < ome.sizeOfImageList())
return ome.getImage(index).getPixels();
}
return null;
}
/**
* Return pixels object at specified index for the specified metaData description.
*/
public static Pixels getPixels(OMEXMLMetadata metaData, int index)
{
return getPixels(getOME(metaData), index);
}
/**
* @deprecated Use {@link #getPixels(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static Pixels getPixels(OMEXMLMetadataImpl metaData, int index)
{
return getPixels((OMEXMLMetadata) metaData, index);
}
/**
* Return plane index for the specified T, Z, C position.
*/
public static int getPlaneIndex(Pixels pix, int t, int z, int c)
{
// can't compute plane index --> return 0 by default
if ((t < 0) || (z < 0) || (c < 0))
return 0;
// trivial opti...
if ((t == 0) && (z == 0) && (c == 0))
return 0;
final int sizeT = OMEUtil.getValue(pix.getSizeT(), 0);
final int sizeZ = OMEUtil.getValue(pix.getSizeZ(), 0);
int sizeC = OMEUtil.getValue(pix.getSizeC(), 0);
// can't compute plane index --> return 0 by default
if ((sizeT == 0) || (sizeZ == 0) || (sizeC == 0))
return 0;
int adjC = c;
if (pix.sizeOfChannelList() > 0)
{
final Channel channel = pix.getChannel(0);
if (channel != null)
{
final int spp = OMEUtil.getValue(channel.getSamplesPerPixel(), 0);
// channel are packed in pixel so consider sizeC = 1
if ((spp != 0) && (spp == sizeC))
{
sizeC = 1;
adjC = 0;
}
}
}
// first try to get index from real plan position
final int len = pix.sizeOfPlaneList();
for (int i = 0; i < len; i++)
{
final Plane plane = pix.getPlane(i);
// plane found --> return index
if ((OMEUtil.getValue(plane.getTheT(), -1) == t) && (OMEUtil.getValue(plane.getTheZ(), -1) == z)
&& (OMEUtil.getValue(plane.getTheC(), -1) == c))
return i;
}
DimensionOrder dimOrder = pix.getDimensionOrder();
// use default dimension order
if (dimOrder == null)
dimOrder = DimensionOrder.XYCZT;
// use computed method
return FormatTools.getIndex(dimOrder.getValue(), sizeZ, sizeC, sizeT, sizeZ * sizeC * sizeT, z, adjC, t);
}
public static Plane getPlane(Pixels pix, int index)
{
if (pix != null)
{
if (index < pix.sizeOfPlaneList())
return pix.getPlane(index);
}
return null;
}
/**
* Return plane object for the specified T, Z, C position.
*/
public static Plane getPlane(Pixels pix, int t, int z, int c)
{
return getPlane(pix, getPlaneIndex(pix, t, z, c));
}
/**
* Ensure the plane at specified index exist for the specified Pixels object.
*/
public static Plane ensurePlane(Pixels pix, int index)
{
// create missing plane
while (pix.sizeOfPlaneList() <= index)
pix.addPlane(new Plane());
return pix.getPlane(index);
}
/**
* Ensure the plane at specified T, Z, C position exist for the specified Pixels object.
*/
public static Plane ensurePlane(Pixels pix, int t, int z, int c)
{
return ensurePlane(pix, getPlaneIndex(pix, t, z, c));
}
/**
* Remove the plane at specified position.
*
* @return <code>true</code> if the operation succeed, <code>false</code> otherwise
*/
public static boolean removePlane(Image img, int index)
{
final Pixels pix = img.getPixels();
if (pix == null)
return false;
final int numPlane = pix.sizeOfPlaneList();
// no plane here --> return false
if (index >= numPlane)
return false;
final Plane plane = getPlane(pix, index);
// remove plane
pix.removePlane(plane);
// remove associated annotation
for (int i = 0; i < plane.sizeOfLinkedAnnotationList(); i++)
img.unlinkAnnotation(plane.getLinkedAnnotation(i));
// clean some data
if (pix.sizeOfBinDataList() == numPlane)
pix.removeBinData(pix.getBinData(index));
if (pix.sizeOfTiffDataList() == numPlane)
pix.removeTiffData(pix.getTiffData(index));
return true;
}
/**
* Remove the plane at specified position.
*
* @return <code>true</code> if the operation succeed, <code>false</code> otherwise
*/
public static boolean removePlane(Image img, int t, int z, int c)
{
final Pixels pix = img.getPixels();
if (pix == null)
return false;
return removePlane(img, getPlaneIndex(pix, t, z, c));
}
/**
* Remove the plane at specified position.
*
* @return <code>true</code> if the operation succeed, <code>false</code> otherwise
*/
public static boolean removePlane(OMEXMLMetadata metadata, int serie, int t, int z, int c)
{
final Image img = getSerie(metadata, serie);
if (img == null)
return false;
return removePlane(img, t, z, c);
}
/**
* @deprecated Use {@link #removePlane(OMEXMLMetadata, int, int, int, int)} instead
*/
@Deprecated
public static boolean removePlane(OMEXMLMetadataImpl metadata, int serie, int t, int z, int c)
{
return removePlane((OMEXMLMetadata) metadata, serie, t, z, c);
}
/**
* Remove planes at given position
*
* @param posT
* T position where we want to remove metadata (-1 for all)
* @param posZ
* Z position where we want to remove metadata (-1 for all)
* @param posC
* C position where we want to remove metadata (-1 for all)
*/
public static void removePlanes(OMEXMLMetadata metadata, int serie, int posT, int posZ, int posC)
{
final int minT, maxT;
final int minZ, maxZ;
final int minC, maxC;
if (posT < 0)
{
minT = 0;
maxT = getSizeT(metadata, serie) - 1;
}
else
{
minT = posT;
maxT = posT;
}
if (posZ < 0)
{
minZ = 0;
maxZ = getSizeZ(metadata, serie) - 1;
}
else
{
minZ = posZ;
maxZ = posZ;
}
if (posC < 0)
{
minC = 0;
maxC = getSizeC(metadata, serie) - 1;
}
else
{
minC = posC;
maxC = posC;
}
for (int t = minT; t <= maxT; t++)
for (int z = minZ; z <= maxZ; z++)
for (int c = minC; c <= maxC; c++)
MetaDataUtil.removePlane(metadata, 0, t, z, c);
}
/**
* @deprecated Use {@link #removePlanes(OMEXMLMetadata, int, int, int, int)} instead
*/
@Deprecated
public static void removePlanes(OMEXMLMetadataImpl metadata, int serie, int posT, int posZ, int posC)
{
removePlanes((OMEXMLMetadata) metadata, serie, posT, posZ, posC);
}
/**
* Returns the data type of the specified image serie.
*/
public static DataType getDataType(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return DataType.getDataTypeFromPixelType(pix.getType());
// assume byte by default
return DataType.UBYTE;
}
/**
* @deprecated Use {@link #getDataType(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static DataType getDataType(OMEXMLMetadataImpl metaData, int serie)
{
return getDataType((OMEXMLMetadata) metaData, serie);
}
/**
* Returns the width (sizeX) of the specified image serie.
*/
public static int getSizeX(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return OMEUtil.getValue(pix.getSizeX(), 0);
return 0;
}
/**
* @deprecated Use {@link #getSizeX(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static int getSizeX(OMEXMLMetadataImpl metaData, int serie)
{
return getSizeX((OMEXMLMetadata) metaData, serie);
}
/**
* Returns the height (sizeY) of the specified image serie.
*/
public static int getSizeY(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return OMEUtil.getValue(pix.getSizeY(), 0);
return 0;
}
/**
* @deprecated Use {@link #getSizeY(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static int getSizeY(OMEXMLMetadataImpl metaData, int serie)
{
return getSizeY((OMEXMLMetadata) metaData, serie);
}
/**
* Returns the number of channel (sizeC) of the specified image serie.
*/
public static int getSizeC(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return OMEUtil.getValue(pix.getSizeC(), 0);
return 0;
}
/**
* @deprecated Use {@link #getSizeC(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static int getSizeC(OMEXMLMetadataImpl metaData, int serie)
{
return getSizeC((OMEXMLMetadata) metaData, serie);
}
/**
* Returns the depth (sizeZ) of the specified image serie.
*/
public static int getSizeZ(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return OMEUtil.getValue(pix.getSizeZ(), 0);
return 0;
}
/**
* @deprecated Use {@link #getSizeZ(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static int getSizeZ(OMEXMLMetadataImpl metaData, int serie)
{
return getSizeZ((OMEXMLMetadata) metaData, serie);
}
/**
* Returns the number of frame (sizeT) of the specified Pixels object.
*/
private static int getSizeT(Pixels pix)
{
return OMEUtil.getValue(pix.getSizeT(), 0);
}
/**
* Returns the number of frame (sizeT) of the specified image serie.
*/
public static int getSizeT(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return getSizeT(pix);
return 0;
}
/**
* @deprecated Use {@link #getSizeT(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static int getSizeT(OMEXMLMetadataImpl metaData, int serie)
{
return getSizeT((OMEXMLMetadata) metaData, serie);
}
/**
* Returns the total data size (in bytes) of the specified image serie.
*/
public static long getDataSize(OMEXMLMetadata metaData, int serie)
{
return getDataSize(metaData, serie, 0);
}
/**
* Returns the total data size (in bytes) of the specified image serie
* for the given resolution (0 = full, 1 = 1/2, ...)
*/
public static long getDataSize(OMEXMLMetadata metaData, int serie, int resolution)
{
return getDataSize(metaData, serie, resolution, getSizeZ(metaData, serie), getSizeT(metaData, serie));
}
/**
* Returns the total data size (in bytes) of the specified image serie
* for the given resolution (0 = full, 1 = 1/2, ...) and size informations
*/
public static long getDataSize(OMEXMLMetadata metaData, int serie, int resolution, int sizeZ, int sizeT)
{
return getDataSize(metaData, serie, resolution, sizeZ, sizeT, getSizeC(metaData, serie));
}
/**
* Returns the total data size (in bytes) of the specified image serie
* for the given resolution (0 = full, 1 = 1/2, ...) and size informations
*/
public static long getDataSize(OMEXMLMetadata metaData, int serie, int resolution, int sizeZ, int sizeT, int sizeC)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
long sizeXY = (long) OMEUtil.getValue(pix.getSizeX(), 0) * (long) OMEUtil.getValue(pix.getSizeY(), 0);
if (resolution > 0)
sizeXY /= Math.pow(4d, resolution);
return sizeXY * sizeC * sizeZ * sizeT * DataType.getDataTypeFromPixelType(pix.getType()).getSize();
}
return 0L;
}
/**
* Sets the data type of the specified image serie.
*/
public static void setDataType(OMEXMLMetadata metaData, int serie, DataType dataType)
{
metaData.setPixelsType(dataType.toPixelType(), serie);
}
/**
* @deprecated Use {@link #setDataType(OMEXMLMetadata, int, DataType)} instead
*/
@Deprecated
public static void setDataType(OMEXMLMetadataImpl metaData, int serie, DataType dataType)
{
setDataType((OMEXMLMetadata) metaData, serie, dataType);
}
/**
* Sets the width (sizeX) of the specified image serie (need to be >= 1).
*/
public static void setSizeX(OMEXMLMetadata metaData, int serie, int sizeX)
{
metaData.setPixelsSizeX(OMEUtil.getPositiveInteger(sizeX), serie);
}
/**
* @deprecated Use {@link #setSizeX(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static void setSizeX(OMEXMLMetadataImpl metaData, int serie, int sizeX)
{
setSizeX((OMEXMLMetadata) metaData, serie, sizeX);
}
/**
* Sets the height (sizeY) of the specified image serie (need to be >= 1).
*/
public static void setSizeY(OMEXMLMetadata metaData, int serie, int sizeY)
{
metaData.setPixelsSizeY(OMEUtil.getPositiveInteger(sizeY), serie);
}
/**
* @deprecated Use {@link #setSizeY(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static void setSizeY(OMEXMLMetadataImpl metaData, int serie, int sizeY)
{
setSizeY((OMEXMLMetadata) metaData, serie, sizeY);
}
/**
* Sets the number of channel (sizeC) of the specified image serie (need to be >= 1).
*/
public static void setSizeC(OMEXMLMetadata metaData, int serie, int sizeC)
{
metaData.setPixelsSizeC(OMEUtil.getPositiveInteger(sizeC), serie);
}
/**
* @deprecated Use {@link #setSizeC(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static void setSizeC(OMEXMLMetadataImpl metaData, int serie, int sizeC)
{
setSizeC((OMEXMLMetadata) metaData, serie, sizeC);
}
/**
* Sets the depth (sizeZ) of the specified image serie (need to be >= 1).
*/
public static void setSizeZ(OMEXMLMetadata metaData, int serie, int sizeZ)
{
metaData.setPixelsSizeZ(OMEUtil.getPositiveInteger(sizeZ), serie);
}
/**
* @deprecated Use {@link #setSizeZ(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static void setSizeZ(OMEXMLMetadataImpl metaData, int serie, int sizeZ)
{
setSizeZ((OMEXMLMetadata) metaData, serie, sizeZ);
}
/**
* Sets the number of frame (sizeT) of the specified image serie (need to be >= 1).
*/
public static void setSizeT(OMEXMLMetadata metaData, int serie, int sizeT)
{
metaData.setPixelsSizeT(OMEUtil.getPositiveInteger(sizeT), serie);
}
/**
* @deprecated Use {@link #setSizeT(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static void setSizeT(OMEXMLMetadataImpl metaData, int serie, int sizeT)
{
setSizeT((OMEXMLMetadata) metaData, serie, sizeT);
}
/**
* Returns the id of the specified image serie.
*/
public static String getImageID(OMEXMLMetadata metaData, int serie)
{
final Image img = getSerie(metaData, serie);
if (img != null)
return StringUtil.getValue(img.getID(), "");
return "";
}
/**
* @deprecated Use {@link #getImageID(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static String getImageID(OMEXMLMetadataImpl metaData, int serie)
{
return getImageID((OMEXMLMetadata) metaData, serie);
}
/**
* Set the id of the specified image serie.
*/
public static void setImageID(OMEXMLMetadata metaData, int serie, String value)
{
metaData.setImageID(value, serie);
}
/**
* @deprecated Use {@link #setImageID(OMEXMLMetadata, int, String)} instead
*/
@Deprecated
public static void setImageID(OMEXMLMetadataImpl metaData, int serie, String value)
{
setImageID((OMEXMLMetadata) metaData, serie, value);
}
/**
* Returns the name of the specified image serie.
*/
public static String getName(OMEXMLMetadata metaData, int serie)
{
final Image img = getSerie(metaData, serie);
if (img != null)
return StringUtil.getValue(img.getName(), "");
return "";
}
/**
* @deprecated Use {@link #getName(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static String getName(OMEXMLMetadataImpl metaData, int serie)
{
return getName((OMEXMLMetadata) metaData, serie);
}
/**
* Set the name of the specified image serie.
*/
public static void setName(OMEXMLMetadata metaData, int serie, String value)
{
metaData.setImageName(value, serie);
}
/**
* @deprecated Use {@link #setName(OMEXMLMetadata, int, String)} instead
*/
@Deprecated
public static void setName(OMEXMLMetadataImpl metaData, int serie, String value)
{
setName((OMEXMLMetadata) metaData, serie, value);
}
/**
* Returns X pixel size (in �m) of the specified image serie.
*/
public static double getPixelSizeX(OMEXMLMetadata metaData, int serie, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return OMEUtil.getValue(pix.getPhysicalSizeX(), defaultValue);
return defaultValue;
}
/**
* @deprecated Use {@link #getPixelSizeX(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static double getPixelSizeX(OMEXMLMetadataImpl metaData, int serie, double defaultValue)
{
return getPixelSizeX((OMEXMLMetadata) metaData, serie, defaultValue);
}
/**
* Returns Y pixel size (in �m) of the specified image serie.
*/
public static double getPixelSizeY(OMEXMLMetadata metaData, int serie, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return OMEUtil.getValue(pix.getPhysicalSizeY(), defaultValue);
return defaultValue;
}
/**
* @deprecated Use {@link #getPixelSizeY(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static double getPixelSizeY(OMEXMLMetadataImpl metaData, int serie, double defaultValue)
{
return getPixelSizeY((OMEXMLMetadata) metaData, serie, defaultValue);
}
/**
* Returns Z pixel size (in �m) of the specified image serie.
*/
public static double getPixelSizeZ(OMEXMLMetadata metaData, int serie, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return OMEUtil.getValue(pix.getPhysicalSizeZ(), defaultValue);
return defaultValue;
}
/**
* @deprecated Use {@link #getPixelSizeZ(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static double getPixelSizeZ(OMEXMLMetadataImpl metaData, int serie, double defaultValue)
{
return getPixelSizeZ((OMEXMLMetadata) metaData, serie, defaultValue);
}
/**
* Computes and returns the T time interval (in second) from internal time positions.<br>
* If there is no internal time positions <code>0d</code> is returned.
*/
public static double getTimeIntervalFromTimePositions(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
// try to compute time interval from time position
if (pix != null)
return computeTimeIntervalFromTimePosition(pix);
return 0d;
}
/**
* @deprecated Use {@link #getTimeIntervalFromTimePositions(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static double getTimeIntervalFromTimePositions(OMEXMLMetadataImpl metaData, int serie)
{
return getTimeIntervalFromTimePositions((OMEXMLMetadata) metaData, serie);
}
/**
* Returns T time interval (in second) for the specified image serie.
*/
public static double getTimeInterval(OMEXMLMetadata metaData, int serie, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
final Time timeInc = pix.getTimeIncrement();
if (timeInc != null)
return OMEUtil.getValue(timeInc, defaultValue);
}
return defaultValue;
}
/**
* @deprecated Use {@link #getTimeInterval(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static double getTimeInterval(OMEXMLMetadataImpl metaData, int serie, double defaultValue)
{
return getTimeInterval((OMEXMLMetadata) metaData, serie, defaultValue);
}
/**
* Set X pixel size (in �m) of the specified image serie.
*/
public static void setPixelSizeX(OMEXMLMetadata metaData, int serie, double value)
{
metaData.setPixelsPhysicalSizeX(OMEUtil.getLength(value), serie);
}
/**
* @deprecated Use {@link #setPixelSizeX(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static void setPixelSizeX(OMEXMLMetadataImpl metaData, int serie, double value)
{
setPixelSizeX((OMEXMLMetadata) metaData, serie, value);
}
/**
* Set Y pixel size (in �m) of the specified image serie.
*/
public static void setPixelSizeY(OMEXMLMetadata metaData, int serie, double value)
{
metaData.setPixelsPhysicalSizeY(OMEUtil.getLength(value), serie);
}
/**
* @deprecated Use {@link #setPixelSizeY(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static void setPixelSizeY(OMEXMLMetadataImpl metaData, int serie, double value)
{
setPixelSizeY((OMEXMLMetadata) metaData, serie, value);
}
/**
* Set Z pixel size (in �m) of the specified image serie.
*/
public static void setPixelSizeZ(OMEXMLMetadata metaData, int serie, double value)
{
metaData.setPixelsPhysicalSizeZ(OMEUtil.getLength(value), serie);
}
/**
* @deprecated Use {@link #setPixelSizeZ(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static void setPixelSizeZ(OMEXMLMetadataImpl metaData, int serie, double value)
{
setPixelSizeZ((OMEXMLMetadata) metaData, serie, value);
}
/**
* Set T time resolution (in second) of the specified image serie.
*/
public static void setTimeInterval(OMEXMLMetadata metaData, int serie, double value)
{
metaData.setPixelsTimeIncrement(OMEUtil.getTime(value), serie);
}
/**
* @deprecated Use {@link #setTimeInterval(OMEXMLMetadata, int, double)} instead
*/
@Deprecated
public static void setTimeInterval(OMEXMLMetadataImpl metaData, int serie, double value)
{
setTimeInterval((OMEXMLMetadata) metaData, serie, value);
}
/**
* Returns the X field position (in �m) for the image at the specified Z, T, C position.
*/
public static double getPositionX(OMEXMLMetadata metaData, int serie, int t, int z, int c, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
final Plane plane = getPlane(pix, t, z, c);
if (plane != null)
return OMEUtil.getValue(plane.getPositionX(), defaultValue);
}
return defaultValue;
}
/**
* Returns the Y field position (in �m) for the image at the specified Z, T, C position.
*/
public static double getPositionY(OMEXMLMetadata metaData, int serie, int t, int z, int c, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
final Plane plane = getPlane(pix, t, z, c);
if (plane != null)
return OMEUtil.getValue(plane.getPositionY(), defaultValue);
}
return defaultValue;
}
/**
* Returns the Z field position (in �m) for the image at the specified Z, T, C position.
*/
public static double getPositionZ(OMEXMLMetadata metaData, int serie, int t, int z, int c, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
final Plane plane = getPlane(pix, t, z, c);
if (plane != null)
return OMEUtil.getValue(plane.getPositionZ(), defaultValue);
}
return defaultValue;
}
/**
* Returns the time position (in second) for the Pixels object at the specified Z, T, C
* position.
*/
private static double getTimePosition(Pixels pix, int t, int z, int c, double defaultValue)
{
final Plane plane = getPlane(pix, t, z, c);
if (plane != null)
return OMEUtil.getValue(plane.getDeltaT(), defaultValue);
return defaultValue;
}
/**
* Returns the time position (in second) for the image at the specified Z, T, C position.
*/
public static double getTimePosition(OMEXMLMetadata metaData, int serie, int t, int z, int c, double defaultValue)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return getTimePosition(pix, t, z, c, defaultValue);
return defaultValue;
}
/**
* Computes time interval from the time position informations.<br>
* Returns <code>0d</code> if time position informations are missing ot if we have only 1 frame in the image.
*/
private static double computeTimeIntervalFromTimePosition(Pixels pix)
{
final int sizeT = getSizeT(pix);
if (sizeT <= 1)
return 0d;
double result = 0d;
double last = -1d;
int lastT = 0;
int num = 0;
for (int t = 0; t < sizeT; t++)
{
final Plane plane = getPlane(pix, t, 0, 0);
if (plane != null)
{
final double timePos = OMEUtil.getValue(plane.getDeltaT(), Double.NaN);
if (!Double.isNaN(timePos))
{
if (last != -1d)
{
// get delta
result += (timePos - last) / (t - lastT);
num++;
}
last = timePos;
lastT = t;
}
}
}
// we need at least 1 delta
if (num == 0)
return 0d;
return result / num;
}
/**
* Sets the X field position (in �m) for the image at the specified Z, T, C position.
*/
public static void setPositionX(OMEXMLMetadata metaData, int serie, int t, int z, int c, double value)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
final Plane plane = ensurePlane(pix, t, z, c);
if (plane != null)
plane.setPositionX(OMEUtil.getLength(value));
}
}
/**
* Sets the Y field position (in �m) for the image at the specified Z, T, C position.
*/
public static void setPositionY(OMEXMLMetadata metaData, int serie, int t, int z, int c, double value)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
final Plane plane = ensurePlane(pix, t, z, c);
if (plane != null)
plane.setPositionY(OMEUtil.getLength(value));
}
}
/**
* Sets the Z field position (in �m) for the image at the specified Z, T, C position.
*/
public static void setPositionZ(OMEXMLMetadata metaData, int serie, int t, int z, int c, double value)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
{
final Plane plane = ensurePlane(pix, t, z, c);
if (plane != null)
plane.setPositionZ(OMEUtil.getLength(value));
}
}
/**
* Get default name for specified channel.
*/
public static String getDefaultChannelName(int channel)
{
return DEFAULT_CHANNEL_NAME + channel;
}
/**
* Returns the number of channel for the specified image serie in metaData description.
*/
public static int getNumChannel(OMEXMLMetadata metaData, int serie)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return pix.sizeOfChannelList();
return 0;
}
/**
* @deprecated Use {@link #getNumChannel(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static int getNumChannel(OMEXMLMetadataImpl metaData, int serie)
{
return getNumChannel((OMEXMLMetadata) metaData, serie);
}
/**
* Return channel object at specified index for the specified image serie.
*/
public static Channel getChannel(OMEXMLMetadata metaData, int serie, int index)
{
final Pixels pix = getPixels(metaData, serie);
if ((pix != null) && (index < pix.sizeOfChannelList()))
return pix.getChannel(index);
return null;
}
/**
* @deprecated Use {@link #getChannel(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static Channel getChannel(OMEXMLMetadataImpl metaData, int serie, int index)
{
return getChannel((OMEXMLMetadata) metaData, serie, index);
}
/**
* Ensure the channel at specified index exist for the specified image serie.
*/
public static Channel ensureChannel(OMEXMLMetadata metaData, int serie, int index)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
return ensureChannel(pix, index);
return null;
}
/**
* @deprecated Use {@link #ensureChannel(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static Channel ensureChannel(OMEXMLMetadataImpl metaData, int serie, int index)
{
return ensureChannel((OMEXMLMetadata) metaData, serie, index);
}
/**
* Ensure the channel at specified index exist for the specified image serie.
*/
public static Channel ensureChannel(Pixels pix, int index)
{
// create missing channel
while (pix.sizeOfChannelList() <= index)
pix.addChannel(new Channel());
return pix.getChannel(index);
}
/**
* Remove a channel for the specified image serie.
*/
public static void removeChannel(OMEXMLMetadata metaData, int serie, int index)
{
final Pixels pix = getPixels(metaData, serie);
if (pix != null)
removeChannel(pix, index);
}
/**
* @deprecated Use {@link #removeChannel(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static void removeChannel(OMEXMLMetadataImpl metaData, int serie, int index)
{
removeChannel((OMEXMLMetadata) metaData, serie, index);
}
/**
* Remove a channel from the specified Pixels object.
*/
public static void removeChannel(Pixels pix, int index)
{
if (pix.sizeOfChannelList() > index)
pix.removeChannel(pix.getChannel(index));
}
/**
* Set the number of channel for the specified image serie in metaData description.<br>
* This is different from {@link #getSizeC(OMEXMLMetadata, int)}.
*/
public static void setNumChannel(OMEXMLMetadata metaData, int serie, int num)
{
final OME ome = getOME(metaData);
ensureSerie(ome, serie);
final Image img = ome.getImage(serie);
Pixels pix = img.getPixels();
if (pix == null)
{
// create pixels object
pix = new Pixels();
img.setPixels(pix);
}
// keep only desired number of image
while (pix.sizeOfChannelList() > num)
removeChannel(pix, pix.sizeOfChannelList() - 1);
// create missing image
ensureChannel(pix, num - 1);
}
/**
* @deprecated Use {@link #setNumChannel(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static void setNumChannel(OMEXMLMetadataImpl metaData, int serie, int num)
{
setNumChannel((OMEXMLMetadata) metaData, serie, num);
}
/**
* Initialize default channel name until specified index if they are missing from the meta data
* description.
*/
private static void prepareMetaChannelName(OMEXMLMetadata metaData, int serie, int channel)
{
int c = getNumChannel(metaData, serie);
while (channel >= c)
{
// set default channel name
metaData.setChannelName(getDefaultChannelName(c), serie, c);
c++;
}
}
/**
* Returns name of specified channel image serie.
*/
public static String getChannelName(OMEXMLMetadata metaData, int serie, int channel)
{
// needed as LOCI does not initialize them on read
prepareMetaChannelName(metaData, serie, channel);
final String result = StringUtil.getValue(metaData.getChannelName(serie, channel),
getDefaultChannelName(channel));
final String cleaned = XMLUtil.filterString(result);
// cleaned string != original value --> set it
if (!cleaned.equals(result))
setChannelName(metaData, serie, channel, cleaned);
return cleaned;
}
/**
* @deprecated Use {@link #getChannelName(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static String getChannelName(OMEXMLMetadataImpl metaData, int serie, int channel)
{
return getChannelName((OMEXMLMetadata) metaData, serie, channel);
}
/**
* Set name of specified channel image serie.
*/
public static void setChannelName(OMEXMLMetadata metaData, int serie, int channel, String value)
{
// needed as LOCI only add current channel if it's missing
prepareMetaChannelName(metaData, serie, channel - 1);
metaData.setChannelName(value, serie, channel);
}
/**
* @deprecated Use {@link #setChannelName(OMEXMLMetadata, int, int, String)} instead
*/
@Deprecated
public static void setChannelName(OMEXMLMetadataImpl metaData, int serie, int channel, String value)
{
setChannelName((OMEXMLMetadata) metaData, serie, channel, value);
}
/**
* Returns Color of specified channel image serie.
*/
public static Color getChannelColor(OMEXMLMetadata metaData, int serie, int channel)
{
// needed as LOCI does not initialize them on read
prepareMetaChannelName(metaData, serie, channel);
return OMEUtil.getJavaColor(metaData.getChannelColor(serie, channel));
}
/**
* @deprecated Use {@link #getChannelColor(OMEXMLMetadata, int, int)} instead
*/
@Deprecated
public static Color getChannelColor(OMEXMLMetadataImpl metaData, int serie, int channel)
{
return getChannelColor((OMEXMLMetadata) metaData, serie, channel);
}
/**
* Create and return a default (OME XML) Metadata object with default image name.
*/
public static OMEXMLMetadata createMetadata(String name)
{
final OMEXMLMetadata result = OMEUtil.createOMEXMLMetadata();
final OME ome = getOME(result);
ensureSerie(ome, 0);
result.setImageID(MetadataTools.createLSID("Image", 0), 0);
result.setImageName(name, 0);
return result;
}
/**
* @deprecated Use {@link #createMetadata(String)} instead.
*/
@Deprecated
public static OMEXMLMetadataImpl createDefaultMetadata(String name)
{
return (OMEXMLMetadataImpl) createMetadata(name);
}
/**
* @deprecated Use {@link OMEUtil#createOMEXMLMetadata(MetadataRetrieve, int)}
*/
@Deprecated
public static OMEXMLMetadata createOMEMetadata(MetadataRetrieve metadata, int serie)
{
return OMEUtil.createOMEXMLMetadata(metadata, serie);
}
/**
* Set metadata object with the given image properties.
*
* @param metadata
* metadata object to fill.
* @param sizeX
* width in pixels (need to be >= 1)
* @param sizeY
* height in pixels (need to be >= 1)
* @param sizeC
* number of channel (need to be >= 1)
* @param sizeZ
* number of Z slices (need to be >= 1)
* @param sizeT
* number of T frames (need to be >= 1)
* @param dataType
* data type.
* @param separateChannel
* true if we want channel data to be separated.
* @throws ServiceException
*/
public static void setMetaData(OMEXMLMetadata metadata, int sizeX, int sizeY, int sizeC, int sizeZ, int sizeT,
DataType dataType, boolean separateChannel) throws ServiceException
{
OME ome = (OME) metadata.getRoot();
if (ome == null)
{
metadata.createRoot();
ome = (OME) metadata.getRoot();
}
// keep only one image
setNumSerie(metadata, 1);
// clean TiffData metadata (can produce error on reloading)
cleanTiffData(ome.getImage(0));
// clean binData metadata (can produce error on reloading)
cleanBinData(ome.getImage(0));
if (StringUtil.isEmpty(metadata.getImageID(0)))
metadata.setImageID(MetadataTools.createLSID("Image", 0), 0);
if (StringUtil.isEmpty(metadata.getImageName(0)))
metadata.setImageName("Sample", 0);
if (StringUtil.isEmpty(metadata.getPixelsID(0)))
metadata.setPixelsID(MetadataTools.createLSID("Pixels", 0), 0);
// prefer big endian as JVM is big endian
metadata.setPixelsBigEndian(Boolean.TRUE, 0);
metadata.setPixelsBinDataBigEndian(Boolean.TRUE, 0, 0);
// force XYCZT dimension order
metadata.setPixelsDimensionOrder(DimensionOrder.XYCZT, 0);
// adjust pixel type and dimension size
metadata.setPixelsType(dataType.toPixelType(), 0);
metadata.setPixelsSizeX(OMEUtil.getPositiveInteger(sizeX), 0);
metadata.setPixelsSizeY(OMEUtil.getPositiveInteger(sizeY), 0);
metadata.setPixelsSizeC(OMEUtil.getPositiveInteger(sizeC), 0);
metadata.setPixelsSizeZ(OMEUtil.getPositiveInteger(sizeZ), 0);
metadata.setPixelsSizeT(OMEUtil.getPositiveInteger(sizeT), 0);
// clean plane metadata outside allowed range
cleanPlanes(ome.getImage(0));
// get time interval information
double timeInterval = MetaDataUtil.getTimeInterval(metadata, 0, 0d);
// not defined ?
if (timeInterval == 0d)
{
// try to compute it from time positions
timeInterval = getTimeIntervalFromTimePositions(metadata, 0);
// we got something --> set it as the time interval
if (timeInterval != 0d)
MetaDataUtil.setTimeInterval(metadata, 0, timeInterval);
}
// fix channel number depending separate channel flag
if (separateChannel)
{
// set channel number
setNumChannel(metadata, 0, sizeC);
for (int c = 0; c < sizeC; c++)
{
if (StringUtil.isEmpty(metadata.getChannelID(0, c)))
metadata.setChannelID(MetadataTools.createLSID("Channel", 0, c), 0, c);
metadata.setChannelSamplesPerPixel(new PositiveInteger(Integer.valueOf(1)), 0, c);
// metadata.getChannelName(0, c);
}
}
else
{
// set channel number
setNumChannel(metadata, 0, 1);
if (StringUtil.isEmpty(metadata.getChannelID(0, 0)))
metadata.setChannelID(MetadataTools.createLSID("Channel", 0, 0), 0, 0);
metadata.setChannelSamplesPerPixel(new PositiveInteger(Integer.valueOf(sizeC)), 0, 0);
}
}
/**
* @deprecated Use {@link #setMetaData(OMEXMLMetadata, int, int, int, int, int, DataType, boolean)} instead
*/
@Deprecated
public static void setMetaData(OMEXMLMetadataImpl metadata, int sizeX, int sizeY, int sizeC, int sizeZ, int sizeT,
DataType dataType, boolean separateChannel) throws ServiceException
{
setMetaData((OMEXMLMetadata) metadata, sizeX, sizeY, sizeC, sizeZ, sizeT, dataType, separateChannel);
}
/**
* Generates meta data for the given image properties.
*
* @param sizeX
* width in pixels.
* @param sizeY
* height in pixels.
* @param sizeC
* number of channel.
* @param sizeZ
* number of Z slices.
* @param sizeT
* number of T frames.
* @param dataType
* data type.
* @param separateChannel
* true if we want channel data to be separated.
* @return OMEXMLMetadata
* @throws ServiceException
*/
public static OMEXMLMetadata generateMetaData(int sizeX, int sizeY, int sizeC, int sizeZ, int sizeT,
DataType dataType, boolean separateChannel) throws ServiceException
{
final OMEXMLMetadata result = createDefaultMetadata("Sample");
setMetaData(result, sizeX, sizeY, sizeC, sizeZ, sizeT, dataType, separateChannel);
return result;
}
/**
* Generates Meta Data for the given arguments.
*
* @see #setMetaData(OMEXMLMetadata, int, int, int, int, int, DataType, boolean)
*/
public static OMEXMLMetadata generateMetaData(int sizeX, int sizeY, int sizeC, DataType dataType,
boolean separateChannel) throws ServiceException
{
return generateMetaData(sizeX, sizeY, sizeC, 1, 1, dataType, separateChannel);
}
/**
* Generates Meta Data for the given BufferedImage.
*
* @see #setMetaData(OMEXMLMetadata, int, int, int, int, int, DataType, boolean)
*/
public static OMEXMLMetadata generateMetaData(IcyBufferedImage image, boolean separateChannel)
throws ServiceException
{
return generateMetaData(image.getSizeX(), image.getSizeY(), image.getSizeC(), image.getDataType_(),
separateChannel);
}
/**
* @deprecated Use {@link #generateMetaData(Sequence, boolean)} instead.
*/
@Deprecated
public static OMEXMLMetadata generateMetaData(Sequence sequence, boolean useZ, boolean useT,
boolean separateChannel) throws ServiceException
{
return generateMetaData(sequence, separateChannel);
}
/**
* @deprecated Use {@link #generateMetaData(Sequence, boolean)} instead.
*/
@Deprecated
public static OMEXMLMetadata generateMetaData(Sequence sequence, int sizeZ, int sizeT, boolean separateChannel)
throws ServiceException
{
return generateMetaData(sequence, separateChannel);
}
/**
* Generates Meta Data for the given Sequence.
*
* @see #setMetaData(OMEXMLMetadata, int, int, int, int, int, DataType, boolean)
*/
public static OMEXMLMetadata generateMetaData(Sequence sequence, boolean separateChannel) throws ServiceException
{
// do a copy as we mean use several time the same source sequence metadata
final OMEXMLMetadata result = OMEUtil.createOMEXMLMetadata(sequence.getMetadata());
setMetaData(result, sequence.getSizeX(), sequence.getSizeY(), sequence.getSizeC(), sequence.getSizeZ(),
sequence.getSizeT(), sequence.getDataType_(), separateChannel);
return result;
}
/**
* Keep only the specified image serie.
*/
public static void keepSingleSerie(OMEXMLMetadata metaData, int num)
{
final OME ome = getOME(metaData);
final int numSeries = ome.sizeOfImageList();
final Image img = getSerie(metaData, num);
// keep only the desired image
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeImage(ome.getImage(i));
final Set<Object> toKeep = new HashSet<Object>();
// try to keep associated dataset only
toKeep.clear();
for (int i = 0; i < img.sizeOfLinkedDatasetList(); i++)
toKeep.add(img.getLinkedDataset(i));
if (!toKeep.isEmpty())
{
for (int i = ome.sizeOfDatasetList() - 1; i >= 0; i--)
{
final Dataset obj = ome.getDataset(i);
if (!toKeep.contains(obj))
ome.removeDataset(obj);
}
}
// just assume they are indirectly linked
else if (ome.sizeOfDatasetList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeDataset(ome.getDataset(i));
}
// try to keep associated ROI only
toKeep.clear();
for (int i = 0; i < img.sizeOfLinkedROIList(); i++)
toKeep.add(img.getLinkedROI(i));
if (!toKeep.isEmpty())
{
for (int i = ome.sizeOfROIList() - 1; i >= 0; i--)
{
final ROI obj = ome.getROI(i);
if (!toKeep.contains(obj))
ome.removeROI(obj);
}
}
// just assume they are indirectly linked
else if (ome.sizeOfROIList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeROI(ome.getROI(i));
}
// try to keep associated experiment only
final Experiment exp = img.getLinkedExperiment();
if (exp != null)
{
for (int i = ome.sizeOfExperimentList() - 1; i >= 0; i--)
{
final Experiment obj = ome.getExperiment(i);
if (obj != exp)
ome.removeExperiment(obj);
}
}
else if (ome.sizeOfExperimentList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeExperiment(ome.getExperiment(i));
}
// try to keep associated experimenter only
final Experimenter expr = img.getLinkedExperimenter();
if (expr != null)
{
for (int i = ome.sizeOfExperimenterList() - 1; i >= 0; i--)
{
final Experimenter obj = ome.getExperimenter(i);
if (obj != expr)
ome.removeExperimenter(obj);
}
}
else if (ome.sizeOfExperimenterList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeExperimenter(ome.getExperimenter(i));
}
// try to keep associated experimenter group only
final ExperimenterGroup exprGroup = img.getLinkedExperimenterGroup();
if (exprGroup != null)
{
for (int i = ome.sizeOfExperimenterGroupList() - 1; i >= 0; i--)
{
final ExperimenterGroup obj = ome.getExperimenterGroup(i);
if (obj != exprGroup)
ome.removeExperimenterGroup(obj);
}
}
else if (ome.sizeOfExperimenterGroupList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeExperimenterGroup(ome.getExperimenterGroup(i));
}
// try to keep associated instrument only
final Instrument instr = img.getLinkedInstrument();
if (instr != null)
{
for (int i = ome.sizeOfInstrumentList() - 1; i >= 0; i--)
{
final Instrument obj = ome.getInstrument(i);
if (obj != instr)
ome.removeInstrument(obj);
}
}
else if (ome.sizeOfInstrumentList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeInstrument(ome.getInstrument(i));
}
// others misc data to clean
if (ome.sizeOfPlateList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removePlate(ome.getPlate(i));
}
if (ome.sizeOfProjectList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeProject(ome.getProject(i));
}
if (ome.sizeOfScreenList() == numSeries)
{
for (int i = numSeries - 1; i >= 0; i--)
if (i != num)
ome.removeScreen(ome.getScreen(i));
}
}
/**
* Keep only the specified plane metadata.
*/
public static void keepSinglePlane(Image img, int index)
{
final Pixels pix = img.getPixels();
if (pix == null)
return;
final int numPlane = pix.sizeOfPlaneList();
final Plane plane = getPlane(pix, index);
// keep only the desired plane
for (int i = numPlane - 1; i >= 0; i--)
{
if (i != index)
pix.removePlane(pix.getPlane(i));
}
final Set<Object> toKeep = new HashSet<Object>();
// try to keep associated annotation only
toKeep.clear();
for (int i = 0; i < plane.sizeOfLinkedAnnotationList(); i++)
toKeep.add(plane.getLinkedAnnotation(i));
if (!toKeep.isEmpty())
{
for (int i = img.sizeOfLinkedAnnotationList() - 1; i >= 0; i--)
{
final Annotation obj = img.getLinkedAnnotation(i);
if (!toKeep.contains(obj))
img.unlinkAnnotation(obj);
}
}
// just assume they are indirectly linked
else if (img.sizeOfLinkedAnnotationList() == numPlane)
{
for (int i = numPlane - 1; i >= 0; i--)
if (i != index)
img.unlinkAnnotation(img.getLinkedAnnotation(i));
}
// clean some data
if (pix.sizeOfBinDataList() == numPlane)
{
for (int i = numPlane - 1; i >= 0; i--)
if (i != index)
pix.removeBinData(pix.getBinData(i));
}
if (pix.sizeOfTiffDataList() == numPlane)
{
for (int i = numPlane - 1; i >= 0; i--)
if (i != index)
pix.removeTiffData(pix.getTiffData(i));
}
}
/**
* @deprecated Use {@link #keepSingleSerie(OMEXMLMetadata, int)} instead
*/
@Deprecated
public static void keepSingleSerie(OMEXMLMetadataImpl metaData, int num)
{
keepSingleSerie((OMEXMLMetadata) metaData, num);
}
/**
* Keep only plane(s) at specified C, Z, T position from the given metadata.
*
* @param img
* image metadata to clean plane from
* @param posT
* keep Plane at given T position (-1 to keep all)
* @param posZ
* keep Plane at given Z position (-1 to keep all)
* @param posC
* keep Plane at given C position (-1 to keep all)
*/
public static void keepPlanes(Image img, int posT, int posZ, int posC)
{
final Pixels pix = img.getPixels();
if (pix == null)
return;
final int sizeT = OMEUtil.getValue(pix.getSizeT(), 0);
final int sizeZ = OMEUtil.getValue(pix.getSizeZ(), 0);
final int sizeC = OMEUtil.getValue(pix.getSizeC(), 0);
for (int t = 0; t < sizeT; t++)
{
boolean remove = (posT != -1) && (posT != t);
for (int z = 0; z < sizeZ; z++)
{
remove |= (posZ != -1) && (posZ != z);
for (int c = 0; c < sizeC; c++)
{
remove |= (posC != -1) && (posC != c);
if (remove)
removePlane(img, t, z, c);
}
}
}
}
/**
* Keep only plane(s) at specified C, Z, T position from the given metadata.
*
* @param posT
* keep Plane at given T position (-1 to keep all)
* @param posZ
* keep Plane at given Z position (-1 to keep all)
* @param posC
* keep Plane at given C position (-1 to keep all)
*/
public static void keepPlanes(OMEXMLMetadata metadata, int serie, int posT, int posZ, int posC)
{
final Image img = getSerie(metadata, serie);
if (img != null)
keepPlanes(img, posT, posZ, posC);
}
/**
* Clean plane(s) which are outside the pixel sizeC / sizeZ and sizeT.
*
* @param img
* image metadata to clean plane from
*/
public static void cleanPlanes(Image img)
{
final Pixels pix = img.getPixels();
if (pix == null)
return;
final int sizeT = OMEUtil.getValue(pix.getSizeT(), 0);
final int sizeZ = OMEUtil.getValue(pix.getSizeZ(), 0);
final int sizeC = OMEUtil.getValue(pix.getSizeC(), 0);
if ((sizeT < 1) || (sizeZ < 1) || (sizeC < 1))
return;
// get allowed maximum plane
final int allowedMaxPlaneIndex = getPlaneIndex(pix, sizeT - 1, sizeZ - 1, sizeC - 1);
// current number of plane
int maxPlaneIndex = pix.sizeOfPlaneList() - 1;
// remove plan outside allowed region
while (maxPlaneIndex > allowedMaxPlaneIndex)
removePlane(img, maxPlaneIndex--);
}
/**
* Clean TiffData packet
*
* @param img
* image metadata to clean TiffData from
*/
public static void cleanTiffData(Image img)
{
final Pixels pix = img.getPixels();
if (pix == null)
return;
while (pix.sizeOfTiffDataList() > 0)
pix.removeTiffData(pix.getTiffData(pix.sizeOfTiffDataList() - 1));
}
/**
* Clean BinData packet
*
* @param img
* image metadata to clean BinData from
*/
public static void cleanBinData(Image img)
{
final Pixels pix = img.getPixels();
if (pix == null)
return;
while (pix.sizeOfBinDataList() > 0)
pix.removeBinData(pix.getBinData(pix.sizeOfBinDataList() - 1));
}
/**
* Cleanup the meta data (sometime we have empty data structure sitting there)
*/
public static void clean(OMEXMLMetadata metaData)
{
final OME ome = getOME(metaData);
final StructuredAnnotations annotations = ome.getStructuredAnnotations();
if (annotations != null)
{
for (int i = annotations.sizeOfXMLAnnotationList() - 1; i >= 0; i--)
{
final XMLAnnotation xmlAnnotation = annotations.getXMLAnnotation(i);
if (isEmpty(xmlAnnotation))
annotations.removeXMLAnnotation(xmlAnnotation);
}
}
}
/**
* @deprecated Use {@link #clean(OMEXMLMetadata)} instead.
*/
@Deprecated
public static void clean(OMEXMLMetadataImpl metaData)
{
clean((OMEXMLMetadata) metaData);
}
/**
* Returns <code>true</code> if the specified XML annotation are empty.
*/
public static boolean isEmpty(XMLAnnotation xmlAnnotation)
{
return StringUtil.isEmpty(xmlAnnotation.getDescription()) && StringUtil.isEmpty(xmlAnnotation.getValue());
}
}