summaryrefslogtreecommitdiff
path: root/doc/source/user.rst
blob: 40dff3992a5e1a7aa9a5a512d89bcbecc6bceb75 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
User documentation
==================

.. currentmodule:: sphere

The `sphere` library is a pure Python package for handling spherical
polygons that represent arbitrary regions of the sky.

Requirements
------------

- Python 2.7

- Numpy 1.4 or later

- PyFITS

- PyWCS

- STWCS

Coordinate representation
-------------------------

Coordinates in world space are traditionally represented by right
ascension and declination (*ra* and *dec*), or longitude and latitude.
While these representations are convenient, they have discontinuities
at the poles, making operations on them trickier at arbitrary
locations on the sky sphere.  Therefore, all internal operations of
this library are done in 3D vector space, where coordinates are
represented as (*x*, *y*, *z*) vectors.  The `sphere.vector` module
contains functions to convert between (*ra*, *dec*) and (*x*, *y*,
*z*) representations.

While any (*x*, *y*, *z*) triple represents a vector and therefore a
location on the sky sphere, a distinction must be made between
normalized coordinates fall exactly on the unit sphere, and
unnormalized coordinates which do not.  A normalized coordinate is
defined as a vector whose length is 1, i.e.:

.. math::

    \sqrt{x^2 + y^2 + z^2} = 1

To prevent unnecessary recomputation, many methods in this library
assume that the vectors passed in are already normalized.  If this is
not the case, `sphere.vector.normalize_vector` can be used to
normalize an array of vectors.

The library allows the user to work in either degrees or radians.  All
methods that require or return an angular value have a `degrees`
keyword argument.  When `degrees` is `True`, these measurements are in
degrees, otherwise they are in radians.

Spherical polygons
------------------

Spherical polygons are arbitrary areas on the sky sphere enclosed by
great circle arcs.  They are represented by the
`~sphere.polygon.SphericalPolygon` class.

Representation
``````````````

The points defining the polygon are available from the
`~polygon.SphericalPolygon.points` property.  It is a Nx3 array where
each row is an (*x*, *y*, *z*) vector, normalized.  The polygon points
are explicitly closed, i.e., the first and last points are the same.

Where is the inside?
^^^^^^^^^^^^^^^^^^^^

The edges of a polygon serve to separate the “inside” from the
“outside” area.  On a traditional 2D planar surface, the “inside” is
defined as the finite area and the “outside” is the infinite area.
However, since the surface of a sphere is cyclical, i.e., it wraps
around on itself, the a spherical polygon actually defines two finite
areas.  To specify which should be considered the “inside” vs. the
“outside”, the definition of the polygon also has an “inside point”
which is just any point that should be considered inside of the
polygon.

In the following image, the inside point (marked with the red dot)
declares that the area of the polygon is the green region, and not the
white region.

.. image:: inside.png

The inside point of the the polygon can be obtained from the
`~polygon.SphericalPolygon.inside` property.

Cut lines
^^^^^^^^^

If the polygon represents two disjoint areas or the polygon has holes,
those areas will be connected by cut lines.  The following image shows
a polygon made from the union of a number of cone areas which has both
a hole and a disjoint region connected by cut lines.

.. image:: cutlines.png

Creating spherical polygons
```````````````````````````

.. currentmodule:: sphere.polygon

`SphericalPolygon` objects have 4 different constructors:

  - `SphericalPolygon`: Takes an array of (*x*, *y*, *z*)
    points and an inside point.

  - `SphericalPolygon.from_radec`: Takes an array of (*ra*, *dec*)
    points and an inside point.

  - `SphericalPolygon.from_cone`: Creates a polygon from a cone on the
    sky shere.  Takes (*ra*, *dec*, *radius*).

  - `SphericalPolygon.from_wcs`: Creates a polygon from the footprint
    of a FITS image using its WCS header keywords.  Takes a FITS
    filename or a `pyfits.Header` object.

Operations on Spherical Polygons
````````````````````````````````

Once one has a `SphericalPolygon` object, there are a number of
operations available:

  - `~SphericalPolygon.contains_point`: Determines if the given point is inside the polygon.

  - `~SphericalPolygon.intersects_poly`: Determines if one polygon intersects with another.

  - `~SphericalPolygon.area`: Determine the area of a polygon.

  - `~SphericalPolygon.union` and `~SphericalPolygon.multi_union`:
    Return a new polygon that is the union of two or more polygons.

  - `~SphericalPolygon.intersection` and
    `~SphericalPolygon.multi_intersection`: Return a new polygon that
    is the intersection of two or more polygons.

  - `~SphericalPolygon.overlap`: Determine how much a given polygon
    overlaps another.

  - `~SphericalPolygon.to_radec`: Convert (*x*, *y*, *z*) points in the
    polygon to (*ra*, *dec*) points.

  - `~SphericalPolygon.same_points_as`: Determines if one polygon has the
    same points as another. When only sorted unique points are considered
    (default behavior), polygons with same points might not be the same
    polygons because the order of the points matter.

  - `~SphericalPolygon.draw`: Plots the polygon using matplotlib’s
    Basemap toolkit.  This feature is rather bare and intended
    primarily for debugging purposes.

Great circle arcs
-----------------

.. currentmodule:: sphere.great_circle_arc

As seen above, great circle arcs are used to define the edges of the
polygon.  The `sphere.great_circle_arc` module contains a number of
functions that are useful for dealing with them.

- `length`: Returns the angular distance between two points on the sphere.

- `intersection`: Returns the intersection point between two great
  circle arcs.

- `intersects`: Determines if two great circle arcs intersect.

- `angle`: Calculate the angle between two great circle arcs.

- `midpoint`: Calculate the midpoint along a great circle arc.

Skylines
--------

Skylines are designed to capture and manipulate HST WCS image information as
spherical polygons. They are represented by the `~sphere.skyline.SkyLine` class,
which is an extension of `~sphere.polygon.SphericalPolygon` class.

Representation
``````````````
Each skyline has a list of members, `~sphere.skyline.SkyLine.members`, and a
composite spherical polygon, `~sphere.skyline.SkyLine.polygon`, defined by those
members. The polygon has all the functionalities of
`~sphere.polygon.SphericalPolygon`.

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(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, 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
`````````````````

`~sphere.skyline.SkyLine` constructor takes an image name and an optional
`extname` keyword, which defaults to "SCI". To create skyline from
single-extension FITS, change `extname` to "PRIMARY".

If `None` is given instead of image name, an empty skyline is created with no
member and an empty spherical polygon.

Operations on skylines
``````````````````````

`~sphere.skyline.SkyLine` has direct access to most of the
`~sphere.polygon.SphericalPolygon` properties and methods *except* for the
following (which are still accessible indirectly via
`~sphere.skyline.SkyLine.polygon`):

  - `~sphere.polygon.SphericalPolygon.from_radec`
  - `~sphere.polygon.SphericalPolygon.from_cone`
  - `~sphere.polygon.SphericalPolygon.from_wcs`
  - `~sphere.polygon.SphericalPolygon.multi_union`
  - `~sphere.polygon.SphericalPolygon.multi_intersection`

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. 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
    actually `~sphere.polygon.SphericalPolygon.union`) that will not include
    members.

  - `~sphere.skyline.SkyLine.find_intersection`: Return a new skyline that is
    the intersection of two skylines. This should be used, *not*
    `SkyLine.intersection` (which is actually
    `~sphere.polygon.SphericalPolygon.intersection`) that will not include
    members.

  - `~sphere.skyline.SkyLine.find_max_overlap` and
    `~sphere.skyline.SkyLine.max_overlap_pair`: Return a pair of skylines that
    overlap the most from a given list of skylines.

  - `~sphere.skyline.SkyLine.mosaic`: Return a new skyline that is a mosaic of
    given skylines that overlap, a list of image names of the skylines used, and
    a list of image names of the excluded skylines. A pair of skylines with the
    most overlap is used as a starting point. Then a skyline that overlaps the
    most with the mosaic is used, and so forth until no overlapping skyline is
    found.