001/**
002 * 
003 */
004package plugins.kernel.roi.descriptor.measure;
005
006import icy.roi.ROI;
007import icy.roi.ROIDescriptor;
008import icy.sequence.Sequence;
009
010/**
011 * Interior ROI descriptor class (see {@link ROIDescriptor})
012 * 
013 * @author Stephane
014 */
015public class ROIInteriorDescriptor extends ROIDescriptor
016{
017    public static final String ID = "Interior";
018
019    public ROIInteriorDescriptor()
020    {
021        super(ID, "Interior", Double.class);
022    }
023
024    @Override
025    public String getUnit(Sequence sequence)
026    {
027        return "px";
028    }
029
030    @Override
031    public String getDescription()
032    {
033        return "Number of points for the interior";
034    }
035
036    @Override
037    public Object compute(ROI roi, Sequence sequence) throws UnsupportedOperationException
038    {
039        return Double.valueOf(computeInterior(roi));
040    }
041
042    /**
043     * Returns the number of point inside the specified ROI.
044     * 
045     * @param roi
046     *        the ROI on which we want to compute the number of contour point
047     * @return the number of point inside the ROI
048     */
049    public static double computeInterior(ROI roi)
050    {
051        return roi.getNumberOfPoints();
052    }
053
054    /**
055     * Returns the interior size from a given number of interior points in the best unit (see
056     * {@link Sequence#getBestPixelSizeUnit(int, int)}) for the specified sequence and dimension.<br>
057     * <ul>
058     * Ex:
059     * <li>computeInterior(sequence, roi, 2) return the area value</li>
060     * <li>computeInterior(sequence, roi, 3) return the volume value</li>
061     * </ul>
062     * It may thrown an <code>UnsupportedOperationException</code> if the operation is not supported for that ROI.
063     * 
064     * @param interiorPoints
065     *        the number of interior points (override the ROI value)
066     * @param roi
067     *        the ROI we want to compute the interior size
068     * @param sequence
069     *        the input sequence used to retrieve operation unit by using pixel size information.
070     * @param dim
071     *        the dimension for the interior size operation (2 = area, 3 = volume, ...)
072     * @return the number of point inside the ROI
073     * @see Sequence#getBestPixelSizeUnit(int, int)
074     * @throws UnsupportedOperationException
075     *         if the interior calculation for the specified dimension is not supported by the ROI
076     */
077    public static double computeInterior(double interiorPoints, ROI roi, Sequence sequence, int dim)
078            throws UnsupportedOperationException
079    {
080        final double mul = ROIBasicMeasureDescriptorsPlugin.getMultiplierFactor(sequence, roi, dim);
081
082        // 0 means the operation is not supported for this ROI
083        if (mul == 0d)
084            throw new UnsupportedOperationException("Can't process '" + ID + "' calculation for dimension " + dim
085                    + " on the ROI: " + roi.getName());
086
087        return sequence.calculateSizeBestUnit(interiorPoints * mul, dim, dim);
088    }
089}