gavo.base.coords module

(Mostly deprecated) code to handle coordinate systems and transform between them.

Basically all of this should be taken over by stc and astropysics.

class gavo.base.coords.Box(x0, x1, y0=None, y1=None)[source]

Bases: object

is a 2D box.

The can be constructed either with two tuples, giving two points delimiting the box, or with four arguments x0, x1, y0, y1.

To access the thing, you can either access the x[01], y[01] attributes or use getitem to retrieve the upper right and lower left corner.

The slightly silly ordering of the bounding points (larger values first) is for consistency with Postgresql.

class gavo.base.coords.Vector3(x, y=None, z=None)[source]

Bases: object

is a 3d vector that responds to both .x… and [0]…

>>> x, y = Vector3(1,2,3), Vector3(2,3,4)
>>> x+y
>>> 4*x
>>> x*4
>>> x*y
>>> "%.6f"%abs(x)
>>> "%.4f"%abs((x+y).normalized())
property x
property y
property z
gavo.base.coords.computeUnitSphereCoords(alpha, delta)[source]

returns the 3d coordinates of the intersection of the direction vector given by the spherical coordinates alpha and delta with the unit sphere.

alpha and delta are given in degrees.

>>> print(computeUnitSphereCoords(0,0))
>>> print(computeUnitSphereCoords(0, 90))
>>> print(computeUnitSphereCoords(90, 90))
>>> print(computeUnitSphereCoords(90, 0))
>>> print(computeUnitSphereCoords(180, -45))

returns alpha, delta in degrees for the direction vector dirVec.

>>> dirVecToCelCoos(computeUnitSphereCoords(25.25, 12.125))
(25.25, 12.125)
>>> dirVecToCelCoos(computeUnitSphereCoords(25.25, 12.125)*16)
(25.25, 12.125)
>>> "%g,%g"%dirVecToCelCoos(computeUnitSphereCoords(25.25, 12.125)+
...   computeUnitSphereCoords(30.75, 20.0))

returns a bounding box for the sequence of 2-sequences points.

The thing returned is a coords.Box.

>>> getBbox([(0.25, 1), (-3.75, 1), (-2, 4)])
Box((0.25,4), (-3.75,1))
gavo.base.coords.getCenterFromWCSFields(wcsFields, spatialAxes=(1, 2))[source]

returns RA and Dec of the center of an image described by wcsFields.

This will use the 1-based axes given by spatialAxes to figure out the pixel lengths of the axes.

gavo.base.coords.getCoveringCircle(wcsFields, spatialAxes=(1, 2))[source]

returns a pgsphere.scircle large enough to cover the image described by wcsFields.

gavo.base.coords.getGCDist(pos1, pos2)[source]

returns the distance along a great circle between two points.

The distance is in degrees, the input positions are in degrees.


returns a callable transforming physical to pixel coordinates.

wcsFields is passed to getWCS, see there for legal types.

gavo.base.coords.getPixelLimits(cooPairs, wcsFields)[source]

returns pixel cutout slices for covering cooPairs in an image with wcsFields.

cooPairs is a sequence of (ra, dec) tuples. wcsFields is a DaCHS-enhanced wcs.WCS instance.

Behaviour if cooPairs use a different coordinate system from wcsFields is undefined at this point.

Each cutout slice is a tuple of (FITS axis number, lower limit, upper limit).

If cooPairs is off the wcsFields coverage, a null cutout on the longAxis is returned.


returns the sizes of a pixel at roughly the center of the image for wcsFields.

Near the pole, this gets a bit weird; we do some limitation of the width of RA pixels there.


returns a pair of a wcs.WCS instance and a sequence of the spatial axes.

This will be None, () if no WCS could be discerned. There’s some heuristics involved in the identification of the spatial coordinates that will probably fail for unconventional datasets.


returns a pgsphere spoly corresponding to wcsFields

wcsFields is passed to getWCS, see there for legal types.

The polygon returned is computed by using the four corner points assuming a rectangular image. This typically is only loosely related to a proper spherical polygon describing the shape, as image boundaries in the usual projects are not great circles.

Also, the spoly will be in the coordinate system of the WCS. If that is not ICRS, you’ll probably get something incompatible with most of the VO.


returns the unit vectors for RA and Dec at the unit circle position cPos.

We compute them by solving u_1*p_1+u_2*p_2=0 (we already know that u_3=0) simultaneously with u_1^2+u_2^2=1 for RA, and by computing the cross product of the RA unit and the radius vector for dec.

This becomes degenerate at the poles. If we’re exactly on a pole, we define the unit vectors as (1,0,0) and (0,1,0).

Orientation is a pain – the convention used here is that unit delta always points to the pole.

>>> cPos = computeUnitSphereCoords(45, -45)
>>> ua, ud = getTangentialUnits(cPos)
>>> print(abs(ua), abs(ud), cPos*ua, cPos*ud)
1.0 1.0 0.0 0.0
>>> print(ua, ud)
[-0.71,0.71,0] [-0.5,-0.5,-0.71]
>>> ua, ud = getTangentialUnits(computeUnitSphereCoords(180, 60))
>>> print(ua, ud)
[0,-1,0] [0.87,0,0.5]
>>> ua, ud = getTangentialUnits(computeUnitSphereCoords(0, 60))
>>> print(ua, ud)
[0,1,0] [-0.87,0,0.5]
>>> ua, ud = getTangentialUnits(computeUnitSphereCoords(0, -60))
>>> print(ua, ud)
[0,1,0] [-0.87,0,-0.5]
gavo.base.coords.getWCS(wcsFields, naxis=(1, 2), relax=True)[source]

returns a WCS instance from wcsFields

wcsFields can be either a dictionary or a pyfits header giving some kind of WCS information, or an wcs.WCS instance that is returned verbatim.

This will return None if no (usable) WCS information is found in the header.

We monkeypatch the resulting WCS structure quite a bit. Among others:

  • there’s longAxis and latAxis attributes taken from naxis

  • there’s _dachs_header, containing the incoming k-v pairs

  • there’s _monkey_naxis_length, the lengths along the WCS axes.


returns a callable transforming pixel to physical coordinates.

wcsFields is passed to getWCS, see there for legal types.


returns a pyfits header with the cards of d.items().

Only keys “looking like” FITS header keywords are used, i.e. all-uppercase and shorter than 9 characters.

gavo.base.coords.movePm(alphaDeg, deltaDeg, pmAlpha, pmDelta, timeDiff, foreshort=0)[source]

returns alpha and delta for an object with pm pmAlpha after timeDiff.

pmAlpha has to have cos(delta) applied, everything is supposed to be in degrees, the time unit is yours to choose.

gavo.base.coords.pix2foc(wcsFields, pixels)[source]

returns the focal plane coordinates for the 2-sequence pixels.

(this is a thin wrapper intended to abstract for pix2world’s funky calling convention; also, we fix on the silly “0 pixel is 1 convention”)

gavo.base.coords.pix2sky(wcsFields, pixels)[source]

returns the sky coordinates for the 2-sequence pixels.

(this is a thin wrapper intended to abstract for pix2world’s funky calling convention; also, we fix on the silly “0 pixel is 1 convention”)

gavo.base.coords.sky2pix(wcsFields, longLat)[source]

returns the pixel coordinates for the 2-sequence longLad.

(this is a thin wrapper intended to abstract for world2pix’s funky calling convention; also, we fix on the silly “0 pixel is 1 convention”)

gavo.base.coords.straddlesStitchingLine(minRA, maxRA)[source]

returns true if something bordered by minRA and maxRA presumably straddles the stitching line.

This assumes minRA<maxRA, and that “something” is less than 180 degrees in longitude.

Angles are in degrees here.