package plugins.kernel.roi.descriptor.measure;
import icy.plugin.abstract_.Plugin;
import icy.plugin.interface_.PluginROIDescriptor;
import icy.roi.ROI;
import icy.roi.ROIDescriptor;
import icy.sequence.Sequence;
import icy.type.rectangle.Rectangle5D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This {@link PluginROIDescriptor} implements the following basic measures ROI descriptors:<br/>
* <li>Contour (in pixel)</li><br/>
* <li>Interior (in pixel)</li><br/>
* <li>Perimeter (pixel size unit - 2D ROI only)</li><br/>
* <li>Surface Area (pixel size unit - 3D ROI only)</li><br/>
* <li>Area (pixel size unit - 2D ROI only)</li><br/>
* <li>Volume (pixel size unit - 3D ROI only)</li><br/>
*
* @author Stephane
*/
public class ROIBasicMeasureDescriptorsPlugin extends Plugin implements PluginROIDescriptor
{
public static final String ID_CONTOUR = ROIContourDescriptor.ID;
public static final String ID_INTERIOR = ROIInteriorDescriptor.ID;
public static final String ID_PERIMETER = ROIPerimeterDescriptor.ID;
public static final String ID_AREA = ROIAreaDescriptor.ID;
public static final String ID_SURFACE_AREA = ROISurfaceAreaDescriptor.ID;
public static final String ID_VOLUME = ROIVolumeDescriptor.ID;
public static final ROIContourDescriptor contourDescriptor = new ROIContourDescriptor();
public static final ROIInteriorDescriptor interiorDescriptor = new ROIInteriorDescriptor();
public static final ROIPerimeterDescriptor perimeterDescriptor = new ROIPerimeterDescriptor();
public static final ROIAreaDescriptor areaDescriptor = new ROIAreaDescriptor();
public static final ROISurfaceAreaDescriptor surfaceAreaDescriptor = new ROISurfaceAreaDescriptor();
public static final ROIVolumeDescriptor volumeDescriptor = new ROIVolumeDescriptor();
/**
* Calculate the multiplier factor depending the wanted dimension information.
*/
public static double getMultiplierFactor(Sequence sequence, ROI roi, int dim)
{
final int dimRoi = roi.getDimension();
// cannot give this information for this roi
if (dimRoi > dim)
return 0d;
final Rectangle5D boundsRoi = roi.getBounds5D();
double mul = 1d;
switch (dim)
{
case 5:
if (dimRoi == 4)
{
final int sizeC = sequence.getSizeC();
if ((boundsRoi.getSizeC() == Double.POSITIVE_INFINITY) && (sizeC > 1))
mul *= sizeC;
// cannot give this information for this roi
else
mul = 0d;
}
case 4:
if (dimRoi == 3)
{
final int sizeT = sequence.getSizeT();
if ((boundsRoi.getSizeT() == Double.POSITIVE_INFINITY) && (sizeT > 1))
mul *= sizeT;
// cannot give this information for this roi
else
mul = 0d;
}
case 3:
if (dimRoi == 2)
{
final int sizeZ = sequence.getSizeZ();
if ((boundsRoi.getSizeZ() == Double.POSITIVE_INFINITY) && (sizeZ > 1))
mul *= sizeZ;
// cannot give this information for this roi
else
mul = 0d;
}
case 2:
if (dimRoi == 1)
{
final int sizeY = sequence.getSizeY();
if ((boundsRoi.getSizeY() == Double.POSITIVE_INFINITY) && (sizeY > 1))
mul *= sizeY;
// cannot give this information for this roi
else
mul = 0d;
}
}
return mul;
}
@Override
public List<ROIDescriptor> getDescriptors()
{
final List<ROIDescriptor> result = new ArrayList<ROIDescriptor>();
result.add(contourDescriptor);
result.add(interiorDescriptor);
result.add(perimeterDescriptor);
result.add(areaDescriptor);
result.add(surfaceAreaDescriptor);
result.add(volumeDescriptor);
return result;
}
@Override
public Map<ROIDescriptor, Object> compute(ROI roi, Sequence sequence) throws UnsupportedOperationException
{
final Map<ROIDescriptor, Object> result = new HashMap<ROIDescriptor, Object>();
// use the contour and interior to compute others descriptors
final double contour = ROIContourDescriptor.computeContour(roi);
final double interior = ROIInteriorDescriptor.computeInterior(roi);
result.put(contourDescriptor, Double.valueOf(contour));
result.put(interiorDescriptor, Double.valueOf(interior));
int notComputed = 0;
try
{
result.put(perimeterDescriptor, Double.valueOf(ROIPerimeterDescriptor.computePerimeter(roi, sequence)));
}
catch (UnsupportedOperationException e)
{
result.put(perimeterDescriptor, null);
notComputed++;
}
try
{
result.put(areaDescriptor, Double.valueOf(ROIAreaDescriptor.computeArea(interior, roi, sequence)));
}
catch (UnsupportedOperationException e)
{
result.put(areaDescriptor, null);
notComputed++;
}
try
{
result.put(surfaceAreaDescriptor,
Double.valueOf(ROISurfaceAreaDescriptor.computeSurfaceArea(roi, sequence)));
}
catch (UnsupportedOperationException e)
{
result.put(surfaceAreaDescriptor, null);
notComputed++;
}
try
{
result.put(volumeDescriptor, Double.valueOf(ROIVolumeDescriptor.computeVolume(interior, roi, sequence)));
}
catch (UnsupportedOperationException e)
{
result.put(volumeDescriptor, null);
notComputed++;
}
if (notComputed == 4)
{
throw new UnsupportedOperationException(getClass().getSimpleName()
+ ": cannot compute any of the descriptors for '" + roi.getName() + "'");
}
return result;
}
}