Exemplo n.º 1
0
def test_invalid_config():
    # Test a few invalid uses of the config parsing.
    if __name__ == '__main__':
        logger = piff.config.setup_logger(verbose=2)
    else:
        logger = piff.config.setup_logger(log_file='output/test_invalid_config.log')
    image_file = os.path.join('output','simple_image.fits')
    cat_file = os.path.join('output','simple_cat.fits')
    psf_file = os.path.join('output','simple_psf.fits')
    config = {
        'input' : {
            'image_file_name' : image_file,
            'cat_file_name' : cat_file,
            'flag_col' : 'flag',
            'use_flag' : 1,
            'skip_flag' : 4,
        },
        'psf' : {
            'model' : { 'type' : 'Gaussian',
                        'fastfit': True,
                        'include_pixel': False},
            'interp' : { 'type' : 'Mean' },
            'max_iter' : 10,
            'chisq_thresh' : 0.2,
        },
        'output' : { 'file_name' : psf_file },
    }
    # Invalid variable specification
    with np.testing.assert_raises(ValueError):
        piff.parse_variables(config, ['verbose:0'], logger=logger)
    # process needs both input and psf
    with np.testing.assert_raises(ValueError):
        piff.process(config={'input':config['input']}, logger=logger)
    with np.testing.assert_raises(ValueError):
        piff.process(config={'psf':config['psf']}, logger=logger)
    # piffify also needs output
    with np.testing.assert_raises(ValueError):
        piff.piffify(config={'input':config['input']}, logger=logger)
    with np.testing.assert_raises(ValueError):
        piff.piffify(config={'psf':config['psf']}, logger=logger)
    with np.testing.assert_raises(ValueError):
        piff.piffify(config={'input':config['input'], 'psf':config['psf']}, logger=logger)
    # plotify doesn't need psf, but needs a 'file_name' in output
    with np.testing.assert_raises(ValueError):
        piff.plotify(config={'input':config['input']}, logger=logger)
    with np.testing.assert_raises(ValueError):
        piff.plotify(config={'input':config['input'], 'output':{}}, logger=logger)

    # Error if missing either model or interp
    config2 = copy.deepcopy(config)
    del config2['psf']['model']
    with np.testing.assert_raises(ValueError):
        piff.piffify(config2, logger)
    config2['psf']['model'] = config['psf']['model']
    del config2['psf']['interp']
    with np.testing.assert_raises(ValueError):
        piff.piffify(config2, logger)
Exemplo n.º 2
0
def test_config():
    # Take DES test image, and test doing a psf run with kNN interpolator
    # Now test running it via the config parser
    psf_file = os.path.join('output', 'knn_psf.fits')
    config = {
        'input': {
            'image_file_name': 'input/DECam_00241238_01.fits.fz',
            'cat_file_name':
            'input/DECam_00241238_01_psfcat_tb_maxmag_17.0_magcut_3.0_findstars.fits',
            # What hdu is everything in?
            'image_hdu': 1,
            'badpix_hdu': 2,
            'weight_hdu': 3,
            'cat_hdu': 2,

            # What columns in the catalog have things we need?
            'x_col': 'XWIN_IMAGE',
            'y_col': 'YWIN_IMAGE',
            'ra': 'TELRA',
            'dec': 'TELDEC',
            'gain': 'GAINA',
            'sky_col': 'BACKGROUND',

            # How large should the postage stamp cutouts of the stars be?
            'stamp_size': 31,
        },
        'psf': {
            'model': {
                'type': 'GSObjectModel',
                'fastfit': True,
                'gsobj': 'galsim.Gaussian(sigma=1.0)'
            },
            'interp': {
                'type': 'kNNInterp',
                'keys': ['u', 'v'],
                'n_neighbors': 115,
            }
        },
        'output': {
            'file_name': psf_file
        },
    }
    if __name__ != '__main__':
        config['verbose'] = 0
        config['input']['nstars'] = 20
        config['psf']['interp']['n_neighbors'] = 19
        test_factor = 0.04
    else:
        test_factor = 0.01

    psf = piff.process(config)

    # by using n_neighbors = 115, when there are only 117 stars in the catalog, we should expect
    # that the standard deviation of the interpolated parameters should be small, since almost the
    # same set of stars are being averaged in every case.
    nstars = len(psf.stars)
    np.testing.assert_array_less(
        np.std([s.fit.params for s in psf.stars], axis=0),
        test_factor * np.mean([s.fit.params for s in psf.stars], axis=0),
        err_msg="Interpolated parameters show too much variation.")
Exemplo n.º 3
0
def test_config():
    # Take DES test image, and test doing a psf run with kNN interpolator
    # Now test running it via the config parser
    psf_file = os.path.join('output','knn_psf.fits')
    config = {
        'input' : {
            'image_file_name' : 'input/DECam_00241238_01.fits.fz',
            'cat_file_name' : 'input/DECam_00241238_01_psfcat_tb_maxmag_17.0_magcut_3.0_findstars.fits',
            # What hdu is everything in?
            'image_hdu': 1,
            'badpix_hdu': 2,
            'weight_hdu': 3,
            'cat_hdu': 2,

            # What columns in the catalog have things we need?
            'x_col': 'XWIN_IMAGE',
            'y_col': 'YWIN_IMAGE',
            'ra': 'TELRA',
            'dec': 'TELDEC',
            'gain': 'GAINA',
            'sky_col': 'BACKGROUND',

            # How large should the postage stamp cutouts of the stars be?
            'stamp_size': 31,
        },
        'psf' : {
            'model' : { 'type': 'GSObjectModel',
                        'fastfit': True,
                        'gsobj': 'galsim.Gaussian(sigma=1.0)' },
            'interp' : { 'type': 'kNNInterp',
                         'keys': ['u', 'v'],
                         'n_neighbors': 115,}
        },
        'output' : { 'file_name' : psf_file },
    }
    if __name__ != '__main__':
        config['verbose'] = 0
        config['input']['nstars'] = 20
        config['psf']['interp']['n_neighbors'] = 19
        test_factor = 0.04
    else:
        test_factor = 0.01

    psf = piff.process(config)

    # by using n_neighbors = 115, when there are only 117 stars in the catalog, we should expect
    # that the standard deviation of the interpolated parameters should be small, since almost the
    # same set of stars are being averaged in every case.
    nstars = len(psf.stars)
    np.testing.assert_array_less(
            np.std([s.fit.params for s in psf.stars], axis=0),
            test_factor*np.mean([s.fit.params for s in psf.stars], axis=0),
            err_msg="Interpolated parameters show too much variation.")
Exemplo n.º 4
0
def test_focal():
    """This test uses 2 input files and two catalogs, but does the interpolation over the
    whole field of view.
    """
    # Give them different wcs's.
    # The centers should be separated by ~0.25 arcsec/pixel * 2048 pixels / cos(dec) = 565 arcsec
    # The actual separation of 10 arcmin gives a bit of a gap between the chips.
    wcs1 = galsim.TanWCS(
            galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees)
            )
    wcs2 = galsim.TanWCS(
            galsim.AffineTransform(0.25, -0.02, 0.01, 0.24, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)
            )
    field_center = galsim.CelestialCoord(0 * galsim.degrees, -25 * galsim.degrees)

    if __name__ == '__main__':
        nstars = 20  # per ccd
    else:
        nstars = 3  # per ccd
    rng = np.random.RandomState(1234)
    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs1._radec(x.copy(),y.copy()), projection='gnomonic')
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u*v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u*v

    data1 = np.array(list(zip(x,y,e1,e2,s)),
                     dtype=[ ('x',float), ('y',float), ('e1',float), ('e2',float), ('s',float) ])
    np.testing.assert_array_equal(data1['x'] , x)
    np.testing.assert_array_equal(data1['y'] , y)
    np.testing.assert_array_equal(data1['e1'] , e1)
    np.testing.assert_array_equal(data1['e2'] , e2)
    np.testing.assert_array_equal(data1['s'] , s)
    im1 = drawImage(2048, 2048, wcs1, x, y, e1, e2, s)
    im1.write('output/test_focal_im1.fits')
    fitsio.write('output/test_focal_cat1.fits', data1, clobber=True)

    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs2._radec(x.copy(),y.copy()), projection='gnomonic')
    # Same functions of u,v, but using the positions on chip 2
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u*v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u*v

    data2 = np.array(list(zip(x,y,e1,e2,s)),
                     dtype=[ ('x',float), ('y',float), ('e1',float), ('e2',float), ('s',float) ])
    im2 = drawImage(2048, 2048, wcs2, x, y, e1, e2, s)
    im2.write('output/test_focal_im2.fits')
    fitsio.write('output/test_focal_cat2.fits', data2, clobber=True)

    # Try to fit with the right model (Moffat) and interpolant (2nd order polyomial)
    # Should work very well, since no noise.
    config = {
        'input' : {
            'image_file_name' : 'output/test_focal_im?.fits',
            'cat_file_name' : 'output/test_focal_cat?.fits',
            'x_col' : 'x',
            'y_col' : 'y',
            'ra' : 0.,
            'dec' : -25.,
        },
        'psf' : {
            'type' : 'Simple',
            'model' : {
                'type' : 'Moffat',
                'beta' : 2.5
            },
            'interp' : {
                'type' : 'Polynomial',
                'order' : 2
            }
        }
    }
    if __name__ != '__main__':
        config['verbose'] = 0
    psf = piff.process(config)

    for data, wcs in [(data1,wcs1), (data2,wcs2)]:
        for k in range(nstars):
            x = data['x'][k]
            y = data['y'][k]
            e1 = data['e1'][k]
            e2 = data['e2'][k]
            s = data['s'][k]
            #print('k,x,y = ',k,x,y)
            #print('  true s,e1,e2 = ',s,e1,e2)
            image_pos = galsim.PositionD(x,y)
            star = piff.Star.makeTarget(x=x, y=y, wcs=wcs, stamp_size=48, pointing=field_center)
            star = psf.drawStar(star)
            #print('  fitted s,e1,e2 = ',star.fit.params)
            np.testing.assert_almost_equal(star.fit.params, [s,e1,e2], decimal=6)
Exemplo n.º 5
0
def test_single():
    """Same as test_focal, but using the SingleCCD PSF type, which does a separate fit on each CCD.
    """
    wcs1 = galsim.TanWCS(
            galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees)
            )
    wcs2 = galsim.TanWCS(
            galsim.AffineTransform(0.25, -0.02, 0.01, 0.24, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)
            )
    field_center = galsim.CelestialCoord(0 * galsim.degrees, -25 * galsim.degrees)

    if __name__ == '__main__':
        nstars = 20  # per ccd
    else:
        nstars = 6  # per ccd
    rng = np.random.RandomState(1234)
    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs1._radec(x.copy(),y.copy()), projection='gnomonic')
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u*v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u*v

    data1 = np.array(list(zip(x,y,e1,e2,s)),
                     dtype=[ ('x',float), ('y',float), ('e1',float), ('e2',float), ('s',float) ])
    im1 = drawImage(2048, 2048, wcs1, x, y, e1, e2, s)
    im1.write('output/test_single_im1.fits')
    fitsio.write('output/test_single_cat1.fits', data1, clobber=True)

    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs2._radec(x.copy(),y.copy()), projection='gnomonic')
    # Same functions of u,v, but using the positions on chip 2
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u*v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u*v

    data2 = np.array(list(zip(x,y,e1,e2,s)),
                     dtype=[ ('x',float), ('y',float), ('e1',float), ('e2',float), ('s',float) ])
    im2 = drawImage(2048, 2048, wcs2, x, y, e1, e2, s)
    im2.write('output/test_single_im2.fits')
    fitsio.write('output/test_single_cat2.fits', data2, clobber=True)

    # Try to fit with the right model (Moffat) and interpolant (2nd order polyomial)
    # Should work very well, since no noise.
    config = {
        'input' : {
            # A third way to input these same file names.  Use GalSim config values and
            # explicitly specify the number of images to read
            'nimages' : 2,
            'image_file_name' : {
                'type' : 'FormattedStr',
                'format' : '%s/test_single_im%d.fits',
                'items' : [ 'output', '$image_num+1' ]
            },
            'cat_file_name' : {
                'type' : 'FormattedStr',
                'format' : '%s/test_single_cat%d.fits',
                'items' : [ 'output', '$image_num+1' ]
            },
            # Use chipnum = 1,2 rather than the default 0,1.
            'chipnum' : '$image_num+1',
            'x_col' : 'x',
            'y_col' : 'y',
            'ra' : 0.,
            'dec' : -25.,
        },
        'psf' : {
            'type' : 'SingleChip',
            'model' : {
                'type' : 'Moffat',
                'beta' : 2.5
            },
            'interp' : {
                'type' : 'Polynomial',
                'order' : 2
            }
        },
    }
    if __name__ != '__main__':
        config['verbose'] = 0
    psf = piff.process(config)

    for chipnum, data, wcs in [(1,data1,wcs1), (2,data2,wcs2)]:
        for k in range(nstars):
            x = data['x'][k]
            y = data['y'][k]
            e1 = data['e1'][k]
            e2 = data['e2'][k]
            s = data['s'][k]
            #print('k,x,y = ',k,x,y)
            #print('  true s,e1,e2 = ',s,e1,e2)
            image_pos = galsim.PositionD(x,y)
            star = piff.Star.makeTarget(x=x, y=y, wcs=wcs, stamp_size=48, pointing=field_center,
                                        chipnum=chipnum)
            star = psf.drawStar(star)
            #print('  fitted s,e1,e2 = ',star.fit.params)
            np.testing.assert_almost_equal(star.fit.params, [s,e1,e2], decimal=6)
Exemplo n.º 6
0
def test_wrongwcs():
    """Same as test_focal, but the images are written out with the wrong wcs.
    """
    wcs1 = galsim.TanWCS(
            galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees)
            )
    wcs2 = galsim.TanWCS(
            galsim.AffineTransform(0.25, -0.02, 0.01, 0.24, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)
            )
    wrong_wcs = galsim.TanWCS(
            galsim.AffineTransform(0.25, 0, 0, 0.25, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(0 * galsim.arcmin, -25 * galsim.degrees)
            )
    field_center = galsim.CelestialCoord(0 * galsim.degrees, -25 * galsim.degrees)

    if __name__ == '__main__':
        nstars = 20  # per ccd
    else:
        nstars = 3  # per ccd
    rng = np.random.RandomState(1234)
    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs1._radec(x.copy(),y.copy()), projection='gnomonic')
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u*v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u*v
    data1 = np.array(list(zip(x,y,e1,e2,s)),
                     dtype=[ ('x',float), ('y',float), ('e1',float), ('e2',float), ('s',float) ])
    im1 = drawImage(2048, 2048, wcs1, x, y, e1, e2, s)

    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs2._radec(x.copy(),y.copy()), projection='gnomonic')
    # Same functions of u,v, but using the positions on chip 2
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u*v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u*v
    data2 = np.array(list(zip(x,y,e1,e2,s)),
                     dtype=[ ('x',float), ('y',float), ('e1',float), ('e2',float), ('s',float) ])
    im2 = drawImage(2048, 2048, wcs2, x, y, e1, e2, s)

    # Put in the wrong wcs before writing them to files.
    im1.wcs = im2.wcs = wrong_wcs
    im1.write('output/test_wrongwcs_im1.fits')
    im2.write('output/test_wrongwcs_im2.fits')
    fitsio.write('output/test_wrongwcs_cat1.fits', data1, clobber=True)
    fitsio.write('output/test_wrongwcs_cat2.fits', data2, clobber=True)

    config = {
        'modules' : [ 'custom_wcs' ],
        'input' : {
            'dir' : 'output',
            # Normally more convenient to use a glob string, but an explicit list is also allowed.
            'image_file_name' : ['test_wrongwcs_im1.fits', 'test_wrongwcs_im2.fits'],
            'cat_file_name' : ['test_wrongwcs_cat1.fits', 'test_wrongwcs_cat2.fits'],
            'x_col' : 'x',
            'y_col' : 'y',
            'ra' : 0.,
            'dec' : -25.,
            # But here tell Piff the correct WCS to use.  This uses a custom WCS builder,
            # mostly so we can test the 'modules' option.  In practice, you might use a
            # galsim_extra Pixmappy WCS class.  Or maybe an LSST DM WCS.
            'wcs' : { 'type' : 'Custom' }
        },
        'psf' : {
            'type' : 'Simple',
            'model' : {
                'type' : 'Moffat',
                'beta' : 2.5
            },
            'interp' : {
                'type' : 'Polynomial',
                'order' : 2
            }
        },
    }
    if __name__ != '__main__':
        config['verbose'] = 0
    psf = piff.process(config)

    for data, wcs in [(data1,wcs1), (data2,wcs2)]:
        for k in range(nstars):
            x = data['x'][k]
            y = data['y'][k]
            e1 = data['e1'][k]
            e2 = data['e2'][k]
            s = data['s'][k]
            #print('k,x,y = ',k,x,y)
            #print('  true s,e1,e2 = ',s,e1,e2)
            image_pos = galsim.PositionD(x,y)
            star = piff.Star.makeTarget(x=x, y=y, wcs=wcs, stamp_size=48, pointing=field_center)
            star = psf.drawStar(star)
            #print('  fitted s,e1,e2 = ',star.fit.params)
            np.testing.assert_almost_equal(star.fit.params, [s,e1,e2], decimal=6)
Exemplo n.º 7
0
def test_focal():
    """This test uses 2 input files and two catalogs, but does the interpolation over the
    whole field of view.
    """
    # Give them different wcs's.
    # The centers should be separated by ~0.25 arcsec/pixel * 2048 pixels / cos(dec) = 565 arcsec
    # The actual separation of 10 arcmin gives a bit of a gap between the chips.
    wcs1 = galsim.TanWCS(
        galsim.AffineTransform(0.26, 0.05, -0.08, -0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees))
    wcs2 = galsim.TanWCS(
        galsim.AffineTransform(0.25, -0.02, 0.01, 0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees))
    field_center = galsim.CelestialCoord(0 * galsim.degrees,
                                         -25 * galsim.degrees)

    if __name__ == '__main__':
        nstars = 20  # per ccd
    else:
        nstars = 3  # per ccd
    rng = np.random.RandomState(1234)
    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs1._radec(x.copy(), y.copy()),
                                    projection='gnomonic')
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v

    data1 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    np.testing.assert_array_equal(data1['x'], x)
    np.testing.assert_array_equal(data1['y'], y)
    np.testing.assert_array_equal(data1['e1'], e1)
    np.testing.assert_array_equal(data1['e2'], e2)
    np.testing.assert_array_equal(data1['s'], s)
    im1 = drawImage(2048, 2048, wcs1, x, y, e1, e2, s)
    im1.write('output/test_focal_im1.fits')
    fitsio.write('output/test_focal_cat1.fits', data1, clobber=True)

    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs2._radec(x.copy(), y.copy()),
                                    projection='gnomonic')
    # Same functions of u,v, but using the positions on chip 2
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v

    data2 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    im2 = drawImage(2048, 2048, wcs2, x, y, e1, e2, s)
    im2.write('output/test_focal_im2.fits')
    fitsio.write('output/test_focal_cat2.fits', data2, clobber=True)

    # Try to fit with the right model (Moffat) and interpolant (2nd order polyomial)
    # Should work very well, since no noise.
    config = {
        'input': {
            'image_file_name': 'output/test_focal_im?.fits',
            'cat_file_name': 'output/test_focal_cat?.fits',
            'x_col': 'x',
            'y_col': 'y',
            'ra': 0.,
            'dec': -25.,
        },
        'psf': {
            'type': 'Simple',
            'model': {
                'type': 'Moffat',
                'beta': 2.5
            },
            'interp': {
                'type': 'Polynomial',
                'order': 2
            }
        }
    }
    if __name__ != '__main__':
        config['verbose'] = 0
    psf = piff.process(config)

    for data, wcs in [(data1, wcs1), (data2, wcs2)]:
        for k in range(nstars):
            x = data['x'][k]
            y = data['y'][k]
            e1 = data['e1'][k]
            e2 = data['e2'][k]
            s = data['s'][k]
            #print('k,x,y = ',k,x,y)
            #print('  true s,e1,e2 = ',s,e1,e2)
            image_pos = galsim.PositionD(x, y)
            star = piff.Star.makeTarget(x=x,
                                        y=y,
                                        wcs=wcs,
                                        stamp_size=48,
                                        pointing=field_center)
            star = psf.drawStar(star)
            #print('  fitted s,e1,e2 = ',star.fit.params)
            np.testing.assert_almost_equal(star.fit.params, [s, e1, e2],
                                           decimal=6)
Exemplo n.º 8
0
def test_single():
    """Same as test_focal, but using the SingleCCD PSF type, which does a separate fit on each CCD.
    """
    wcs1 = galsim.TanWCS(
        galsim.AffineTransform(0.26, 0.05, -0.08, -0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees))
    wcs2 = galsim.TanWCS(
        galsim.AffineTransform(0.25, -0.02, 0.01, 0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees))
    field_center = galsim.CelestialCoord(0 * galsim.degrees,
                                         -25 * galsim.degrees)

    if __name__ == '__main__':
        nstars = 20  # per ccd
    else:
        nstars = 6  # per ccd
    rng = np.random.RandomState(1234)
    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs1._radec(x.copy(), y.copy()),
                                    projection='gnomonic')
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v

    data1 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    im1 = drawImage(2048, 2048, wcs1, x, y, e1, e2, s)
    im1.write('output/test_single_im1.fits')
    fitsio.write('output/test_single_cat1.fits', data1, clobber=True)

    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs2._radec(x.copy(), y.copy()),
                                    projection='gnomonic')
    # Same functions of u,v, but using the positions on chip 2
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v

    data2 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    im2 = drawImage(2048, 2048, wcs2, x, y, e1, e2, s)
    im2.write('output/test_single_im2.fits')
    fitsio.write('output/test_single_cat2.fits', data2, clobber=True)

    # Try to fit with the right model (Moffat) and interpolant (2nd order polyomial)
    # Should work very well, since no noise.
    config = {
        'input': {
            # A third way to input these same file names.  Use GalSim config values and
            # explicitly specify the number of images to read
            'nimages': 2,
            'image_file_name': {
                'type': 'FormattedStr',
                'format': '%s/test_single_im%d.fits',
                'items': ['output', '$image_num+1']
            },
            'cat_file_name': {
                'type': 'FormattedStr',
                'format': '%s/test_single_cat%d.fits',
                'items': ['output', '$image_num+1']
            },
            # Use chipnum = 1,2 rather than the default 0,1.
            'chipnum': '$image_num+1',
            'x_col': 'x',
            'y_col': 'y',
            'ra': 0.,
            'dec': -25.,
        },
        'psf': {
            'type': 'SingleChip',
            'model': {
                'type': 'Moffat',
                'beta': 2.5
            },
            'interp': {
                'type': 'Polynomial',
                'order': 2
            }
        },
    }
    if __name__ != '__main__':
        config['verbose'] = 0
    psf = piff.process(config)

    for chipnum, data, wcs in [(1, data1, wcs1), (2, data2, wcs2)]:
        for k in range(nstars):
            x = data['x'][k]
            y = data['y'][k]
            e1 = data['e1'][k]
            e2 = data['e2'][k]
            s = data['s'][k]
            #print('k,x,y = ',k,x,y)
            #print('  true s,e1,e2 = ',s,e1,e2)
            image_pos = galsim.PositionD(x, y)
            star = piff.Star.makeTarget(x=x,
                                        y=y,
                                        wcs=wcs,
                                        stamp_size=48,
                                        pointing=field_center,
                                        chipnum=chipnum)
            star = psf.drawStar(star)
            #print('  fitted s,e1,e2 = ',star.fit.params)
            np.testing.assert_almost_equal(star.fit.params, [s, e1, e2],
                                           decimal=6)
Exemplo n.º 9
0
def test_wrongwcs():
    """Same as test_focal, but the images are written out with the wrong wcs.
    """
    wcs1 = galsim.TanWCS(
        galsim.AffineTransform(0.26, 0.05, -0.08, -0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees))
    wcs2 = galsim.TanWCS(
        galsim.AffineTransform(0.25, -0.02, 0.01, 0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees))
    wrong_wcs = galsim.TanWCS(
        galsim.AffineTransform(0.25, 0, 0, 0.25, galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(0 * galsim.arcmin, -25 * galsim.degrees))
    field_center = galsim.CelestialCoord(0 * galsim.degrees,
                                         -25 * galsim.degrees)

    if __name__ == '__main__':
        nstars = 20  # per ccd
    else:
        nstars = 3  # per ccd
    rng = np.random.RandomState(1234)
    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs1._radec(x.copy(), y.copy()),
                                    projection='gnomonic')
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v
    data1 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    im1 = drawImage(2048, 2048, wcs1, x, y, e1, e2, s)

    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    u, v = field_center.project_rad(*wcs2._radec(x.copy(), y.copy()),
                                    projection='gnomonic')
    # Same functions of u,v, but using the positions on chip 2
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v
    data2 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    im2 = drawImage(2048, 2048, wcs2, x, y, e1, e2, s)

    # Put in the wrong wcs before writing them to files.
    im1.wcs = im2.wcs = wrong_wcs
    im1.write('output/test_wrongwcs_im1.fits')
    im2.write('output/test_wrongwcs_im2.fits')
    fitsio.write('output/test_wrongwcs_cat1.fits', data1, clobber=True)
    fitsio.write('output/test_wrongwcs_cat2.fits', data2, clobber=True)

    config = {
        'modules': ['custom_wcs'],
        'input': {
            'dir': 'output',
            # Normally more convenient to use a glob string, but an explicit list is also allowed.
            'image_file_name':
            ['test_wrongwcs_im1.fits', 'test_wrongwcs_im2.fits'],
            'cat_file_name':
            ['test_wrongwcs_cat1.fits', 'test_wrongwcs_cat2.fits'],
            'x_col': 'x',
            'y_col': 'y',
            'ra': 0.,
            'dec': -25.,
            # But here tell Piff the correct WCS to use.  This uses a custom WCS builder,
            # mostly so we can test the 'modules' option.  In practice, you might use a
            # galsim_extra Pixmappy WCS class.  Or maybe an LSST DM WCS.
            'wcs': {
                'type': 'Custom'
            }
        },
        'psf': {
            'type': 'Simple',
            'model': {
                'type': 'Moffat',
                'beta': 2.5
            },
            'interp': {
                'type': 'Polynomial',
                'order': 2
            }
        },
    }
    if __name__ != '__main__':
        config['verbose'] = 0
    psf = piff.process(config)

    for data, wcs in [(data1, wcs1), (data2, wcs2)]:
        for k in range(nstars):
            x = data['x'][k]
            y = data['y'][k]
            e1 = data['e1'][k]
            e2 = data['e2'][k]
            s = data['s'][k]
            #print('k,x,y = ',k,x,y)
            #print('  true s,e1,e2 = ',s,e1,e2)
            image_pos = galsim.PositionD(x, y)
            star = piff.Star.makeTarget(x=x,
                                        y=y,
                                        wcs=wcs,
                                        stamp_size=48,
                                        pointing=field_center)
            star = psf.drawStar(star)
            #print('  fitted s,e1,e2 = ',star.fit.params)
            np.testing.assert_almost_equal(star.fit.params, [s, e1, e2],
                                           decimal=6)
Exemplo n.º 10
0
def test_parallel():
    # Run the same test as test_single, but using nproc
    wcs1 = galsim.TanWCS(
        galsim.AffineTransform(0.26, 0.05, -0.08, -0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees))
    wcs2 = galsim.TanWCS(
        galsim.AffineTransform(0.25, -0.02, 0.01, 0.24,
                               galsim.PositionD(1024, 1024)),
        galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees))
    field_center = galsim.CelestialCoord(0 * galsim.degrees,
                                         -25 * galsim.degrees)

    if __name__ == '__main__':
        nstars = 20  # per ccd
    else:
        nstars = 6  # per ccd
    rng = np.random.RandomState(1234)
    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    ra1, dec1 = wcs1.toWorld(x, y, units='rad')
    u, v = field_center.project_rad(ra1, dec1, projection='gnomonic')
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v

    data1 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    im1 = drawImage(2048, 2048, wcs1, x, y, e1, e2, s)
    im1.write('output/test_parallel_im1.fits')

    x = rng.random_sample(nstars) * 2000 + 24
    y = rng.random_sample(nstars) * 2000 + 24
    ra2, dec2 = wcs2.toWorld(x, y, units='rad')
    u, v = field_center.project_rad(ra1, dec1, projection='gnomonic')
    # Same functions of u,v, but using the positions on chip 2
    e1 = 0.02 + 2.e-5 * u - 3.e-9 * u**2 + 2.e-9 * v**2
    e2 = -0.04 - 3.e-5 * v + 1.e-9 * u * v + 3.e-9 * v**2
    s = 0.3 + 8.e-9 * (u**2 + v**2) - 1.e-9 * u * v

    data2 = np.array(list(zip(x, y, e1, e2, s)),
                     dtype=[('x', float), ('y', float), ('e1', float),
                            ('e2', float), ('s', float)])
    im2 = drawImage(2048, 2048, wcs2, x, y, e1, e2, s)
    im2.write('output/test_parallel_im2.fits')

    ra12 = np.concatenate([ra1, ra2])
    dec12 = np.concatenate([dec1, dec2])
    data12 = np.array(list(zip(ra12, dec12)),
                      dtype=[('ra', float), ('dec', float)])
    fitsio.write('output/test_parallel.fits', data12, clobber=True)

    # im3 is blank.  Will give errors trying to measure PSF from it.
    im3 = galsim.Image(2048, 2048, wcs=wcs2)
    im3.write('output/test_parallel_im3.fits')

    psf_file = os.path.join('output', 'test_single.fits')
    config = {
        'input': {
            # A third way to input these same file names.  Use GalSim config values and
            # explicitly specify the number of images to read
            'nimages': 2,
            'image_file_name': {
                'type': 'FormattedStr',
                'format': '%s/test_parallel_im%d.fits',
                'items': ['output', '$image_num+1'],
            },
            'cat_file_name': 'output/test_parallel.fits',
            'chipnum': '$image_num+1',
            'ra_col': 'ra',
            'dec_col': 'dec',
            'ra_units': 'rad',
            'dec_units': 'rad',
            'nproc': -1,
        },
        'psf': {
            'type': 'SingleChip',
            'model': {
                'type': 'Moffat',
                'beta': 2.5,
            },
            'interp': {
                'type': 'Polynomial',
                'order': 2,
            },
            'nproc': 2,
        },
        'output': {
            'file_name': psf_file,
        },
    }
    with CaptureLog(level=2) as cl:
        piff.piffify(config, logger=cl.logger)
    psf = piff.read(psf_file)

    for chipnum, data, wcs in [(1, data1, wcs1), (2, data2, wcs2)]:
        for k in range(nstars):
            x = data['x'][k]
            y = data['y'][k]
            e1 = data['e1'][k]
            e2 = data['e2'][k]
            s = data['s'][k]
            image_pos = galsim.PositionD(x, y)
            star = piff.Star.makeTarget(x=x,
                                        y=y,
                                        wcs=wcs,
                                        stamp_size=48,
                                        pointing=field_center,
                                        chipnum=chipnum)
            star = psf.drawStar(star)
            np.testing.assert_almost_equal(star.fit.params, [s, e1, e2],
                                           decimal=6)

    # Finally, check that the logger properly captures the subprocess logs
    with CaptureLog(level=2) as cl:
        psf = piff.process(config, cl.logger)
    #print('with nproc=2, log = ',cl.output)
    assert "Processing catalog 1" in cl.output
    assert "Processing catalog 2" in cl.output
    assert "Building solution for chip 1" in cl.output
    assert "Building solution for chip 2" in cl.output

    # Check that errors in the solution get properly reported.
    config['input']['nimages'] = 3
    with CaptureLog(level=2) as cl:
        psf = piff.process(config, cl.logger)
    assert "Removed 6 stars in initialize" in cl.output
    assert "No stars.  Cannot find PSF model." in cl.output
    assert "Solutions failed for chipnums: [3]" in cl.output

    # Check that errors in the multiprocessing input get properly reported.
    config['input']['ra_col'] = 'invalid'
    with CaptureLog(level=2) as cl:
        with np.testing.assert_raises(ValueError):
            psf = piff.process(config, cl.logger)
    assert "ra_col = invalid is not a column" in cl.output

    # With nproc=1, the error is raised directly.
    config['input']['nproc'] = 1
    config['verbose'] = 0
    with np.testing.assert_raises(ValueError):
        psf = piff.process(config)

    # But just the input error.  Not the one in fitting.
    config['psf']['nproc'] = 1
    config['input']['ra_col'] = 'ra'
    config['verbose'] = 1
    with CaptureLog(level=1) as cl:
        psf = piff.process(config, logger=cl.logger)
    assert "No stars.  Cannot find PSF model." in cl.output
    assert "Ignoring this failure and continuing on." in cl.output