def test_power_spectrum_from_profile(self):
     #
     # this test was added, because there were issues calling
     # power spectrum 1D with a window given
     #
     t = UniformLineScan([2, 4, 6, 8], 4)
     t.power_spectrum_from_profile(window='hann')
Beispiel #2
0
def test_checkerboard_detrend_order2_1d():
    arr = np.zeros([6])
    arr[:3] = 1.0
    outarr = UniformLineScan(arr,
                             arr.shape).checkerboard_detrend_profile(2,
                                                                     order=2)
    np.testing.assert_allclose(outarr, np.zeros([6]), atol=1e-12)

    arr[0] = -1.0
    outarr = UniformLineScan(arr,
                             arr.shape).checkerboard_detrend_profile(2,
                                                                     order=2)
    np.testing.assert_allclose(outarr, np.zeros([6]), atol=1e-12)

    arr[1] = 1.5
    outarr = UniformLineScan(arr,
                             arr.shape).checkerboard_detrend_profile(2,
                                                                     order=2)
    np.testing.assert_allclose(outarr, np.zeros([6]), atol=1e-12)

    # Order 1 (linear) cannot detrend this topography to zeros
    arr[1] = 1.5
    outarr = UniformLineScan(arr,
                             arr.shape).checkerboard_detrend_profile(2,
                                                                     order=1)
    np.testing.assert_allclose(outarr, [-0.5, 1.0, -0.5, 0.0, 0.0, 0.0],
                               atol=1e-12)
def test_uniform():
    for periodic in [True, False]:
        for L in [1.3, 10.6]:
            for k in [2, 4]:
                for n in [16, 128]:
                    x = np.arange(n) * L / n
                    h = np.sin(2 * np.pi * k * x / L)
                    t = UniformLineScan(h, physical_sizes=L, periodic=periodic)
                    q, C = t.power_spectrum_from_profile()

                    # The ms height of the sine is 1/2. The sum over the PSD
                    # (from -q to +q) is the ms height. Our PSD only contains
                    # *half* of the full PSD (on the +q branch, the -q branch
                    # is identical), therefore the sum over it is 1/4.
                    assert_almost_equal(C.sum() / L, 1 / 4)

                    if periodic:
                        # The value at the individual wavevector must also
                        # equal 1/4. This is only exactly true for the
                        # periodic case. In the nonperiodic, this is convolved
                        # with the Fourier transform of the window function.
                        C /= L
                        r = np.zeros_like(C)
                        r[k] = 1 / 4
                        assert_array_almost_equal(C, r)
 def test_squeeze(self):
     x = np.linspace(0, 4 * np.pi, 101)
     h = np.sin(x)
     surface = UniformLineScan(h, 4 * np.pi).scale(2.0)
     surface2 = surface.squeeze()
     self.assertTrue(isinstance(surface2, UniformLineScan))
     np.testing.assert_allclose(surface.heights(), surface2.heights())
    def test_init_with_lists_calling_scale_and_detrend(self):

        t = UniformLineScan([2, 4, 6, 8],
                            4)  # initialize with list instead of arrays

        # the following commands should be possible without errors
        st = t.scale(1)
        st.detrend(detrend_mode='center')
Beispiel #6
0
def test_numeric_vs_analytical():
    nx = 1001
    L = 7.3
    qs = 2 * np.pi * 8 / L
    t1 = UniformLineScan(np.sin(np.arange(nx) * L * qs / nx), L, periodic=True)

    x, y = t1.scale_dependent_slope_from_profile()
    assert_array_almost_equal(y, np.sqrt(1 - np.cos(qs * x)) / x)
def test_different_dictionary_instance_UniformLineScan():
    """
    see issue #301
    """
    a = UniformLineScan(np.array([1, 2, 3, 4]), physical_sizes=2)
    b = UniformLineScan(np.array([1, 8, 2, 4]), physical_sizes=1)

    assert id(a.info) != id(b.info)
Beispiel #8
0
def test_checkerboard_detrend_1d():
    arr = np.zeros([6])
    arr[:2] = 1.0
    outarr = UniformLineScan(arr, arr.shape).checkerboard_detrend_profile(3)
    np.testing.assert_allclose(outarr, np.zeros([6]), atol=1e-12)

    arr[0] = -1.0
    outarr = UniformLineScan(arr, arr.shape).checkerboard_detrend_profile(3)
    np.testing.assert_allclose(outarr, np.zeros([6]), atol=1e-12)
def test_rms_curvature_paraboloid_uniform_1D():
    n = 16
    x = np.arange(n)
    curvature = 0.1
    heights = 0.5 * curvature * x**2

    surf = UniformLineScan(heights, physical_sizes=(n, ), periodic=False)
    # central finite differences are second order and so exact for the parabola
    assert abs(
        (surf.rms_curvature_from_profile() - curvature) / curvature) < 1e-14
def test_analytic():
    nb_pts = 1488
    s = 4 * np.pi
    x = np.arange(nb_pts) * s / nb_pts
    h = np.sin(x)
    t1 = UniformLineScan(h, (s, ))
    t2 = UniformLineScan(h, (s, ), periodic=True)
    t3 = t1.to_nonuniform()

    d1 = t1.derivative(1)
    d2 = t2.derivative(1)
    d3 = t3.derivative(1)

    np.testing.assert_allclose(d1,
                               np.cos(x[:-1] + (x[1] - x[0]) / 2),
                               atol=1e-5)
    np.testing.assert_allclose(d2, np.cos(x + (x[1] - x[0]) / 2), atol=1e-5)
    np.testing.assert_allclose(d3,
                               np.cos(x[:-1] + (x[1] - x[0]) / 2),
                               atol=1e-5)

    d1 = t1.derivative(2)
    d2 = t2.derivative(2)
    d3 = t3.derivative(2)

    np.testing.assert_allclose(d1, -np.sin(x[:-2] + (x[1] - x[0])), atol=1e-5)
    np.testing.assert_allclose(d2, -np.sin(x), atol=1e-5)
    np.testing.assert_allclose(d3, -np.sin(x[:-2] + (x[1] - x[0])), atol=1e-5)
    def test_detrend_heights_call(self):
        """ tests if the call of heights make no mistake
        """
        n = 10
        dx = 0.5
        h = np.random.normal(size=n)

        t = UniformLineScan(h, dx * n)
        for mode in ["height", "curvature", "slope"]:
            detrended = t.detrend(detrend_mode=mode)
            detrended.heights()
    def test_detrend_curvature(self):
        n = 10
        dx = 0.5
        x = np.arange(n) * dx

        R = 4.
        h = x ** 2 / R

        t = UniformLineScan(h, dx * n)

        detrended = t.detrend(detrend_mode="curvature")

        assert abs(detrended.coeffs[-1] / detrended.physical_sizes[0] ** 2 - 1 / R) < 1e-12
    def test_positions_and_heights(self):

        h = np.array((0, 1, 2, 3, 4))

        t = UniformLineScan(h, 4)

        assert_array_equal(t.heights(), h)

        expected_x = np.array((0., 0.8, 1.6, 2.4, 3.2))
        np.testing.assert_allclose(t.positions(), expected_x)

        x2, h2 = t.positions_and_heights()
        np.testing.assert_allclose(x2, expected_x)
        assert_array_equal(h2, h)
    def test_detrend_same_positions(self):
        """asserts that the detrended topography has the same x
        """
        n = 10
        dx = 0.5
        h = np.random.normal(size=n)

        t = UniformLineScan(h, dx * n)

        for mode in ["curvature", "slope", "height"]:
            detrended = t.detrend(detrend_mode=mode)
            np.testing.assert_allclose(detrended.positions(), t.positions())
            np.testing.assert_allclose(detrended.positions_and_heights()[0],
                                       t.positions_and_heights()[0])
def test_uniform_brute_force_autocorrelation_from_profile():
    n = 10
    for surf in [UniformLineScan(np.ones(n), n, periodic=False),
                 UniformLineScan(np.arange(n), n, periodic=False),
                 Topography(np.random.random(n).reshape(n, 1), (n, 1),
                            periodic=False)]:
        r, A = surf.autocorrelation_from_profile()

        n = len(A)
        dir_A = np.zeros(n)
        for d in range(n):
            for i in range(n - d):
                dir_A[d] += (surf.heights()[i] - surf.heights()[
                    i + d]) ** 2 / 2
            dir_A[d] /= (n - d)
        assert_array_almost_equal(A, dir_A)
 def test_detrend_reduces(self):
     """ tests if detrending really reduces the heights (or slope) as claimed
     """
     n = 10
     dx = 0.5
     h = [0.82355941, -1.32205074, 0.77084813, 0.49928252, 0.57872149,
          2.80200331, 0.09551251, -1.11616977,
          2.07630937, -0.65408072]
     t = UniformLineScan(h, dx * n)
     for mode in ['height', 'curvature', 'slope']:
         detrended = t.detrend(detrend_mode=mode)
         self.assertAlmostEqual(detrended.mean(), 0)
         if mode == 'slope':
             self.assertGreater(t.rms_slope_from_profile(),
                                detrended.rms_slope_from_profile(),
                                msg=mode)
         else:
             self.assertGreater(t.rms_height_from_profile(),
                                detrended.rms_height_from_profile(),
                                msg=mode)
    def test_attribute_error(self):

        h = np.array((0, 1, 2, 3, 4))
        t = UniformLineScan(h, 4)

        with self.assertRaises(AttributeError):
            t.height_scale_factor
        # a scaled line scan has a scale_factor
        self.assertEqual(t.scale(1).height_scale_factor, 1)

        #
        # This should also work after the topography has been pickled
        #
        pt = pickle.dumps(t)
        t2 = pickle.loads(pt)

        with self.assertRaises(AttributeError):
            t2.height_scale_factor
        # a scaled line scan has a scale_factor
        self.assertEqual(t2.scale(1).height_scale_factor, 1)
def test_window_line_scan():
    nx = 27
    sx = 1.3
    h = np.ones((nx, ))

    t = UniformLineScan(h, physical_sizes=(sx, ), periodic=True).window()
    np.testing.assert_almost_equal(t.heights()[0], 1.0)
    np.testing.assert_almost_equal((t.heights()**2).sum() / nx, 1.0)

    t = UniformLineScan(h, physical_sizes=(sx, ), periodic=False).window()
    np.testing.assert_almost_equal(t.heights()[0], 0.0)
    np.testing.assert_almost_equal((t.heights()**2).sum() / nx, 1.0)

    with pytest.raises(ValueError):
        UniformLineScan(h, physical_sizes=(sx, ),
                        periodic=False).window(direction='y').window_data

    with pytest.raises(ValueError):
        UniformLineScan(h, physical_sizes=(sx, ),
                        periodic=False).window(direction='radial').window_data
def test_uniform_impulse_autocorrelation():
    nx = 16
    for x, w, h, p in [(nx // 2, 3, 1, True), (nx // 3, 2, 2, True),
                       (nx // 2, 5, 1, False), (nx // 3, 6, 2.5, False)]:
        y = np.zeros(nx)
        y[x - w // 2:x + (w + 1) // 2] = h
        r, A = UniformLineScan(y, nx, periodic=True).autocorrelation_from_profile()

        A_ana = np.zeros_like(A)
        A_ana[:w] = h ** 2 * np.linspace(w / nx, 1 / nx, w)
        A_ana = A_ana[0] - A_ana
        assert_array_almost_equal(A, A_ana)
Beispiel #20
0
    def test_setting_info_dict(self):

        h = np.array((0, 1, 2, 3, 4))
        t = UniformLineScan(h, 4)

        assert t.info == {}

        t = UniformLineScan(h, 4, info=dict(unit='A'))
        assert t.info['unit'] == 'A'

        #
        # This info should be inherited in the pipeline
        #
        st = t.scale(2)
        assert st.info['unit'] == 'A'

        #
        # It should be also possible to set the info
        #
        st = t.scale(2, info=dict(unit='B'))
        assert st.info['unit'] == 'B'

        #
        # Again the info should be passed
        #
        dt = st.detrend(detrend_mode='center')
        assert dt.info['unit'] == 'B'

        #
        # Alternatively, it can be changed
        #
        dt = st.detrend(detrend_mode='center', info=dict(unit='C'))
        assert dt.info['unit'] == 'C'
def uniform_line_scan(request):
    """Returns a uniform line scan, with all combinations of scaled and detrended.

    Detrended is always executed after scaling, if requested.

    Returns
    -------
    A uniform line scan.
    """
    x = np.linspace(0, 4 * np.pi, 11)
    h = np.sin(x)
    uniform_line_scan = UniformLineScan(h, 4 * np.pi)
    return apply_param(uniform_line_scan, request.param)
    def test_setting_info_dict(self):

        h = np.array((0, 1, 2, 3, 4))
        t = UniformLineScan(h, 4)

        assert t.info == {}

        with pytest.deprecated_call():
            t = UniformLineScan(h, 4, info=dict(unit='A'))
        t = UniformLineScan(h, 4, unit='A')
        with pytest.deprecated_call():
            assert t.info['unit'] == 'A'

        #
        # This info should be inherited in the pipeline
        #
        st = t.scale(2)
        with pytest.deprecated_call():
            assert st.info['unit'] == 'A'

        #
        # It should be also possible to set the info
        #
        with pytest.deprecated_call():
            st = t.scale(2, info=dict(unit='B'))
        st = t.scale(2, 2, unit='B')
        with pytest.deprecated_call():
            assert st.info['unit'] == 'B'

        #
        # Again the info should be passed
        #
        dt = st.detrend(detrend_mode='center')
        with pytest.deprecated_call():
            assert dt.info['unit'] == 'B'

        #
        # It can no longer be changed in detrend (you need to use scale)
        #
        with pytest.deprecated_call():
            dt = st.detrend(detrend_mode='center', info=dict(unit='C'))
def test_default_window_1D():
    x = np.linspace(0, 1, 200)
    heights = np.cos(2 * np.pi * x * 8.3)
    topography = UniformLineScan(heights, physical_sizes=1, periodic=True)

    if True:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots()
        ax.plot(*topography.power_spectrum_1D(), label="periodic=True")
        ax.set_xscale("log")
        ax.set_yscale("log")

    topography = UniformLineScan(heights, physical_sizes=1, periodic=False)

    if True:
        import matplotlib.pyplot as plt
        ax.plot(*topography.power_spectrum_1D(), label="periodic=False")
        ax.set_xscale("log")
        ax.set_yscale("log")
        ax.set_ylim(bottom=1e-6)
        ax.legend()
        plt.show(block=True)
 def test_rms_slope_uniform(self):
     numerical = UniformLineScan(self.sinsurf[:-1],
                                 self.L).rms_slope_from_profile()
     analytical = np.sqrt(2 * np.pi**2 * self.hm**2 / self.L**2)
     # print(numerical-analytical)
     self.assertAlmostEqual(numerical, analytical, self.precision)
def test_scale_factor():
    nx = 8
    sx = 1

    topography = fourier_synthesis((nx, ), (sx, ),
                                   0.8,
                                   rms_height=1.,
                                   periodic=True)
    topography1 = UniformLineScan(topography.heights()[::2], sx, periodic=True)
    topography2 = UniformLineScan(topography.heights()[1::2],
                                  sx,
                                  periodic=True)

    d1 = topography.derivative(1, scale_factor=1)
    d2 = topography.derivative(1, scale_factor=np.uint32(2))
    d3 = topography1.derivative(1, scale_factor=1)
    d4 = topography2.derivative(1, scale_factor=1)

    assert len(d2) == len(d1)
    np.testing.assert_allclose(d3, d2[::2])
    np.testing.assert_allclose(d4, d2[1::2])

    topography = fourier_synthesis((nx, ), (sx, ),
                                   0.8,
                                   rms_height=1.,
                                   periodic=False)
    topography1 = UniformLineScan(topography.heights()[::2],
                                  sx,
                                  periodic=False)
    topography2 = UniformLineScan(topography.heights()[1::2],
                                  sx,
                                  periodic=False)

    d1, d2 = topography.derivative(1, scale_factor=[1, 2])
    d3 = topography1.derivative(1, scale_factor=1)
    d4 = topography2.derivative(1, scale_factor=1)

    assert len(d2) == len(d1) - 1
    np.testing.assert_allclose(d3, d2[::2])
    np.testing.assert_allclose(d4, d2[1::2])

    ny = 10
    sy = 0.8
    topography = fourier_synthesis((nx, ny), (sx, sy),
                                   0.8,
                                   rms_height=1.,
                                   periodic=False)

    dx, dy = topography.derivative(1, scale_factor=[1, 2, 4])
    dx1, dx2, dx4 = dx
    dy1, dy2, dy4 = dy

    assert dx1.shape[0] == nx - 1
    assert dx1.shape[1] == ny - 1
    assert dy1.shape[0] == nx - 1
    assert dy1.shape[1] == ny - 1
    assert dx2.shape[0] == nx - 2
    assert dx2.shape[1] == ny - 2
    assert dy2.shape[0] == nx - 2
    assert dy2.shape[1] == ny - 2
    assert dx4.shape[0] == nx - 4
    assert dx4.shape[1] == ny - 4
    assert dy4.shape[0] == nx - 4
    assert dy4.shape[1] == ny - 4

    dx, dy = topography.derivative(1, scale_factor=[(1, 4), (2, 1), (4, 2)])
    dxn1, dxn2, dxn4 = dx
    dyn4, dyn1, dyn2 = dy
    np.testing.assert_allclose(dxn1, dx1)
    np.testing.assert_allclose(dyn1, dy1)
    np.testing.assert_allclose(dxn2, dx2)
    np.testing.assert_allclose(dyn2, dy2)
    np.testing.assert_allclose(dxn4, dx4)
    np.testing.assert_allclose(dyn4, dy4)
def test_lbfgsb_1D(dx, n):
    # test the 1D periodic objective is working

    s = n * dx

    Es = 1.

    substrate = PeriodicFFTElasticHalfSpace((n,), young=Es,
                                            physical_sizes=(s,), fft='serial')

    surface = UniformLineScan(np.cos(2 * np.pi * np.arange(n) / n), (s,))
    system = make_system(substrate, surface)

    offset = 0.005
    lbounds = np.zeros(n)
    bnds = system._reshape_bounds(lbounds, )
    init_gap = np.zeros(n, )  # .flatten()
    disp = init_gap + surface.heights() + offset

    res = optim.minimize(system.primal_objective(offset, gradient=True),
                         disp,
                         method='L-BFGS-B', jac=True,
                         bounds=bnds,
                         options=dict(gtol=1e-5 * Es * surface.rms_slope_from_profile()
                                      * surface.area_per_pt,
                                      ftol=0))

    forces = res.jac
    gap = res.x
    converged = res.success
    assert converged
    if hasattr(res.message, "decode"):
        decoded_message = res.message.decode()
    else:
        decoded_message = res.message

    assert decoded_message == \
        'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'

    x = np.arange(n) * s / n
    mean_pressure = np.mean(forces) / substrate.area_per_pt

    assert mean_pressure > 0

    pth = mean_pressure * _pressure(
        x / s,
        mean_pressure=s * mean_pressure / Es)

    if False:
        import matplotlib.pyplot as plt
        plt.figure()
        # plt.plot(np.arange(n)*s/n, surface.heights())
        plt.plot(x, gap + (surface.heights()[:] + offset), 'r-')
        plt.plot(x, (surface.heights()[:] + offset), 'k-')
        plt.figure()
        plt.plot(x, forces / substrate.area_per_pt, 'k-')
        plt.plot(x, pth, 'r-')
        plt.show()

    assert (np.allclose(
        forces /
        substrate.area_per_pt, pth, atol=1e-2))
    def test_properties(self):

        x = np.array((0, 1, 2, 3, 4))
        h = 2 * x
        t = UniformLineScan(h, 5)
        self.assertEqual(t.dim, 1)
    def test_smooth_flat_1d(self):
        arr = self._flat_arr

        a = 1.2
        d = .2
        arr = np.arange(5) * a + d

        surf = UniformLineScan(arr, (1,)).detrend(detrend_mode='center')
        self.assertTrue(surf.is_uniform)
        self.assertAlmostEqual(surf.mean(), 0)

        surf = UniformLineScan(arr, (1.5,)).detrend(detrend_mode='slope')
        self.assertEqual(surf.dim, 1)
        self.assertTrue(surf.is_uniform)
        self.assertAlmostEqual(surf.mean(), 0)
        self.assertAlmostEqual(surf.rms_slope_from_profile(), 0)

        surf = UniformLineScan(arr, arr.shape).detrend(detrend_mode='height')
        self.assertEqual(surf.dim, 1)
        self.assertTrue(surf.is_uniform)
        self.assertAlmostEqual(surf.mean(), 0)
        self.assertAlmostEqual(surf.rms_slope_from_profile(), 0)
        self.assertTrue(
            surf.rms_height_from_profile() < UniformLineScan(arr, arr.shape).rms_height_from_profile())

        surf2 = UniformLineScan(arr, (1,)).detrend(detrend_mode='height')
        self.assertEqual(surf.dim, 1)
        self.assertTrue(surf2.is_uniform)
        self.assertAlmostEqual(surf2.rms_slope_from_profile(), 0)
        self.assertTrue(
            surf2.rms_height_from_profile() < UniformLineScan(arr, arr.shape).rms_height_from_profile())

        self.assertAlmostEqual(surf.rms_height_from_profile(), surf2.rms_height_from_profile())

        x, z = surf2.positions_and_heights()
        self.assertAlmostEqual(np.mean(np.diff(x)),
                               surf2.physical_sizes[0] / surf2.nb_grid_pts[0])
Beispiel #29
0
 def test_checkerboard_detrend_1d(self):
     arr = np.zeros([4])
     arr[:2] = 1.0
     outarr = UniformLineScan(arr, arr.shape).checkerboard_detrend((2,))
     np.testing.assert_allclose(outarr, np.zeros([4]))