Esempio n. 1
0
def test_Filament2D_iteratbranchprune_leavenone():
    '''
    Add multiple branches that should be pruned, leaving a single branch
    skeleton.

    Longest path will have a length of 7 + sqrt(2)
    '''

    pixels = (np.array([0, 2, 1, 4, 1, 2, 3, 1, 4, 5, 1, 1, 1]) + 1,
              np.array([0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6]) + 1)

    prune_pixels = (np.array([1, 1, 1, 1, 1, 2, 3, 4, 5]) + 1,
                    np.array([2, 3, 4, 5, 6, 2, 2, 3, 3]) + 1)

    shape = (7, 8)

    image = np.zeros(shape)
    image[pixels] = 2.

    fil = Filament2D(pixels)

    assert all([(out == inp).all()
                for out, inp in zip(fil.pixel_coords, pixels)])
    assert fil.pixel_extents == [(1, 1), (pixels[0].max(), pixels[1].max())]

    mask_expect = np.zeros(shape, dtype=bool)
    mask_expect[pixels] = True

    # Now run the skeleton analysis
    fil.skeleton_analysis(image,
                          prune_criteria='length',
                          branch_thresh=2 * u.pix)

    for pix_exp, pix_have in zip(prune_pixels, fil.pixel_coords):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()

    # The extra branch should now be removed.
    mask_prune = fil.skeleton(pad_size=1)
    pix = np.where(mask_prune)
    for pix_exp, pix_have in zip(prune_pixels, pix):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()

    assert (fil.skeleton() == fil.skeleton(out_type='longpath')).all()

    # The pruned graph should be reduced to a single node representing the
    # remaining branch
    assert list(fil.graph.nodes()) == [1]
    assert dict(fil.graph.degree()) == {1: 0}

    # The branch properties should match those of the longest path
    assert fil.branch_properties['length'] == fil.length()
    assert fil.branch_properties['number'] == 1
    assert fil.branch_properties['intensity'] == fil.median_brightness(image)
    for pix_exp, pix_have in zip(prune_pixels,
                                 fil.branch_properties['pixels'][0].T):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()
Esempio n. 2
0
def test_Filament2D_with_distance():

    pixels = (np.array([0, 0, 0]), np.array([0, 1, 2]))

    image = np.zeros((1, 3))
    image[0, :] = 2.

    mywcs = WCS()
    mywcs.wcs.ctype = ['GLON-CAR', 'GLAT-CAR']
    mywcs.wcs.cunit = ['deg', 'deg']

    fil = Filament2D(pixels, wcs=mywcs, distance=100 * u.pc)
    fil.skeleton_analysis(image)

    # Check the length
    assert fil.length().value == 2.0
    assert fil.length().unit == u.pix

    assert fil.length(unit=u.deg) == 2.0 * u.deg

    assert fil.length(unit=u.pc) == (2.0 * u.deg).to(u.rad).value * 100 * u.pc
Esempio n. 3
0
def test_Filament2D_onebranchprune_wpadding():
    '''
    Longest path will be in a straight line. Expect length of 8
    '''

    from fil_finder.filament import Filament2D

    pixels = (np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2]) + 1,
              np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 3, 3]) + 1)

    prune_pixels = (np.array([0, 0, 0, 0, 0, 0, 0, 0, 0]) + 1,
                    np.array([0, 1, 2, 3, 4, 5, 6, 7, 8]) + 1)

    shape = (5, 11)

    image = np.zeros(shape)
    image[pixels] = 2.

    fil = Filament2D(pixels)

    assert all([(out == inp).all()
                for out, inp in zip(fil.pixel_coords, pixels)])
    assert fil.pixel_extents == [(1, 1), (pixels[0].max(), pixels[1].max())]

    mask_expect = np.zeros(shape, dtype=bool)
    mask_expect[pixels] = True

    mask = fil.skeleton(pad_size=1)
    for pix_exp, pix_have in zip(pixels, fil.pixel_coords):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()
    pix = np.where(mask)
    for pix_exp, pix_have in zip(pixels, pix):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()

    # Now run the skeleton analysis
    fil.skeleton_analysis(image,
                          prune_criteria='length',
                          branch_thresh=2 * u.pix)

    for pix_exp, pix_have in zip(prune_pixels, fil.pixel_coords):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()

    # The extra branch should now be removed.
    mask_prune = fil.skeleton(pad_size=1)
    pix = np.where(mask_prune)
    for pix_exp, pix_have in zip(prune_pixels, pix):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()

    assert (fil.skeleton() == fil.skeleton(out_type='longpath')).all()

    # The pruned graph should be reduced to a single node representing the
    # remaining branch
    assert list(fil.graph.nodes()) == [1]
    assert dict(fil.graph.degree()) == {1: 0}

    # The branch properties should match those of the longest path
    assert fil.branch_properties['length'] == fil.length()
    assert fil.branch_properties['number'] == 1
    assert fil.branch_properties['intensity'] == fil.median_brightness(image)
    for pix_exp, pix_have in zip(prune_pixels,
                                 fil.branch_properties['pixels'][0].T):
        assert pix_exp.size == pix_have.size
        assert (pix_exp == pix_have).all()
Esempio n. 4
0
def test_Filament2D_onebranch_wpadding():
    '''
    Longest path will be in a straight line. Expect length of 8
    '''

    pixels = (np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2]) + 1,
              np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 3, 3]) + 1)

    shape = (5, 11)

    image = np.zeros(shape)
    image[pixels] = 2.

    fil = Filament2D(pixels)

    assert all([(out == inp).all()
                for out, inp in zip(fil.pixel_coords, pixels)])
    assert fil.pixel_extents == [(1, 1), (pixels[0].max(), pixels[1].max())]

    mask_expect = np.zeros(shape, dtype=bool)
    mask_expect[pixels] = True

    mask = fil.skeleton(pad_size=1)

    assert (mask == mask_expect).all()

    # Long path mask should fail without skeleton_analysis
    with pytest.raises(AttributeError):
        fil.skeleton(out_type='longpath')

    # Now run the skeleton analysis
    fil.skeleton_analysis(image)

    # Remove the one branch pixel
    mask_expect = np.zeros(shape, dtype=bool)
    mask_expect[pixels[0][:-2], pixels[1][:-2]] = True

    pad = 1
    mask = fil.skeleton(out_type='longpath', pad_size=pad)
    mask_expect_slice = fil.image_slicer(mask_expect, mask.shape, pad_size=pad)
    assert (mask == mask_expect_slice).all()

    # Check the length
    assert fil.length().value == 8.0
    assert fil.length().unit == u.pix

    # Angular and physical conversion should fail b/c no WCS or distance is
    # given
    with pytest.raises(AttributeError):
        fil.length(unit=u.deg)

    with pytest.raises(AttributeError):
        fil.length(unit=u.pc)

    # The branches should all have the same average intensity
    for branch_int in fil.branch_properties['intensity']:
        assert branch_int == 2.0

    # Finally, make sure the transpose shape gives the same length, masks
    fil = Filament2D((pixels[1], pixels[0]))

    assert all([(out == inp).all()
                for out, inp in zip(fil.pixel_coords, pixels[::-1])])
    assert fil.pixel_extents == [(1, 1), (pixels[1].max(), pixels[0].max())]

    mask_expect = np.zeros(shape, dtype=bool)
    mask_expect[pixels] = True

    mask = fil.skeleton(pad_size=1)

    assert (mask == mask_expect.T).all()

    fil.skeleton_analysis(image.T)

    assert fil.length().value == 8.0

    mask_expect = np.zeros(shape, dtype=bool)
    mask_expect[pixels[0][:-2], pixels[1][:-2]] = True

    mask = fil.skeleton(out_type='longpath', pad_size=pad)
    assert (mask == mask_expect.T).all()
Esempio n. 5
0
def test_Filament2D():

    pixels = (np.array([0, 0, 0]), np.array([0, 1, 2]))

    image = np.zeros((1, 3))
    image[0, :] = 2.

    fil = Filament2D(pixels)

    assert all([(out == inp).all()
                for out, inp in zip(fil.pixel_coords, pixels)])
    assert fil.pixel_extents == [(0, 0), (0, 2)]

    assert fil.position() == [0 * u.pix, 1 * u.pix]

    # Should return pixels again because no WCS info is given
    with warnings.catch_warnings(record=True) as w:
        assert fil.position(world_coord=True) == [0 * u.pix, 1 * u.pix]

    assert len(w) == 1
    assert w[0].category == UserWarning
    assert str(w[0].message) == ("No WCS information given. Returning pixel"
                                 " position.")

    mask_expect = np.zeros((1, 3), dtype=bool)
    mask_expect[pixels] = True

    mask = fil.skeleton()

    assert (mask == mask_expect).all()

    # Test out the padding
    pad = 1
    mask_expect = np.zeros((1 + 2 * pad, 3 + 2 * pad), dtype=bool)
    mask_expect[pixels[0] + pad, pixels[1] + pad] = True

    mask = fil.skeleton(pad_size=pad)

    assert (mask == mask_expect).all()

    # Long path mask should fail without skeleton_analysis
    with pytest.raises(AttributeError):
        fil.skeleton(out_type='longpath')

    # Now run the skeleton analysis
    fil.skeleton_analysis(image)

    mask = fil.skeleton(out_type='longpath', pad_size=pad)
    assert (mask == mask_expect).all()

    # Check the length
    assert fil.length().value == 2.0
    assert fil.length().unit == u.pix

    # Check the intersection and end points
    assert len(fil.intersec_pts) == 0
    assert fil.intersec_pts == []
    assert len(fil.end_pts) == 2
    assert fil.end_pts[0] == (0, 0)
    assert fil.end_pts[1] == (0, 2)

    # Angular and physical conversion should fail b/c no WCS or distance is
    # given
    with pytest.raises(AttributeError):
        fil.length(unit=u.deg)

    with pytest.raises(AttributeError):
        fil.length(unit=u.pc)

    # Test pickling
    fil.to_pickle("pickled_fil.pkl")

    loaded_fil = Filament2D.from_pickle("pickled_fil.pkl")

    # Compare a few properties

    assert (loaded_fil.length() == fil.length()).all()
    assert (loaded_fil.skeleton(out_type='longpath',
                                pad_size=pad) == mask_expect).all()

    import os
    os.remove('pickled_fil.pkl')