/** * */ package plugins.kernel.roi.descriptor.measure; import icy.math.UnitUtil; import icy.math.UnitUtil.UnitPrefix; import icy.roi.ROI; import icy.roi.ROI3D; import icy.roi.ROIDescriptor; import icy.sequence.Sequence; import icy.sequence.SequenceEvent; import icy.sequence.SequenceEvent.SequenceEventSourceType; import icy.util.StringUtil; /** * Surface area ROI descriptor class (see {@link ROIDescriptor}) * * @author Stephane */ public class ROISurfaceAreaDescriptor extends ROIDescriptor { public static final String ID = "Surface area"; public ROISurfaceAreaDescriptor() { super(ID, "Surface Area", Double.class); } @Override public String getDescription() { return "Surface area"; } @Override public String getUnit(Sequence sequence) { if (sequence != null) return sequence.getBestPixelSizeUnit(3, 2).toString() + "m2"; return UnitPrefix.MICRO.toString() + "m2"; } @Override public boolean needRecompute(SequenceEvent change) { final SequenceEventSourceType sourceType = change.getSourceType(); if (sourceType == SequenceEventSourceType.SEQUENCE_DATA) return true; if (sourceType == SequenceEventSourceType.SEQUENCE_META) { final String metaName = (String) change.getSource(); return StringUtil.isEmpty(metaName) || StringUtil.equals(metaName, Sequence.ID_PIXEL_SIZE_X) || StringUtil.equals(metaName, Sequence.ID_PIXEL_SIZE_Y) || StringUtil.equals(metaName, Sequence.ID_PIXEL_SIZE_Z); } return false; } @Override public Object compute(ROI roi, Sequence sequence) throws UnsupportedOperationException { return Double.valueOf(computeSurfaceArea(roi, sequence)); } /** * Computes and returns the surface area expressed in the unit of the descriptor (see {@link #getUnit(Sequence)}) * for the specified ROI.<br> * It may thrown an <code>UnsupportedOperationException</code> if the operation is not supported for that ROI. * * @param roi * the ROI on which we want to compute the surface area * @param sequence * the sequence from which the pixel size can be retrieved * @return the surface area expressed in the unit of the descriptor (see {@link #getUnit(Sequence)}) * @throws UnsupportedOperationException * if the operation is not supported for this ROI */ public static double computeSurfaceArea(ROI roi, Sequence sequence) throws UnsupportedOperationException { if (!(roi instanceof ROI3D)) throw new UnsupportedOperationException("Surface area not supported on " + roi.getDimension() + "D ROI !"); if (sequence == null) throw new UnsupportedOperationException("Cannot compute Surface area with null Sequence parameter !"); final UnitPrefix bestUnit = sequence.getBestPixelSizeUnit(3, 2); final double surfaceArea = ((ROI3D) roi).getSurfaceArea(sequence); return UnitUtil.getValueInUnit(surfaceArea, UnitPrefix.MICRO, bestUnit, 2); } // /** // * Computes and returns the surface area from a given number of contour points expressed in the // * unit of the descriptor (see {@link #getUnit(Sequence)}) for the specified sequence and ROI.<br> // * It may returns <code>Double.Nan</code> if the operation is not supported for that ROI. // * // * @param contourPoints // * the number of contour points (override the ROI value) // * @param roi // * the ROI we want to compute the surface area // * @param sequence // * the input sequence used to retrieve operation unit by using pixel size // * information. // * @return the surface area // * @throws UnsupportedOperationException // * if the operation is not supported for this ROI // */ // static double computeSurfaceArea(double contourPoints, ROI roi, Sequence sequence) // throws UnsupportedOperationException // { // return ROIContourDescriptor.computeContour(contourPoints, roi, sequence, 3); // } }