Skip to content

Commit

Permalink
Merge pull request #26 from joleroi/compound
Browse files Browse the repository at this point in the history
Implement compound regions
  • Loading branch information
joleroi committed May 4, 2016
2 parents 95b4408 + c094b9c commit 7b8aab6
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 18 deletions.
13 changes: 9 additions & 4 deletions regions/core/compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,21 @@ class CompoundSkyRegion(SkyRegion):
Represents the logical combination of two regions in sky coordinates.
"""

def __init__(self, region1, operator, region2):
def __init__(self, region1, region2, operator):
self.region1 = region1
self.region2 = region2
self.operator = operator

def __contains__(self, skycoord):
raise NotImplementedError("")
def contains(self, skycoord):
return self.operator(self.region1.contains(skycoord),
self.region2.contains(skycoord))

def to_pixel(self, wcs, mode='local', tolerance=None):
raise NotImplementedError("")

def __repr__(self):
return "({0} {1} {2})".format(self.region1, self.operator, self.region2)
return "({0}\n{1}\n{2})".format(self.region1, self.operator, self.region2)

@property
def area(self):
raise NotImplementedError("")
8 changes: 6 additions & 2 deletions regions/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def __or__(self, other):
def __xor__(self, other):
return self.symmetric_difference(other)

def __contains__(self, coord):
# Todo: only works for scalar cases, test for this?
return self.contains(coord)


@six.add_metaclass(abc.ABCMeta)
class PixelRegion(Region):
Expand Down Expand Up @@ -72,7 +76,7 @@ def union(self, other):
return CompoundPixelRegion(self, other, operator.or_)

@abc.abstractmethod
def __contains__(self, pixcoord):
def contains(self, pixcoord):
"""
Checks whether a position or positions fall inside the region.
Expand Down Expand Up @@ -192,7 +196,7 @@ def union(self, other):
return CompoundSkyRegion(self, other, operator.or_)

@abc.abstractmethod
def __contains__(self, skycoord):
def contains(self, skycoord):
"""
Checks whether a position or positions fall inside the region.
Expand Down
4 changes: 4 additions & 0 deletions regions/core/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
This packages contains affiliated package tests.
"""
31 changes: 31 additions & 0 deletions regions/core/tests/coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[run]
source = {packagename}
omit =
{packagename}/_astropy_init*
{packagename}/conftest*
{packagename}/cython_version*
{packagename}/setup_package*
{packagename}/*/setup_package*
{packagename}/*/*/setup_package*
{packagename}/tests/*
{packagename}/*/tests/*
{packagename}/*/*/tests/*
{packagename}/version*

[report]
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover

# Don't complain about packages we have installed
except ImportError

# Don't complain if tests don't hit assertions
raise AssertionError
raise NotImplementedError

# Don't complain about script hooks
def main\(.*\):

# Ignore branches that don't pertain to this version of Python
pragma: py{ignore_python_version}
46 changes: 46 additions & 0 deletions regions/core/tests/test_compound.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import astropy.units as u
from astropy.coordinates import SkyCoord

from regions.shapes import CircleSkyRegion


def test_compound():

skycoord1 = SkyCoord(0 * u.deg, 0 * u.deg, frame='galactic')
c1 = CircleSkyRegion(skycoord1, 1 * u.deg)

skycoord2 = SkyCoord(1 * u.deg, 1 * u.deg, frame='galactic')
c2 = CircleSkyRegion(skycoord2, 0.5 * u.deg)

test_coord1 = SkyCoord(1.2 * u.deg, 1.2 * u.deg, frame='galactic')
test_coord2 = SkyCoord(0.5 * u.deg, 0.5 * u.deg, frame='galactic')
test_coord3 = SkyCoord(0.7 * u.deg, 0.7 * u.deg, frame='galactic')
test_coord4 = SkyCoord(2 * u.deg, 5 * u.deg, frame='galactic')

assert test_coord1 in c2 and test_coord1 not in c1
assert test_coord2 not in c2 and test_coord2 in c1
assert test_coord3 in c1 and test_coord3 in c2
assert test_coord4 not in c2 and test_coord4 not in c1

coords = SkyCoord([test_coord1, test_coord2, test_coord3, test_coord4], frame='galactic')

union = c1 | c2
assert (union.contains(coords) == [True, True, True, False]).all()

intersection = c1 & c2
assert (intersection.contains(coords) == [False, False, True, False]).all()

diff = c1 ^ c2
assert (diff.contains(coords) == [True, True, False, False]).all()


c3 = CircleSkyRegion(test_coord4, 0.1 * u.deg)

union = c1 | c2 | c3
assert (union.contains(coords) == [True, True, True, True]).all()

intersection = c1 & c2 & c3
assert (intersection.contains(coords) == [False, False, False, False]).all()

diff = c1 ^ c2 ^ c3
assert (diff.contains(coords) == [True, True, False, True]).all()
12 changes: 9 additions & 3 deletions regions/shapes/circle.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(self, center, radius, meta=None, visual=None):
def area(self):
return math.pi * self.radius ** 2

def __contains__(self, pixcoord):
def contains(self, pixcoord):
return np.hypot(pixcoord.x - self.center.x,
pixcoord.y - self.center.y) < self.radius

Expand Down Expand Up @@ -87,8 +87,14 @@ def __init__(self, center, radius, meta=None, visual=None):
def area(self):
return math.pi * self.radius ** 2

def __contains__(self, skycoord):
return self.center.separation(skycoord)
def contains(self, skycoord):
return self.center.separation(skycoord) < self.radius

def __repr__(self):
clsnm = self.__class__.__name__
coord = self.center
rad = self.radius
return '{clsnm}\nCenter:{coord}\nRadius:{rad}'.format(**locals())

def to_pixel(self, mywcs, mode='local', tolerance=None):
"""
Expand Down
4 changes: 2 additions & 2 deletions regions/shapes/ellipse.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __init__(self, center, minor, major, angle=0. * u.deg, meta=None,
def area(self):
return math.pi * self.minor * self.major

def __contains__(self, pixcoord):
def contains(self, pixcoord):
# TODO: needs to be implemented
raise NotImplementedError("")

Expand Down Expand Up @@ -85,7 +85,7 @@ def area(self):
# TODO: needs to be implemented
raise NotImplementedError("")

def __contains__(self, skycoord):
def contains(self, skycoord):
# TODO: needs to be implemented
raise NotImplementedError("")

Expand Down
4 changes: 2 additions & 2 deletions regions/shapes/point.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, center, meta=None, visual=None):
def area(self):
return 0

def __contains__(self, pixcoord):
def contains(self, pixcoord):
return False

def to_shapely(self):
Expand Down Expand Up @@ -62,7 +62,7 @@ def __init__(self, center, meta=None, visual=None):
def area(self):
return 0

def __contains__(self, skycoord):
def contains(self, skycoord):
return False

def to_pixel(self, wcs, mode='local', tolerance=None):
Expand Down
5 changes: 2 additions & 3 deletions regions/shapes/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def area(self):
# TODO: needs to be implemented
raise NotImplementedError("")

def __contains__(self, pixcoord):
def contains(self, pixcoord):
# TODO: needs to be implemented
raise NotImplementedError("")

Expand All @@ -39,7 +39,6 @@ def to_mask(self, mode='center'):
raise NotImplementedError("")



class PolygonSkyRegion(SkyRegion):
"""
A polygon in sky coordinates.
Expand All @@ -61,7 +60,7 @@ def area(self):
# TODO: needs to be implemented
raise NotImplementedError("")

def __contains__(self, skycoord):
def contains(self, skycoord):
# TODO: needs to be implemented
raise NotImplementedError("")

Expand Down
4 changes: 2 additions & 2 deletions regions/shapes/rectangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, center, height, width, angle=0 * u.deg, meta=None, visual=Non
def area(self):
return self.width * self.height

def __contains__(self, pixcoord):
def contains(self, pixcoord):
# TODO: needs to be implemented
raise NotImplementedError("")

Expand Down Expand Up @@ -81,7 +81,7 @@ def __init__(self, center, height, width, angle=0 * u.deg, meta=None, visual=Non
def area(self):
return self.width * self.height

def __contains__(self, skycoord):
def contains(self, skycoord):
# TODO: needs to be implemented
raise NotImplementedError("")

Expand Down
1 change: 1 addition & 0 deletions regions/shapes/tests/test_circle.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def test_init_sky():


# Todo : restructure test to use same circle everywhere
# see https://github.com/astropy/regions/pull/20
@pytest.mark.skipif('not HAS_MATPLOTLIB')
def test_plot():
import matplotlib.pyplot as plt
Expand Down

0 comments on commit 7b8aab6

Please sign in to comment.