Commit e9dff884 authored by jlaura's avatar jlaura
Browse files

Merge pull request #117 from acpaquette/testing

Update to the Spatial Suppression function in outlier detector and various tests
parents 4d828dd9 f4750eb3
Loading
Loading
Loading
Loading
+13 −8
Original line number Diff line number Diff line
@@ -138,7 +138,7 @@ class SpatialSuppression(Observable):

    """

    def __init__(self, df, domain, min_radius=1, k=250, error_k=0.1):
    def __init__(self, df, domain, min_radius=1.5, k=250, error_k=0.1):
        columns = df.columns
        for i in ['x', 'y', 'strength']:
            if i not in columns:
@@ -182,14 +182,13 @@ class SpatialSuppression(Observable):
            self.k = len(self.df)
            result = self.df.index
            process = False
        search_space = np.linspace(self.min_radius, self.max_radius / 16, 250)
        cell_sizes = (search_space / math.sqrt(2)).astype(np.int)
        search_space = np.linspace(self.min_radius, self.max_radius, 100)
        cell_sizes = search_space / math.sqrt(2)
        min_idx = 0
        max_idx = len(search_space) - 1

        while process:
            mid_idx = int((min_idx + max_idx) / 2)
            r = search_space[mid_idx]

            cell_size = cell_sizes[mid_idx]
            n_x_cells = int(self.domain[0] / cell_size)
@@ -222,19 +221,19 @@ class SpatialSuppression(Observable):
                        min_idx = mid_idx
                        break

                    y_min = y_center - 5
                    y_min = y_center - int(round(cell_size, 0))
                    if y_min < 0:
                        y_min = 0

                    x_min = x_center - 5
                    x_min = x_center - int(round(cell_size, 0))
                    if x_min < 0:
                        x_min = 0

                    y_max = y_center + 5
                    y_max = y_center + int(round(cell_size, 0))
                    if y_max > grid.shape[0]:
                        y_max = grid.shape[0]

                    x_max = x_center + 5
                    x_max = x_center + int(round(cell_size, 0))
                    if x_max > grid.shape[1]:
                        x_max = grid.shape[1]

@@ -242,18 +241,24 @@ class SpatialSuppression(Observable):
                    grid[y_min: y_max,
                         x_min: x_max] = True


            #  Check break conditions
            if self.k - self.k * self.error_k <= len(result) <= self.k + self.k * self.error_k:
                process = False
            elif len(result) < self.k:
                # The radius is too large
                max_idx = mid_idx
                if max_idx == 0:
                    warnings.warn('Unable to retrieve {} points. Consider reducing the amount of points you request(k)'
                                  .format(self.k))
                    process = False
                if min_idx == max_idx:
                    process = False
            elif min_idx == mid_idx or mid_idx == max_idx:
                warnings.warn('Unable to optimally solve.  Returning with {} points'.format(len(result)))
                process = False

        self.mask = pd.Series(False, self.df.index)
        self.mask.loc[list(result)] = True
        state_package = {'mask': self.mask,
                         'k': self.k,
+37 −3
Original line number Diff line number Diff line
@@ -6,11 +6,11 @@ import warnings
import numpy as np
import pandas as pd

from .. import outlier_detector
from .. import matcher, outlier_detector
from autocnet.matcher.outlier_detector import SpatialSuppression

sys.path.append(os.path.abspath('..'))


class TestOutlierDetector(unittest.TestCase):

    def test_distance_ratio(self):
@@ -91,7 +91,7 @@ class TestSpatialSuppression(unittest.TestCase):
    def test_suppress(self):
        self.suppression_obj.k = 30
        self.suppression_obj.suppress()
        self.assertIn(self.suppression_obj.mask.sum(), list(range(27, 34)))
        self.assertIn(self.suppression_obj.mask.sum(), list(range(27, 35)))

        with warnings.catch_warnings(record=True) as w:
            self.suppression_obj.k = 101
@@ -99,3 +99,37 @@ class TestSpatialSuppression(unittest.TestCase):
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[0].category, UserWarning))

class testSuppressionRanges(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.r = np.random.RandomState(12345)

    def test_one_by_one(self):
        df = pd.DataFrame(self.r.uniform(0,1,(500, 3)), columns=['x', 'y', 'strength'])
        sup = SpatialSuppression(df, (1,1), k = 1)
        self.assertRaises(ValueError, sup.suppress())

    def test_min_max(self):
        df = pd.DataFrame(self.r.uniform(0,2,(500, 3)), columns=['x', 'y', 'strength'])
        sup = SpatialSuppression(df, (1.5,1.5), k = 1)
        sup.suppress()
        self.assertEqual(len(df[sup.mask]), 1)

    def test_point_overload(self):
        df = pd.DataFrame(self.r.uniform(0,15,(500, 3)), columns=['x', 'y', 'strength'])
        sup = SpatialSuppression(df, (15,15), k = 200)
        sup.suppress()
        self.assertEqual(len(df[sup.mask]), 70)

    def test_small_distribution(self):
        df = pd.DataFrame(self.r.uniform(0,25,(500, 3)), columns=['x', 'y', 'strength'])
        sup = SpatialSuppression(df, (25,25), k = 25)
        sup.suppress()
        self.assertEqual(len(df[sup.mask]), 28)

    def test_normal_distribution(self):
        df = pd.DataFrame(self.r.uniform(0,100,(500, 3)), columns=['x', 'y', 'strength'])
        sup = SpatialSuppression(df, (100,100), k = 15)
        sup.suppress()
        self.assertEqual(len(df[sup.mask]), 17)
+0 −543

File deleted.

Preview size limit exceeded, changes collapsed.