Bug report
Describe the bug
The behavior of Analyze → Spatial analysis → Delaunay cluster features 2D is not well-defined when applying the command to annotations that are nested (in the hierarchy) or overlapping.
For 'flat' annotation arrangements the behavior is mostly ok, except that it does rely on hierarchy relationships rather than spatial relationships.
Which is to say, it hasn't really changed since v0.1.2.
To Reproduce
Create an arrangement of objects similar to that shown below:

- If I run Delaunay cluster features 2D with all annotations selected, I see triangulation lines which do not cross the boundary between the annotations containing cells.

But I also get a ConcurrentModificationException:
15:47:01.829 [Plugin thread] ERROR qupath.lib.plugins.AbstractTaskRunner Error running plugin: java.util.ConcurrentModificationException java.util.concurrent.ExecutionException: java.util.ConcurrentModificationException
at java.base/java.util.concurrent.FutureTask.report(Unknown Source)
at java.base/java.util.concurrent.FutureTask.get(Unknown Source)
at qupath.lib.plugins.AbstractTaskRunner.awaitCompletion(AbstractTaskRunner.java:147)
at qupath.lib.plugins.AbstractTaskRunner.runTasks(AbstractTaskRunner.java:117)
at qupath.lib.gui.TaskRunnerFX.runTasks(TaskRunnerFX.java:106)
at qupath.lib.plugins.AbstractPlugin.runPlugin(AbstractPlugin.java:147)
at qupath.lib.gui.ParameterDialogWrapper$1.run(ParameterDialogWrapper.java:177)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.base/java.util.ArrayList$Itr.next(Unknown Source)
at java.base/java.util.Collections$UnmodifiableCollection$1.next(Unknown Source)
at java.base/java.util.AbstractCollection.addAll(Unknown Source)
at qupath.lib.objects.PathObjectTools.getAvailableFeatures(PathObjectTools.java:2026)
at qupath.opencv.features.DelaunayTriangulation.<init>(DelaunayTriangulation.java:86)
at qupath.opencv.features.DelaunayClusteringPlugin$DelaunayRunnable.run(DelaunayClusteringPlugin.java:208)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
... 1 more
- If I repeat with the outer rectangle selected, then I do see connections.
This is because the triangulation uses all descendant detections below the rectangle, based on the object hierarchy.

- If I repeat with the outer ellipse selected, I get no connections at all.
This is because the ellipse isn't set to be a parent of any of the other objects - this would change if I called Resolve hierarchy first.

- If I repeat with the inner rectangles selected, I get connections that don't cross and I don't get any exception.
This is because each cell is only handled once, so I don't get the concurrency trouble.

- If I repeat with only 1 inner rectangle selected, I get connections within that rectangle only.

Expected behavior
This isn't obvious... Nevertheless:
- The
ConcurrentModificationException is clearly bad. But it's also kind of helpful here, because 2. and 4. give different results... and when that's the case, if we select all the annotations in 2. and 4. in one go, it's not obvious what should happen.
- The reliance on hierarchical relationships may not be very intuitive to a user, since measurements like 'Positive %' are dynamically computed using spatial location relative to any selected annotation - not hierarchical relationships.
Desktop (please complete the following information):
- OS: All
- QuPath Version: v0.5.1 (and earlier)
Additional context
This relates to:
The behavior of Delaunay cluster features 2D is in general not very good for more reasons than these.
For example, the display of the connection lines is already a bit of a hack (smuggled into ImageData properties) - and showing/hiding these can be unreliable.
But fixing #1466 risks swallowing the ConcurrentModificationException, meaning we get unexpected results rather than an exception - which is potentially worse.
Bug report
Describe the bug
The behavior of Analyze → Spatial analysis → Delaunay cluster features 2D is not well-defined when applying the command to annotations that are nested (in the hierarchy) or overlapping.
For 'flat' annotation arrangements the behavior is mostly ok, except that it does rely on hierarchy relationships rather than spatial relationships.
Which is to say, it hasn't really changed since v0.1.2.
To Reproduce
Create an arrangement of objects similar to that shown below:
But I also get a
ConcurrentModificationException:This is because the triangulation uses all descendant detections below the rectangle, based on the object hierarchy.
This is because the ellipse isn't set to be a parent of any of the other objects - this would change if I called Resolve hierarchy first.
This is because each cell is only handled once, so I don't get the concurrency trouble.
Expected behavior
This isn't obvious... Nevertheless:
ConcurrentModificationExceptionis clearly bad. But it's also kind of helpful here, because 2. and 4. give different results... and when that's the case, if we select all the annotations in 2. and 4. in one go, it's not obvious what should happen.Desktop (please complete the following information):
Additional context
This relates to:
The behavior of Delaunay cluster features 2D is in general not very good for more reasons than these.
For example, the display of the connection lines is already a bit of a hack (smuggled into
ImageDataproperties) - and showing/hiding these can be unreliable.But fixing #1466 risks swallowing the
ConcurrentModificationException, meaning we get unexpected results rather than an exception - which is potentially worse.