Source code for stonesoup.types.multihypothesis

# -*- coding: utf-8 -*-
from collections.abc import Sized, Iterable, Container
from typing import Sequence

from ..base import Property
from ..types import Type
from ..types.detection import Detection
from ..types.hypothesis import SingleHypothesis
from ..types.prediction import Prediction
from .numeric import Probability
from .detection import MissedDetection


[docs]class MultipleHypothesis(Type, Sized, Iterable, Container): """Multiple Hypothesis base type A Multiple Hypothesis is a container to store a collection of hypotheses. """ single_hypotheses: Sequence[SingleHypothesis] = Property( default=None, doc="The initial list of :class:`~.SingleHypothesis`. Default `None` " "which initialises with empty list.") normalise: bool = Property( default=False, doc="Normalise probabilities of :class:`~.SingleHypothesis`. Default " "is `False`.") total_weight: float = Property( default=1, doc="When normalising, weights will sum to this. Default is 1.") def __init__(self, single_hypotheses=None, normalise=False, *args, **kwargs): if single_hypotheses is None: single_hypotheses = [] if any(not isinstance(hypothesis, SingleHypothesis) for hypothesis in single_hypotheses): raise ValueError("Cannot form MultipleHypothesis out of " "non-SingleHypothesis inputs!") super().__init__(single_hypotheses, normalise, *args, **kwargs) # normalise the weights of 'single_hypotheses', if indicated if self.normalise: self.normalise_probabilities() def __len__(self): return self.single_hypotheses.__len__() def __contains__(self, index): # check if 'single_hypotheses' contains any SingleHypotheses with # Detection matching 'index' if isinstance(index, Detection): for hypothesis in self.single_hypotheses: if hypothesis.measurement is index: return True return False # check if 'single_hypotheses' contains any SingleHypotheses with # Prediction matching 'index' if isinstance(index, Prediction): for hypothesis in self.single_hypotheses: if hypothesis.prediction is index: return True return False # check if 'single_hypotheses' contains any SingleHypotheses # matching 'index' if isinstance(index, SingleHypothesis): return index in self.single_hypotheses def __iter__(self): for hypothesis in self.single_hypotheses: yield hypothesis def __getitem__(self, index): # retrieve SingleHypothesis by array index if isinstance(index, int): return self.single_hypotheses[index] # retrieve SingleHypothesis by measurement if isinstance(index, Detection): for hypothesis in self.single_hypotheses: if hypothesis.measurement is index: return hypothesis return None # retrieve SingleHypothesis by prediction if isinstance(index, Prediction): for hypothesis in self.single_hypotheses: if hypothesis.prediction is index: return hypothesis return None def normalise_probabilities(self, total_weight=None): if total_weight is None: total_weight = self.total_weight # verify that SingleHypotheses composing this MultipleHypothesis # all have Probabilities if any(not hasattr(hypothesis, 'probability') for hypothesis in self.single_hypotheses): raise ValueError("MultipleHypothesis not composed of Probability" " hypotheses!") sum_weights = Probability.sum( hypothesis.probability for hypothesis in self.single_hypotheses) for hypothesis in self.single_hypotheses: hypothesis.probability =\ (hypothesis.probability * total_weight)/sum_weights def get_missed_detection_probability(self): for hypothesis in self.single_hypotheses: if isinstance(hypothesis.measurement, MissedDetection): if hasattr(hypothesis, 'probability'): return hypothesis.probability return None