예제 #1
0
def test_disk_derivative_bin():

    # Read the data to fit
    data_root = remote_data_file()
    kin = manga.MaNGAStellarKinematics.from_plateifu(8138, 12704, cube_path=data_root,
                                                     maps_path=data_root)

    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])

    # Include the beam-smearing
    try:
        cnvfftw = ConvolveFFTW(kin.spatial_shape)
    except:
        cnvfftw = None
    v, sig, dv, dsig = disk.deriv_model(disk.par, x=kin.grid_x, y=kin.grid_y, sb=kin.grid_sb, 
                                        beam=kin.beam_fft, is_fft=True, cnvfftw=cnvfftw)
    # Now also include the binning
    bv, dbv = kin.deriv_bin(v, dv)
    bsig, dbsig = kin.deriv_bin(sig, dsig)

    vp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    sigp = numpy.empty(v.shape+(disk.par.size,), dtype=float)
    bvp = numpy.empty(bv.shape+(disk.par.size,), dtype=float)
    bsigp = numpy.empty(bv.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, sb, beam,
        # and cnvfftw
        vp[...,i], sigp[...,i] = disk.model(_p)
        bvp[...,i] = kin.bin(vp[...,i])
        bsigp[...,i] = kin.bin(sigp[...,i])
    disk._set_par(p)

    fd_dbv = (bvp - bv[...,None])/dp[None,:]
    fd_dbsig = (bsigp - bsig[...,None])/dp[None,:]

    for i in range(disk.par.size):
        assert numpy.allclose(dbv[...,i], fd_dbv[...,i], rtol=0., atol=1e-4), \
                f'Finite difference produced different derivative for parameter {i+1}!'
        # The difference is relatively large (again) for the dispersion data
        assert numpy.allclose(dbsig[...,i], fd_dbsig[...,i], rtol=0., atol=3e-3), \
                f'Finite difference produced different sigma derivative for parameter {i+1}!'
예제 #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}!'
예제 #3
0
def test_disk_fit_derivative():

    # Read the data to fit
    data_root = remote_data_file()
    kin = manga.MaNGAStellarKinematics.from_plateifu(8138, 12704, cube_path=data_root,
                                                     maps_path=data_root)

    disk = AxisymmetricDisk(rc=HyperbolicTangent(), dc=Exponential())

    # Set the parameters close to the best-fitting parameters from a previous
    # run
    p0 = numpy.array([-0.2, -0.08, 166.3, 53.0, 25.6, 217.0, 2.82, 189.7, 16.2])
    # 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])

    # Run the fit preparation
    disk._fit_prep(kin, p0, None, None, True, True, True, None)
    # Get the method used to generate the figure-of-merit and the jacobian
    fom = disk._get_fom()
    jac = disk._get_jac()
    # Get the fom and the jacobian
    chi = fom(p0)
    dchi = jac(p0)

    # Brute force it
    chip = numpy.empty(dchi.shape, dtype=float)
    p = disk.par.copy()
    for i in range(disk.par.size):
        _p = p.copy()
        _p[i] += dp[i]
        chip[...,i] = fom(_p)
    disk._set_par(p)

    # Compare them
    fd_dchi = (chip - chi[...,None])/dp[None,:]
    for i in range(disk.par.size):
#        diff = numpy.absolute(dchi[...,i]-fd_dchi[...,i])
#        print(i, numpy.amax(diff), numpy.amin(diff))
#        continue
        assert numpy.allclose(dchi[...,i], fd_dchi[...,i], rtol=0., atol=1e-3), \
                f'Finite difference produced different derivative for parameter {i+1}!'
예제 #4
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}!'