Esempio n. 1
0
def test_beam():
    """
    Test that the convolution doesn't shift the center (at least when
    the kernel is constructed with gauss2d_kernel).

    Note this test fails if you use scipy.fftconvolve because the
    kernels are treated differently.
    """
    n = 50
    synth = beam.gauss2d_kernel(n, 3.)
    _synth = beam.convolve_fft(synth, synth)
    assert numpy.argmax(synth) == numpy.argmax(_synth), \
            'Beam kernel shifted the center for an even image size.'

    n = 51
    synth = beam.gauss2d_kernel(n, 3.)
    _synth = beam.convolve_fft(synth, synth)
    assert numpy.argmax(synth) == numpy.argmax(_synth), \
            'Beam kernel shifted the center for an odd image size.'
Esempio n. 2
0
def test_disk_derivative_nosig():
    disk = AxisymmetricDisk()
    
    # Ensure that center is offset from 0,0 because of derivative calculation when r==0.
    disk.par[:2] = 0.1
    # Use a slowly rising rotation curve.  More quickly rising rotation curves
    # show a greater difference between the finite-difference and direct
    # derivative calculations after the convolution.
    disk.par[-1] = 20.

    # Finite difference test steps
    #                 x0      y0      pa     inc    vsys   vinf   hv
    dp = numpy.array([0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001])

    n = 101
    x = numpy.arange(n, dtype=float)[::-1] - n//2
    y = numpy.arange(n, dtype=float) - n//2
    x, y = numpy.meshgrid(x, y)

    v, dv = disk.deriv_model(disk.par, x=x, y=y)
    vp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    p = disk.par.copy()
    for i in range(disk.par.size):
        _p = p.copy()
        _p[i] += dp[i]
        # These calls to `model` reuse the previously provided x and y
        vp[...,i] = disk.model(_p)
    disk._set_par(p)

    fd_dv = (vp - v[...,None])/dp[None,:]
    for i in range(disk.par.size):
        assert numpy.allclose(dv[...,i], fd_dv[...,i], rtol=0., atol=1e-4), \
                f'Finite difference produced different derivative for parameter {i+1}!'

    # Now include the beam-smearing
    beam = gauss2d_kernel(n, 3.)
    try:
        cnvfftw = ConvolveFFTW(beam.shape)
    except:
        cnvfftw = None
    v, dv = disk.deriv_model(disk.par, x=x, y=y, beam=beam, cnvfftw=cnvfftw)
    vp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    p = disk.par.copy()
    for i in range(disk.par.size):
        _p = p.copy()
        _p[i] += dp[i]
        # These calls to `model` reuse the previously provided x, y, beam, and
        # cnvfftw
        vp[...,i] = disk.model(_p)
    disk._set_par(p)

    fd_dv = (vp - v[...,None])/dp[None,:]
    for i in range(disk.par.size):
        assert numpy.allclose(dv[...,i], fd_dv[...,i], rtol=0., atol=1e-4), \
                f'Finite difference produced different derivative for parameter {i+1}!'
Esempio n. 3
0
def test_convolve():
    """
    Test that the results of the convolution match astropy.
    """
    synth = beam.gauss2d_kernel(73, 3.)
    astsynth = convolution.convolve_fft(synth,
                                        synth,
                                        fft_pad=False,
                                        psf_pad=False,
                                        boundary='wrap')
    intsynth = beam.convolve_fft(synth, synth)
    assert numpy.all(numpy.isclose(
        astsynth, intsynth)), 'Difference wrt astropy convolution'
Esempio n. 4
0
def test_disk():
    disk = AxisymmetricDisk()
    disk.par[:2] = 0.       # Ensure that the center is at 0,0
    disk.par[-1] = 1.       # Put in a quickly rising RC

    n = 51
    x = numpy.arange(n, dtype=float)[::-1] - n//2
    y = numpy.arange(n, dtype=float) - n//2
    x, y = numpy.meshgrid(x, y)

    vel = disk.model(disk.par, x=x, y=y)
    beam = gauss2d_kernel(n, 3.)
    _vel = disk.model(disk.par, x=x, y=y, beam=beam)

    assert numpy.isclose(vel[n//2,n//2], _vel[n//2,n//2]), 'Smearing moved the center.'
Esempio n. 5
0
def test_fft():
    synth = beam.gauss2d_kernel(73, 3.)
    synth_fft = numpy.fft.fftn(numpy.fft.ifftshift(synth))
    _convolve_fft = beam.ConvolveFFTW(synth.shape)

    # Compare numpy with direct vs. FFT kernel input
    synth2 = beam.convolve_fft(synth, synth)
    _synth2 = beam.convolve_fft(synth, synth_fft, kernel_fft=True)
    assert numpy.allclose(synth2,
                          _synth2), 'Difference if FFT is passed for numpy'

    # Compare numpy and FFTW with direct input
    _synth2 = _convolve_fft(synth, synth)
    assert numpy.allclose(synth2, _synth2), 'Difference between numpy and FFTW'

    # Compare FFTW with direct vs. FFT kernel input
    synth2 = _convolve_fft(synth, synth_fft, kernel_fft=True)
    assert numpy.allclose(synth2,
                          _synth2), 'Difference if FFT is passed for FFTW'

    # Compare numpy and FFTW with direct input and FFT output
    synth2 = beam.convolve_fft(synth, synth, return_fft=True)
    _synth2 = _convolve_fft(synth, synth, return_fft=True)
    assert numpy.allclose(synth2, _synth2), 'Difference between numpy and FFTW'
Esempio n. 6
0
def test_disk_derivative():
    disk = AxisymmetricDisk(rc=HyperbolicTangent(), dc=Exponential())
    
    # Ensure that center is offset from 0,0 because of derivative calculation when r==0.
    disk.par[:2] = 0.1
    # Use a slowly rising rotation curve.  More quickly rising rotation curves
    # show a greater difference between the finite-difference and direct
    # derivative calculations after the convolution.
    disk.par[-3] = 20.

    # Finite difference test steps
    #                 x0      y0      pa     inc    vsys   vinf   hv      sig0   hsig
    dp = numpy.array([0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.0001])

    n = 101
    x = numpy.arange(n, dtype=float)[::-1] - n//2
    y = numpy.arange(n, dtype=float) - n//2
    x, y = numpy.meshgrid(x, y)

    v, sig, dv, dsig = disk.deriv_model(disk.par, x=x, y=y)
    vp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    sigp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    p = disk.par.copy()
    for i in range(disk.par.size):
        _p = p.copy()
        _p[i] += dp[i]
        # These calls to `model` reuse the previously provided x and y
        vp[...,i], sigp[...,i] = disk.model(_p)
    disk._set_par(p)

    fd_dv = (vp - v[...,None])/dp[None,:]
    fd_dsig = (sigp - sig[...,None])/dp[None,:]
    for i in range(disk.par.size):
        assert numpy.allclose(dv[...,i], fd_dv[...,i], rtol=0., atol=1e-4), \
                f'Finite difference produced different velocity derivative for parameter {i+1}!'
        # The precision is worse for dsig/dx0 and dsig/dy0 at x=y=0.0.  Not sure
        # why.  The larger atol is to account for this.
        assert numpy.allclose(dsig[...,i], fd_dsig[...,i], rtol=0., atol=3e-3), \
                f'Finite difference produced different sigma derivative for parameter {i+1}!'

    # Now include the beam-smearing
    beam = gauss2d_kernel(n, 3.)
    try:
        cnvfftw = ConvolveFFTW(beam.shape)
    except:
        cnvfftw = None
    v, sig, dv, dsig = disk.deriv_model(disk.par, x=x, y=y, beam=beam, cnvfftw=cnvfftw)
    vp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    sigp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    p = disk.par.copy()
    for i in range(disk.par.size):
        _p = p.copy()
        _p[i] += dp[i]
        # These calls to `model` reuse the previously provided x, y, beam, and
        # cnvfftw
        vp[...,i], sigp[...,i] = disk.model(_p)
    disk._set_par(p)

    fd_dv = (vp - v[...,None])/dp[None,:]
    fd_dsig = (sigp - sig[...,None])/dp[None,:]
    for i in range(disk.par.size):
        assert numpy.allclose(dv[...,i], fd_dv[...,i], rtol=0., atol=1e-4), \
                f'Finite difference produced different derivative for parameter {i+1}!'
        # Apparently the convolution smooths out the difference seen in the test above
        assert numpy.allclose(dsig[...,i], fd_dsig[...,i], rtol=0., atol=1e-4), \
                f'Finite difference produced different sigma derivative for parameter {i+1}!'
Esempio n. 7
0
def test_smear():

    n = 51
    x = numpy.arange(n, dtype=float)[::-1] - n // 2
    y = numpy.arange(n, dtype=float) - n // 2
    x, y = numpy.meshgrid(x, y)

    r, theta = projected_polar(x, y, *numpy.radians([45., 30.]))

    rc = oned.HyperbolicTangent(par=numpy.array([100., 1.]))
    sig = oned.Exponential(par=numpy.array([100., 20.]))
    sb = oned.Sersic1D(par=numpy.array([1., 10., 1.]))

    sb_field = sb.sample(r)
    vel_field = rc.sample(r) * numpy.cos(theta)
    sig_field = sig.sample(r)

    cnvlv = beam.ConvolveFFTW(x.shape)
    synth = beam.gauss2d_kernel(n, 3.)
    synth_fft = cnvlv.fft(synth, shift=True)

    vel_smear = beam.smear(vel_field, synth)[1]
    _vel_smear = beam.smear(vel_field, synth, cnvfftw=cnvlv)[1]
    assert numpy.allclose(
        vel_smear, _vel_smear), 'Velocity-field-only convolution difference.'

    vel_smear = beam.smear(vel_field, synth)[1]
    _vel_smear = beam.smear(vel_field, synth_fft, beam_fft=True)[1]
    assert numpy.allclose(vel_smear, _vel_smear), \
            'Velocity-field difference w/ vs. w/o precomputing the beam FFT for numpy.'

    vel_smear = beam.smear(vel_field, synth, cnvfftw=cnvlv)[1]
    _vel_smear = beam.smear(vel_field, synth_fft, beam_fft=True,
                            cnvfftw=cnvlv)[1]
    assert numpy.allclose(vel_smear, _vel_smear), \
            'Velocity-field difference w/ vs. w/o precomputing the beam FFT for ConvolveFFTW.'

    sb_smear, vel_smear, _ = beam.smear(vel_field, synth, sb=sb_field)
    _sb_smear, _vel_smear, _ = beam.smear(vel_field,
                                          synth,
                                          sb=sb_field,
                                          cnvfftw=cnvlv)
    assert numpy.allclose(sb_smear,
                          _sb_smear), 'SB+Vel convolution difference in SB.'
    assert numpy.allclose(vel_smear,
                          _vel_smear), 'SB+Vel convolution difference in Vel.'

    sb_smear, vel_smear, sig_smear = beam.smear(vel_field,
                                                synth,
                                                sb=sb_field,
                                                sig=sig_field)
    _sb_smear, _vel_smear, _sig_smear = beam.smear(vel_field,
                                                   synth,
                                                   sb=sb_field,
                                                   sig=sig_field,
                                                   cnvfftw=cnvlv)
    assert numpy.allclose(
        sb_smear, _sb_smear), 'SB+Vel+Sig convolution difference in SB.'
    assert numpy.allclose(
        vel_smear, _vel_smear), 'SB+Vel+Sig convolution difference in vel.'
    assert numpy.allclose(
        sig_smear, _sig_smear), 'SB+Vel+Sig convolution difference in sig.'