Пример #1
0
    def test__init__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__init__` method.
        """

        signal = Signal(self._range)
        np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1))
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(self._range, self._domain)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(signal)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        if is_pandas_installed():
            from pandas import Series

            signal = Signal(Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(signal.domain, self._domain)
            np.testing.assert_array_equal(signal.range, self._range)
Пример #2
0
    def test_signal_unpack_data(self):
        """
        Tests :func:`colour.continuous.signal.Signal.signal_unpack_data`
        method.
        """

        domain, range_ = Signal.signal_unpack_data(self._range)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, np.arange(0, 10, 1))

        domain, range_ = Signal.signal_unpack_data(self._range, self._domain)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            Signal(self._range, self._domain))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        if is_pandas_installed():
            from pandas import Series

            domain, range_ = Signal.signal_unpack_data(
                Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(range_, self._range)
            np.testing.assert_array_equal(domain, self._domain)
Пример #3
0
    def setUp(self):
        """Initialise the common tests attributes."""

        self._range = np.linspace(10, 100, 10)
        self._domain = np.arange(100, 1100, 100)

        self._signal = Signal(self._range)
Пример #4
0
    def test__repr__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__repr__` method.
        """

        self.assertEqual(
            re.sub(r'extrapolator_args={.*}', 'extrapolator_args={...}',
                   repr(self._signal)),
            textwrap.dedent("""
                Signal([[   0.,   10.],
                        [   1.,   20.],
                        [   2.,   30.],
                        [   3.,   40.],
                        [   4.,   50.],
                        [   5.,   60.],
                        [   6.,   70.],
                        [   7.,   80.],
                        [   8.,   90.],
                        [   9.,  100.]],
                       interpolator=KernelInterpolator,
                       interpolator_args={},
                       extrapolator=Extrapolator,
                       extrapolator_args={...})""")[1:])

        self.assertIsInstance(repr(Signal()), string_types)
Пример #5
0
    def test_raise_exception_function(self):
        """
        Tests :func:`colour.continuous.signal.Signal.function` property raised
        exception.
        """

        self.assertRaises(RuntimeError, Signal().function, 0)
Пример #6
0
    def setUp(self):
        """
        Initialises common tests attributes.
        """

        self._range = np.linspace(10, 100, 10)
        self._domain = np.arange(100, 1100, 100)

        self._signal = Signal(self._range)
Пример #7
0
    def test_to_series(self):
        """Test :func:`colour.continuous.signal.Signal.to_series` method."""

        if is_pandas_installed():
            from pandas import Series

            self.assertEqual(
                Signal(self._range, self._domain).to_series().all(),
                Series(dict(zip(self._domain, self._range))).all(),
            )
Пример #8
0
    def test_signal_unpack_data(self):
        """
        Tests :func:`colour.continuous.signal.Signal.signal_unpack_data`
        method.
        """

        domain, range_ = Signal.signal_unpack_data(self._range)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, np.arange(0, 10, 1))

        domain, range_ = Signal.signal_unpack_data(self._range, self._domain)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            Signal(self._range, self._domain))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        if is_pandas_installed():
            from pandas import Series

            domain, range_ = Signal.signal_unpack_data(
                Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(range_, self._range)
            np.testing.assert_array_equal(domain, self._domain)
Пример #9
0
    def read(self):
        """
        Reads and parses the spectral data JSON file path.

        Returns
        -------
        bool
            Definition success.
        """

        with open(self._path, 'r') as json_file:
            content = json.load(json_file)

        self._header = SpectralDataHeader_AMPAS(**content['header'])
        for attribute in ('units', 'reflection_geometry',
                          'transmission_geometry', 'bandwidth_FWHM',
                          'bandwidth_corrected'):
            setattr(self, '_{0}'.format(attribute),
                    content['spectral_data'][attribute])

        index = content['spectral_data']['index']['main']
        data = content['spectral_data']['data']['main']

        if len(index) == 1:
            self.domain, self.range = Signal.signal_unpack_data(
                {k: v[0]
                 for k, v in data.items()})
        else:
            self.signals = MultiSignals.multi_signals_unpack_data(data,
                                                                  labels=index)

        # TODO: Re-instate "manufacturer", "model", "illuminant" and "type"
        # attributes according to outcome of
        # https://github.com/ampas/rawtoaces/issues/114.
        if ('manufacturer' in self._header._kwargs
                and 'model' in self._header._kwargs):
            self.name = '{0} {1}'.format(self._header._kwargs['manufacturer'],
                                         self._header._kwargs['model'])
        elif 'illuminant' in self._header._kwargs:
            self.name = self._header._kwargs['illuminant']
        elif 'type' in self._header._kwargs:
            self.name = self._header._kwargs['type']

        return self
Пример #10
0
    def test__str__(self):
        """Test :func:`colour.continuous.signal.Signal.__str__` method."""

        self.assertEqual(
            str(self._signal),
            textwrap.dedent("""
                [[   0.   10.]
                 [   1.   20.]
                 [   2.   30.]
                 [   3.   40.]
                 [   4.   50.]
                 [   5.   60.]
                 [   6.   70.]
                 [   7.   80.]
                 [   8.   90.]
                 [   9.  100.]]""")[1:],
        )

        self.assertIsInstance(str(Signal()), str)
Пример #11
0
class TestSignal(unittest.TestCase):
    """
    Defines :class:`colour.continuous.signal.Signal` class unit tests methods.
    """

    def setUp(self):
        """
        Initialises common tests attributes.
        """

        self._range = np.linspace(10, 100, 10)
        self._domain = np.arange(100, 1100, 100)

        self._signal = Signal(self._range)

    def test_required_attributes(self):
        """
        Tests presence of required attributes.
        """

        required_attributes = ('dtype', 'domain', 'range', 'interpolator',
                               'interpolator_args', 'extrapolator',
                               'extrapolator_args', 'function')

        for attribute in required_attributes:
            self.assertIn(attribute, dir(Signal))

    def test_required_methods(self):
        """
        Tests presence of required methods.
        """

        required_methods = ('__str__', '__repr__', '__hash__', '__getitem__',
                            '__setitem__', '__contains__', '__eq__', '__ne__',
                            'arithmetical_operation', 'signal_unpack_data',
                            'fill_nan', 'domain_distance', 'to_series')

        for method in required_methods:
            self.assertIn(method, dir(Signal))

    def test_dtype(self):
        """
        Tests :func:`colour.continuous.signal.Signal.dtype` property.
        """

        self.assertEqual(self._signal.dtype, None)

        signal = self._signal.copy()
        signal.dtype = DEFAULT_FLOAT_DTYPE
        self.assertEqual(signal.dtype, DEFAULT_FLOAT_DTYPE)

    def test_domain(self):
        """
        Tests :func:`colour.continuous.signal.Signal.domain` property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

        signal.domain = np.arange(0, 10, 1) * 10

        np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1) * 10)

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2]) * 10],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

        # TODO: Use "assertWarns" when dropping Python 2.7.
        domain = np.linspace(0, 1, 10)
        domain[0] = -np.inf
        signal.domain = domain

    def test_range(self):
        """
        Tests :func:`colour.continuous.signal.Signal.range` property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

        signal.range = self._range * 10

        np.testing.assert_array_equal(signal.range, self._range * 10)

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]) * 10,
            decimal=7)

    def test_interpolator(self):
        """
        Tests :func:`colour.continuous.signal.Signal.interpolator` property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 22.83489024, 34.80044921, 47.55353925, 60.00000000
            ]),
            decimal=7)

        signal.interpolator = CubicSplineInterpolator

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([10.0, 22.5, 35.0, 47.5, 60.0]),
            decimal=7)

    def test_interpolator_args(self):
        """
        Tests :func:`colour.continuous.signal.Signal.interpolator_args`
        property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 22.83489024, 34.80044921, 47.55353925, 60.00000000
            ]),
            decimal=7)

        signal.interpolator_args = {'window': 1, 'kernel_args': {'a': 1}}

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 18.91328761, 28.36993142, 44.13100443, 60.00000000
            ]),
            decimal=7)

    def test_extrapolator(self):
        """
        Tests :func:`colour.continuous.signal.Signal.extrapolator` property.
        """

        self.assertIsInstance(self._signal.extrapolator(), Extrapolator)

    def test_extrapolator_args(self):
        """
        Tests :func:`colour.continuous.signal.Signal.extrapolator_args`
        property.
        """

        signal = self._signal.copy()

        assert np.all(np.isnan(signal[np.array([-1000, 1000])]))

        signal.extrapolator_args = {
            'method': 'Linear',
        }

        np.testing.assert_almost_equal(
            signal[np.array([-1000, 1000])],
            np.array([-9990.0, 10010.0]),
            decimal=7)

    def test_function(self):
        """
        Tests :func:`colour.continuous.signal.Signal.function` property.
        """

        assert hasattr(self._signal.function, '__call__')

    def test_raise_exception_function(self):
        """
        Tests :func:`colour.continuous.signal.Signal.function` property raised
        exception.
        """

        self.assertRaises(RuntimeError, Signal().function, 0)

    def test__init__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__init__` method.
        """

        signal = Signal(self._range)
        np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1))
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(self._range, self._domain)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(signal)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        if is_pandas_installed():
            from pandas import Series

            signal = Signal(Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(signal.domain, self._domain)
            np.testing.assert_array_equal(signal.range, self._range)

    def test__hash__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__hash__` method.
        """

        self.assertIsInstance(hash(self._signal), int)

    def test__str__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__str__` method.
        """

        self.assertEqual(
            str(self._signal),
            textwrap.dedent("""
                [[   0.   10.]
                 [   1.   20.]
                 [   2.   30.]
                 [   3.   40.]
                 [   4.   50.]
                 [   5.   60.]
                 [   6.   70.]
                 [   7.   80.]
                 [   8.   90.]
                 [   9.  100.]]""")[1:])

        self.assertIsInstance(str(Signal()), string_types)

    def test__repr__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__repr__` method.
        """

        self.assertEqual(
            re.sub(r'extrapolator_args={.*}', 'extrapolator_args={...}',
                   repr(self._signal)),
            textwrap.dedent("""
                Signal([[   0.,   10.],
                        [   1.,   20.],
                        [   2.,   30.],
                        [   3.,   40.],
                        [   4.,   50.],
                        [   5.,   60.],
                        [   6.,   70.],
                        [   7.,   80.],
                        [   8.,   90.],
                        [   9.,  100.]],
                       interpolator=KernelInterpolator,
                       interpolator_args={},
                       extrapolator=Extrapolator,
                       extrapolator_args={...})""")[1:])

        self.assertIsInstance(repr(Signal()), string_types)

    def test__getitem__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__getitem__` method.
        """

        self.assertEqual(self._signal[0], 10.0)

        np.testing.assert_almost_equal(
            self._signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 22.83489024, 34.80044921, 47.55353925, 60.00000000
            ]),
            decimal=7)

        assert np.all(np.isnan(self._signal[np.array([-1000, 1000])]))

        signal = self._signal.copy()
        signal.extrapolator_args = {
            'method': 'Linear',
        }
        np.testing.assert_array_equal(signal[np.array([-1000, 1000])],
                                      np.array([-9990.0, 10010.0]))

        signal.extrapolator_args = {
            'method': 'Constant',
            'left': 0,
            'right': 1
        }
        np.testing.assert_array_equal(signal[np.array([-1000, 1000])],
                                      np.array([0.0, 1.0]))

    def test__setitem__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__setitem__` method.
        """

        signal = self._signal.copy()

        signal[0] = 20
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [20.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]))

        signal[np.array([0, 1, 2])] = 30
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [30.0, 30.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7)

        signal[0:3] = 40
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [40.0, 40.0, 40.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7)

        signal[np.linspace(0, 5, 5)] = 50
        np.testing.assert_almost_equal(
            signal.domain,
            np.array([
                0.00, 1.00, 1.25, 2.00, 2.50, 3.00, 3.75, 4.00, 5.00, 6.00,
                7.00, 8.00, 9.00
            ]),
            decimal=7)
        np.testing.assert_almost_equal(
            signal.range,
            np.array([
                50.0, 40.0, 50.0, 40.0, 50.0, 40.0, 50.0, 50.0, 50.0, 70.0,
                80.0, 90.0, 100.0
            ]),
            decimal=7)

        signal[np.array([0, 1, 2])] = np.array([10, 20, 30])
        np.testing.assert_almost_equal(
            signal.range,
            np.array([
                10.0, 20.0, 50.0, 30.0, 50.0, 40.0, 50.0, 50.0, 50.0, 70.0,
                80.0, 90.0, 100.0
            ]),
            decimal=7)

    def test__contains__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__contains__` method.
        """

        self.assertIn(0, self._signal)
        self.assertIn(0.5, self._signal)
        self.assertNotIn(1000, self._signal)

    def test__len__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__len__` method.
        """

        self.assertEqual(len(self._signal), 10)

    def test__eq__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__eq__` method.
        """

        signal_1 = self._signal.copy()
        signal_2 = self._signal.copy()

        self.assertEqual(signal_1, signal_2)

    def test__ne__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__ne__` method.
        """

        signal_1 = self._signal.copy()
        signal_2 = self._signal.copy()

        signal_2[0] = 20
        self.assertNotEqual(signal_1, signal_2)

        signal_2[0] = 10
        self.assertEqual(signal_1, signal_2)

        signal_2.interpolator = CubicSplineInterpolator
        self.assertNotEqual(signal_1, signal_2)

        signal_2.interpolator = KernelInterpolator
        self.assertEqual(signal_1, signal_2)

        signal_2.interpolator_args = {'window': 1}
        self.assertNotEqual(signal_1, signal_2)

        signal_2.interpolator_args = {}
        self.assertEqual(signal_1, signal_2)

        class NotExtrapolator(Extrapolator):
            """
            Not :class:`Extrapolator` class.
            """

            pass

        signal_2.extrapolator = NotExtrapolator
        self.assertNotEqual(signal_1, signal_2)

        signal_2.extrapolator = Extrapolator
        self.assertEqual(signal_1, signal_2)

        signal_2.extrapolator_args = {}
        self.assertNotEqual(signal_1, signal_2)

        signal_2.extrapolator_args = {
            'method': 'Constant',
            'left': np.nan,
            'right': np.nan
        }
        self.assertEqual(signal_1, signal_2)

    def test_arithmetical_operation(self):
        """
        Tests :func:`colour.continuous.signal.Signal.arithmetical_operation`
        method.
        """

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '+', False).range,
            self._range + 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '-', False).range,
            self._range - 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '*', False).range,
            self._range * 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '/', False).range,
            self._range / 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '**', False).range,
            self._range ** 10,
            decimal=7)

        np.testing.assert_almost_equal(
            (self._signal + 10).range, self._range + 10, decimal=7)

        np.testing.assert_almost_equal(
            (self._signal - 10).range, self._range - 10, decimal=7)

        np.testing.assert_almost_equal(
            (self._signal * 10).range, self._range * 10, decimal=7)

        np.testing.assert_almost_equal(
            (self._signal / 10).range, self._range / 10, decimal=7)

        np.testing.assert_almost_equal(
            (self._signal ** 10).range, self._range ** 10, decimal=7)

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '+', True).range,
            self._range + 10,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '-', True).range,
            self._range,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '*', True).range,
            self._range * 10,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '/', True).range,
            self._range,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '**', True).range,
            self._range ** 10,
            decimal=7)

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(self._range, '+', False).range,
            signal.range + self._range,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(signal, '+', False).range,
            signal.range + signal._range,
            decimal=7)

    def test_is_uniform(self):
        """
        Tests :func:`colour.continuous.signal.Signal.is_uniform` method.
        """

        self.assertTrue(self._signal.is_uniform())

        signal = self._signal.copy()
        signal[0.5] = 1.0
        self.assertFalse(signal.is_uniform())

    def test_copy(self):
        """
        Tests :func:`colour.continuous.signal.Signal.copy` method.
        """

        self.assertIsNot(self._signal, self._signal.copy())
        self.assertEqual(self._signal, self._signal.copy())

    def test_signal_unpack_data(self):
        """
        Tests :func:`colour.continuous.signal.Signal.signal_unpack_data`
        method.
        """

        domain, range_ = Signal.signal_unpack_data(self._range)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, np.arange(0, 10, 1))

        domain, range_ = Signal.signal_unpack_data(self._range, self._domain)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            Signal(self._range, self._domain))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        if is_pandas_installed():
            from pandas import Series

            domain, range_ = Signal.signal_unpack_data(
                Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(range_, self._range)
            np.testing.assert_array_equal(domain, self._domain)

    def test_fill_nan(self):
        """
        Tests :func:`colour.continuous.signal.Signal.fill_nan` method.
        """

        signal = self._signal.copy()

        signal[3:7] = np.nan

        np.testing.assert_almost_equal(
            signal.fill_nan().range,
            np.array(
                [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7)

        signal[3:7] = np.nan

        np.testing.assert_almost_equal(
            signal.fill_nan(method='Constant').range,
            np.array([10.0, 20.0, 30.0, 0.0, 0.0, 0.0, 0.0, 80.0, 90.0,
                      100.0]),
            decimal=7)

    def test_domain_distance(self):
        """
        Tests :func:`colour.continuous.signal.Signal.domain_distance` method.
        """

        self.assertAlmostEqual(
            self._signal.domain_distance(0.5), 0.5, places=7)

        np.testing.assert_almost_equal(
            self._signal.domain_distance(np.linspace(0, 9, 10) + 0.5),
            np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]),
            decimal=7)

    def test_to_series(self):
        """
        Tests :func:`colour.continuous.signal.Signal.to_series` method.
        """

        if is_pandas_installed():
            from pandas import Series

            self.assertEqual(
                Signal(self._range, self._domain).to_series().all(),
                Series(dict(zip(self._domain, self._range))).all())
Пример #12
0
class TestSignal(unittest.TestCase):
    """Define :class:`colour.continuous.signal.Signal` class unit tests methods."""
    def setUp(self):
        """Initialise the common tests attributes."""

        self._range = np.linspace(10, 100, 10)
        self._domain = np.arange(100, 1100, 100)

        self._signal = Signal(self._range)

    def test_required_attributes(self):
        """Test the presence of required attributes."""

        required_attributes = (
            "dtype",
            "domain",
            "range",
            "interpolator",
            "interpolator_kwargs",
            "extrapolator",
            "extrapolator_kwargs",
            "function",
        )

        for attribute in required_attributes:
            self.assertIn(attribute, dir(Signal))

    def test_required_methods(self):
        """Test the presence of required methods."""

        required_methods = (
            "__init__",
            "__str__",
            "__repr__",
            "__hash__",
            "__getitem__",
            "__setitem__",
            "__contains__",
            "__eq__",
            "__ne__",
            "arithmetical_operation",
            "signal_unpack_data",
            "fill_nan",
            "domain_distance",
            "to_series",
        )

        for method in required_methods:
            self.assertIn(method, dir(Signal))

    def test_dtype(self):
        """Test :func:`colour.continuous.signal.Signal.dtype` property."""

        self.assertEqual(self._signal.dtype, DEFAULT_FLOAT_DTYPE)

        signal = self._signal.copy()
        signal.dtype = np.float32
        self.assertEqual(signal.dtype, np.float32)

    def test_domain(self):
        """Test :func:`colour.continuous.signal.Signal.domain` property."""

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7,
        )

        signal.domain = np.arange(0, 10, 1) * 10

        np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1) * 10)

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2]) * 10],
            np.array([10.0, 20.0, 30.0]),
            decimal=7,
        )

        domain = np.linspace(0, 1, 10)
        domain[0] = -np.inf

        def assert_warns():
            """Help to test the runtime warning."""

            signal.domain = domain

        self.assertWarns(ColourRuntimeWarning, assert_warns)

    def test_range(self):
        """Test :func:`colour.continuous.signal.Signal.range` property."""

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7,
        )

        signal.range = self._range * 10

        np.testing.assert_array_equal(signal.range, self._range * 10)

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]) * 10,
            decimal=7,
        )

    def test_interpolator(self):
        """Test :func:`colour.continuous.signal.Signal.interpolator` property."""

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000,
                22.83489024,
                34.80044921,
                47.55353925,
                60.00000000,
            ]),
            decimal=7,
        )

        signal.interpolator = CubicSplineInterpolator

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([10.0, 22.5, 35.0, 47.5, 60.0]),
            decimal=7,
        )

    def test_interpolator_kwargs(self):
        """
        Test :func:`colour.continuous.signal.Signal.interpolator_kwargs`
        property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000,
                22.83489024,
                34.80044921,
                47.55353925,
                60.00000000,
            ]),
            decimal=7,
        )

        signal.interpolator_kwargs = {"window": 1, "kernel_kwargs": {"a": 1}}

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000,
                18.91328761,
                28.36993142,
                44.13100443,
                60.00000000,
            ]),
            decimal=7,
        )

    def test_extrapolator(self):
        """Test :func:`colour.continuous.signal.Signal.extrapolator` property."""

        self.assertIsInstance(self._signal.extrapolator(), Extrapolator)

    def test_extrapolator_kwargs(self):
        """
        Test :func:`colour.continuous.signal.Signal.extrapolator_kwargs`
        property.
        """

        signal = self._signal.copy()

        attest(np.all(np.isnan(signal[np.array([-1000, 1000])])))

        signal.extrapolator_kwargs = {
            "method": "Linear",
        }

        np.testing.assert_almost_equal(
            signal[np.array([-1000, 1000])],
            np.array([-9990.0, 10010.0]),
            decimal=7,
        )

    def test_function(self):
        """Test :func:`colour.continuous.signal.Signal.function` property."""

        attest(hasattr(self._signal.function, "__call__"))

    def test_raise_exception_function(self):
        """
        Test :func:`colour.continuous.signal.Signal.function` property raised
        exception.
        """

        self.assertRaises(ValueError, Signal().function, 0)

    def test__init__(self):
        """Test :func:`colour.continuous.signal.Signal.__init__` method."""

        signal = Signal(self._range)
        np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1))
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(self._range, self._domain)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(signal)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        if is_pandas_installed():
            from pandas import Series

            signal = Signal(Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(signal.domain, self._domain)
            np.testing.assert_array_equal(signal.range, self._range)

    def test__hash__(self):
        """Test :func:`colour.continuous.signal.Signal.__hash__` method."""

        self.assertIsInstance(hash(self._signal), int)

    def test__str__(self):
        """Test :func:`colour.continuous.signal.Signal.__str__` method."""

        self.assertEqual(
            str(self._signal),
            textwrap.dedent("""
                [[   0.   10.]
                 [   1.   20.]
                 [   2.   30.]
                 [   3.   40.]
                 [   4.   50.]
                 [   5.   60.]
                 [   6.   70.]
                 [   7.   80.]
                 [   8.   90.]
                 [   9.  100.]]""")[1:],
        )

        self.assertIsInstance(str(Signal()), str)

    def test__repr__(self):
        """Test :func:`colour.continuous.signal.Signal.__repr__` method."""

        self.assertEqual(
            re.sub(
                r"extrapolator_kwargs={.*}",
                "extrapolator_kwargs={...}",
                repr(self._signal),
            ),
            textwrap.dedent("""
                Signal([[   0.,   10.],
                        [   1.,   20.],
                        [   2.,   30.],
                        [   3.,   40.],
                        [   4.,   50.],
                        [   5.,   60.],
                        [   6.,   70.],
                        [   7.,   80.],
                        [   8.,   90.],
                        [   9.,  100.]],
                       interpolator=KernelInterpolator,
                       interpolator_kwargs={},
                       extrapolator=Extrapolator,
                       extrapolator_kwargs={...})""")[1:],
        )

        self.assertIsInstance(repr(Signal()), str)

    def test__getitem__(self):
        """Test :func:`colour.continuous.signal.Signal.__getitem__` method."""

        self.assertEqual(self._signal[0], 10.0)

        np.testing.assert_almost_equal(
            self._signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            self._signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000,
                22.83489024,
                34.80044921,
                47.55353925,
                60.00000000,
            ]),
            decimal=7,
        )

        attest(np.all(np.isnan(self._signal[np.array([-1000, 1000])])))

        signal = self._signal.copy()
        signal.extrapolator_kwargs = {
            "method": "Linear",
        }
        np.testing.assert_array_equal(signal[np.array([-1000, 1000])],
                                      np.array([-9990.0, 10010.0]))

        signal.extrapolator_kwargs = {
            "method": "Constant",
            "left": 0,
            "right": 1,
        }
        np.testing.assert_array_equal(signal[np.array([-1000, 1000])],
                                      np.array([0.0, 1.0]))

    def test__setitem__(self):
        """Test :func:`colour.continuous.signal.Signal.__setitem__` method."""

        signal = self._signal.copy()

        signal[0] = 20
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [20.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
        )

        signal[np.array([0, 1, 2])] = 30
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [30.0, 30.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7,
        )

        signal[0:3] = 40
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [40.0, 40.0, 40.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7,
        )

        signal[np.linspace(0, 5, 5)] = 50
        np.testing.assert_almost_equal(
            signal.domain,
            np.array([
                0.00,
                1.00,
                1.25,
                2.00,
                2.50,
                3.00,
                3.75,
                4.00,
                5.00,
                6.00,
                7.00,
                8.00,
                9.00,
            ]),
            decimal=7,
        )
        np.testing.assert_almost_equal(
            signal.range,
            np.array([
                50.0,
                40.0,
                50.0,
                40.0,
                50.0,
                40.0,
                50.0,
                50.0,
                50.0,
                70.0,
                80.0,
                90.0,
                100.0,
            ]),
            decimal=7,
        )

        signal[np.array([0, 1, 2])] = np.array([10, 20, 30])
        np.testing.assert_almost_equal(
            signal.range,
            np.array([
                10.0,
                20.0,
                50.0,
                30.0,
                50.0,
                40.0,
                50.0,
                50.0,
                50.0,
                70.0,
                80.0,
                90.0,
                100.0,
            ]),
            decimal=7,
        )

    def test__contains__(self):
        """Test :func:`colour.continuous.signal.Signal.__contains__` method."""

        self.assertIn(0, self._signal)
        self.assertIn(0.5, self._signal)
        self.assertNotIn(1000, self._signal)

    def test__len__(self):
        """Test :func:`colour.continuous.signal.Signal.__len__` method."""

        self.assertEqual(len(self._signal), 10)

    def test__eq__(self):
        """Test :func:`colour.continuous.signal.Signal.__eq__` method."""

        signal_1 = self._signal.copy()
        signal_2 = self._signal.copy()

        self.assertEqual(signal_1, signal_2)

    def test__ne__(self):
        """Test :func:`colour.continuous.signal.Signal.__ne__` method."""

        signal_1 = self._signal.copy()
        signal_2 = self._signal.copy()

        signal_2[0] = 20
        self.assertNotEqual(signal_1, signal_2)

        signal_2[0] = 10
        self.assertEqual(signal_1, signal_2)

        signal_2.interpolator = CubicSplineInterpolator
        self.assertNotEqual(signal_1, signal_2)

        signal_2.interpolator = KernelInterpolator
        self.assertEqual(signal_1, signal_2)

        signal_2.interpolator_kwargs = {"window": 1}
        self.assertNotEqual(signal_1, signal_2)

        signal_2.interpolator_kwargs = {}
        self.assertEqual(signal_1, signal_2)

        class NotExtrapolator(Extrapolator):
            """Not :class:`Extrapolator` class."""

            pass

        signal_2.extrapolator = NotExtrapolator
        self.assertNotEqual(signal_1, signal_2)

        signal_2.extrapolator = Extrapolator
        self.assertEqual(signal_1, signal_2)

        signal_2.extrapolator_kwargs = {}
        self.assertNotEqual(signal_1, signal_2)

        signal_2.extrapolator_kwargs = {
            "method": "Constant",
            "left": np.nan,
            "right": np.nan,
        }
        self.assertEqual(signal_1, signal_2)

    def test_arithmetical_operation(self):
        """
        Test :meth:`colour.continuous.signal.Signal.arithmetical_operation`
        method.
        """

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, "+", False).range,
            self._range + 10,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, "-", False).range,
            self._range - 10,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, "*", False).range,
            self._range * 10,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, "/", False).range,
            self._range / 10,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, "**", False).range,
            self._range**10,
            decimal=7,
        )

        np.testing.assert_almost_equal((self._signal + 10).range,
                                       self._range + 10,
                                       decimal=7)

        np.testing.assert_almost_equal((self._signal - 10).range,
                                       self._range - 10,
                                       decimal=7)

        np.testing.assert_almost_equal((self._signal * 10).range,
                                       self._range * 10,
                                       decimal=7)

        np.testing.assert_almost_equal((self._signal / 10).range,
                                       self._range / 10,
                                       decimal=7)

        np.testing.assert_almost_equal((self._signal**10).range,
                                       self._range**10,
                                       decimal=7)

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, "+", True).range,
            self._range + 10,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, "-", True).range,
            self._range,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, "*", True).range,
            self._range * 10,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, "/", True).range,
            self._range,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, "**", True).range,
            self._range**10,
            decimal=7,
        )

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(self._range, "+", False).range,
            signal.range + self._range,
            decimal=7,
        )

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(signal, "+", False).range,
            signal.range + signal._range,
            decimal=7,
        )

    def test_is_uniform(self):
        """Test :func:`colour.continuous.signal.Signal.is_uniform` method."""

        self.assertTrue(self._signal.is_uniform())

        signal = self._signal.copy()
        signal[0.5] = 1.0
        self.assertFalse(signal.is_uniform())

    def test_copy(self):
        """Test :func:`colour.continuous.signal.Signal.copy` method."""

        self.assertIsNot(self._signal, self._signal.copy())
        self.assertEqual(self._signal, self._signal.copy())

    def test_signal_unpack_data(self):
        """
        Test :meth:`colour.continuous.signal.Signal.signal_unpack_data`
        method.
        """

        domain, range_ = Signal.signal_unpack_data(self._range)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, np.arange(0, 10, 1))

        domain, range_ = Signal.signal_unpack_data(self._range, self._domain)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            self._range,
            dict(zip(self._domain, self._range)).keys())
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            Signal(self._range, self._domain))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        if is_pandas_installed():
            from pandas import Series

            domain, range_ = Signal.signal_unpack_data(
                Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(range_, self._range)
            np.testing.assert_array_equal(domain, self._domain)

    def test_fill_nan(self):
        """Test :func:`colour.continuous.signal.Signal.fill_nan` method."""

        signal = self._signal.copy()

        signal[3:7] = np.nan

        np.testing.assert_almost_equal(
            signal.fill_nan().range,
            np.array(
                [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7,
        )

        signal[3:7] = np.nan

        np.testing.assert_almost_equal(
            signal.fill_nan(method="Constant").range,
            np.array([10.0, 20.0, 30.0, 0.0, 0.0, 0.0, 0.0, 80.0, 90.0,
                      100.0]),
            decimal=7,
        )

    def test_domain_distance(self):
        """Test :func:`colour.continuous.signal.Signal.domain_distance` method."""

        self.assertAlmostEqual(self._signal.domain_distance(0.5),
                               0.5,
                               places=7)

        np.testing.assert_almost_equal(
            self._signal.domain_distance(np.linspace(0, 9, 10) + 0.5),
            np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]),
            decimal=7,
        )

    def test_to_series(self):
        """Test :func:`colour.continuous.signal.Signal.to_series` method."""

        if is_pandas_installed():
            from pandas import Series

            self.assertEqual(
                Signal(self._range, self._domain).to_series().all(),
                Series(dict(zip(self._domain, self._range))).all(),
            )
Пример #13
0
class TestSignal(unittest.TestCase):
    """
    Defines :class:`colour.continuous.signal.Signal` class unit tests methods.
    """

    def setUp(self):
        """
        Initialises common tests attributes.
        """

        self._range = np.linspace(10, 100, 10)
        self._domain = np.arange(100, 1100, 100)

        self._signal = Signal(self._range)

    def test_required_attributes(self):
        """
        Tests presence of required attributes.
        """

        required_attributes = ('dtype', 'domain', 'range', 'interpolator',
                               'interpolator_args', 'extrapolator',
                               'extrapolator_args', 'function')

        for attribute in required_attributes:
            self.assertIn(attribute, dir(Signal))

    def test_required_methods(self):
        """
        Tests presence of required methods.
        """

        required_methods = ('__str__', '__repr__', '__hash__', '__getitem__',
                            '__setitem__', '__contains__', '__eq__', '__ne__',
                            'arithmetical_operation', 'signal_unpack_data',
                            'fill_nan', 'domain_distance', 'to_series')

        for method in required_methods:
            self.assertIn(method, dir(Signal))

    def test_domain(self):
        """
        Tests :func:`colour.continuous.signal.Signal.domain` property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

        signal.domain = np.arange(0, 10, 1) * 10

        np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1) * 10)

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2]) * 10],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

    def test_range(self):
        """
        Tests :func:`colour.continuous.signal.Signal.range` property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

        signal.range = self._range * 10

        np.testing.assert_array_equal(signal.range, self._range * 10)

        np.testing.assert_almost_equal(
            signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]) * 10,
            decimal=7)

    def test_interpolator(self):
        """
        Tests :func:`colour.continuous.signal.Signal.interpolator` property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 22.83489024, 34.80044921, 47.55353925, 60.00000000
            ]),
            decimal=7)

        signal.interpolator = CubicSplineInterpolator

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([10.0, 22.5, 35.0, 47.5, 60.0]),
            decimal=7)

    def test_interpolator_args(self):
        """
        Tests :func:`colour.continuous.signal.Signal.interpolator_args`
        property.
        """

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 22.83489024, 34.80044921, 47.55353925, 60.00000000
            ]),
            decimal=7)

        signal.interpolator_args = {'window': 1, 'kernel_args': {'a': 1}}

        np.testing.assert_almost_equal(
            signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 18.91328761, 28.36993142, 44.13100443, 60.00000000
            ]),
            decimal=7)

    def test_extrapolator(self):
        """
        Tests :func:`colour.continuous.signal.Signal.extrapolator` property.
        """

        self.assertIsInstance(self._signal.extrapolator(), Extrapolator)

    def test_extrapolator_args(self):
        """
        Tests :func:`colour.continuous.signal.Signal.extrapolator_args`
        property.
        """

        signal = self._signal.copy()

        assert np.all(np.isnan(signal[np.array([-1000, 1000])]))

        signal.extrapolator_args = {
            'method': 'Linear',
        }

        np.testing.assert_almost_equal(
            signal[np.array([-1000, 1000])],
            np.array([-9990.0, 10010.0]),
            decimal=7)

    def test_function(self):
        """
        Tests :func:`colour.continuous.signal.Signal.function` property.
        """

        assert hasattr(self._signal.function, '__call__')

    def test__init__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__init__` method.
        """

        signal = Signal(self._range)
        np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1))
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(self._range, self._domain)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        signal = Signal(signal)
        np.testing.assert_array_equal(signal.domain, self._domain)
        np.testing.assert_array_equal(signal.range, self._range)

        if is_pandas_installed():
            from pandas import Series

            signal = Signal(Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(signal.domain, self._domain)
            np.testing.assert_array_equal(signal.range, self._range)

    def test__str__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__str__` method.
        """

        self.assertEqual(
            str(self._signal),
            textwrap.dedent("""
                [[   0.   10.]
                 [   1.   20.]
                 [   2.   30.]
                 [   3.   40.]
                 [   4.   50.]
                 [   5.   60.]
                 [   6.   70.]
                 [   7.   80.]
                 [   8.   90.]
                 [   9.  100.]]""")[1:])

    def test__repr__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__repr__` method.
        """

        self.assertEqual(
            re.sub(r'extrapolator_args={.*}', 'extrapolator_args={...}',
                   repr(self._signal)),
            textwrap.dedent("""
                Signal([[   0.,   10.],
                        [   1.,   20.],
                        [   2.,   30.],
                        [   3.,   40.],
                        [   4.,   50.],
                        [   5.,   60.],
                        [   6.,   70.],
                        [   7.,   80.],
                        [   8.,   90.],
                        [   9.,  100.]],
                       interpolator=KernelInterpolator,
                       interpolator_args={},
                       extrapolator=Extrapolator,
                       extrapolator_args={...})""")[1:])

    def test__getitem__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__getitem__` method.
        """

        self.assertEqual(self._signal[0], 10.0)

        np.testing.assert_almost_equal(
            self._signal[np.array([0, 1, 2])],
            np.array([10.0, 20.0, 30.0]),
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal[np.linspace(0, 5, 5)],
            np.array([
                10.00000000, 22.83489024, 34.80044921, 47.55353925, 60.00000000
            ]),
            decimal=7)

        assert np.all(np.isnan(self._signal[np.array([-1000, 1000])]))

        signal = self._signal.copy()
        signal.extrapolator_args = {
            'method': 'Linear',
        }
        np.testing.assert_array_equal(signal[np.array([-1000, 1000])],
                                      np.array([-9990.0, 10010.0]))

        signal.extrapolator_args = {
            'method': 'Constant',
            'left': 0,
            'right': 1
        }
        np.testing.assert_array_equal(signal[np.array([-1000, 1000])],
                                      np.array([0.0, 1.0]))

    def test__setitem__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__setitem__` method.
        """

        signal = self._signal.copy()

        signal[0] = 20
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [20.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]))

        signal[np.array([0, 1, 2])] = 30
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [30.0, 30.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7)

        signal[0:3] = 40
        np.testing.assert_almost_equal(
            signal.range,
            np.array(
                [40.0, 40.0, 40.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7)

        signal[np.linspace(0, 5, 5)] = 50
        np.testing.assert_almost_equal(
            signal.domain,
            np.array([
                0.00, 1.00, 1.25, 2.00, 2.50, 3.00, 3.75, 4.00, 5.00, 6.00,
                7.00, 8.00, 9.00
            ]),
            decimal=7)
        np.testing.assert_almost_equal(
            signal.range,
            np.array([
                50.0, 40.0, 50.0, 40.0, 50.0, 40.0, 50.0, 50.0, 50.0, 70.0,
                80.0, 90.0, 100.0
            ]),
            decimal=7)

        signal[np.array([0, 1, 2])] = np.array([10, 20, 30])
        np.testing.assert_almost_equal(
            signal.range,
            np.array([
                10.0, 20.0, 50.0, 30.0, 50.0, 40.0, 50.0, 50.0, 50.0, 70.0,
                80.0, 90.0, 100.0
            ]),
            decimal=7)

    def test__contains__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__contains__` method.
        """

        self.assertIn(0, self._signal)
        self.assertIn(0.5, self._signal)
        self.assertNotIn(1000, self._signal)

    def test__len__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__len__` method.
        """

        self.assertEqual(len(self._signal), 10)

    def test__eq__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__eq__` method.
        """

        signal_1 = self._signal.copy()
        signal_2 = self._signal.copy()

        self.assertEqual(signal_1, signal_2)

    def test__ne__(self):
        """
        Tests :func:`colour.continuous.signal.Signal.__ne__` method.
        """

        signal_1 = self._signal.copy()
        signal_2 = self._signal.copy()

        signal_2[0] = 20
        self.assertNotEqual(signal_1, signal_2)

        signal_2[0] = 10
        self.assertEqual(signal_1, signal_2)

        signal_2.interpolator = CubicSplineInterpolator
        self.assertNotEqual(signal_1, signal_2)

        signal_2.interpolator = KernelInterpolator
        self.assertEqual(signal_1, signal_2)

        signal_2.interpolator_args = {'window': 1}
        self.assertNotEqual(signal_1, signal_2)

        signal_2.interpolator_args = {}
        self.assertEqual(signal_1, signal_2)

        class NotExtrapolator(Extrapolator):
            """
            Not :class:`Extrapolator` class.
            """

            pass

        signal_2.extrapolator = NotExtrapolator
        self.assertNotEqual(signal_1, signal_2)

        signal_2.extrapolator = Extrapolator
        self.assertEqual(signal_1, signal_2)

        signal_2.extrapolator_args = {}
        self.assertNotEqual(signal_1, signal_2)

        signal_2.extrapolator_args = {
            'method': 'Constant',
            'left': np.nan,
            'right': np.nan
        }
        self.assertEqual(signal_1, signal_2)

    def test_arithmetical_operation(self):
        """
        Tests :func:`colour.continuous.signal.Signal.arithmetical_operation`
        method.
        """

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '+', False).range,
            self._range + 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '-', False).range,
            self._range - 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '*', False).range,
            self._range * 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '/', False).range,
            self._range / 10,
            decimal=7)

        np.testing.assert_almost_equal(
            self._signal.arithmetical_operation(10, '**', False).range,
            self._range ** 10,
            decimal=7)

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '+', True).range,
            self._range + 10,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '-', True).range,
            self._range,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '*', True).range,
            self._range * 10,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '/', True).range,
            self._range,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(10, '**', True).range,
            self._range ** 10,
            decimal=7)

        signal = self._signal.copy()

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(self._range, '+', False).range,
            signal.range + self._range,
            decimal=7)

        np.testing.assert_almost_equal(
            signal.arithmetical_operation(signal, '+', False).range,
            signal.range + signal._range,
            decimal=7)

    def test_is_uniform(self):
        """
        Tests :func:`colour.continuous.signal.Signal.is_uniform` method.
        """

        self.assertTrue(self._signal.is_uniform())

        signal = self._signal.copy()
        signal[0.5] = 1.0
        self.assertFalse(signal.is_uniform())

    def test_copy(self):
        """
        Tests :func:`colour.continuous.signal.Signal.copy` method.
        """

        self.assertIsNot(self._signal, self._signal.copy())
        self.assertEqual(self._signal, self._signal.copy())

    def test_signal_unpack_data(self):
        """
        Tests :func:`colour.continuous.signal.Signal.signal_unpack_data`
        method.
        """

        domain, range_ = Signal.signal_unpack_data(self._range)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, np.arange(0, 10, 1))

        domain, range_ = Signal.signal_unpack_data(self._range, self._domain)
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            dict(zip(self._domain, self._range)))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        domain, range_ = Signal.signal_unpack_data(
            Signal(self._range, self._domain))
        np.testing.assert_array_equal(range_, self._range)
        np.testing.assert_array_equal(domain, self._domain)

        if is_pandas_installed():
            from pandas import Series

            domain, range_ = Signal.signal_unpack_data(
                Series(dict(zip(self._domain, self._range))))
            np.testing.assert_array_equal(range_, self._range)
            np.testing.assert_array_equal(domain, self._domain)

    def test_fill_nan(self):
        """
        Tests :func:`colour.continuous.signal.Signal.fill_nan` method.
        """

        signal = self._signal.copy()

        signal[3:7] = np.nan

        np.testing.assert_almost_equal(
            signal.fill_nan().range,
            np.array(
                [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]),
            decimal=7)

        signal[3:7] = np.nan

        np.testing.assert_almost_equal(
            signal.fill_nan(method='Constant').range,
            np.array([10.0, 20.0, 30.0, 0.0, 0.0, 0.0, 0.0, 80.0, 90.0,
                      100.0]),
            decimal=7)

    def test_domain_distance(self):
        """
        Tests :func:`colour.continuous.signal.Signal.domain_distance` method.
        """

        self.assertAlmostEqual(
            self._signal.domain_distance(0.5), 0.5, places=7)

        np.testing.assert_almost_equal(
            self._signal.domain_distance(np.linspace(0, 9, 10) + 0.5),
            np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]),
            decimal=7)

    def test_to_series(self):
        """
        Tests :func:`colour.continuous.signal.Signal.to_series` method.
        """

        if is_pandas_installed():
            from pandas import Series

            self.assertEqual(
                Signal(self._range, self._domain).to_series().all(),
                Series(dict(zip(self._domain, self._range))).all())