Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Bioimage Analysis
ROI blocks
Commits
3a40a81b
Commit
3a40a81b
authored
Apr 20, 2020
by
Stephane Dallongeville
Browse files
Support filtering on text / object descriptor
- 'value' field now support String value - better handling of desriptor type
parent
dceabdf8
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/plugins/stef/roi/bloc/op/FilterROI.java
View file @
3a40a81b
...
...
@@ -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"
,
0
d
);
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment