Skip to content

config

sleap.qc.config

Configuration for Label QC detector.

Classes:

Name Description
QCConfig

Configuration for QC detector.

QCConfig dataclass

Configuration for QC detector.

Attributes:

Name Type Description
use_gmm bool

Whether to use GMM-based anomaly detection.

use_curvature Literal['auto'] | bool

Whether to compute curvature features. If "auto", enables when skeleton has chains >= 5 nodes.

use_symmetry Literal['auto'] | bool

Whether to compute symmetry features. If "auto", enables when skeleton has symmetry pairs defined.

use_anatomical bool

Whether to compute anatomical features (signed angles).

use_chirality Literal['auto'] | bool

Whether to compute the whole-instance left/right mirror-flip (chirality) feature. If "auto", enables when the skeleton has symmetry pairs (defined or inferred by name). Reliable detector, default-ON.

use_split_detection bool

Whether to compute the pose-split (chimera) feature that flags a single instance spanning two animals. Reliable detector, default-ON.

use_duplicate_score bool

Whether to fold the complementary split-duplicate signal into frame-level duplicate detection. Reliable detector, default-ON.

use_chain_ordering Literal['auto'] | bool

Whether to compute the keypoint chain-ordering feature (wrong order along an ordered chain). If "auto", enables when the longest chain has >= 4 nodes. Experimental, default-OFF.

use_missing_node_check bool

Whether to run the missing-node check (a node a instance's peers usually keep is absent). Experimental, default-OFF.

use_appearance bool

Whether to run the appearance-outlier channel (a node placed on visually-wrong pixels, e.g. on bedding instead of fur). Needs decoded image frames; scored outside the GMM as the "appearance" channel. Experimental, default-OFF.

appearance_patch_size int

Side length (pixels) of the square image patch cut around each node for the appearance descriptor.

appearance_min_samples int

Minimum number of patch samples a node needs at fit time before the appearance model has an opinion on it.

use_insample_prediction bool

Whether to run the in-sample model-prediction channel (Tier-2 missing-node): run a trained sleap-nn model on the labeled frames and flag unlabeled nodes the model confidently localizes. Scored outside the GMM as the "prediction" channel. EXPENSIVE (full model inference). Experimental, default-OFF.

insample_model_path str

Path to a trained sleap-nn model directory for the in-sample prediction channel. Empty disables the channel (no-op).

insample_peak_threshold float

Peak-finding confidence threshold passed to the in-sample model inference (lower = more candidate peaks).

insample_min_confidence float

Confidence at/above which a model prediction at an unlabeled node counts as a disagreement (gates the channel score).

insample_device str

Torch device for the in-sample inference ("auto"/"cpu"/"cuda"/"mps").

instance_threshold float

Threshold for flagging instances (0-1). Higher = fewer flags, lower = more flags.

frame_threshold float

Threshold for frame-level checks.

duplicate_iou_threshold float

IOU threshold for duplicate detection.

duplicate_node_overlap_ratio float

Node overlap ratio for partial duplicates.

chirality_flip_threshold float

chirality_wrong_fraction at/above which an instance is force-flagged as a whole-instance L/R flip.

duplicate_score_threshold float

Combined duplicate-score at/above which a pair is flagged as a duplicate at the frame level.

chain_turn_angle_deg float

Per-interior-node turning angle (degrees) above which a chain node counts as an ordering inversion.

order_inversion_threshold float

order_inversion_rate at/above which an instance is force-flagged as having wrong keypoint order.

missing_node_prob_threshold float

Minimum expected-visibility probability for a missing node to be flagged as suspicious.

ordered_chains list

User-defined ordered chains as lists of node names (ground truth ordering for the chain-ordering detector). Empty = fall back to auto-detected skeleton chains.

gmm_n_components int

Number of GMM components.

gmm_min_samples int

Minimum samples required for GMM fitting. Below this, falls back to z-score thresholding.

gmm_percentile_threshold float

Percentile below which instances are anomalies.

auto_calibrate bool

Whether to auto-calibrate threshold from data.

calibration_percentile float

Percentile for auto-calibration.

Methods:

Name Description
should_use_chain_ordering

Determine if the chain-ordering feature should be used.

should_use_chirality

Determine if the chirality (L/R mirror-flip) feature should be used.

should_use_curvature

Determine if curvature features should be used.

should_use_symmetry

Determine if symmetry features should be used.

Source code in sleap/qc/config.py
@dataclass
class QCConfig:
    """Configuration for QC detector.

    Attributes:
        use_gmm: Whether to use GMM-based anomaly detection.
        use_curvature: Whether to compute curvature features.
            If "auto", enables when skeleton has chains >= 5 nodes.
        use_symmetry: Whether to compute symmetry features.
            If "auto", enables when skeleton has symmetry pairs defined.
        use_anatomical: Whether to compute anatomical features (signed angles).
        use_chirality: Whether to compute the whole-instance left/right
            mirror-flip (chirality) feature. If "auto", enables when the
            skeleton has symmetry pairs (defined or inferred by name). Reliable
            detector, default-ON.
        use_split_detection: Whether to compute the pose-split (chimera) feature
            that flags a single instance spanning two animals. Reliable
            detector, default-ON.
        use_duplicate_score: Whether to fold the complementary split-duplicate
            signal into frame-level duplicate detection. Reliable detector,
            default-ON.
        use_chain_ordering: Whether to compute the keypoint chain-ordering
            feature (wrong order along an ordered chain). If "auto", enables
            when the longest chain has >= 4 nodes. Experimental, default-OFF.
        use_missing_node_check: Whether to run the missing-node check (a node a
            instance's peers usually keep is absent). Experimental, default-OFF.
        use_appearance: Whether to run the appearance-outlier channel (a node
            placed on visually-wrong pixels, e.g. on bedding instead of fur).
            Needs decoded image frames; scored outside the GMM as the
            ``"appearance"`` channel. Experimental, default-OFF.
        appearance_patch_size: Side length (pixels) of the square image patch
            cut around each node for the appearance descriptor.
        appearance_min_samples: Minimum number of patch samples a node needs at
            fit time before the appearance model has an opinion on it.
        use_insample_prediction: Whether to run the in-sample model-prediction
            channel (Tier-2 missing-node): run a trained sleap-nn model on the
            labeled frames and flag unlabeled nodes the model confidently
            localizes. Scored outside the GMM as the ``"prediction"`` channel.
            EXPENSIVE (full model inference). Experimental, default-OFF.
        insample_model_path: Path to a trained sleap-nn model directory for the
            in-sample prediction channel. Empty disables the channel (no-op).
        insample_peak_threshold: Peak-finding confidence threshold passed to the
            in-sample model inference (lower = more candidate peaks).
        insample_min_confidence: Confidence at/above which a model prediction at
            an unlabeled node counts as a disagreement (gates the channel score).
        insample_device: Torch device for the in-sample inference
            (``"auto"``/``"cpu"``/``"cuda"``/``"mps"``).
        instance_threshold: Threshold for flagging instances (0-1).
            Higher = fewer flags, lower = more flags.
        frame_threshold: Threshold for frame-level checks.
        duplicate_iou_threshold: IOU threshold for duplicate detection.
        duplicate_node_overlap_ratio: Node overlap ratio for partial duplicates.
        chirality_flip_threshold: ``chirality_wrong_fraction`` at/above which an
            instance is force-flagged as a whole-instance L/R flip.
        duplicate_score_threshold: Combined duplicate-score at/above which a
            pair is flagged as a duplicate at the frame level.
        chain_turn_angle_deg: Per-interior-node turning angle (degrees) above
            which a chain node counts as an ordering inversion.
        order_inversion_threshold: ``order_inversion_rate`` at/above which an
            instance is force-flagged as having wrong keypoint order.
        missing_node_prob_threshold: Minimum expected-visibility probability for
            a missing node to be flagged as suspicious.
        ordered_chains: User-defined ordered chains as lists of node *names*
            (ground truth ordering for the chain-ordering detector). Empty =
            fall back to auto-detected skeleton chains.
        gmm_n_components: Number of GMM components.
        gmm_min_samples: Minimum samples required for GMM fitting.
            Below this, falls back to z-score thresholding.
        gmm_percentile_threshold: Percentile below which instances are anomalies.
        auto_calibrate: Whether to auto-calibrate threshold from data.
        calibration_percentile: Percentile for auto-calibration.
    """

    # Feature selection
    use_gmm: bool = True
    use_curvature: Literal["auto"] | bool = "auto"
    use_symmetry: Literal["auto"] | bool = "auto"
    use_anatomical: bool = False
    # New detectors: reliable ones default-ON, experimental ones default-OFF.
    use_chirality: Literal["auto"] | bool = "auto"  # (c)
    use_split_detection: bool = True  # (d)
    use_duplicate_score: bool = True  # (a)
    use_chain_ordering: Literal["auto"] | bool = False  # (b) experimental
    use_missing_node_check: bool = False  # (f, Tier-1) experimental
    # B2 non-GMM channels (default-OFF / experimental).
    use_appearance: bool = False  # (e) appearance outlier / wrong-object
    use_insample_prediction: bool = False  # (f, Tier-2) in-sample model prediction

    # Thresholds (validated in v4 investigation)
    instance_threshold: float = 0.7  # Default: balanced
    frame_threshold: float = 0.5
    duplicate_iou_threshold: float = 0.5
    duplicate_node_overlap_ratio: float = 0.8
    duplicate_node_distance_threshold: float = 10.0

    # New-detector thresholds.
    chirality_flip_threshold: float = 0.5
    duplicate_score_threshold: float = 0.5
    chain_turn_angle_deg: float = 60.0
    order_inversion_threshold: float = 0.3
    missing_node_prob_threshold: float = 0.9

    # B2 appearance-outlier channel settings.
    appearance_patch_size: int = 7
    appearance_min_samples: int = 20

    # B2 in-sample model-prediction channel settings.
    insample_model_path: str = ""
    insample_peak_threshold: float = 0.2
    insample_min_confidence: float = 0.5
    insample_device: str = "auto"

    # User-defined ordered chains (lists of node NAMES) for chain-ordering.
    ordered_chains: list = field(default_factory=list)

    # GMM settings
    gmm_n_components: int = 5
    gmm_min_samples: int = 50
    gmm_percentile_threshold: float = 5.0

    # Calibration (reserved: NOT consumed anywhere yet — no auto-calibration is
    # implemented. Flagging uses the fixed instance_threshold / GUI slider value.)
    auto_calibrate: bool = True
    calibration_percentile: float = 95.0

    def should_use_curvature(self, max_chain_length: int) -> bool:
        """Determine if curvature features should be used."""
        if isinstance(self.use_curvature, bool):
            return self.use_curvature
        # Auto mode: enable for chains >= 5 nodes
        return max_chain_length >= 5

    def should_use_symmetry(self, has_symmetry: bool) -> bool:
        """Determine if symmetry features should be used."""
        if isinstance(self.use_symmetry, bool):
            return self.use_symmetry
        # Auto mode: enable if skeleton has symmetry pairs
        return has_symmetry

    def should_use_chirality(self, has_symmetry: bool) -> bool:
        """Determine if the chirality (L/R mirror-flip) feature should be used."""
        if isinstance(self.use_chirality, bool):
            return self.use_chirality
        # Auto mode: enable if skeleton has symmetry pairs (defined or inferred).
        return has_symmetry

    def should_use_chain_ordering(self, max_chain_length: int) -> bool:
        """Determine if the chain-ordering feature should be used."""
        if isinstance(self.use_chain_ordering, bool):
            return self.use_chain_ordering
        # Auto mode: enable for chains >= 4 nodes (need an interior turning angle).
        return max_chain_length >= 4

should_use_chain_ordering(max_chain_length)

Determine if the chain-ordering feature should be used.

Source code in sleap/qc/config.py
def should_use_chain_ordering(self, max_chain_length: int) -> bool:
    """Determine if the chain-ordering feature should be used."""
    if isinstance(self.use_chain_ordering, bool):
        return self.use_chain_ordering
    # Auto mode: enable for chains >= 4 nodes (need an interior turning angle).
    return max_chain_length >= 4

should_use_chirality(has_symmetry)

Determine if the chirality (L/R mirror-flip) feature should be used.

Source code in sleap/qc/config.py
def should_use_chirality(self, has_symmetry: bool) -> bool:
    """Determine if the chirality (L/R mirror-flip) feature should be used."""
    if isinstance(self.use_chirality, bool):
        return self.use_chirality
    # Auto mode: enable if skeleton has symmetry pairs (defined or inferred).
    return has_symmetry

should_use_curvature(max_chain_length)

Determine if curvature features should be used.

Source code in sleap/qc/config.py
def should_use_curvature(self, max_chain_length: int) -> bool:
    """Determine if curvature features should be used."""
    if isinstance(self.use_curvature, bool):
        return self.use_curvature
    # Auto mode: enable for chains >= 5 nodes
    return max_chain_length >= 5

should_use_symmetry(has_symmetry)

Determine if symmetry features should be used.

Source code in sleap/qc/config.py
def should_use_symmetry(self, has_symmetry: bool) -> bool:
    """Determine if symmetry features should be used."""
    if isinstance(self.use_symmetry, bool):
        return self.use_symmetry
    # Auto mode: enable if skeleton has symmetry pairs
    return has_symmetry