001/** 002 * 003 */ 004package plugins.kernel.roi.descriptor.measure; 005 006import icy.math.UnitUtil; 007import icy.math.UnitUtil.UnitPrefix; 008import icy.roi.ROI; 009import icy.roi.ROI3D; 010import icy.roi.ROIDescriptor; 011import icy.sequence.Sequence; 012import icy.sequence.SequenceEvent; 013import icy.sequence.SequenceEvent.SequenceEventSourceType; 014import icy.util.StringUtil; 015 016/** 017 * Surface area ROI descriptor class (see {@link ROIDescriptor}) 018 * 019 * @author Stephane 020 */ 021public class ROISurfaceAreaDescriptor extends ROIDescriptor 022{ 023 public static final String ID = "Surface area"; 024 025 public ROISurfaceAreaDescriptor() 026 { 027 super(ID, "Surface Area", Double.class); 028 } 029 030 @Override 031 public String getDescription() 032 { 033 return "Surface area"; 034 } 035 036 @Override 037 public String getUnit(Sequence sequence) 038 { 039 if (sequence != null) 040 return sequence.getBestPixelSizeUnit(3, 2).toString() + "m2"; 041 042 return UnitPrefix.MICRO.toString() + "m2"; 043 } 044 045 @Override 046 public boolean needRecompute(SequenceEvent change) 047 { 048 final SequenceEventSourceType sourceType = change.getSourceType(); 049 050 if (sourceType == SequenceEventSourceType.SEQUENCE_DATA) 051 return true; 052 if (sourceType == SequenceEventSourceType.SEQUENCE_META) 053 { 054 final String metaName = (String) change.getSource(); 055 056 return StringUtil.isEmpty(metaName) || StringUtil.equals(metaName, Sequence.ID_PIXEL_SIZE_X) 057 || StringUtil.equals(metaName, Sequence.ID_PIXEL_SIZE_Y) 058 || StringUtil.equals(metaName, Sequence.ID_PIXEL_SIZE_Z); 059 } 060 061 return false; 062 } 063 064 @Override 065 public Object compute(ROI roi, Sequence sequence) throws UnsupportedOperationException 066 { 067 return Double.valueOf(computeSurfaceArea(roi, sequence)); 068 } 069 070 /** 071 * Computes and returns the surface area expressed in the unit of the descriptor (see {@link #getUnit(Sequence)}) 072 * for the specified ROI.<br> 073 * It may thrown an <code>UnsupportedOperationException</code> if the operation is not supported for that ROI. 074 * 075 * @param roi 076 * the ROI on which we want to compute the surface area 077 * @param sequence 078 * the sequence from which the pixel size can be retrieved 079 * @return the surface area expressed in the unit of the descriptor (see {@link #getUnit(Sequence)}) 080 * @throws UnsupportedOperationException 081 * if the operation is not supported for this ROI 082 */ 083 public static double computeSurfaceArea(ROI roi, Sequence sequence) throws UnsupportedOperationException 084 { 085 if (!(roi instanceof ROI3D)) 086 throw new UnsupportedOperationException("Surface area not supported on " + roi.getDimension() + "D ROI !"); 087 if (sequence == null) 088 throw new UnsupportedOperationException("Cannot compute Surface area with null Sequence parameter !"); 089 090 final UnitPrefix bestUnit = sequence.getBestPixelSizeUnit(3, 2); 091 final double surfaceArea = ((ROI3D) roi).getSurfaceArea(sequence); 092 093 return UnitUtil.getValueInUnit(surfaceArea, UnitPrefix.MICRO, bestUnit, 2); 094 } 095 096 // /** 097 // * Computes and returns the surface area from a given number of contour points expressed in the 098 // * unit of the descriptor (see {@link #getUnit(Sequence)}) for the specified sequence and ROI.<br> 099 // * It may returns <code>Double.Nan</code> if the operation is not supported for that ROI. 100 // * 101 // * @param contourPoints 102 // * the number of contour points (override the ROI value) 103 // * @param roi 104 // * the ROI we want to compute the surface area 105 // * @param sequence 106 // * the input sequence used to retrieve operation unit by using pixel size 107 // * information. 108 // * @return the surface area 109 // * @throws UnsupportedOperationException 110 // * if the operation is not supported for this ROI 111 // */ 112 // static double computeSurfaceArea(double contourPoints, ROI roi, Sequence sequence) 113 // throws UnsupportedOperationException 114 // { 115 // return ROIContourDescriptor.computeContour(contourPoints, roi, sequence, 3); 116 // } 117}