diff options
-rw-r--r-- | doc/source/user.rst | 13 | ||||
-rw-r--r-- | lib/skyline.py | 79 | ||||
-rw-r--r-- | lib/test/test_skyline.py | 8 |
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) |