Point class provides a more comfortable interface for handling coordinates and coord transformations. Point is capable of moving and setting of new coordinate values in any frame while maintaning consistency across all coordinates.

There are two coordinate systems to manage: ‘frame’ and ‘ccd’. Both are expressed in units of pixels and both have an inverted y axis (increases from from top to bottom such that the y coordinate remains positive within the CCD array).

  • ‘ccd’ coordinate system represents the whole CCD array, the area from (0, 0) to (MAX_W_CCDARRAY, MAX_H_CCDARRAY). This area contains all CCDs. One CCD is defined by (camcol, filter). There are 6 camcols and 5 filters. A point anywhere in this area can be represented in the ‘ccd’ coordinate system. The names of ‘ccd’ coordinates are (cx, cy).
  • The ‘frame’ coordinate system is used to represent image-coordinates. These are the values measured by the detecttrails package. The origin of the coordinate system is set to be reference CCD’s upper left corner. Coordinates (x, y) change if the chosen reference CCD changes. The ‘frame’ coordinate system is a slight misnomer as within each CCD there can be up to 3 frames-xxxx-xx-x-xxx.fits images at once. The frame dimensions are 2048x2048 but images are cut to 1489px height with 139px of overlap between following images. A point within any CCD can be represented in the ‘frame’ coordinate system.

To see the values defining both coordinate systems and how to convert between them look at the ccd_dimensions and coord_conversion modules.

Warnings will be produced in an inconsistent situations to warn that, logically, the performed operations do not make sense, but will not enforce consistency at all times.

Important Notes

Point is capable of interpreting the coordinates in two different context. One is as an absolute coordinate, usually in ccd coordinate system, and the other as a frame-referenced coordinates in which case the coordinates remember a reference to the frame they’re defined in. In the latter case it is possible to have ‘frame’ coordinates with numerically determined values even when they are not within a CCD bounary, while in the former it is not because no reference frame has been set. This can be bit confusing:

p = res.Point(3790, 5415, coordsys="ccd")
<lfd.results.point.Point(x=None, y=None, cx=3790, cy=5415)>

p2 = res.Point(-1, -1, camcol=2, filter="u")
<lfd.results.point.Point(x=-1, y=-1, cx=3790.820956, cy=5415.8870802)>

Both points reference approximately the same coordinate except that the frame-referenced Point understands which frame’s (0, 0) point to use to calculate the ‘frame’ coordinates x and y from. The same point can be expressed referenced from a different frame:

p2 = res.Point(-7584.64, 2707, camcol=4, filter="i")
<lfd.results.point.Point(x=-7584, y=2707, cx=3790.88, cy=5415.44)>

This makes more sense in the context of using the Point class to represent the linear feature in the Event class, but it has some merrits as a feature on its own.

class lfd.results.point.Point(x=None, y=None, cx=None, cy=None, camcol=None, filter=None, coordsys='frame')[source]

Provides a more comfortable interface for handling coordinates and coord transformations while maintaning consistency across all coordinates.

  • x (float) – ‘ccd’ or ‘frame’ coordinate, depending on coordsys
  • y (float) – ‘ccd’ or ‘frame’ coordinate, depending on coordsys
  • coordsys (str) – ‘ccd’ or ‘frame’, designation of coordinate system
  • inCcd (bool) – True if the current coordinate is within a CCD
  • camcol (int) – the camera column of reference frame
  • filter – the filter row of the reference frame


>>> p = Point(10, 10, coordsys="ccd")
>>> p = Point(10, 10, camcol=2, filter='r')

To switch between coordinate system:

>>> p.useCoordSys('ccd')
>>> p.switchSys()

Check if current Point is in CCD or not

>>> p.inCcd

Moving the point can be by assignment or method. Method will try to resolve intended coordsys, or default to current coordsys, but assignment always uses currentl coordsys. Mixing coord. sys. is possible:

>>> p.move(x=10, y=10)
>>> p.move(cx=100, y=10)
>>> p.y = 100

For a given attribute attr checks for a series of conditions that indicate an illogical operation or in some cases operations that could leave an Event in an inconsistent state. Is not always correct, but that’s why it’s a warning not Error.

Attrs Conditions
camcol, filter if coord. sys. is ccd providing these makes no sense
frame if frame is sent as attr and self.inCcd is False the frame coordinate system coordinates are not defined.
move(*args, **kwargs)[source]

Move a point to different coordinates. Supports a more flexible way to change Point coordinates than direct assignment. Checks are are performed and if the ingoing coordiantes do not match the coordsys, the Point is NOT moved and a warning is issued. This makes move very oppinionated and annoying, but it forces explicit statements about where and how the point is moved in the code.


Implicitly resolves coordinates

>>> move(1, 1, "frame") # --> x=1, y=1
>>> move((1, 1), "frame") # --> x=1, y=1
>>> move(1, 1, "ccd") # --> cx=1, cy=1
>>> move((1, 1), "ccd") # --> cx=1, cy=1

Refuses to work without coordsys specification

>>> move(1, 1) # --> will always fail with error, no coordsys sent

Missmatched coordinates and coordinate systems issue warnings

>>> move(x=1, y=1, coordsys="ccd") # --> not moved, warning issued
>>> move(cx=1, cy=1, coordsys="frame") # --> not moved, warning issued

Partially specified coordinates will work only if coordsys is properly matched to the given coordiante which must be explicitly specified

>>> move(1, "frame") # --> fails
>>> move(x=1, coordsys="frame") # --> moves the x coordinate only
>>> move(cx=1, coordsys="frame") # --> isses a warning, doesn't move x
  • **kwargs (dict) – x, y or cx, cy or coordsys and their values
  • **kwargs – x, y or cx, cy and coordsys and their values

Switch to the other coordinate system (‘frame’-> ‘ccd’ and vice-versa). Not particularily useful as both are usually accessible, but practical to state which coordinate system we are currently in.


Use a particular coordinate system, either ‘frame’ or ‘ccd’.

Parameters:coordsys (str) – coordsys designation, ‘frame’ or ‘ccd’

Dimensions & Constants

This module contains all neccessary constants to define a usable coordinate system on, and between, the images:

     1            2             3            4            5          6 CAMCOLS
 |x---------   x---------   x---------   x---------   x---------   x---------
 ||        |   |        |*P1|        |   |        |   |        |   |        |
r||  CCD   |   |  CCD   | \ |  CCD   |   |  CCD   |   |  CCD   |   |  CCD   |
 ||        |   |        |  \|        |   |        |   |        |   |        |
 |----------   ----------   \---------   ---------- __----------   ----------
 |                           \-->lin. feat           ^ H_FILTER_SPACING
 |x---------   x---------   x-\--------   x---------_|_
 ||        |   |        |   |  \      |   |        | ^
i||  CCD   |   |  CCD   |   |   * P2  |   |  CCD   | | H_FILTER
 ||        |   |        |   |         |   |        | |
 |----------   ----------   -----------   ----------_|_
 . FILTERS (riuzg)

Widths and heights were fixed to the official values and while the values of spaces in between the CCD dimensions were availible in the literature they did not correspond exactly to calculable quantities - so they have been replaced by these new values that seem to match the data better than the ones provided in literature.


W_CAMCOL : float
2048, the width of one CCD, in pixels, corresponds to image width
H_FILTER : float
2048, the height one one CCD, in pixels, images are cut to 1489px height with 139px of overlap between them, there are usually 3 images in a CCD at a given time, although only 2 is also possible.
1743.820956, the width the gap beween two camera columns
660.4435401, the spacing between two rows of filters, these gaps can not be noticed on the images but it takes some time for the sky to drift through them.
21008.0, unrounded: 21007.10478, the lower edge of the CCD array, in pixels, if all W_CAMCOL and W_CAMCOL_SPACINGS were added together
12882.0, unrounded: 12881.77416, the lower edge of the CCD array, in pixels, if all H_FILTER and H_FILTER_SPACINGS were added together
ARCMIN2PIX : float
0.0066015625, arcminutes/pixel, pixel scale, corresponds to0.396 arcsec/pixel , but expressed in minutes because of how values were given in the tables.
MM2ARCMIN : float
3.63535503, detector image scale, mm/arcminute.

Coordinate Conversion Functions

exception lfd.results.coord_conversion.CoordinateConversionError(incoords, outcoords, msg=None, *args)[source]

Generic Error to be called when no sollution to coordinate conversions between CCD and frame coordinate systems are not possible. A light wrapper around ArithmeticError.


>>> raise CoordinateConversionError(incoords, outcoords)
  • incoords (tuple, list) – a set of ingoing to-be-converted coordinates
  • outcoords (tuple, list) – set of (miss)calculated coordinates
  • msg (str) – customize the error message
  • *args (tuple, list) – any additional args can be supplemented and are appended to the end of the error message
  • are (cx, cy) CCD coordinates and outcoords are the frame (incoords) –
  • y, camcol, filter) coordinates or vice-versa. ((x,) –
lfd.results.coord_conversion.convert_ccd2frame(x, y)[source]

Conversts the coordinate pair (x, y) from the CCD coordinate system to a frame coordinate system by applying the following formulae:

x = cx - {camcol} * (W_CAMCOL + W_CAMCOL_SPACING)
y = cy - {filter} * (H_FILTER + H_FILTER_SPACING)

Where camcol and filter are iterated over untill a possible sollution is found. A sollution is possible if it is contained within the width and height of a single CCD respective to its (0, 0) point in the frame coord. system. Only one such sollution is guaranteed to exists.

lfd.results.coord_conversion.convert_frame2ccd(x, y, camcol, filter)[source]

Converts from frame coordinates (x, y, camcol, filter) to CCD coordinates (cx, cy) via the following formulae:

cx = x + (camcol-1) * (W_CAMCOL + W_CAMCOL_SPACING)
cy = y +  filter    * (H_FILTER + H_FILTER_SPACING)

Filter can be sent as an integer or a string from {riuzg}.


Provides translation between an integer row value of the filter and its string value where the top row is indexed with a zero:

0 -> r
1 -> i
2 -> u
3 -> z
4 -> g

Provides the mapping between filter in string form and integer value based on the row the searched for filter is in, starting from the top:

r -> 0
i -> 1
u -> 2
z -> 3
g -> 4