Beispiel #1
0
def test_align_wcs_simple_twpwcs_ref(mock_fits_wcs):
    shift = (12, -34)
    rot = (15, 17)
    scale = (1.0123, 0.9876)

    xy = 1024 * np.random.random((100, 2))
    m = build_fit_matrix(rot, scale)
    xyr = np.dot(xy, m.T) + shift
    imcat = Table(xy, names=('x', 'y'))
    refcat = Table(xyr, names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})
    reftpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': refcat})
    status = align_wcs(tpwcs,
                       reftpwcs,
                       ref_tpwcs=tpwcs,
                       fitgeom='general',
                       match=None)

    assert status
    assert tpwcs.meta['fit_info']['status'] == 'SUCCESS'
    assert tpwcs.meta['fit_info']['fitgeom'] == 'general'
    assert np.allclose(tpwcs.meta['fit_info']['shift'], shift)
    assert np.allclose(tpwcs.meta['fit_info']['matrix'], m)
    assert np.allclose(tpwcs.meta['fit_info']['rot'], rot)
    assert tpwcs.meta['fit_info']['proper']
    assert np.allclose(tpwcs.meta['fit_info']['scale'], scale)
    assert tpwcs.meta['fit_info']['rmse'] < 1.0e-8
Beispiel #2
0
def test_align_wcs_refcat_from_imcat(mock_fits_wcs, enforce):
    shift = (12, -34)
    rot = (15, 17)
    scale = (1.0123, 0.9876)

    crpix = mock_fits_wcs.wcs.crpix - 1
    xy = 1024 * np.random.random((100, 2))
    m = build_fit_matrix(rot, scale)
    xyr = np.dot(xy - crpix, m) + crpix + shift
    imcat = Table(xy, names=('x', 'y'))
    refcat = Table(xyr, names=('x', 'y'))
    tpwcs1 = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})
    tpwcs2 = copy.deepcopy(tpwcs1)
    reftpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': refcat})

    input_catalogs = [reftpwcs, tpwcs1, tpwcs2]
    status = align_wcs(
        input_catalogs, refcat=None, fitgeom='general',
        match=None, enforce_user_order=enforce, expand_refcat=True
    )
    assert status

    for cat in input_catalogs:
        if cat.meta['fit_info']['status'] == 'REFERENCE':
            if enforce:
                assert cat is reftpwcs
            continue
        assert cat.meta['fit_info']['status'] == 'SUCCESS'
Beispiel #3
0
def test_align_wcs_tpwcs_refcat_must_have_catalog(mock_fits_wcs):
    xy = np.array([[1, 0], [2, 3], [3, 1], [4, 5]])
    imcat = Table(xy, names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})
    reftpwcs = FITSWCS(mock_fits_wcs)

    with pytest.raises(ValueError) as e:
        align_wcs(tpwcs, refcat=reftpwcs)
    assert (e.value.args[0] == "Reference 'TPWCS' must contain a catalog.")
Beispiel #4
0
def test_fit_wcs_malformed_meta(mock_fits_wcs):
    tpwcs = FITSWCS(mock_fits_wcs)
    tpwcs._meta = None  # bad

    x = list(range(10))
    y = [10 * random.random() for _ in range(10)]
    imcat = Table([x, y], names=('x', 'y'))
    ra, dec = mock_fits_wcs.all_pix2world(x, y, 0)
    refcat = Table([ra, dec], names=('RA', 'DEC'))

    with pytest.raises(AttributeError) as e:
        tpwcs = fit_wcs(refcat, imcat, tpwcs, fitgeom='shift')
    assert e.value.args[0] == "Unable to set/modify tpwcs.meta attribute."
Beispiel #5
0
def test_align_wcs_simple_ref_image_general(shift, rot, scale, fitgeom,
                                            weighted, mock_fits_wcs):
    xy = 1024 * np.random.random((100, 2))
    if weighted:
        w = np.ones((100, 1))
        xy = np.hstack((xy, w))
        names = ('x', 'y', 'weight')
    else:
        names = ('x', 'y')
    m = build_fit_matrix(rot, scale)
    xyr = np.dot(xy[:, :2], m.T) + shift
    imcat = Table(xy, names=names)
    radec = mock_fits_wcs.wcs_pix2world(xyr, 0)
    if weighted:
        radec = np.hstack((radec, w))
        names = ('RA', 'DEC', 'weight')
    else:
        names = ('RA', 'DEC')
    refcat = Table(radec, names=names)
    tpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})
    status = align_wcs(tpwcs, refcat, fitgeom=fitgeom, match=None)

    assert status
    assert tpwcs.meta['fit_info']['status'] == 'SUCCESS'
    assert tpwcs.meta['fit_info']['fitgeom'] == fitgeom
    assert np.allclose(tpwcs.meta['fit_info']['shift'], shift)
    assert np.allclose(tpwcs.meta['fit_info']['matrix'], m)
    assert np.allclose(tpwcs.meta['fit_info']['rot'], rot)
    assert tpwcs.meta['fit_info']['proper']
    assert np.allclose(tpwcs.meta['fit_info']['scale'], scale)
    assert tpwcs.meta['fit_info']['rmse'] < 1.0e-8
Beispiel #6
0
def rect_imcat(mock_fits_wcs):
    x = np.array([0.0, 0.0, 10.0, 10.0, 0.0]) - 5
    y = np.array([0.0, 10.0, 10.0, 0.0, 0.0]) - 5
    imcat = Table([x, y], names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs)
    w = WCSImageCatalog(imcat, tpwcs)
    return w
Beispiel #7
0
def test_fit_wcs_missing_req_col_names(empty_refcat, mock_fits_wcs):
    tpwcs = FITSWCS(mock_fits_wcs)
    imcat = Table([[], []], names=('x', 'weird'))
    with pytest.raises(ValueError) as e:
        fit_wcs(empty_refcat, imcat, tpwcs)
    assert (e.value.args[0] == "An image catalog must contain 'x' "
            "and 'y' columns!")
Beispiel #8
0
def test_fit_wcs_1_image_source_empty_ref(empty_refcat, mock_fits_wcs):
    tpwcs = FITSWCS(mock_fits_wcs)
    imcat = Table([[1], [2]], names=('x', 'y'))
    with pytest.raises(ValueError) as e:
        fit_wcs(empty_refcat, imcat, tpwcs)
    assert (e.value.args[0] == "Reference catalog must contain at "
            "least one source.")
Beispiel #9
0
def test_wcsimcat_no_wcs_bb(mock_fits_wcs, rect_cat):
    tpwcs = FITSWCS(mock_fits_wcs)
    tpwcs._owcs.pixel_bounds = None
    tpwcs._owcs.pixel_shape = None

    assert tpwcs.bounding_box is None

    WCSImageCatalog(rect_cat, tpwcs)
Beispiel #10
0
def test_align_wcs_1im_no_ref(mock_fits_wcs):
    xy = np.array([[1, 0], [2, 3], [3, 1], [4, 5]])
    imcat = Table(xy, names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})

    with pytest.raises(ValueError) as e:
        align_wcs(tpwcs, refcat=None, fitgeom='shift', match=None)
    assert e.value.args[0] == "Too few input images (or groups of images)."
Beispiel #11
0
def test_fit_wcs_less_than_minsrc(mock_fits_wcs):
    x = [1, 20]
    y = [1, 20]
    tpwcs = FITSWCS(mock_fits_wcs)
    imcat = Table([x, y], names=('x', 'y'))
    ra, dec = mock_fits_wcs.all_pix2world(x, y, 0)
    refcat = Table([ra, dec], names=('RA', 'DEC'))
    tpwcs = fit_wcs(refcat, imcat, tpwcs, fitgeom='general')
    assert tpwcs.meta['fit_info']['status'] == 'FAILED: not enough matches'
Beispiel #12
0
def test_align_wcs_unknown_fitgeom(mock_fits_wcs):
    xy = np.array([[1, 0], [2, 3], [3, 1], [4, 5]])
    imcat = Table(xy, names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})

    with pytest.raises(ValueError) as e:
        align_wcs(tpwcs, fitgeom='unknown')
    assert (e.value.args[0] == "Unsupported 'fitgeom'. Valid values are: "
            "'shift', 'rshift', 'rscale', or 'general'")
Beispiel #13
0
def test_align_wcs_wrong_refcat_type(mock_fits_wcs):
    xy = np.array([[1, 0], [2, 3], [3, 1], [4, 5]])
    imcat = Table(xy, names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})

    with pytest.raises(TypeError) as e:
        align_wcs(tpwcs, refcat=xy, fitgeom='shift', match=None)
    assert (e.value.args[0] == "Unsupported 'refcat' type. Supported 'refcat' "
            "types are 'tweakwcs.tpwcs.TPWCS' and 'astropy.table.Table'")
Beispiel #14
0
def test_wcsimcat_calc_cat_convex_hull_adjacent():
    h = fits.Header.fromfile(get_pkg_data_filename('data/wfc3_uvis1.hdr'))
    w = wcs.WCS(h)
    tpwcs = FITSWCS(w)
    cat = Table.read(get_pkg_data_filename('data/convex_hull_proximity.cat'),
                     format='ascii.tab',
                     delimiter='\t',
                     names=['x', 'y'])
    w = WCSImageCatalog(cat, tpwcs)
    assert len(list(w.polygon.points)[0]) == 14
Beispiel #15
0
def test_align_wcs_no_radec_in_refcat(mock_fits_wcs):
    xy = np.array([[1, 0], [2, 3], [3, 1], [4, 5]])
    imcat = Table(xy, names=('x', 'y'))
    refcat = Table(xy, names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})

    with pytest.raises(KeyError) as e:
        align_wcs(tpwcs, refcat, fitgeom='shift', match=None)
    assert (e.value.args[0] == "Reference catalogs *must* contain *both* 'RA' "
            "and 'DEC' columns.")
Beispiel #16
0
def test_fit_wcs_empty_cat(empty_refcat, empty_imcat, mock_fits_wcs):
    tpwcs = FITSWCS(
        mock_fits_wcs,
        meta={'catalog': Table([[], []], names=('x', 'y')), 'group_id': 1}
    )

    with pytest.raises(ValueError) as e:
        align_wcs([tpwcs, tpwcs, tpwcs])
    assert e.value.args[0] == ("Too few input images (or groups of images) "
                               "with non-empty catalogs.")
Beispiel #17
0
def test_fit_wcs_unsupported_fitgeom(mock_fits_wcs):
    tpwcs = FITSWCS(mock_fits_wcs)
    x = list(range(10))
    y = [10 * random.random() for _ in range(10)]
    imcat = Table([x, y], names=('x', 'y'))
    ra, dec = mock_fits_wcs.all_pix2world(x, y, 0)
    refcat = Table([ra, dec], names=('RA', 'DEC'))

    with pytest.raises(ValueError) as e:
        tpwcs = fit_wcs(refcat, imcat, tpwcs, fitgeom='unsupported')
    assert (e.value.args[0] == "Unsupported 'fitgeom'. Valid values are: "
            "'shift', 'rshift', 'rscale', or 'general'")
Beispiel #18
0
def test_fit_wcs_minsrc_img_ref(mock_fits_wcs, x, y, fitgeom):
    tpwcs = FITSWCS(mock_fits_wcs)
    imcat = Table([x, y], names=('x', 'y'))
    ra, dec = mock_fits_wcs.all_pix2world(x, y, 0)
    refcat = Table([ra, dec], names=('RA', 'DEC'))

    tpwcs = fit_wcs(refcat, imcat, tpwcs, fitgeom=fitgeom)

    fi = tpwcs.meta['fit_info']
    assert fi['status'] == 'SUCCESS'
    assert np.allclose(fi['shift'], (0, 0), rtol=0, atol=1e4 * _ATOL)
    assert np.max(np.abs(fi['matrix'] - np.identity(2))) < 1e4 * _ATOL
Beispiel #19
0
def test_fit_drop_empty(mock_fits_wcs):
    t0 = Table([[], []], names=('x', 'y'))
    t1 = Table([[1], [3]], names=('x', 'y'))
    wcscats = [
        FITSWCS(
            copy.deepcopy(mock_fits_wcs),
            meta={'catalog': t0.copy(), 'group_id': 1}
        ),
        FITSWCS(
            copy.deepcopy(mock_fits_wcs),
            meta={'catalog': t1.copy(), 'group_id': 2}
        ),
        FITSWCS(
            copy.deepcopy(mock_fits_wcs),
            meta={'catalog': t0.copy(), 'group_id': 2}
        ),
        FITSWCS(
            copy.deepcopy(mock_fits_wcs),
            meta={'catalog': t0.copy(), 'group_id': 3}
        ),
        FITSWCS(
            copy.deepcopy(mock_fits_wcs),
            meta={'catalog': t0.copy(), 'group_id': 3}
        ),
        FITSWCS(
            copy.deepcopy(mock_fits_wcs),
            meta={'catalog': t1.copy(), 'group_id': 4}
        ),
        FITSWCS(
            copy.deepcopy(mock_fits_wcs),
            meta={'catalog': t1.copy(), 'group_id': 4}
        )
    ]

    align_wcs(wcscats, fitgeom='shift')

    status = [w.meta.get('fit_info')['status'] for w in wcscats]

    assert status[0] == 'FAILED: empty source catalog'
    assert status[3] == 'FAILED: empty source catalog'
    assert status[4] == 'FAILED: empty source catalog'

    if status[1] == 'SUCCESS':
        assert status[2] == 'SUCCESS'
        assert status[5] == 'REFERENCE'
        assert status[6] == 'REFERENCE'

    elif status[1] == 'REFERENCE':
        assert status[2] == 'REFERENCE'
        assert status[5] == 'SUCCESS'
        assert status[6] == 'SUCCESS'

    else:
        assert False
Beispiel #20
0
def test_align_wcs_minobj(mock_fits_wcs):
    shift = (12, -34)
    rot = (15, 17)
    scale = (1.0123, 0.9876)

    crpix = mock_fits_wcs.wcs.crpix - 1
    xy = 1024 * np.random.random((100, 2))
    m = build_fit_matrix(rot, scale)
    xyr = np.dot(xy - crpix, m) + crpix + shift
    imcat = Table(xy, names=('x', 'y'))
    refcat = Table(xyr, names=('x', 'y'))
    tpwcs1 = FITSWCS(mock_fits_wcs, meta={'catalog': imcat})
    reftpwcs = FITSWCS(mock_fits_wcs, meta={'catalog': refcat})

    status = align_wcs([reftpwcs, tpwcs1],
                       refcat=None,
                       fitgeom='general',
                       minobj=200,
                       match=None,
                       enforce_user_order=True,
                       expand_refcat=False)
    assert status
    assert reftpwcs.meta['fit_info']['status'] == 'REFERENCE'
    assert tpwcs1.meta['fit_info']['status'] == 'FAILED: not enough matches'
Beispiel #21
0
def test_wcsimcat_wcs_transforms_roundtrip(mock_fits_wcs):
    x = np.arange(5)
    y = np.random.permutation(5)
    imcat = Table([x, y], names=('x', 'y'))
    tpwcs = FITSWCS(mock_fits_wcs)
    w = WCSImageCatalog(imcat, tpwcs)

    assert np.allclose(w.world_to_det(*w.det_to_world(x, y)), (x, y),
                       rtol=0,
                       atol=1.0e-5)

    assert np.allclose(w.tanp_to_det(*w.det_to_tanp(x, y)), (x, y),
                       rtol=0,
                       atol=1.0e-5)

    assert np.allclose(
        w.world_to_tanp(*w.tanp_to_world(1.0e-5 * x, 1.0e-5 * y)),
        (1.0e-5 * x, 1.0e-5 * y),
        rtol=0,
        atol=1.0e-5)
Beispiel #22
0
def test_fit_wcs_empty_cat(empty_refcat, empty_imcat, mock_fits_wcs):
    tpwcs = FITSWCS(mock_fits_wcs)
    with pytest.raises(ValueError) as e:
        fit_wcs(empty_refcat, empty_imcat, tpwcs)
    assert e.value.args[0] == "Image catalog must contain at least one entry."
Beispiel #23
0
def test_multi_image_set(mock_fits_wcs):
    np.random.seed(1)
    v1 = 1e10 * np.finfo(np.double).eps
    v2 = 1 - v1
    corners = np.array([[v1, v1], [v1, v2], [v2, v2], [v2, v1]])
    n = 1

    def get_points():
        nonlocal n, v1, v2
        pts = []
        for _ in range(4):
            v1 *= n
            v2 = 1 - v1
            n += 1
            corners = np.array([[v1, v1], [v1, v2], [v2, v2], [v2, v1]])
            pts += [
                v1 + (v2 - v1) * np.random.random((250 - len(corners), 2)),
                corners
            ]
        return np.vstack(pts)

    # reference catalog sources:
    wcsref = copy.deepcopy(mock_fits_wcs)
    xyref = 512 * get_points()
    xyref[250:500, 0] += 512
    xyref[500:750, 1] += 512
    xyref[750:, :] += 512

    radec = wcsref.wcs_pix2world(xyref, 0)
    refcat = Table(radec, names=('RA', 'DEC'))

    wcsref = copy.deepcopy(mock_fits_wcs)
    refcat = Table(xyref, names=('x', 'y'))
    ref_img_tpwcs = FITSWCS(wcsref, meta={'catalog': refcat,
                                          'name': 'ref_img_tpwcs'})

    # single overlap catalog sources:
    wcsim1 = copy.deepcopy(mock_fits_wcs)
    wcsim1.wcs.crval += 1e-5

    xyim1 = 512 + 512 * np.vstack((np.random.random((1000, 2)), corners))
    xyim1[:250, :] = xyref[750:, :]  # overlap
    xyim1[250:500, 0] += 512
    xyim1[500:750, 1] += 512
    xyim1[750:, :] += 512

    imcat = Table(xyim1, names=('x', 'y'))
    im1_tpwcs = FITSWCS(wcsim1, meta={'catalog': imcat, 'name': 'im1_tpwcs'})

    # non-overlaping image:
    wcsim2 = copy.deepcopy(mock_fits_wcs)
    xyim2 = xyim1.copy()
    xyim2[:, 0] += 2000.0
    imcat = Table(xyim2, names=('x', 'y'))
    im2_tpwcs = FITSWCS(wcsim2, meta={'catalog': imcat, 'name': 'im2_tpwcs'})

    # grouped images overlap reference catalog sources:
    wcsim3 = copy.deepcopy(mock_fits_wcs)

    xyim3 = 512 * np.vstack((np.random.random((1000, 2)), corners))
    xyim3[:250, :] = xyref[250:500, :]  # overlap
    xyim3[250:750, 0] += 1024
    xyim3[750:, 0] += 512
    xyim3[500:, 1] -= 512

    imcat = Table(xyim3, names=('x', 'y'))
    im3_tpwcs = FITSWCS(wcsim3, meta={
        'catalog': imcat, 'group_id': 'group1', 'name': 'im3_tpwcs'
    })

    wcsim4 = copy.deepcopy(mock_fits_wcs)
    xyim4 = (512, -512) + 1024 * np.vstack((np.random.random((1000, 2)),
                                            corners))
    imcat = Table(xyim4, names=('x', 'y'))
    im4_tpwcs = FITSWCS(wcsim4, meta={  # noqa: F841
        'catalog': imcat, 'group_id': 'group1', 'name': 'im4_tpwcs'
    })

    wcsim5 = copy.deepcopy(mock_fits_wcs)
    xyim5 = (512, -512 - 1024) + 1024 * np.vstack((np.random.random((1000, 2)),
                                                   corners))
    imcat = Table(xyim5, names=('x', 'y'))
    im5_tpwcs = FITSWCS(wcsim5, meta={
        'catalog': imcat, 'group_id': 'group1', 'name': 'im5_tpwcs'
    })

    # Temporarily remove im4_tpwcs from imglist due to crashes in
    # spherical_geometry.
    imglist = [
        ref_img_tpwcs, im1_tpwcs, im2_tpwcs, im5_tpwcs, im3_tpwcs,  # im4_tpwcs
    ]

    status = align_wcs(imglist, None, fitgeom='general',
                       enforce_user_order=False, expand_refcat=True)

    assert status
    assert im1_tpwcs.meta['fit_info']['status'] == 'SUCCESS'
    assert im1_tpwcs.meta['fit_info']['fitgeom'] == 'general'
    assert im1_tpwcs.meta['fit_info']['rmse'] < 1e8 * _ATOL
    assert np.allclose(im1_tpwcs.wcs.wcs.crval, ref_img_tpwcs.wcs.wcs.crval,
                       rtol=0, atol=1.0e-10)
def build_wcscat(image, group_id, source_catalog):
    """ Return a list of `~tweakwcs.tpwcs.FITSWCS` objects for all chips in an image.

    Parameters
    ----------
    image : str, `~astropy.io.fits.HDUList`
        Either filename or HDUList of a single HST observation.

    group_id : int
        Integer ID for group this image should be associated with; primarily
        used when separate chips are in separate files to treat them all as one
        exposure.

    source_catalog : dict
        If provided, these catalogs will be attached as `catalog`
        entries in each chip's ``FITSWCS`` object.  It should be provided as a
        dict of astropy Tables identified by chip number with
        each table containing sources from image extension ``('sci', chip)`` as
        generated by `generate_source_catalog()`.

    Returns
    -------
    wcs_catalogs : list of `~tweakwcs.tpwcs.FITSWCS`
        List of `~tweakwcs.tpwcs.FITSWCS` objects defined for all chips in input image.

    """
    open_file = False
    if isinstance(image, str):
        hdulist = fits.open(image)
        open_file = True
    elif isinstance(image, fits.HDUList):
        hdulist = image
    else:
        log.info("Wrong type of input, {}, for build_wcscat...".format(
            type(image)))
        raise ValueError

    wcs_catalogs = []
    numsci = countExtn(hdulist)
    for chip in range(1, numsci + 1):
        w = wcsutil.HSTWCS(hdulist, ('SCI', chip))

        imcat = source_catalog[chip]
        # rename xcentroid/ycentroid columns, if necessary, to be consistent with tweakwcs
        if 'xcentroid' in imcat.colnames:
            imcat.rename_column('xcentroid', 'x')
            imcat.rename_column('ycentroid', 'y')

        wcscat = FITSWCS(w,
                         meta={
                             'chip': chip,
                             'group_id': group_id,
                             'filename': image,
                             'catalog': imcat,
                             'name': image
                         })

        wcs_catalogs.append(wcscat)

    if open_file:
        hdulist.close()

    return wcs_catalogs
Beispiel #25
0
def test_align_wcs_tpwcs_missing_cat(mock_fits_wcs):
    tpwcs = FITSWCS(mock_fits_wcs)
    with pytest.raises(ValueError) as e:
        align_wcs(tpwcs)
    assert (e.value.args[0] == "Each object in 'wcscat' must have a valid "
            "catalog.")