Commit 3a40a81b authored by Stephane Dallongeville's avatar Stephane Dallongeville
Browse files

Support filtering on text / object descriptor

- 'value' field now support String value
- better handling of desriptor type
parent dceabdf8
......@@ -3,6 +3,10 @@
*/
package plugins.stef.roi.bloc.op;
import java.awt.Color;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
......@@ -17,10 +21,10 @@ import icy.sequence.Sequence;
import icy.system.IcyExceptionHandler;
import icy.type.collection.CollectionUtil;
import icy.util.StringUtil;
import icy.util.StringUtil.AlphanumComparator;
import plugins.adufour.blocks.tools.roi.ROIBlock;
import plugins.adufour.blocks.util.VarList;
import plugins.adufour.vars.gui.model.ValueSelectionModel;
import plugins.adufour.vars.lang.VarDouble;
import plugins.adufour.vars.lang.VarEnum;
import plugins.adufour.vars.lang.VarROIArray;
import plugins.adufour.vars.lang.VarSequence;
......@@ -88,12 +92,18 @@ public class FilterROI extends Plugin implements ROIBlock, PluginLibrary, Plugin
}
}
private static final DecimalFormat format = (DecimalFormat) NumberFormat.getInstance();
private static final DecimalFormatSymbols symbols = format.getDecimalFormatSymbols();
private static final char decimalSep = symbols.getDecimalSeparator();
private static final AlphanumComparator comp = new AlphanumComparator();
protected final VarROIArray roiSet = new VarROIArray("ROI(s)", null);
protected final VarSequence sequence = new VarSequence("Sequence", null);
protected final VarString descriptors = new VarString("Filter on", "");
protected final VarEnum<CompareOperator> operator = new VarEnum<CompareOperator>("Accept if",
CompareOperator.EQUAL);
protected final VarDouble value = new VarDouble("Value", 0d);
protected final VarString value = new VarString("Value", "0.0");
// protected final VarDouble value = new VarDouble("Value", 0d);
protected final VarROIArray output = new VarROIArray("Filtered ROI(s)");
@Override
......@@ -102,7 +112,7 @@ public class FilterROI extends Plugin implements ROIBlock, PluginLibrary, Plugin
try
{
final List<ROI> result = filterROIs(CollectionUtil.asList(roiSet.getValue()), sequence.getValue(),
descriptors.getValue(), operator.getValue(), value.getValue().doubleValue());
descriptors.getValue(), operator.getValue(), value.getValue());
output.setValue(result.toArray(new ROI[result.size()]));
}
......@@ -158,6 +168,93 @@ public class FilterROI extends Plugin implements ROIBlock, PluginLibrary, Plugin
return RoiBlocks.class.getName();
}
private static Object getTypedValue(String value)
{
final String adjValue = value.replace('.', decimalSep).replace(',', decimalSep);
try
{
return Double.valueOf(Double.parseDouble(adjValue));
}
catch (NumberFormatException e1)
{
try
{
return Float.valueOf(Float.parseFloat(adjValue));
}
catch (NumberFormatException e2)
{
try
{
return Integer.valueOf(Integer.parseInt(adjValue));
}
catch (NumberFormatException e3)
{
try
{
return Long.valueOf(Long.parseLong(adjValue));
}
catch (NumberFormatException e4)
{
// probably not a number then...
}
}
}
}
// ok so this is probably just a String
return value;
}
private static String colorToString(Color color)
{
return StringUtil.toHexaString(color.getAlpha(), 2) + StringUtil.toHexaString(color.getRed(), 2)
+ StringUtil.toHexaString(color.getGreen(), 2) + StringUtil.toHexaString(color.getBlue(), 2);
}
private static boolean compareNumber(CompareOperator op, double value1, double value2)
{
// compute comparison
final int compResult = Double.compare(value1, value2);
switch (op)
{
default:
case EQUAL:
return compResult == 0;
case NOT_EQUAL:
return compResult != 0;
case LOWER:
return compResult < 0;
case LOWER_OR_EQUAL:
return compResult <= 0;
case GREATER:
return compResult > 0;
case GREATER_OR_EQUAL:
return compResult >= 0;
}
}
private static boolean compareString(CompareOperator op, String value1, String value2, String value2Regex)
{
switch (op)
{
default:
case EQUAL:
return value1.matches(value2Regex);
case NOT_EQUAL:
return !value1.matches(value2Regex);
case LOWER:
return comp.compare(value1, value2) < 0;
case LOWER_OR_EQUAL:
return comp.compare(value1, value2) <= 0;
case GREATER:
return comp.compare(value1, value2) > 0;
case GREATER_OR_EQUAL:
return comp.compare(value1, value2) >= 0;
}
}
/**
* Filter a set of ROIs using a specific descriptor and the compare operation (keep ROIS where result of comparison is true).
*
......@@ -170,13 +267,13 @@ public class FilterROI extends Plugin implements ROIBlock, PluginLibrary, Plugin
* @param op
* Compare operation to use
* @param value
* the value for the comparison
* the value for the comparison (can be a Number or just a String)
* @return filtered list of ROIS
* @throws IllegalArgumentException
* if given ROI descriptor id is not found
*/
public static List<ROI> filterROIs(Collection<ROI> rois, Sequence sequence, String descriptorId, CompareOperator op,
double value) throws IllegalArgumentException
String value) throws IllegalArgumentException
{
final List<ROI> result = new ArrayList<ROI>();
final ROIDescriptor roiDescriptor = ROIDescriptor.getDescriptor(ROIDescriptor.getDescriptors().keySet(),
......@@ -185,58 +282,123 @@ public class FilterROI extends Plugin implements ROIBlock, PluginLibrary, Plugin
if (roiDescriptor == null)
throw new IllegalArgumentException("Cannot found '" + descriptorId + "' ROI descriptor !");
for (ROI roi : rois)
// try to get the type behind
final Object typedValue = getTypedValue(value);
// get regex from String
final String regexValue = StringUtil.wildcardToRegex(value);
// number comparison
if (typedValue instanceof Number)
{
if (roi != null)
final double doubleValue = ((Number) typedValue).doubleValue();
for (ROI roi : rois)
{
try
if (roi != null)
{
final Object res = roiDescriptor.compute(roi, sequence);
boolean accepted;
try
{
final Object res = roiDescriptor.compute(roi, sequence);
final boolean accepted;
// get double value if possible
if (res instanceof Number)
accepted = compareNumber(op, ((Number) res).doubleValue(), doubleValue);
else if (res instanceof Color)
accepted = compareNumber(op, ((Color) res).getRGB(), doubleValue);
// can't filter --> show error message
else if (res instanceof String)
accepted = compareString(op, (String) res, value, regexValue);
else if (res != null)
accepted = compareString(op, res.toString(), value, regexValue);
else
// don't accept when result is null
accepted = false;
// throw new VarException(null,
// "Descriptor result is null, can't apply filtering criterion !");
// we only support Number result for filtering
if (res instanceof Number)
if (accepted)
result.add(roi);
}
catch (VarException e1)
{
final double computedValue = ((Number) res).doubleValue();
switch (op)
{
default:
case EQUAL:
accepted = computedValue == value;
break;
case NOT_EQUAL:
accepted = computedValue != value;
break;
case LOWER:
accepted = computedValue < value;
break;
case LOWER_OR_EQUAL:
accepted = computedValue <= value;
break;
case GREATER:
accepted = computedValue > value;
break;
case GREATER_OR_EQUAL:
accepted = computedValue >= value;
break;
}
throw e1;
}
else
accepted = true;
if (accepted)
catch (Exception e2)
{
IcyExceptionHandler.showErrorMessage(e2, false, true);
// if we can't compute the descriptor we accept the ROI by default...
result.add(roi);
}
}
catch (Exception e)
}
}
else if (typedValue instanceof String)
{
for (ROI roi : rois)
{
if (roi != null)
{
IcyExceptionHandler.showErrorMessage(e, false, true);
// if we can't compute the descriptor we accept the ROI by default...
result.add(roi);
try
{
final Object res = roiDescriptor.compute(roi, sequence);
final String stringRes;
// not really safe to compare number with a String here
if (res instanceof Number)
throw new VarException(null,
"Can't apply filtering criterion, you need to provide a valid number in 'Value' field.");
// stringRes = ((Number) res).toString();
else if (res instanceof String)
stringRes = (String) res;
else if (res instanceof Color)
stringRes = colorToString((Color) res);
else if (res != null)
stringRes = res.toString();
else
stringRes = "";
if (compareString(op, stringRes, value, regexValue))
result.add(roi);
}
catch (VarException e1)
{
throw e1;
}
catch (Exception e2)
{
IcyExceptionHandler.showErrorMessage(e2, false, true);
// if we can't compute the descriptor we accept the ROI by default...
result.add(roi);
}
}
}
}
return result;
}
/**
* Filter a set of ROIs using a specific descriptor and the compare operation (keep ROIS where result of comparison is true).
*
* @param rois
* input ROIS to filter
* @param sequence
* input sequence used for ROI descriptor computation (can be null if not required)
* @param descriptorId
* the {@link ROIDescriptor} id to use for filtering
* @param op
* Compare operation to use
* @param value
* the value for the comparison
* @return filtered list of ROIS
* @throws IllegalArgumentException
* if given ROI descriptor id is not found
*/
public static List<ROI> filterROIs(Collection<ROI> rois, Sequence sequence, String descriptorId, CompareOperator op,
double value) throws IllegalArgumentException
{
return filterROIs(rois, sequence, descriptorId, op, Double.toString(value));
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment