summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/user.rst13
-rw-r--r--lib/skyline.py79
-rw-r--r--lib/test/test_skyline.py8
3 files changed, 65 insertions, 35 deletions
diff --git a/doc/source/user.rst b/doc/source/user.rst
index 60b77d8..40dff39 100644
--- a/doc/source/user.rst
+++ b/doc/source/user.rst
@@ -192,10 +192,14 @@ What is a skyline member?
Each member in `~sphere.skyline.SkyLine.members` belongs to the
`~sphere.skyline.SkyLineMember` class, which contains image name (with path if
-given), science extension, and WCS object and polygon of that extension.
+given), science extension(s), and composite WCS and polygon of the extension(s).
+All skylines start out with a single member from a single image. When operations
+are used to find composite or intersecting skylines, the resulting skyline can
+have multiple members.
-For example, an ACS/WFC full-frame image would give 2 members, one from EXT 1
-and another from EXT 4.
+For example, a skyline from an ACS/WFC full-frame image would give 1 member,
+which is a composite of extensions 1 and 4. A skyline from the union of 2 such
+images would have 2 members, and so forth.
Creating skylines
`````````````````
@@ -224,7 +228,8 @@ following (which are still accessible indirectly via
In addition, `~sphere.skyline.SkyLine` also has these operations available:
- `~sphere.skyline.SkyLine.to_wcs`: Return a composite HST WCS object defined
- by all the members.
+ by all the members. In a skyline resulting from intersection, this does
+ *not* return the WCS of the intersecting polygons.
- `~sphere.skyline.SkyLine.add_image`: Return a new skyline that is the union
of two skylines. This should be used, *not* `SkyLine.union` (which is
diff --git a/lib/skyline.py b/lib/skyline.py
index 77d6848..04c4afa 100644
--- a/lib/skyline.py
+++ b/lib/skyline.py
@@ -88,33 +88,53 @@ from .polygon import SphericalPolygon
SKYLINE_DEBUG = True
__all__ = ['SkyLineMember', 'SkyLine']
-__version__ = '0.3a'
-__vdate__ = '10-Jul-2012'
+__version__ = '0.4a'
+__vdate__ = '11-Jul-2012'
class SkyLineMember(object):
"""
Container for `SkyLine` members with these attributes:
* `fname`: Image name (with path if given)
- * `ext`: Extension read
- * `wcs`: `HSTWCS` object the data data
- * `polygon`: `~sphere.polygon.SphericalPolygon` object of the data
+ * `ext`: Tuple of extensions read
+ * `wcs`: `HSTWCS` object the composite data
+ * `polygon`: `~sphere.polygon.SphericalPolygon` object of the composite data
"""
- def __init__(self, fname, ext):
+ def __init__(self, fname, extname):
"""
Parameters
----------
fname : str
FITS image.
- ext : int
- Image extension.
+ extname : str
+ EXTNAME to use. SCI is recommended for normal
+ HST images. PRIMARY if image is single ext.
"""
+ extname = extname.upper()
+ ext_list = []
+ wcs_list = []
+
+ with pyfits.open(fname) as pf:
+ for i,ext in enumerate(pf):
+ if ext.name.upper() == extname:
+ ext_list.append(i)
+ wcs_list.append(wcsutil.HSTWCS(fname, ext=i))
+
+ # By combining WCS first before polygon, will remove chip gaps
+
+ n_wcs = len(wcs_list)
+ if n_wcs > 1:
+ self._wcs = output_wcs(wcs_list)
+ elif n_wcs == 1:
+ self._wcs = wcs_list[0]
+ else:
+ raise ValueError('%s has no WCS' % fname)
+
self._fname = fname
- self._ext = ext
- self._wcs = wcsutil.HSTWCS(fname, ext=ext)
+ self._ext = tuple(ext_list)
self._polygon = SphericalPolygon.from_wcs(self.wcs)
def __repr__(self):
@@ -157,24 +177,22 @@ class SkyLine(object):
EXTNAME to use. SCI is recommended for normal
HST images. PRIMARY if image is single ext.
- """
- extname = extname.upper()
-
+ """
# Convert SCI data to SkyLineMember
if fname is not None:
- with pyfits.open(fname) as pf:
- self.members = [SkyLineMember(fname, i)
- for i,ext in enumerate(pf)
- if extname in ext.name.upper()]
+ self.members = [SkyLineMember(fname, extname)]
else:
self.members = []
# Put mosaic of all the chips in SkyLine
- if len(self.members) > 0:
- self.polygon = SphericalPolygon.multi_union(
- [m.polygon for m in self.members])
- else:
+ n = len(self.members)
+ if n == 0:
self.polygon = SphericalPolygon([])
+ elif n == 1:
+ self.polygon = copy(self.members[0].polygon)
+ else:
+ raise ValueError('%s cannot initialize polygon with '
+ 'multiple members' % self.__class__.__name__)
def __getattr__(self, what):
"""Control attribute access to `~sphere.polygon.SphericalPolygon`."""
@@ -238,10 +256,16 @@ class SkyLine(object):
.. warning:: This cannot return WCS of intersection.
"""
- wcs = None
+ wcs_list = []
- if len(self.members) > 0:
- wcs = output_wcs([m.wcs for m in self.members])
+ for m in self.members:
+ for i in m.ext:
+ wcs_list.append(wcsutil.HSTWCS(m.fname, ext=i))
+
+ if len(wcs_list) > 0:
+ wcs = output_wcs(wcs_list)
+ else:
+ wcs = None
return wcs
@@ -254,7 +278,8 @@ class SkyLine(object):
def _draw_members(self, map, **kwargs):
"""
- Draw individual members. Useful for debugging.
+ Draw individual extensions in members.
+ Useful for debugging.
Parameters
----------
@@ -264,7 +289,9 @@ class SkyLine(object):
"""
for m in self.members:
- m.polygon.draw(map, **kwargs)
+ for i in m.ext:
+ poly = SphericalPolygon.from_wcs(wcsutil.HSTWCS(m.fname, ext=i))
+ poly.draw(map, **kwargs)
def _find_members(self, given_members):
"""
diff --git a/lib/test/test_skyline.py b/lib/test/test_skyline.py
index 1ce3e09..ac47549 100644
--- a/lib/test/test_skyline.py
+++ b/lib/test/test_skyline.py
@@ -75,11 +75,9 @@ def test_membership():
do_member_overlap(im_2chipB)
do_member_overlap(im_66_tan)
- assert len(im_2chipA.members) == 2
+ assert len(im_2chipA.members) == 1
assert im_2chipA.members[0].fname == f_2chipA
- assert im_2chipA.members[0].ext == 1
- assert im_2chipA.members[1].fname == f_2chipA
- assert im_2chipA.members[1].ext == 4
+ assert im_2chipA.members[0].ext == (1,4)
#----- COPY -----
@@ -220,7 +218,7 @@ def DISABLED_unstable_overlap():
u1 = im_2chipA.add_image(im_2chipB)
u2 = im_2chipB.add_image(im_2chipA)
- # failed here - known bug
+ # failed here before - known bug
# failure not always the same due to hash mapping
assert_almost_equal(i1.overlap(u1), 1.0)
assert_almost_equal(i1.overlap(i2), 1.0)