Class PathObjectTools

java.lang.Object
qupath.lib.objects.PathObjectTools

public class PathObjectTools extends Object
A collection of static methods to help work with PathObjects.
Author:
Pete Bankhead
  • Constructor Details

    • PathObjectTools

      public PathObjectTools()
  • Method Details

    • hasPointROI

      public static boolean hasPointROI(PathObject pathObject)
      Returns true if a PathObject has a Point ROI.
      Parameters:
      pathObject -
      Returns:
    • countObjectsWithClass

      public static int countObjectsWithClass(Collection<? extends PathObject> pathObjects, PathClass pathClass, boolean useBaseClass)
      Count the number of PathObjects in a collection with a specified class or base class.
      Parameters:
      pathObjects -
      pathClass -
      useBaseClass -
      Returns:
    • getObjectsOfClass

      public static List<PathObject> getObjectsOfClass(Collection<PathObject> pathObjects, Class<? extends PathObject> cls)
      Get the PathObjects in a collection that are instances of a specified class.
      Parameters:
      pathObjects -
      cls -
      Returns:
    • createImageRegionPredicate

      public static Predicate<PathObject> createImageRegionPredicate(ImageRegion region)
      Create a predicate that only accepts PathObjects if they have ROIs that fall within a specified ImageRegion.
      Parameters:
      region -
      Returns:
    • getLineObjects

      public static <T extends PathObject> List<T> getLineObjects(Collection<T> pathObjects)
      Get a list of objects with line ROIs from a collection of objects.
      Type Parameters:
      T -
      Parameters:
      pathObjects -
      Returns:
      Since:
      v0.5.0
    • getAreaObjects

      public static <T extends PathObject> List<T> getAreaObjects(Collection<T> pathObjects)
      Get a list of objects with area ROIs from a collection of objects.
      Type Parameters:
      T -
      Parameters:
      pathObjects -
      Returns:
      Since:
      v0.5.0
    • getPointObjects

      public static <T extends PathObject> List<T> getPointObjects(Collection<T> pathObjects)
      Get a list of objects with point ROIs from a collection of objects.
      Type Parameters:
      T -
      Parameters:
      pathObjects -
      Returns:
      Since:
      v0.5.0
    • getFlattenedObjectList

      public static List<PathObject> getFlattenedObjectList(PathObject parentObject, List<PathObject> list, boolean includeParent)
      Get all descendant objects as a flattened list.
      Parameters:
      parentObject - the parent objects whose children and descendants should be added to the list
      list - output list, optional
      includeParent - if true, parentObject will be included in the output list
      Returns:
      either list, or a new list created if necessary
    • countDescendants

      public static int countDescendants(PathObject pathObject)
      Count the descendants of a PathObject recursively.
      Parameters:
      pathObject -
      Returns:
    • containsROI

      @Deprecated public static boolean containsROI(ROI parentROI, ROI childROI)
      Deprecated.
      Test whether one ROI is can completely contain a second ROI. Returns false if either ROI is null.

      Note: This is not a perfect test, since it really only checks if the vertices of the child ROI fall within the parent - it is possible that connecting lines stray outside the parent, yet it still returns true. This behavior may change in later versions.

      TODO: Consider improving 'containsROI' method accuracy.

      Parameters:
      parentROI -
      childROI -
      Returns:
    • findObjectsOutsideImage

      public static List<PathObject> findObjectsOutsideImage(Collection<? extends PathObject> pathObjects, ImageServer<?> server, boolean ignoreIntersecting)
      Get all the objects with ROIs that are outside the bounds of an image.
      Parameters:
      pathObjects - the input objects to check
      server - the image to check
      ignoreIntersecting - if true, consider objects that overlap the image boundary to be inside (and therefore don't include them in the output); if false, consider them to be outside and include them in the output
      Returns:
      a filtered list of the input object containing those considered outside the image
      Since:
      v0.4.0
      See Also:
    • findObjectsOutsideRegion

      public static List<PathObject> findObjectsOutsideRegion(Collection<? extends PathObject> pathObjects, ImageRegion region, boolean ignoreIntersecting)
      Get all the objects in a collection that are outside a defined region.
      Parameters:
      pathObjects - input objects to check
      region - 2D region
      ignoreIntersecting - if true, consider objects that overlap the region boundary to be inside (and therefore don't include them in the output); if false, consider them to be outside and include them in the output
      Returns:
      a filtered list of the input object containing those considered outside the region
      Since:
      v0.4.0
      See Also:
    • findObjectsOutsideRegion

      public static List<PathObject> findObjectsOutsideRegion(Collection<? extends PathObject> pathObjects, ImageRegion region, int minZ, int maxZ, int minT, int maxT, boolean ignoreIntersecting)
      Get all the objects in a collection that are outside a defined region, expanded for multiple z-slices and timepoints.
      Parameters:
      pathObjects - input objects to check
      region - 2D region
      minZ - minimum z for the region (inclusive)
      maxZ - maximum z for the region (exclusive)
      minT - minimum t for the region (inclusive)
      maxT - maximum t for the region (exclusive)
      ignoreIntersecting - if true, consider objects that overlap the region boundary to be inside (and therefore don't include them in the output); if false, consider them to be outside and include them in the output
      Returns:
      a filtered list of the input object containing those considered outside the region
      Since:
      v0.4.0
      See Also:
    • updatePlaneRecursive

      public static PathObject updatePlaneRecursive(PathObject pathObject, ImagePlane plane, boolean copyMeasurements, boolean createNewIDs)
      Update the ROI plane for a single object, and any descendant objects.
      Parameters:
      pathObject - the original object (this will be unchanged)
      plane - the plane for the new ROIs
      copyMeasurements - if true, measurements and metadata should be copied; this may not be suitable since intensity measurements probably aren't appropriate for the new plane
      createNewIDs - if true, create new IDs for the object (recommended)
      Returns:
      the new object, with ROIs on the requested plane
      Since:
      v0.4.0
      See Also:
    • updatePlaneRecursive

      public static PathObject updatePlaneRecursive(PathObject pathObject, ImagePlane plane)
      Update the ROI plane for a single object and any descendant objects, creating new object IDs and ignoring any additional measurements.
      Parameters:
      pathObject - the original object (this will be unchanged)
      plane - the plane for the new ROIs
      Returns:
      the new object, with ROIs on the requested plane
      Since:
      v0.4.0
      See Also:
    • updatePlane

      public static PathObject updatePlane(PathObject pathObject, ImagePlane plane, boolean copyMeasurements, boolean createNewIDs)
      Update the ROI plane for a single object. Any child objects are discarded; if these should also be copied (and updated), use updatePlaneRecursive(PathObject, ImagePlane, boolean, boolean).
      Parameters:
      pathObject - the original object (this will be unchanged)
      plane - the plane for the new ROIs
      copyMeasurements - if true, measurements and metadata should be copied; this may not be suitable since intensity measurements probably aren't appropriate for the new plane
      createNewIDs - if true, create new IDs for the object (recommended)
      Returns:
      the new object, with ROIs on the requested plane
      Since:
      v0.4.0
      See Also:
    • getSuitableName

      public static String getSuitableName(Class<? extends PathObject> cls, boolean makePlural)
      Get a user-friendly name for a specific type of PathObject, based on its Java class.
      Parameters:
      cls -
      makePlural -
      Returns:
    • containsObject

      @Deprecated public static boolean containsObject(PathObject parentObject, PathObject childObject)
      Deprecated.
      Test whether the ROI associated with one object can completely the ROI of a second object. Returns false if either ROI is null.
      Parameters:
      parentObject -
      childObject -
      Returns:
    • isAncestor

      public static boolean isAncestor(PathObject pathObject, PathObject possibleAncestor)
      Query if one object is the ancestor of another.
      Parameters:
      pathObject -
      possibleAncestor -
      Returns:
    • getTMACoreObjects

      public static List<TMACoreObject> getTMACoreObjects(PathObjectHierarchy hierarchy, boolean includeMissingCores)
      Extract a list of TMA cores from an object hierarchy. If no cores are present, an empty list is returned.
      Parameters:
      hierarchy -
      includeMissingCores -
      Returns:
    • getAncestorTMACore

      public static TMACoreObject getAncestorTMACore(PathObject pathObject)
      Get the TMA core object that contains a specified PathObject, or null if the object is not contained within a TMA core.

      If the passed object already is a TMACore, it is returned directly. Otherwise, all ancestors are checked.

      Parameters:
      pathObject -
      Returns:
    • getTMACoreForPixel

      public static TMACoreObject getTMACoreForPixel(TMAGrid tmaGrid, double x, double y)
      Get the TMA core that contains the specified x & y coordinate, or null if no core is available for the coordinates give.
      Parameters:
      tmaGrid -
      x -
      y -
      Returns:
    • addTMAGrid

      public static void addTMAGrid(ImageData<?> imageData, String hLabels, String vLabels, boolean rowFirst, double diameterCalibrated)
      Create a new regular TMAGrid and set it as active on the hierarchy for an image.

      For the label string format, see see parseTMALabelString(String).

      Parameters:
      imageData - the image to which the TMA grid should be added. This is used to determine dimensions and pixel calibration. If there is a ROI selected, it will be used to define the bounding box for the grid.
      hLabels - a String representing horizontal labels
      vLabels - a String representing vertical labels
      rowFirst - true if the horizontal label should be added before the vertical label, false otherwise
      diameterCalibrated - the diameter of each core, in calibrated units
    • createTMAGrid

      public static TMAGrid createTMAGrid(String hLabels, String vLabels, boolean rowFirst, double diameterPixels, ImageRegion region)
      Create a new regular TMAGrid, fit within a specified region.

      For the label string format, see see parseTMALabelString(String).

      Parameters:
      hLabels - a String representing horizontal labels
      vLabels - a String representing vertical labels
      rowFirst - true if the horizontal label should be added before the vertical label, false otherwise
      diameterPixels - the diameter of each core, in pixels
      region - bounding box and spacing for the grid (required)
      Returns:
    • relabelTMAGrid

      public static boolean relabelTMAGrid(TMAGrid grid, String labelsHorizontal, String labelsVertical, boolean rowFirst)
      Relabel a TMA grid. This will only be effective if enough labels are supplied for the full grid - otherwise no changes will be made.

      For a TMA core at column c and row r, the label format will be 'Hc-Vr' or 'Hc-Vr', where H is the horizontal label and V the vertical label, depending upon the status of the 'rowFirst' flag.

      An examples of label would be 'A-1', 'A-2', 'B-1', 'B-2' etc.

      Parameters:
      grid - the TMA grid to relabel
      labelsHorizontal - a String containing labels for each TMA column, separated by spaces, or a numeric or alphabetic range (e.g. 1-10, or A-G)
      labelsVertical - a String containing labels for each TMA row, separated by spaces, or a numeric or alphabetic range (e.g. 1-10, or A-G)
      rowFirst - true if the horizontal label should be added before the vertical label, false otherwise
      Returns:
      true if there were sufficient horizontal and vertical labels to label the entire grid, false otherwise.
    • convertToPoints

      public static void convertToPoints(PathObjectHierarchy hierarchy, Collection<PathObject> pathObjects, boolean preferNucleus, boolean deleteObjects)
      Convert a collection of PathObjects to Point annotations, based on ROI centroids, and add the points to the hierarchy.
      Parameters:
      hierarchy - the object hierarchy containing the objects, and to which the points should be added
      pathObjects - input objects; these are expected to have ROIs
      preferNucleus - if true, request the nucleus ROI from cell objects where possible; if false, request the outer ROI. This has no effect if the object is not a cell, or does not have two ROIs.
      deleteObjects - if true, delete the objects from the input collection after point conversion; if false, retain both original objects and points
      See Also:
    • convertToPoints

      public static Collection<PathObject> convertToPoints(Collection<PathObject> pathObjects, boolean preferNucleus)
      Convert a collection of PathObjects to Point annotations, based on ROI centroids. Each output annotation contains all points corresponding to input objects with the same classification. Consequently, the size of the output collection is equal to the number of distinct classifications found among the input objects.
      Parameters:
      pathObjects - input objects; these are expected to have ROIs
      preferNucleus - if true, request the nucleus ROI from cell objects where possible; if false, request the outer ROI. This has no effect if the object is not a cell, or does not have two ROIs.
      Returns:
      a collection of annotations with point ROIs
      See Also:
    • hierarchyContainsObject

      public static boolean hierarchyContainsObject(PathObjectHierarchy hierarchy, PathObject pathObject)
      Check if a hierarchy contains a specified PathObject. The actual check if carried out by seeing in the PathObject is descended from the root object of the hierarchy.
      Parameters:
      hierarchy -
      pathObject -
      Returns:
    • getObjectsForLocation

      public static Collection<PathObject> getObjectsForLocation(PathObjectHierarchy hierarchy, double x, double y, int zPos, int tPos, double vertexDistance)
      Get a collection of objects that overlap a specified pixel location.

      For area ROIs, this means the ROI should contain the pixel. For non-area ROIs an optional vertex distance can be used to define a distance tolerance to the nearest vertex or line segment.

      Parameters:
      hierarchy - object hierarchy within which to find the object
      x - x-coordinate of the pixel
      y - y-coordinate of the pixel
      zPos - z-slice number
      tPos - time-point number
      vertexDistance - for non-area ROIs, the distance from the closest vertex or line segment (or < 0 to ignore non-area ROIs).
      Returns:
    • getAncestorList

      public static List<PathObject> getAncestorList(PathObject pathObject)
      Return a list of object ancestors, starting from the root object and ending with PathObject (assuming that the object is part of a hierarchy with a root).
      Parameters:
      pathObject -
      Returns:
    • swapNameAndClass

      public static void swapNameAndClass(PathObject pathObject, boolean includeColor)
      Swap the name and PathClass of an object. This can be used as a simple way to preserve a classification that might be required later.
      Parameters:
      pathObject - the object to adjust
      includeColor - optionally set the color of the object to the color of the classification
    • parseTMALabelString

      public static String[] parseTMALabelString(String labelString)
      Parse a string input representing potential TMA core labels. This can be a space-separated list, or an ascending or descending numeric or alphabetic range.

      Examples:

      • "A-H"
      • "1-9"
      • "H-A"
      • "A B D E"
      Parameters:
      labelString -
      Returns:
    • getSupportedObjects

      public static Collection<? extends PathObject> getSupportedObjects(Collection<? extends PathObject> availableObjects, Collection<Class<? extends PathObject>> supportedClasses)
      From a collection of available objects, extract those that are instances of specified supported classes.
      Parameters:
      availableObjects -
      supportedClasses -
      Returns:
    • getROI

      public static ROI getROI(PathObject pathObject, boolean preferNucleus)
      Get the ROI for a PathObject, with a preference for the nucleus ROI of a cell.
      Parameters:
      pathObject -
      preferNucleus -
      Returns:
    • getNucleusOrMainROI

      public static ROI getNucleusOrMainROI(PathObject pathObject)
      Get the nucleus ROI for a cell, or the main ROI if no nucleus is found. This is equivalent to getROI(pathObject, true), but avoids the mysterious boolean flag to make code more readable.
      Parameters:
      pathObject -
      Returns:
      Since:
      v0.5.0
      See Also:
    • getNucleusROI

      public static ROI getNucleusROI(PathObject pathObject)
      Get the nucleus ROI for a cell, or null if the input is not a cell or no nucleus is found.
      Parameters:
      pathObject -
      Returns:
      Since:
      v0.5.0
      See Also:
    • getDescendantObjects

      public static Collection<PathObject> getDescendantObjects(PathObject pathObject, Collection<PathObject> pathObjects, Class<? extends PathObject> cls)
      Get all descendant objects with a specified type.
      Parameters:
      pathObject -
      pathObjects -
      cls -
      Returns:
    • splitAreasByLines

      public static Map<PathObject,List<PathObject>> splitAreasByLines(Collection<? extends PathObject> pathObjects)
      Given a collection of objects, split the objects with area ROIs using dividing lines extracted from the objects with line ROIs.
      Parameters:
      pathObjects - an input collection of objects, containing objects with different ROI types
      Returns:
      a map containing the original area objects as keys, and the split objects as values. This only contains entries for objects that are split; if no objects are split, an empty map is returned.
      Since:
      v0.5.0
      See Also:
    • splitAreasByLines

      public static Map<PathObject,List<PathObject>> splitAreasByLines(Collection<? extends PathObject> areaObjects, Collection<? extends PathObject> lineObjects)
      Given a collection of objects with area ROIs, split these using dividing lines extracted from objects with line ROIs.
      Parameters:
      areaObjects - objects with area ROIs; non-area ROIs will be ignored
      lineObjects - objects with line ROIs; area ROIs can still be used, but will be treated as lines
      Returns:
      a map containing the original area objects as keys, and the split objects as values. This only contains entries for objects that are split; if no objects are split, an empty map is returned.
      Since:
      v0.5.0
      See Also:
    • splitAreasByBufferedLines

      public static Map<PathObject,List<PathObject>> splitAreasByBufferedLines(Collection<? extends PathObject> pathObjects, double buffer)
      Given a collection of objects, split the objects with area ROIs using dividing lines extracted from the objects with line ROIs, after 'buffering' the lines to increase their thickness.
      Parameters:
      pathObjects - an input collection of objects, containing objects with different ROI types
      buffer - the distance by which to buffer the lines (can be considered a radius). If 0, this is equivalent to #splitAreasByLines(Collection)
      Returns:
      a map containing the original area objects as keys, and the split objects as values. This only contains entries for objects that are split; if no objects are split, an empty map is returned.
      Since:
      v0.5.0
      See Also:
    • splitAreasByBufferedLines

      public static Map<PathObject,List<PathObject>> splitAreasByBufferedLines(Collection<? extends PathObject> areaObjects, Collection<? extends PathObject> lineObjects, double buffer)
      Split the objects with area ROIs using dividing lines extracted from the objects with line ROIs, after 'buffering' the lines to increase their thickness.
      Parameters:
      areaObjects - objects with area ROIs; non-area ROIs will be ignored
      lineObjects - objects with line ROIs; non-line ROIs will be ignored
      buffer - the distance by which to buffer the lines (can be considered a radius). If 0, this is equivalent to #splitAreasByLines(Collection)
      Returns:
      a map containing the original area objects as keys, and the split objects as values. This only contains entries for objects that are split; if no objects are split, an empty map is returned.
      Since:
      v0.5.0
      See Also:
    • mergePointsForSelectedObjectClasses

      public static boolean mergePointsForSelectedObjectClasses(PathObjectHierarchy hierarchy)
      Merge point annotations sharing the same PathClass and ImagePlane as the selected annotations, creating multi-point annotations for all matching points and removing the (previously-separated) annotations.
      Parameters:
      hierarchy - object hierarchy to modify
      Returns:
      true if changes are made to the hierarchy, false otherwise
    • mergePointsForAllClasses

      public static boolean mergePointsForAllClasses(PathObjectHierarchy hierarchy)
      Merge point annotations sharing the same PathClass and ImagePlane, creating multi-point annotations for all matching points and removing the (previously-separated) annotations.
      Parameters:
      hierarchy - object hierarchy to modify
      Returns:
      true if changes are made to the hierarchy, false otherwise
    • mergePointsForClass

      public static boolean mergePointsForClass(PathObjectHierarchy hierarchy, PathClass pathClass)
      Merge point annotations with the specified PathClass sharing the same ImagePlane, creating a single multi-point annotation for all matching points and removing the (previously-separated) annotations.
      Parameters:
      hierarchy - object hierarchy to modify
      pathClass - classification for annotations to merge
      Returns:
      true if changes are made to the hierarchy, false otherwise
      See Also:
    • standardizeClassifications

      public static boolean standardizeClassifications(Collection<PathObject> pathObjects)
      Standardize the classifications for a collection of objects. This involves sorting the names of derived classes alphabetically, and removing duplicates.
      Parameters:
      pathObjects - collection of objects with classifications that should be standardized
      Returns:
      true if changes were made, false otherwise
    • standardizeClassifications

      public static boolean standardizeClassifications(Collection<PathObject> pathObjects, Comparator<String> comparator)
      Standardize the classifications for a collection of objects. This involves sorting the names of derived classes, and removing duplicates.
      Parameters:
      pathObjects - collection of objects with classifications that should be standardized
      comparator - comparator to use when sorting
      Returns:
      true if changes were made, false otherwise
    • transformObject

      public static PathObject transformObject(PathObject pathObject, AffineTransform transform, boolean copyMeasurements)
      Create a transformed version of a PathObject with a new ID. If the transform is null or the identity transform, then a duplicate object is generated instead.

      Note: only detections (including tiles and cells) and annotations are fully supported by this method. Root objects are duplicated. TMA core objects are transformed only if the resulting transform creates an ellipse ROI, since this is currently the only ROI type supported for a TMA core (this behavior may change). Any other object types result in an UnsupportedOperationException being thrown.

      Parameters:
      pathObject - the object to transform; this will be unchanged
      transform - optional affine transform; if null, this effectively acts to duplicate the object
      copyMeasurements - if true, the measurement list of the new object will be populated with the measurements of pathObject
      Returns:
      a duplicate of pathObject, with affine transform applied to the object's ROI(s) if required
      See Also:
    • transformObject

      public static PathObject transformObject(PathObject pathObject, AffineTransform transform, boolean copyMeasurements, boolean createNewIDs)
      Create a transformed version of a PathObject, optionally with a new ID. If the transform is null or the identity transform, then a duplicate object is generated instead.

      Note: only detections (including tiles and cells), annotations and root objects are fully supported by this method. TMA core objects are transformed only if the resulting transform creates an ellipse ROI, since this is currently the only ROI type supported for a TMA core (this behavior may change). Any other object types result in an UnsupportedOperationException being thrown.

      Parameters:
      pathObject - the object to transform; this will be unchanged
      transform - optional affine transform; if null, this effectively acts to duplicate the object
      copyMeasurements - if true, the measurements and metadata maps of the new object will be populated with those from the pathObject
      createNewIDs - if true, create new IDs for each copied object; otherwise, retain the same ID.
      Returns:
      a duplicate of pathObject, with affine transform applied to the object's ROI(s) if required
      Since:
      v0.4.0
    • transformObjectRecursive

      public static PathObject transformObjectRecursive(PathObject pathObject, AffineTransform transform, boolean copyMeasurements)
      Create (optionally) transformed versions of the PathObject and all its descendants, recursively. This method can be applied to all objects in a hierarchy by supplying its root object. The parent-children relationships are kept after transformation. Measurements are copied to the new object, and new IDs are created.
      Parameters:
      pathObject - the object to transform; this will be unchanged
      transform - optional affine transform; if null, this effectively acts to duplicate the object
      copyMeasurements - if true, the measurement list of the new object will be populated with the measurements of pathObject
      Returns:
      the new object, including all child objects
    • transformObjectRecursive

      public static PathObject transformObjectRecursive(PathObject pathObject, AffineTransform transform, boolean copyMeasurements, boolean createNewIDs)
      Create (optionally) transformed versions of the PathObject and all its descendants, recursively, optionally assigning new IDs to the created objects. This method can be applied to all objects in a hierarchy by supplying its root object. The parent-children relationships are kept after transformation.
      Parameters:
      pathObject - the object to transform; this will be unchanged
      transform - optional affine transform; if null, this effectively acts to duplicate the object
      copyMeasurements - if true, the measurement list of the new object will be populated with the measurements of pathObject
      createNewIDs - if true, create new IDs for each copied object; otherwise, retain the same ID.
      Returns:
      the new object, including all child objects
      Since:
      v0.4.0
    • findByStringID

      public static Map<String,PathObject> findByStringID(Collection<String> ids, Collection<? extends PathObject> pathObjects)
      Find objects based on a String representation of their IDs.
      Parameters:
      ids - IDs to match; each will correspond to a key in the output map
      pathObjects - the objects that may contain corresponding IDs
      Returns:
      a map between ids and any matched objects (or null if no matched object was found)
      Since:
      v0.4.0
      See Also:
    • findByUUID

      public static Map<UUID,PathObject> findByUUID(Collection<UUID> ids, Collection<? extends PathObject> pathObjects)
      Find objects based on their IDs.
      Parameters:
      ids - IDs to match; each will correspond to a key in the output map
      pathObjects - the objects that may contain corresponding IDs
      Returns:
      a map between ids and any matched objects (or null if no matched object was found)
      Since:
      v0.4.0
      See Also:
    • matchByID

      public static Map<PathObject,PathObject> matchByID(Collection<? extends PathObject> sourceObjects, Collection<? extends PathObject> targetObjects)
      Match objects according to their IDs.
      Parameters:
      sourceObjects - source objects; each will correspond to a key in the output map
      targetObjects - target objects; each will correspond to a value in the output map provided it has a match in sourceObjects
      Returns:
      a map between sourceObjects and any matched target objects (or null if no matched object was found)
      Since:
      v0.4.0
      See Also:
    • duplicateAllSelectedObjects

      public static boolean duplicateAllSelectedObjects(PathObjectHierarchy hierarchy)
      Duplicate all the selected objects in a hierarchy.
      Parameters:
      hierarchy - the hierarchy containing the objects to duplicate
      Returns:
      true if the hierarchy is changed, false otherwise
    • duplicateSelectedAnnotations

      public static boolean duplicateSelectedAnnotations(PathObjectHierarchy hierarchy)
      Duplicate the selected annotation objects. Selected objects that are not annotations will be ignored.
      Parameters:
      hierarchy - the hierarchy containing the objects to duplicate
      Returns:
      true if the hierarchy is changed, false otherwise
    • duplicateSelectedObjects

      public static boolean duplicateSelectedObjects(PathObjectHierarchy hierarchy, Predicate<PathObject> predicate)
      Duplicate the selected objects
      Parameters:
      hierarchy - the hierarchy containing the objects to duplicate
      predicate - optional predicate (may be null) used to filter out invalid selected options that should not be duplicated
      Returns:
      true if the hierarchy is changed, false otherwise
    • duplicateObjects

      public static boolean duplicateObjects(PathObjectHierarchy hierarchy, Collection<PathObject> pathObjects)
      Duplicate the specified objects, assigning new IDs for each object.
      Parameters:
      hierarchy - hierarchy containing the objects to duplicate
      pathObjects - objects that should be duplicated
      Returns:
      true if the hierarchy is changed, false otherwise
      See Also:
    • duplicateObjects

      public static boolean duplicateObjects(PathObjectHierarchy hierarchy, Collection<PathObject> pathObjects, boolean createNewIDs)
      Duplicate the specified objects, optionally creating new IDs.
      Parameters:
      hierarchy - hierarchy containing the objects to duplicate
      pathObjects - objects that should be duplicated
      createNewIDs - if true, create new IDs for each copied object; otherwise, retain the same ID.
      Returns:
      true if the hierarchy is changed, false otherwise
      Since:
      v0.4.0
    • removeOverlapsBySize

      public static Collection<PathObject> removeOverlapsBySize(Collection<? extends PathObject> pathObjects, double overlapTolerance)
      Resolve overlapping objects by size, retaining the object with the larger ROI and discarding the object with the smaller ROI.
      Parameters:
      pathObjects - input object collection, which may contain overlapping objects
      overlapTolerance - amount of overlap to permit; recommended value is 0, see removeOverlaps(Collection, Comparator, double)
      Returns:
      output collection of objects, which should have smaller overlapping objects removed
    • removeOverlapsByLocation

      public static Collection<PathObject> removeOverlapsByLocation(Collection<? extends PathObject> pathObjects, double overlapTolerance)
      Resolve overlapping object by location, retaining the object closest to the image 'origin' and discarding the object further away. Note that this is determined using first the bounding box, then the centroid. This is a simpler (and faster) criterion than measuring distance to the original from the ROI itself.
      Parameters:
      pathObjects - input object collection, which may contain overlapping objects
      overlapTolerance - amount of overlap to permit; recommended value is 0, see removeOverlaps(Collection, Comparator, double)
      Returns:
      output collection of objects, which should have smaller overlapping objects removed
    • removeOverlaps

      public static Collection<PathObject> removeOverlaps(Collection<? extends PathObject> pathObjects, Comparator<PathObject> comparator, double overlapTolerance)
      Resolve overlaps, discarding one and keeping the other. It assumes that the objects have been sorted so that 'preferred' objects occur first.

      'How overlapping' can be controlled by the overlapTolerance, where an overlap will be removed

      • if overlapTolerance > 0 and the area of the intersection between ROIs is < overlapTolerance (an absolute comparison)
      • if overlapTolerance < 0 and the proportion of the smaller ROI intersecting the larger ROI is < -overlapTolerance (a relative comparison)
      • if overlapTolerance == 0 and there is any non-zero area intersection between ROIs
      For example, overlapTolerance == 10 will require at least 10 pixels between ROIs to intersect to be considered an overlap, while overlapTolerance == 0.01 will require at least 1% of the area of the smaller ROI to intersect.

      It is recommended to keep overlapTolerance == 0 in most instances to remove all overlaps. This is also less computationally expensive because it means intersection areas do not need to be calculated.

      Parameters:
      pathObjects - input object collection, which may contain overlapping objects
      comparator - comparator, which determines which object is retained when overlaps are found. Considering the collection to be sorted by the comparator, the 'first' object is the one that will be kept.
      overlapTolerance - amount of overlap to permit
      Returns:
      collection of objects, which should have smaller overlapping objects removed
    • mergeObjects

      public static PathObject mergeObjects(Collection<? extends PathObject> pathObjects)
      Merge objects by calculating the union of their ROIs.
      Parameters:
      pathObjects - a collection of annotations, cells, detections or tiles. Note that all objects must be of the same type.
      Returns:
      a single object with ROI(s) determined by union. The classification and name will be taken from the first ROI in the collection.
      Throws:
      IllegalArgumentException - if no objects are provided (either null or empty list)
    • mergeObjects

      public static <K> List<PathObject> mergeObjects(Collection<? extends PathObject> pathObjects, Function<? super PathObject,? extends K> classifier)
      Merge objects that share a property in common.

      Note that objects must all be of the same type (e.g. cells, detections, annotations).

      Parameters:
      pathObjects -
      classifier - function extracting the shared property, e.g. p -> p.getName()
      Returns:
      a new list of objects generated by merging grouped objects.
      See Also:
    • createLike

      public static PathObject createLike(PathObject pathObject, ROI roiNew)
      Create a new object with the same type and classification as the input object, but a new ROI and ID.

      Note that TMA core objects are not supported.

      Parameters:
      pathObject - the template object
      roiNew - the new ROI
      Returns:
      a new object with the same type and classification as the input object, but different ROI and ID.
      Since:
      v0.5.0
    • createLike

      public static PathObject createLike(PathObject pathObject, ROI roiNew, ROI roiNucleus)
      Create a new object with the same type and classification as the input object, but a new ROI and ID. This version of the method supports cell objects with a nucleus ROI.

      Note that TMA core objects are not supported.

      Parameters:
      pathObject - the template object
      roiNew - the new ROI
      roiNucleus - nucleus ROI; only relevant if the template object is a cell
      Returns:
      a new object with the same type and classification as the input object, but different ROI and ID.
      Since:
      v0.5.0
    • lockObjects

      public static void lockObjects(PathObjectHierarchy hierarchy, Collection<? extends PathObject> pathObjects)
      Set specified objects to be 'locked'.
      Parameters:
      hierarchy - if not null, fire an update event if the locked status for any object is changed
      pathObjects - the objects to update
    • unlockObjects

      public static void unlockObjects(PathObjectHierarchy hierarchy, Collection<? extends PathObject> pathObjects)
      Set specified objects to be 'unlocked'.
      Parameters:
      hierarchy - if not null, fire an update event if the locked status for any object is changed
      pathObjects - the objects to update
    • lockSelectedObjects

      public static void lockSelectedObjects(PathObjectHierarchy hierarchy)
      Set selected objects to be 'locked', firing an update event if the status of any object is changed.
      Parameters:
      hierarchy -
    • unlockSelectedObjects

      public static void unlockSelectedObjects(PathObjectHierarchy hierarchy)
      Set selected objects to be 'unlocked', firing an update event if the status of any object is changed.
      Parameters:
      hierarchy -
    • toggleSelectedObjectsLocked

      public static void toggleSelectedObjectsLocked(PathObjectHierarchy hierarchy)
      Toggle the 'locked' status of selected objects, firing an update event if the status of any object is changed.
      Parameters:
      hierarchy -
    • toggleObjectsLocked

      public static void toggleObjectsLocked(PathObjectHierarchy hierarchy, Collection<? extends PathObject> pathObjects)
      Toggle the 'locked' status of specified objects.
      Parameters:
      hierarchy - if not null, fire an update event if the locked status for any object is changed
      pathObjects - the objects to update
    • getAvailableFeatures

      public static Set<String> getAvailableFeatures(Collection<? extends PathObject> pathObjects)
      Get a set containing the names of all measurements found in the measurement lists of a specified object collection.
      Parameters:
      pathObjects -
      Returns:
    • createClassificationMap

      public static Map<PathObject,PathClass> createClassificationMap(Collection<? extends PathObject> pathObjects)
      Create a mapping between PathObjects and their current PathClasses. This can be useful to preserve a classification so that it may be reset later.

      Note: classification probabilities are not retained using this approach.

      Parameters:
      pathObjects - the objects containing classifications
      Returns:
      a mapping between objects and their current classifications
      See Also:
    • restoreClassificationsFromMap

      public static Collection<PathObject> restoreClassificationsFromMap(Map<PathObject,PathClass> classificationMap)
      Reassign classifications to objects, as were previously obtained using createClassificationMap(Collection).
      Parameters:
      classificationMap - the map containing objects and the classifications that should be applied
      Returns:
      a collection containing all objects with classifications that were changed. This can be used to fire update events.
      See Also:
    • getRepresentedPathClasses

      public static Set<PathClass> getRepresentedPathClasses(PathObjectHierarchy hierarchy, Class<? extends PathObject> cls)
      Get a set of the represented path classes, i.e. those with at least 1 manually-labelled object.
      Parameters:
      hierarchy -
      cls -
      Returns:
    • setIntensityClassification

      public static PathClass setIntensityClassification(PathObject pathObject, String measurementName, double... thresholds)
      Assign cell classifications as positive or negative based upon a specified measurement, using up to 3 intensity bins. An IllegalArgumentException is thrown if < 1 or > 3 intensity thresholds are provided.

      If the object does not have the required measurement, its PathClass will be set to its first 'non-intensity' ancestor PathClass.

      Note that as of v0.3.0, all ignored classes (see PathClassTools.isIgnoredClass(PathClass) are ignored and therefore will not be 'intensity classified'.

      Parameters:
      pathObject - the object to classify.
      measurementName - the name of the measurement to use for thresholding.
      thresholds - between 1 and 3 intensity thresholds, used to indicate negative/positive, or negative/1+/2+/3+
      Returns:
      the PathClass of the object after running this method.
    • setIntensityClassifications

      public static void setIntensityClassifications(Collection<? extends PathObject> pathObjects, String measurementName, double... thresholds)
      Set the intensity classifications for the specified objects.
      Parameters:
      pathObjects -
      measurementName - measurement to threshold
      thresholds - either 1 or 3 thresholds, depending upon whether objects should be classified as Positive/Negative or Negative/1+/2+/3+