예제 #1
0
    def test_crop(self, use_indices):
        axis = UniformDataAxis(size=10, scale=0.1, offset=10)
        start = 10.2
        if use_indices:
            start = axis.value2index(start)
        axis.crop(start)
        assert axis.size == 8
        np.testing.assert_almost_equal(axis.axis[0], 10.2)
        np.testing.assert_almost_equal(axis.axis[-1], 10.9)
        np.testing.assert_almost_equal(axis.offset, 10.2)
        np.testing.assert_almost_equal(axis.scale, 0.1)

        axis = UniformDataAxis(size=10, scale=0.1, offset=10)
        end = 10.4
        if use_indices:
            end = axis.value2index(end)
        axis.crop(start, end)
        assert axis.size == 2
        np.testing.assert_almost_equal(axis.axis[0], 10.2)
        np.testing.assert_almost_equal(axis.axis[-1], 10.3)
        np.testing.assert_almost_equal(axis.offset, 10.2)
        np.testing.assert_almost_equal(axis.scale, 0.1)

        axis = UniformDataAxis(size=10, scale=0.1, offset=10)
        axis.crop(None, end)
        assert axis.size == 4
        np.testing.assert_almost_equal(axis.axis[0], 10.0)
        np.testing.assert_almost_equal(axis.axis[-1], 10.3)
        np.testing.assert_almost_equal(axis.offset, 10.0)
        np.testing.assert_almost_equal(axis.scale, 0.1)
예제 #2
0
def test_rounding_consistency_axis_type_half(shift):

    axis = UniformDataAxis(size=20, scale=0.1, offset=-1.0);
    test_vals = axis.axis[:-1] + shift

    uaxis_indices = axis.value2index(test_vals)
    nuaxis_indices = super(type(axis), axis).value2index(test_vals)

    np.testing.assert_allclose(uaxis_indices, nuaxis_indices)
예제 #3
0
def test_rounding_consistency_axis_type():
    scales = [0.1, -0.1, 0.1, -0.1]
    offsets = [-11.0, -10.9, 10.9, 11.0]
    values = [-10.95, -10.95, 10.95, 10.95]

    for i, (scale, offset, value) in enumerate(zip(scales, offsets, values)):
        ax = UniformDataAxis(scale=scale, offset=offset, size=3)
        ua_idx = ax.value2index(value)
        nua_idx = super(type(ax), ax).value2index(value)
        print('scale', scale)
        print('offset', offset)
        print('Axis values:', ax.axis)
        print(f"value: {value} --> uniform: {ua_idx}, non-uniform: {nua_idx}")
        print("\n")
        assert nua_idx == ua_idx
예제 #4
0
class TestUniformDataAxis:

    def setup_method(self, method):
        self.axis = UniformDataAxis(size=10, scale=0.1, offset=10)

    def _test_initialisation_parameters(self, axis):
        assert axis.scale == 0.1
        assert axis.offset == 10
        def func(x): return axis.scale * x + axis.offset
        np.testing.assert_allclose(axis.axis, func(np.arange(10)))

    def test_initialisation_parameters(self):
        self._test_initialisation_parameters(self.axis)

    def test_create_axis(self):
        axis = create_axis(**self.axis.get_axis_dictionary())
        assert isinstance(axis, UniformDataAxis)
        self._test_initialisation_parameters(axis)

    def test_value_range_to_indices_in_range(self):
        assert self.axis.is_uniform
        assert (
            self.axis.value_range_to_indices(
                10.1, 10.8) == (1, 8))

    def test_value_range_to_indices_endpoints(self):
        assert self.axis.value_range_to_indices(10, 10.9) == (0, 9)

    def test_value_range_to_indices_out(self):
        assert self.axis.value_range_to_indices(9, 11) == (0, 9)

    def test_value_range_to_indices_None(self):
        assert self.axis.value_range_to_indices(None, None) == (0, 9)

    def test_value_range_to_indices_v1_greater_than_v2(self):
        with pytest.raises(ValueError):
            self.axis.value_range_to_indices(2, 1)

    def test_deepcopy(self):
        ac = copy.deepcopy(self.axis)
        ac.offset = 100
        assert self.axis.offset != ac.offset
        assert self.axis.navigate == ac.navigate
        assert self.axis.is_binned == ac.is_binned

    def test_deepcopy_on_trait_change(self):
        ac = copy.deepcopy(self.axis)
        ac.offset = 100
        assert ac.axis[0] == ac.offset

    def test_uniform_value2index(self):
        #Tests for value2index
        #Works as intended
        assert self.axis.value2index(10.15) == 1
        assert self.axis.value2index(10.17, rounding=math.floor) == 1
        assert self.axis.value2index(10.13, rounding=math.ceil) == 2
        # Test that output is integer
        assert isinstance(self.axis.value2index(10.15), (int, np.integer))
        #Endpoint left
        assert self.axis.value2index(10.) == 0
        #Endpoint right
        assert self.axis.value2index(10.9) == 9
        #Input None --> output None
        assert self.axis.value2index(None) == None
        #NaN in --> error out
        with pytest.raises(ValueError):
            self.axis.value2index(np.nan)
        #Values in out of bounds --> error out (both sides of axis)
        with pytest.raises(ValueError):
            self.axis.value2index(-2)
        with pytest.raises(ValueError):
            self.axis.value2index(111)
        #str without unit in --> error out
        with pytest.raises(ValueError):
            self.axis.value2index("69")
        #Empty str in --> error out
        with pytest.raises(ValueError):
            self.axis.value2index("")
        #Value with unit when axis is unitless --> Error out
        with pytest.raises(ValueError):
            self.axis.value2index("0.0101um")

        #Tests with array Input
        #Arrays work as intended
        arval = np.array([[10.15, 10.15], [10.24, 10.28]])
        assert np.all(self.axis.value2index(arval) \
                        == np.array([[1, 1], [2, 3]]))
        assert np.all(self.axis.value2index(arval, rounding=math.floor) \
                        == np.array([[1, 1], [2, 2]]))
        assert np.all(self.axis.value2index(arval, rounding=math.ceil)\
                        == np.array([[2, 2], [3, 3]]))
        #List in --> array out
        assert np.all(self.axis.value2index(arval.tolist()) \
                                            == np.array([[1, 1], [2, 3]]))
        #One value out of bound in array in --> error out (both sides)
        arval[1, 1] = 111
        with pytest.raises(ValueError):
            self.axis.value2index(arval)
        arval[1, 1] = -0.3
        with pytest.raises(ValueError):
            self.axis.value2index(arval)
        #One NaN in array in --> error out
        if platform.machine() != 'aarch64':
            # Skip aarch64 platform because it doesn't raise error
            arval[1, 1] = np.nan
            with pytest.raises(ValueError):
                self.axis.value2index(arval)

        #Copy of axis with units
        axis = copy.deepcopy(self.axis)
        axis.units = 'nm'

        #Value with unit in --> OK out
        assert axis.value2index("0.0101um") == 1
        #Value with relative units in --> OK out
        assert self.axis.value2index("rel0.5") == 4

        #Works with arrays of values with units in
        np.testing.assert_allclose(
            axis.value2index(['0.01um', '0.0101um', '0.0103um']),
            np.array([0, 1, 3])
            )
        #Raises errors if a weird unit is passed in
        with pytest.raises(BaseException):
            axis.value2index(["0.01uma", '0.0101uma', '0.0103uma'])
        #Values
        np.testing.assert_allclose(
            self.axis.value2index(["rel0.0", "rel0.5", "rel1.0"]),
            np.array([0, 4, 9])
            )

    def test_slice_me(self):
        assert (
            self.axis._slice_me(slice(np.float32(10.2), 10.4, 2)) ==
            slice(2, 4, 2)
            )

    def test_update_from(self):
        ax2 = UniformDataAxis(size=2, units="nm", scale=0.5)
        self.axis.update_from(ax2, attributes=("units", "scale"))
        assert ((ax2.units, ax2.scale) ==
                (self.axis.units, self.axis.scale))

    def test_value_changed_event(self):
        ax = self.axis
        m = mock.Mock()
        ax.events.value_changed.connect(m.trigger_me)
        ax.value = ax.value
        assert not m.trigger_me.called
        ax.value = ax.value + ax.scale * 0.3
        assert not m.trigger_me.called
        ax.value = ax.value + ax.scale
        assert m.trigger_me.called

    def test_index_changed_event(self):
        ax = self.axis
        m = mock.Mock()
        ax.events.index_changed.connect(m.trigger_me)
        ax.index = ax.index
        assert not m.trigger_me.called
        ax.index += 1
        assert m.trigger_me.called

    def test_convert_to_non_uniform_axis(self):
        axis = np.copy(self.axis.axis)
        is_binned = self.axis.is_binned
        navigate = self.axis.navigate
        self.axis.name = "parrot"
        self.axis.units = "plumage"
        s = Signal1D(np.arange(10), axes=[self.axis])
        index_in_array = s.axes_manager[0].index_in_array
        s.axes_manager[0].convert_to_non_uniform_axis()
        assert isinstance(s.axes_manager[0], DataAxis)
        assert s.axes_manager[0].name == "parrot"
        assert s.axes_manager[0].units == "plumage"
        assert s.axes_manager[0].size == 10
        assert s.axes_manager[0].low_value == 10
        assert s.axes_manager[0].high_value == 10 + 0.1 * 9
        np.testing.assert_allclose(s.axes_manager[0].axis, axis)
        with pytest.raises(AttributeError):
            s.axes_manager[0].offset
        with pytest.raises(AttributeError):
            s.axes_manager[0].scale
        assert index_in_array == s.axes_manager[0].index_in_array
        assert is_binned == s.axes_manager[0].is_binned
        assert navigate == s.axes_manager[0].navigate

    def test_convert_to_functional_data_axis(self):
        axis = np.copy(self.axis.axis)
        is_binned = self.axis.is_binned
        navigate = self.axis.navigate
        self.axis.name = "parrot"
        self.axis.units = "plumage"
        s = Signal1D(np.arange(10), axes=[self.axis])
        index_in_array = s.axes_manager[0].index_in_array
        s.axes_manager[0].convert_to_functional_data_axis(expression = 'x**2')
        assert isinstance(s.axes_manager[0], FunctionalDataAxis)
        assert s.axes_manager[0].name == "parrot"
        assert s.axes_manager[0].units == "plumage"
        assert s.axes_manager[0].size == 10
        assert s.axes_manager[0].low_value == 10**2
        assert s.axes_manager[0].high_value == (10 + 0.1 * 9)**2
        assert s.axes_manager[0]._expression == 'x**2'
        assert isinstance(s.axes_manager[0].x, UniformDataAxis)
        np.testing.assert_allclose(s.axes_manager[0].axis, axis**2)
        with pytest.raises(AttributeError):
            s.axes_manager[0].offset
        with pytest.raises(AttributeError):
            s.axes_manager[0].scale
        assert index_in_array == s.axes_manager[0].index_in_array
        assert is_binned == s.axes_manager[0].is_binned
        assert navigate == s.axes_manager[0].navigate

    @pytest.mark.parametrize("use_indices", (False, True))
    def test_crop(self, use_indices):
        axis = UniformDataAxis(size=10, scale=0.1, offset=10)
        start = 10.2
        if use_indices:
            start = axis.value2index(start)
        axis.crop(start)
        assert axis.size == 8
        np.testing.assert_almost_equal(axis.axis[0], 10.2)
        np.testing.assert_almost_equal(axis.axis[-1], 10.9)
        np.testing.assert_almost_equal(axis.offset, 10.2)
        np.testing.assert_almost_equal(axis.scale, 0.1)

        axis = UniformDataAxis(size=10, scale=0.1, offset=10)
        end = 10.4
        if use_indices:
            end = axis.value2index(end)
        axis.crop(start, end)
        assert axis.size == 2
        np.testing.assert_almost_equal(axis.axis[0], 10.2)
        np.testing.assert_almost_equal(axis.axis[-1], 10.3)
        np.testing.assert_almost_equal(axis.offset, 10.2)
        np.testing.assert_almost_equal(axis.scale, 0.1)

        axis = UniformDataAxis(size=10, scale=0.1, offset=10)
        axis.crop(None, end)
        assert axis.size == 4
        np.testing.assert_almost_equal(axis.axis[0], 10.0)
        np.testing.assert_almost_equal(axis.axis[-1], 10.3)
        np.testing.assert_almost_equal(axis.offset, 10.0)
        np.testing.assert_almost_equal(axis.scale, 0.1)

    @pytest.mark.parametrize("mixed", (False, True))
    def test_crop_reverses_indexing(self, mixed):
        axis = UniformDataAxis(size=10, scale=0.1, offset=10)
        if mixed:
            i1, i2 = 2, -6
        else:
            i1, i2 = -8, -6
        axis.crop(i1, i2)
        assert axis.size == 2
        np.testing.assert_almost_equal(axis.axis[0], 10.2)
        np.testing.assert_almost_equal(axis.axis[-1], 10.3)
        np.testing.assert_almost_equal(axis.offset, 10.2)
        np.testing.assert_almost_equal(axis.scale, 0.1)

    def test_parse_value(self):
        ax = copy.deepcopy(self.axis)
        ax.units = 'nm'
        # slicing by index
        assert ax._parse_value(5) == 5
        assert type(ax._parse_value(5)) is int
        # slicing by calibrated value
        assert ax._parse_value(10.5) == 10.5
        assert type(ax._parse_value(10.5)) is float
        # slicing by unit
        assert ax._parse_value('10.5nm') == 10.5
        np.testing.assert_almost_equal(ax._parse_value('10500pm'), 10.5)

    def test_parse_value_from_relative_string(self):
        ax = self.axis
        assert ax._parse_value_from_string('rel0.0') == 10.0
        assert ax._parse_value_from_string('rel0.5') == 10.45
        assert ax._parse_value_from_string('rel1.0') == 10.9

    def test_slice_empty_string(self):
        ax = self.axis
        with pytest.raises(ValueError):
            ax._parse_value("")

    def test_calibrate(self):
        offset, scale = self.axis.calibrate(value_tuple=(11,12), \
                                index_tuple=(0,5), modify_calibration=False)
        assert scale == 0.2
        assert offset == 11
        self.axis.calibrate(value_tuple=(11,12), index_tuple=(0,5))
        assert self.axis.scale == 0.2
        assert self.axis.offset == 11