Skip to content

Creating classifications and checking equality could be confusing #45

@petebankhead

Description

@petebankhead

When looking at #44 I noticed that the behavior of Classification is different from what I’d expect.

In QuPath, PathClass should be a singleton and so you need to get it from PathClass.fromString(String) or similar. QuPath’s PathClass has a private constructor and tries to make it very hard to use accidentally (e.g. from Groovy).

Here, Classification.get_cached_classification() has that role - but if I’m reading it right, it’s still very possible to use the constructor. Additionally, there isn’t a check to make sure that names really is a tuple.

def __init__(
        self,
        names: Union[str, tuple[str]],
        color: Optional[tuple[int, int, int]] = None,
    ):
        """
        :param names: the names of the classification
        :param color: the RGB color (each component between 0 and 255) of the classification. Can be None to use a random color
        """
        if isinstance(names, str):
            names = (names,)
        self._names = names
        self._color = (
            tuple(random.randint(0, 255) for _ in range(3)) if color is None else color
        )

Also, the equality test is currently

def __eq__(self, other):
        if isinstance(other, Classification):
            return self.name == other.name and self.color == other.color
        return False

If Classification is used properly, then I think an is test should come first for efficiency: we’d expect the same classification to be the same object, and we don’t want the overhead of string joining every time (although that could be mitigated if we cached the joined string as well).

But also, this seems to suggest that a classification of (for example) Tumor might differ from another classification of Tumor if they have different colors. This shouldn’t be possible in QuPath, because the constructor can’t be used - but if it were possible, the color shouldn’t matter for equality tests.

Ultimately, the behavior aims to make sure that each classification can only have one color. When requesting a classification, the user might specify a color - but that is only used if a classification with the same name doesn’t already exist. If it does exist, then the existing classification should always be returned.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions