Example #1
0
def structure_function(image):
    """Estimate the angularly-averaged structure function of a 2D random field.

    The angularly-averaged structure function D(r) of the 2D field phi is defined as:

    D(|r|) = <|phi(x) - phi(x+r)|^2>

    where the x and r on the RHS are 2D vectors, but the |r| on the LHS is just a scalar length.

    @param image  Image containing random field realization.  The `.scale` attribute here *is* used
                  in the calculation.  If it's `None`, then the code will use 1.0 for the scale.
    @returns      A python callable mapping a separation length r to the estimate of the structure
                  function D(r).
    """
    array = image.array
    nx, ny = array.shape
    scale = image.scale
    if scale is None:
        scale = 1.0

    # The structure function can be derived from the correlation function B(r) as:
    # D(r) = 2 * [B(0) - B(r)]

    corr = np.fft.ifft2(np.abs(np.fft.fft2(np.fft.fftshift(array)))**2).real / (nx * ny)
    # Check that the zero-lag correlation function is equal to the variance before doing the
    # ifftshift.
    assert (corr[0, 0] / np.var(array) - 1.0) < 1e-6
    corr = np.fft.ifftshift(corr)

    x = scale * (np.arange(nx) - nx//2)
    y = scale * (np.arange(ny) - ny//2)
    tab = galsim.LookupTable2D(x, y, corr)
    thetas = np.arange(0., 2*np.pi, 100)  # Average over these angles.

    return lambda r: 2*(tab(0.0, 0.0) - np.mean(tab(r*np.cos(thetas), r*np.sin(thetas))))
Example #2
0
def shrink_layer(layer, factor):
    tab2d = layer._tab2d
    orig = tab2d.f[:-1, :-1]

    new = orig[::factor, ::factor]

    ret = galsim.AtmosphericScreen.__new__(galsim.AtmosphericScreen)
    ret.npix = new.shape[0]
    ret.screen_scale = layer.screen_scale * factor
    ret.screen_size = layer.screen_size
    ret.altitude = layer.altitude
    ret.time_step = layer.time_step
    ret.r0_500 = layer.r0_500
    ret.L0 = layer.L0
    ret.vx = layer.vx
    ret.vy = layer.vy
    ret.alpha = layer.alpha
    ret._time = layer._time
    ret._orig_rng = layer._orig_rng.duplicate()
    ret.dynamic = layer.dynamic
    ret.reversible = layer.reversible
    ret.rng = layer.rng.duplicate()
    ret._xs = layer._xs[::factor]
    ret._ys = layer._ys[::factor]
    ret._tab2d = galsim.LookupTable2D(ret._xs,
                                      ret._ys,
                                      new,
                                      interpolant='linear',
                                      edge_mode='wrap')
    ret.kmin = layer.kmin
    ret.kmax = layer.kmax

    return ret
Example #3
0
 def _seek(self, t):
     """Set layer's internal clock to time t."""
     if t == self._time:
         return
     if not self.reversible:
         # Can't reverse, so reset and move forward.
         if t < self._time:
             if t < 0.0:
                 raise ValueError(
                     "Can't rewind irreversible screen to t < 0.0")
             self._reset()
         # Find number of boiling updates we need to perform.
         previous_update_number = int(self._time // self.time_step)
         final_update_number = int(t // self.time_step)
         n_updates = final_update_number - previous_update_number
         if n_updates > 0:
             for _ in range(n_updates):
                 self._screen *= self.alpha
                 self._screen += np.sqrt(
                     1. - self.alpha**2) * self._random_screen()
             self._tab2d = galsim.LookupTable2D(self._xs,
                                                self._ys,
                                                self._screen,
                                                edge_mode='wrap')
     self._time = float(t)
Example #4
0
 def advance(self):
     """Advance phase screen realization by self.time_step."""
     # Moving the origin of the aperture in the opposite direction of the wind is equivalent to
     # moving the screen with the wind.
     self.origin -= (self.vx*self.time_step, self.vy*self.time_step)
     # "Boil" the atmsopheric screen if alpha not 1.
     if self.alpha != 1.0:
         self.screen = self.alpha*self.screen + np.sqrt(1.-self.alpha**2)*self._random_screen()
         self.tab2d = galsim.LookupTable2D(self._xs, self._ys, self.screen, edge_mode='wrap')
Example #5
0
    def _reset(self):
        """Reset phase screen back to time=0."""
        self.rng = self._orig_rng.duplicate()
        self._time = 0.0

        # Only need to reset/create tab2d if not frozen or doesn't already exist
        if not self.reversible or not hasattr(self, '_tab2d'):
            self._screen = self._random_screen()
            self._xs = np.linspace(-0.5*self.screen_size, 0.5*self.screen_size, self.npix,
                                   endpoint=False)
            self._ys = self._xs
            self._tab2d = galsim.LookupTable2D(self._xs, self._ys, self._screen, edge_mode='wrap')
Example #6
0
def test_ne():
    """ Check that inequality works as expected."""
    # These should all compare as unequal.
    x = [1, 2, 3]
    f = [4, 5, 6]
    x2 = [1.1, 2.2, 3.3]
    f2 = [4.4, 5.5, 6.6]
    lts = [
        galsim.LookupTable(x, f),
        galsim.LookupTable(x, f2),
        galsim.LookupTable(x2, f),
        galsim.LookupTable(x, f, interpolant='floor'),
        galsim.LookupTable(x, f, x_log=True),
        galsim.LookupTable(x, f, f_log=True)
    ]

    ff = f + np.array(f)[:, None]
    ff2 = f2 + np.array(f2)[:, None]
    lts.extend([
        galsim.LookupTable2D(x, x, ff),
        galsim.LookupTable2D(x2, x, ff),
        galsim.LookupTable2D(x, x2, ff),
        galsim.LookupTable2D(x, x2, ff2),
        galsim.LookupTable2D(x, x, ff, interpolant='nearest'),
        galsim.LookupTable2D(x, x, ff, interpolant=galsim.Nearest()),
        galsim.LookupTable2D(x, x, ff, edge_mode='wrap'),
        galsim.LookupTable2D(x, x, ff, constant=1),
        galsim.LookupTable2D(x, x, ff, interpolant='spline'),
        galsim.LookupTable2D(x,
                             x,
                             ff,
                             interpolant='spline',
                             dfdx=ff,
                             dfdy=ff,
                             d2fdxdy=ff)
    ])
    all_obj_diff(lts)
Example #7
0
def test_table2d():
    """Check LookupTable2D functionality.
    """
    has_scipy = False
    try:
        import scipy
        from distutils.version import LooseVersion
        if LooseVersion(scipy.__version__) < LooseVersion('0.11'):
            raise ImportError
    except ImportError:
        print("SciPy tests require SciPy version 0.11 or greater")
    else:
        from scipy.interpolate import interp2d
        has_scipy = True

    def f(x_, y_):
        return np.sin(x_) * np.cos(y_) + x_

    x = np.linspace(0.1, 3.3, 25)
    y = np.linspace(0.2, 10.4, 75)
    yy, xx = np.meshgrid(y,
                         x)  # Note the ordering of both input and output here!
    z = f(xx, yy)

    tab2d = galsim.LookupTable2D(x, y, z)
    do_pickle(tab2d)
    do_pickle(tab2d.table)

    newx = np.linspace(0.2, 3.1, 45)
    newy = np.linspace(0.3, 10.1, 85)
    newyy, newxx = np.meshgrid(newy, newx)

    # Compare different ways of evaluating Table2D
    ref = tab2d(newxx, newyy)
    np.testing.assert_array_almost_equal(
        ref, np.array([[tab2d(x0, y0) for y0 in newy] for x0 in newx]))
    if has_scipy:
        scitab2d = interp2d(x, y, np.transpose(z))
        np.testing.assert_array_almost_equal(
            ref, np.transpose(scitab2d(newx, newy)))

    # Test non-equally-spaced table.
    x = np.delete(x, 10)
    y = np.delete(y, 10)
    yy, xx = np.meshgrid(y, x)
    z = f(xx, yy)
    tab2d = galsim.LookupTable2D(x, y, z)
    ref = tab2d(newxx, newyy)
    np.testing.assert_array_almost_equal(
        ref, np.array([[tab2d(x0, y0) for y0 in newy] for x0 in newx]))
    if has_scipy:
        scitab2d = interp2d(x, y, np.transpose(z))
        np.testing.assert_array_almost_equal(
            ref, np.transpose(scitab2d(newx, newy)))

    # Try a simpler interpolation function.  We should be able to interpolate a (bi-)linear function
    # exactly with a linear interpolant.
    def f(x_, y_):
        return 2 * x_ + 3 * y_

    z = f(xx, yy)
    tab2d = galsim.LookupTable2D(x, y, z)

    np.testing.assert_array_almost_equal(f(newxx, newyy), tab2d(newxx, newyy))
    np.testing.assert_array_almost_equal(
        f(newxx, newyy),
        np.array([[tab2d(x0, y0) for y0 in newy] for x0 in newx]))

    # Test edge exception
    try:
        np.testing.assert_raises(ValueError, tab2d, 1e6, 1e6)
    except ImportError:
        print('The assert_raises tests require nose')

    # Test edge wrapping
    # Check that can't construct table with edge-wrapping if edges don't match
    try:
        np.testing.assert_raises(ValueError, galsim.LookupTable, (x, y, z),
                                 dict(edge_mode='wrap'))
    except ImportError:
        print('The assert_warns tests require nose')

    # Extend edges and make vals match
    x = np.append(x, x[-1] + (x[-1] - x[-2]))
    y = np.append(y, y[-1] + (y[-1] - y[-2]))
    z = np.pad(z, [(0, 1), (0, 1)], mode='wrap')
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='wrap')

    np.testing.assert_array_almost_equal(
        tab2d(newxx, newyy), tab2d(newxx + 3 * (x[-1] - x[0]), newyy))
    np.testing.assert_array_almost_equal(
        tab2d(newxx, newyy), tab2d(newxx, newyy + 13 * (y[-1] - y[0])))

    # Test edge_mode='constant'
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='constant', constant=42)
    assert type(tab2d(x[0] - 1, y[0] - 1)) == float
    assert tab2d(x[0] - 1, y[0] - 1) == 42.0
    # One in-bounds, one out-of-bounds
    np.testing.assert_array_almost_equal(
        tab2d([x[0], x[0] - 1], [y[0], y[0] - 1]), [tab2d(x[0], y[0]), 42.0])

    # Test floor/ceil/nearest interpolant
    x = y = np.arange(5)
    z = x + y[:, np.newaxis]
    tab2d = galsim.LookupTable2D(x, y, z, interpolant='ceil')
    assert tab2d(2.4, 3.6) == 3 + 4, "Ceil interpolant failed."
    tab2d = galsim.LookupTable2D(x, y, z, interpolant='floor')
    assert tab2d(2.4, 3.6) == 2 + 3, "Floor interpolant failed."
    tab2d = galsim.LookupTable2D(x, y, z, interpolant='nearest')
    assert tab2d(2.4, 3.6) == 2 + 4, "Nearest interpolant failed."

    # Test that x,y arrays need to be strictly increasing.
    try:
        x[0] = x[1]
        np.testing.assert_raises(ValueError, galsim.LookupTable2D, x, y, z)
        x[0] = x[1] + 1
        np.testing.assert_raises(ValueError, galsim.LookupTable2D, x, y, z)
        x[0] = x[1] - 1
        y[0] = y[1]
        np.testing.assert_raises(ValueError, galsim.LookupTable2D, x, y, z)
        y[0] = y[1] + 1
        np.testing.assert_raises(ValueError, galsim.LookupTable2D, x, y, z)
    except ImportError:
        print('The assert_raises tests require nose')
Example #8
0
def test_table2d_cubic():
    # A few functions that should be exactly interpolatable with bicubic
    # interpolation
    def f1(x_, y_):
        return 2 * x_ + 3 * y_

    def df1dx(x_, y_):
        return np.ones_like(x_) * 2

    def df1dy(x_, y_):
        return np.ones_like(x_) * 3

    def f2(x_, y_):
        return 2 * x_ * x_

    def df2dx(x_, y_):
        return 4 * x_

    def df2dy(x_, y_):
        return np.zeros_like(x_)

    def f3(x_, y_):
        return 2 * y_ * y_

    def df3dx(x_, y_):
        return np.zeros_like(x_)

    def df3dy(x_, y_):
        return 4 * y_

    def f4(x_, y_):
        return 2 * y_ * y_ + 3 * x_ * x_

    def df4dx(x_, y_):
        return 6 * x_

    def df4dy(x_, y_):
        return 4 * y_

    def f5(x_, y_):
        return 2 * y_ * y_ + 3 * x_ * x_ + 4 * x_ * y_

    def df5dx(x_, y_):
        return 6 * x_ + 4 * y_

    def df5dy(x_, y_):
        return 4 * y_ + 4 * x_

    fs = [f1, f2, f3, f4, f5]
    dfdxs = [df1dx, df2dx, df3dx, df4dx, df5dx]
    dfdys = [df1dy, df2dy, df3dy, df4dy, df5dy]

    x = np.linspace(0.1, 3.3, 250)
    y = np.linspace(0.2, 10.4, 750)
    yy, xx = np.meshgrid(y,
                         x)  # Note the ordering of both input and output here!

    for f, dfdx, dfdy in zip(fs, dfdxs, dfdys):
        z = f(xx, yy)
        tab2d = galsim.LookupTable2D(x, y, z, interpolant='spline')

        # Check single value functionality.
        x1, y1 = 2.3, 1.2
        np.testing.assert_allclose(tab2d(x1, y1),
                                   f(x1, y1),
                                   atol=1e-11,
                                   rtol=0)
        ref_dfdx = dfdx(x1, y1)
        ref_dfdy = dfdy(x1, y1)
        test_dfdx, test_dfdy = tab2d.gradient(x1, y1)
        np.testing.assert_allclose(test_dfdx, ref_dfdx, atol=1e-11, rtol=0)
        np.testing.assert_allclose(test_dfdy, ref_dfdy, atol=1e-11, rtol=0)

        # Check vectorized output
        newx = np.linspace(0.2, 3.1, 45)
        newy = np.linspace(0.3, 10.1, 85)
        newyy, newxx = np.meshgrid(newy, newx)

        np.testing.assert_allclose(tab2d(newxx, newyy),
                                   f(newxx, newyy),
                                   atol=1e-11,
                                   rtol=0)
        ref_dfdx = dfdx(newxx, newyy)
        ref_dfdy = dfdy(newxx, newyy)
        test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy)
        np.testing.assert_allclose(test_dfdx, ref_dfdx, atol=1e-11, rtol=0)
        np.testing.assert_allclose(test_dfdy, ref_dfdy, atol=1e-11, rtol=0)

    # I think it ought to be possible to exactly interpolate the following,
    # provided the exact derivatives are provided.  Use slightly looser tolerances,
    # which seems reasonable since these are varying more rapidly.
    def f6(x_, y_):
        return y_ * y_ * y_

    def df6dx(x_, y_):
        return np.zeros_like(x_)

    def df6dy(x_, y_):
        return 3 * y_ * y_

    def d2f6dxdy(x_, y_):
        return np.zeros_like(x_)

    def f7(x_, y_):
        return 2 * y_ * y_ * y_ + 3 * x_ * x_ * x_ + 4 * x_ * y_ * y_

    def df7dx(x_, y_):
        return 9 * x_ * x_ + 4 * y_ * y_

    def df7dy(x_, y_):
        return 6 * y_ * y_ + 8 * x_ * y_

    def d2f7dxdy(x_, y_):
        return 8 * y_

    fs = [f6, f7]
    dfdxs = [df6dx, df7dx]
    dfdys = [df6dy, df7dy]
    d2fdxdys = [d2f6dxdy, d2f7dxdy]

    for f, dfdx, dfdy, d2fdxdy in zip(fs, dfdxs, dfdys, d2fdxdys):
        z = f(xx, yy)
        tab2d = galsim.LookupTable2D(x,
                                     y,
                                     z,
                                     interpolant='spline',
                                     dfdx=dfdx(xx, yy),
                                     dfdy=dfdy(xx, yy),
                                     d2fdxdy=d2fdxdy(xx, yy))

        # Check single value functionality.
        x1, y1 = 2.3, 1.2
        np.testing.assert_allclose(tab2d(x1, y1),
                                   f(x1, y1),
                                   atol=1e-10,
                                   rtol=0)
        ref_dfdx = dfdx(x1, y1)
        ref_dfdy = dfdy(x1, y1)
        test_dfdx, test_dfdy = tab2d.gradient(x1, y1)
        np.testing.assert_allclose(test_dfdx, ref_dfdx, atol=1e-10, rtol=0)
        np.testing.assert_allclose(test_dfdy, ref_dfdy, atol=1e-10, rtol=0)

        # Check vectorized output
        newx = np.linspace(0.2, 3.1, 45)
        newy = np.linspace(0.3, 10.1, 85)
        newyy, newxx = np.meshgrid(newy, newx)

        np.testing.assert_allclose(tab2d(newxx, newyy),
                                   f(newxx, newyy),
                                   atol=1e-10,
                                   rtol=0)
        ref_dfdx = dfdx(newxx, newyy)
        ref_dfdy = dfdy(newxx, newyy)
        test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy)
        np.testing.assert_allclose(test_dfdx, ref_dfdx, atol=1e-10, rtol=0)
        np.testing.assert_allclose(test_dfdy, ref_dfdy, atol=1e-10, rtol=0)
Example #9
0
def test_table2d_gradient():
    """Check LookupTable2D gradient function
    """

    # Same function as the above test
    def f(x_, y_):
        return np.sin(x_) * np.cos(y_) + x_

    # The gradient is analytic for this:
    def dfdx(x_, y_):
        return np.cos(x_) * np.cos(y_) + 1.

    def dfdy(x_, y_):
        return -np.sin(x_) * np.sin(y_)

    x = np.linspace(0.1, 3.3, 250)
    y = np.linspace(0.2, 10.4, 750)
    yy, xx = np.meshgrid(y,
                         x)  # Note the ordering of both input and output here!
    z = f(xx, yy)

    tab2d = galsim.LookupTable2D(x, y, z)

    newx = np.linspace(0.2, 3.1, 45)
    newy = np.linspace(0.3, 10.1, 85)
    newyy, newxx = np.meshgrid(newy, newx)

    # Check single value functionality.
    x1, y1 = 1.1, 4.9
    np.testing.assert_almost_equal(tab2d.gradient(x1, y1),
                                   (dfdx(x1, y1), dfdy(x1, y1)),
                                   decimal=2)

    # Check that the gradient function comes out close to the analytic derivatives.
    ref_dfdx = dfdx(newxx, newyy)
    ref_dfdy = dfdy(newxx, newyy)
    test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy)
    np.testing.assert_almost_equal(test_dfdx, ref_dfdx, decimal=2)
    np.testing.assert_almost_equal(test_dfdy, ref_dfdy, decimal=2)
    test2_dfdx, test2_dfdy = tab2d.gradient(newx, newy, grid=True)
    np.testing.assert_almost_equal(test2_dfdx, ref_dfdx, decimal=2)
    np.testing.assert_almost_equal(test2_dfdy, ref_dfdy, decimal=2)

    # Check edge wrapping
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='wrap')

    test_dfdx, test_dfdy = tab2d.gradient(newxx + 13 * tab2d.xperiod, newyy)
    test2_dfdx, test2_dfdy = tab2d.gradient(newx + 13 * tab2d.xperiod,
                                            newy,
                                            grid=True)
    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx, decimal=2)
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy, decimal=2)
    np.testing.assert_array_almost_equal(ref_dfdx, test2_dfdx, decimal=2)
    np.testing.assert_array_almost_equal(ref_dfdy, test2_dfdy, decimal=2)

    test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy + 12 * tab2d.yperiod)
    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx, decimal=2)
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy, decimal=2)

    # Test single value:
    np.testing.assert_almost_equal(tab2d.gradient(x1, y1),
                                   tab2d.gradient(x1 - 9 * tab2d.xperiod, y1))
    np.testing.assert_almost_equal(tab2d.gradient(x1, y1),
                                   tab2d.gradient(x1, y1 - 7 * tab2d.yperiod))

    # Check constant edge_mode
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='constant')

    # Should work the same inside original boundary
    test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy)
    test2_dfdx, test2_dfdy = tab2d.gradient(newx, newy, grid=True)
    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx, decimal=2)
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy, decimal=2)
    np.testing.assert_array_almost_equal(ref_dfdx, test2_dfdx, decimal=2)
    np.testing.assert_array_almost_equal(ref_dfdy, test2_dfdy, decimal=2)

    # Should come out zero outside original boundary
    test_dfdx, test_dfdy = tab2d.gradient(newxx + 2 * np.max(newxx),
                                          newyy + 2 * np.max(newyy))
    test2_dfdx, test2_dfdy = tab2d.gradient(newx + 2 * np.max(newx),
                                            newy + 2 * np.max(newy),
                                            grid=True)
    np.testing.assert_array_equal(0.0, test_dfdx)
    np.testing.assert_array_equal(0.0, test_dfdy)
    np.testing.assert_array_equal(0.0, test2_dfdx)
    np.testing.assert_array_equal(0.0, test2_dfdy)

    # Test single value
    np.testing.assert_almost_equal(tab2d.gradient(x1, y1),
                                   (dfdx(x1, y1), dfdy(x1, y1)),
                                   decimal=2)
    np.testing.assert_equal(tab2d.gradient(x1 + 2 * np.max(newxx), y1),
                            (0.0, 0.0))

    # Try a simpler interpolation function.  Derivatives should be exact.
    def f(x_, y_):
        return 2 * x_ + 3 * y_ - 4 * x_ * y_

    z = f(xx, yy)

    tab2d = galsim.LookupTable2D(x, y, z)
    test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy)
    test2_dfdx, test2_dfdy = tab2d.gradient(newx, newy, grid=True)
    np.testing.assert_almost_equal(test_dfdx, 2. - 4 * newyy, decimal=7)
    np.testing.assert_almost_equal(test_dfdy, 3. - 4 * newxx, decimal=7)
    np.testing.assert_almost_equal(test2_dfdx, 2. - 4 * newyy, decimal=7)
    np.testing.assert_almost_equal(test2_dfdy, 3. - 4 * newxx, decimal=7)

    # Check single value functionality.
    np.testing.assert_almost_equal(tab2d.gradient(x1, y1),
                                   (2. - 4 * y1, 3. - 4 * x1))

    # Check edge wrapping
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='wrap')

    ref_dfdx, ref_dfdy = tab2d.gradient(newxx, newyy)
    test_dfdx, test_dfdy = tab2d.gradient(newxx + 3 * tab2d.xperiod, newyy)
    test2_dfdx, test2_dfdy = tab2d.gradient(newx + 3 * tab2d.xperiod,
                                            newy,
                                            grid=True)
    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx)
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy)
    np.testing.assert_array_almost_equal(ref_dfdx, test2_dfdx)
    np.testing.assert_array_almost_equal(ref_dfdy, test2_dfdy)

    test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy + 13 * tab2d.yperiod)
    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx)
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy)

    # Test single value
    np.testing.assert_almost_equal(tab2d.gradient(x1, y1),
                                   (2 - 4 * y1, 3 - 4 * x1))
    np.testing.assert_almost_equal(tab2d.gradient(x1 + 2 * tab2d.xperiod, y1),
                                   (2 - 4 * y1, 3 - 4 * x1))

    # Test mix of inside and outside original boundary
    test_dfdx, test_dfdy = tab2d.gradient(
        np.dstack([newxx, newxx + 3 * tab2d.xperiod]),
        np.dstack([newyy, newyy]))

    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx[:, :, 0])
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy[:, :, 0])
    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx[:, :, 1])
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy[:, :, 1])

    # Check that edge_mode='constant' behaves as expected.

    # Should work the same inside original boundary
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='constant')
    test_dfdx, test_dfdy = tab2d.gradient(newxx, newyy)
    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx)
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy)

    # Should come out zero outside original boundary
    test_dfdx, test_dfdy = tab2d.gradient(newxx + 2 * np.max(newxx), newyy)
    np.testing.assert_array_equal(0.0, test_dfdx)
    np.testing.assert_array_equal(0.0, test_dfdy)

    # Test single value
    np.testing.assert_almost_equal(tab2d.gradient(x1, y1),
                                   (2 - 4 * y1, 3 - 4 * x1))
    np.testing.assert_equal(tab2d.gradient(x1 + 2 * np.max(newxx), y1),
                            (0.0, 0.0))

    # Test mix of inside and outside original boundary
    test_dfdx, test_dfdy = tab2d.gradient(
        np.dstack([newxx, newxx + 2 * np.max(newxx)]),
        np.dstack([newyy, newyy]))

    np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx[:, :, 0])
    np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy[:, :, 0])
    np.testing.assert_array_equal(0.0, test_dfdx[:, :, 1])
    np.testing.assert_array_equal(0.0, test_dfdy[:, :, 1])
Example #10
0
def test_table2d():
    """Check LookupTable2D functionality.
    """
    has_scipy = False
    try:
        import scipy
        from distutils.version import LooseVersion
        if LooseVersion(scipy.__version__) < LooseVersion('0.11'):
            raise ImportError
    except ImportError:
        print("SciPy tests require SciPy version 0.11 or greater")
    else:
        from scipy.interpolate import interp2d
        has_scipy = True

    def f(x_, y_):
        return np.sin(x_) * np.cos(y_) + x_

    x = np.linspace(0.1, 3.3, 25)
    y = np.linspace(0.2, 10.4, 75)
    yy, xx = np.meshgrid(y,
                         x)  # Note the ordering of both input and output here!
    z = f(xx, yy)

    tab2d = galsim.LookupTable2D(x, y, z)
    do_pickle(tab2d)

    np.testing.assert_array_equal(tab2d.getXArgs(), x)
    np.testing.assert_array_equal(tab2d.getYArgs(), y)
    np.testing.assert_array_equal(tab2d.getVals(), z)
    assert tab2d.interpolant == 'linear'
    assert tab2d.edge_mode == 'raise'

    newx = np.linspace(0.2, 3.1, 45)
    newy = np.linspace(0.3, 10.1, 85)
    newyy, newxx = np.meshgrid(newy, newx)

    # Compare different ways of evaluating Table2D
    ref = tab2d(newxx, newyy)
    np.testing.assert_array_almost_equal(ref, tab2d(newx, newy, grid=True))
    np.testing.assert_array_almost_equal(
        ref, np.array([[tab2d(x0, y0) for y0 in newy] for x0 in newx]))

    if has_scipy:
        scitab2d = interp2d(x, y, np.transpose(z))
        np.testing.assert_array_almost_equal(
            ref, np.transpose(scitab2d(newx, newy)))

    # Try using linear GSInterp
    tab2d2 = galsim.LookupTable2D(x, y, z, interpolant=galsim.Linear())
    np.testing.assert_array_almost_equal(tab2d(newxx, newyy),
                                         tab2d2(newxx, newyy))
    np.testing.assert_array_almost_equal(tab2d(newxx.T, newyy.T),
                                         tab2d2(newxx.T, newyy.T))

    # Try again using Nearest()
    tab2d2 = galsim.LookupTable2D(x, y, z, interpolant=galsim.Nearest())
    tab2d3 = galsim.LookupTable2D(x, y, z, interpolant='nearest')
    np.testing.assert_array_almost_equal(tab2d2(newxx, newyy),
                                         tab2d3(newxx, newyy))
    np.testing.assert_array_almost_equal(tab2d2(newxx.T, newyy.T),
                                         tab2d3(newxx.T, newyy.T))
    # Make sure we exercise the special case in T2DInterpolant2D::interp
    np.testing.assert_array_almost_equal(tab2d2(0.3, 0.4), tab2d3(0.3, 0.4))
    np.testing.assert_array_almost_equal(tab2d2(0.3, 0.4), tab2d3(0.3, 0.4))

    # Test non-equally-spaced table.
    x = np.delete(x, 10)
    y = np.delete(y, 10)
    yy, xx = np.meshgrid(y, x)
    z = f(xx, yy)
    tab2d = galsim.LookupTable2D(x, y, z)
    ref = tab2d(newxx, newyy)
    np.testing.assert_array_almost_equal(ref, tab2d(newx, newy, grid=True))
    np.testing.assert_array_almost_equal(
        ref, np.array([[tab2d(x0, y0) for y0 in newy] for x0 in newx]))
    if has_scipy:
        scitab2d = interp2d(x, y, np.transpose(z))
        np.testing.assert_array_almost_equal(
            ref, np.transpose(scitab2d(newx, newy)))

    # Using a galsim.Interpolant should raise an exception if x/y are not equal spaced.
    with assert_raises(galsim.GalSimIncompatibleValuesError):
        tab2d2 = galsim.LookupTable2D(x, y, z, interpolant=galsim.Linear())

    # Try a simpler interpolation function.  We should be able to interpolate a (bi-)linear function
    # exactly with a linear interpolant.
    def f(x_, y_):
        return 2 * x_ + 3 * y_

    z = f(xx, yy)
    tab2d = galsim.LookupTable2D(x, y, z)

    np.testing.assert_array_almost_equal(f(newxx, newyy), tab2d(newxx, newyy))
    np.testing.assert_array_almost_equal(
        f(newxx, newyy),
        np.array([[tab2d(x0, y0) for y0 in newy] for x0 in newx]))

    # Test edge exception
    with assert_raises(ValueError):
        tab2d(1e6, 1e6)
    with assert_raises(ValueError):
        tab2d(np.array([1e5, 1e6]), np.array([1e5, 1e6]))
    with assert_raises(ValueError):
        tab2d(np.array([1e5, 1e6]), np.array([1e5, 1e6]), grid=True)
    with assert_raises(ValueError):
        tab2d.gradient(1e6, 1e6)
    with assert_raises(ValueError):
        tab2d.gradient(np.array([1e5, 1e6]), np.array([1e5, 1e6]))
    with assert_raises(ValueError):
        tab2d.gradient(np.array([1e5, 1e6]), np.array([1e5, 1e6]), grid=True)
    with assert_raises(galsim.GalSimError):
        galsim.utilities.find_out_of_bounds_position(
            np.array([1, 3]), np.array([2, 4]), galsim.BoundsD(0, 5, 0, 5))
    with assert_raises(galsim.GalSimError):
        galsim.utilities.find_out_of_bounds_position(np.array([1, 3]),
                                                     np.array([2, 4]),
                                                     galsim.BoundsD(
                                                         0, 5, 0, 5),
                                                     grid=True)

    # Check warning mode
    tab2dw = galsim.LookupTable2D(x, y, z, edge_mode='warn', constant=1)
    with assert_warns(galsim.GalSimWarning):
        assert tab2dw(1e6, 1e6) == 1
    with assert_warns(galsim.GalSimWarning):
        np.testing.assert_array_equal(
            tab2dw(np.array([1e5, 1e6]), np.array([1e5, 1e6])),
            np.array([1.0, 1.0]))
    with assert_warns(galsim.GalSimWarning):
        np.testing.assert_array_equal(
            tab2dw(np.array([1e5, 1e6]), np.array([1e5, 1e6]), grid=True),
            np.array([[1.0, 1.0], [1.0, 1.0]]))
    with assert_warns(galsim.GalSimWarning):
        assert tab2dw.gradient(1e6, 1e6) == (0.0, 0.0)
    with assert_warns(galsim.GalSimWarning):
        np.testing.assert_array_equal(
            tab2dw.gradient(np.array([1e5, 1e6]), np.array([1e5, 1e6])),
            np.zeros((2, 2), dtype=float))
    with assert_warns(galsim.GalSimWarning):
        np.testing.assert_array_equal(
            tab2dw.gradient(np.array([1e5, 1e6]),
                            np.array([1e5, 1e6]),
                            grid=True), np.zeros((2, 2, 2), dtype=float))

    # But doesn't warn if in bounds
    tab2dw(1.0, 1.0)
    tab2dw(np.array([1.0]), np.array([1.0]))
    tab2dw(np.array([1.0]), np.array([1.0]), grid=True)
    tab2dw.gradient(1.0, 1.0)
    tab2dw.gradient(np.array([1.0]), np.array([1.0]))

    # Test edge wrapping
    # Check that can't construct table with edge-wrapping if edges don't match
    with assert_raises(ValueError):
        galsim.LookupTable2D(x, y, z, edge_mode='wrap')

    # Extend edges and make vals match
    x = np.append(x, x[-1] + (x[-1] - x[-2]))
    y = np.append(y, y[-1] + (y[-1] - y[-2]))
    z = np.pad(z, [(0, 1), (0, 1)], mode='wrap')
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='wrap')

    np.testing.assert_array_almost_equal(
        tab2d(newxx, newyy), tab2d(newxx + 3 * (x[-1] - x[0]), newyy))
    np.testing.assert_array_almost_equal(
        tab2d(newx, newy, grid=True), tab2d(newxx + 3 * (x[-1] - x[0]), newyy))
    np.testing.assert_array_almost_equal(
        tab2d(newxx, newyy), tab2d(newxx, newyy + 13 * (y[-1] - y[0])))
    np.testing.assert_array_almost_equal(
        tab2d(newxx, newyy), tab2d(newx, newy + 13 * (y[-1] - y[0]),
                                   grid=True))

    # Test edge_mode='constant'
    tab2d = galsim.LookupTable2D(x, y, z, edge_mode='constant', constant=42)
    assert type(tab2d(x[0] - 1, y[0] - 1)) in [float, np.float64]
    assert tab2d(x[0] - 1, y[0] - 1) == 42.0
    # One in-bounds, one out-of-bounds
    np.testing.assert_array_almost_equal(
        tab2d([x[0], x[0] - 1], [y[0], y[0] - 1]), [tab2d(x[0], y[0]), 42.0])

    # Test floor/ceil/nearest interpolant
    x = np.arange(5)
    y = np.arange(5)
    z = x + y[:, np.newaxis]
    tab2d = galsim.LookupTable2D(x, y, z, interpolant='ceil')
    assert tab2d(2.4, 3.6) == 3 + 4, "Ceil interpolant failed."
    tab2d = galsim.LookupTable2D(x, y, z, interpolant='floor')
    assert tab2d(2.4, 3.6) == 2 + 3, "Floor interpolant failed."
    tab2d = galsim.LookupTable2D(x, y, z, interpolant='nearest')
    assert tab2d(2.4, 3.6) == 2 + 4, "Nearest interpolant failed."
    tab2d = galsim.LookupTable2D(x, y, z, interpolant=galsim.Nearest())
    assert tab2d(2.4, 3.6) == 2 + 4, "Nearest interpolant failed."

    assert_raises(ValueError,
                  galsim.LookupTable2D,
                  x,
                  y,
                  z,
                  interpolant='invalid')
    assert_raises(ValueError,
                  galsim.LookupTable2D,
                  x,
                  y,
                  z,
                  edge_mode='invalid')
    assert_raises(ValueError, galsim.LookupTable2D, x, y, z[:-1, :-1])

    # Test that x,y arrays need to be strictly increasing.
    x[0] = x[1]
    assert_raises(ValueError, galsim.LookupTable2D, x, y, z)
    x[0] = x[1] + 1
    assert_raises(ValueError, galsim.LookupTable2D, x, y, z)
    x[0] = x[1] - 1
    y[0] = y[1]
    assert_raises(ValueError, galsim.LookupTable2D, x, y, z)
    y[0] = y[1] + 1
    assert_raises(ValueError, galsim.LookupTable2D, x, y, z)

    # Test that x,y arrays are larger than interpolant
    x = y = np.arange(2)
    z = x[:, None] + y
    assert_raises(ValueError,
                  galsim.LookupTable2D,
                  x,
                  y,
                  z,
                  interpolant='spline',
                  edge_mode='wrap')

    # Check dfdx input
    x = y = np.arange(20)
    z = x[:, None] + y
    # Not using interpolant='spline'
    assert_raises(ValueError, galsim.LookupTable2D, x, y, z, dfdx=z)
    # Only specifying one derivative
    assert_raises(ValueError,
                  galsim.LookupTable2D,
                  x,
                  y,
                  z,
                  dfdx=z,
                  interpolant='spline')
    # Derivative is wrong shape
    assert_raises(ValueError,
                  galsim.LookupTable2D,
                  x,
                  y,
                  z,
                  dfdx=z,
                  dfdy=z,
                  d2fdxdy=z[::2],
                  interpolant='spline')

    # Check private shortcut instantiation
    new_tab2d = galsim.table._LookupTable2D(tab2d.x, tab2d.y, tab2d.f,
                                            tab2d.interpolant, tab2d.edge_mode,
                                            tab2d.constant, tab2d.dfdx,
                                            tab2d.dfdy, tab2d.d2fdxdy)
    assert tab2d == new_tab2d
    assert tab2d(2.4, 3.6) == new_tab2d(2.4, 3.6)
Example #11
0
def test_table2d_GSInterp():
    def f(x_, y_):
        return 2 * y_ * y_ + 3 * x_ * x_ + 4 * x_ * y_ - np.cos(x_)

    x = np.linspace(0.1, 3.3, 25)
    y = np.linspace(0.2, 10.4, 75)
    yy, xx = np.meshgrid(y,
                         x)  # Note the ordering of both input and output here!

    interpolants = ['lanczos3', 'lanczos3F', 'lanczos7', 'sinc', 'quintic']

    for interpolant in interpolants:
        z = f(xx, yy)
        tab2d = galsim.LookupTable2D(x, y, z, interpolant=interpolant)
        do_pickle(tab2d)
        # Make sure precomputed-hash gets covered
        hash(tab2d)

        # Use InterpolatedImage to validate
        wcs = galsim.JacobianWCS(
            (max(x) - min(x)) / (len(x) - 1),
            0,
            0,
            (max(y) - min(y)) / (len(y) - 1),
        )
        img = galsim.Image(z.T, wcs=wcs)
        ii = galsim.InterpolatedImage(
            img,
            use_true_center=True,
            offset=(galsim.PositionD(img.xmin, img.ymin) - img.true_center),
            x_interpolant=interpolant,
            normalization='sb',
            calculate_maxk=False,
            calculate_stepk=False).shift(min(x), min(y))

        # Check single value functionality.
        x1, y1 = 2.3, 3.2
        np.testing.assert_allclose(tab2d(x1, y1),
                                   ii.xValue(x1, y1),
                                   atol=1e-10,
                                   rtol=0)

        # Check vectorized output
        newx = np.linspace(0.2, 3.1, 15)
        newy = np.linspace(0.3, 10.1, 25)
        newyy, newxx = np.meshgrid(newy, newx)
        np.testing.assert_allclose(
            tab2d(newxx, newyy).ravel(),
            np.array([
                ii.xValue(x_, y_)
                for x_, y_ in zip(newxx.ravel(), newyy.ravel())
            ]).ravel(),
            atol=1e-10,
            rtol=0)
        np.testing.assert_array_almost_equal(tab2d(newxx, newyy),
                                             tab2d(newx, newy, grid=True))

        # Check that edge_mode='wrap' works
        tab2d = galsim.LookupTable2D(x, y, z, edge_mode='wrap')

        ref_dfdx, ref_dfdy = tab2d.gradient(newxx, newyy)
        test_dfdx, test_dfdy = tab2d.gradient(newxx + 3 * tab2d.xperiod, newyy)
        np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx)
        np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy)

        test_dfdx, test_dfdy = tab2d.gradient(newxx,
                                              newyy + 13 * tab2d.yperiod)
        np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx)
        np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy)

        test_dfdx, test_dfdy = tab2d.gradient(newx,
                                              newy + 13 * tab2d.yperiod,
                                              grid=True)
        np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx)
        np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy)

        # Test mix of inside and outside original boundary
        test_dfdx, test_dfdy = tab2d.gradient(
            np.dstack([newxx, newxx + 3 * tab2d.xperiod]),
            np.dstack([newyy, newyy]))

        np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx[:, :, 0])
        np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy[:, :, 0])
        np.testing.assert_array_almost_equal(ref_dfdx, test_dfdx[:, :, 1])
        np.testing.assert_array_almost_equal(ref_dfdy, test_dfdy[:, :, 1])