Source code for lfd.results.coord_conversion

from lfd.results import ccd_dimensions as ccd


__all__ = ["convert_ccd2frame", "convert_frame2ccd",
           "CoordinateConversionError"]


[docs]class CoordinateConversionError(ArithmeticError): """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. Example ------- >>> raise CoordinateConversionError(incoords, outcoords) Parameters ---------- 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 incoords are (cx, cy) CCD coordinates and outcoords are the frame (x, y, camcol, filter) coordinates or vice-versa. """ def __init__(self, incoords, outcoords, msg=None, *args): """CoordinateConversionError(incoords, outcoords) where incoords are (cx, cy) CCD coordinates and outcoords are the frame (x, y, camcol, filter) coordinates or vice-versa. Optionally supply a custom message by providing msg and a set of args that will be appended to said msg. Parameters ---------- 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. String .format method with positional arguments with incoords and outcoords always being the first two, rest is then appended in the order it was given in *args. *args : tuple, list any additional args can be supplemented and are appended to the end of the error message incoords are (cx, cy) CCD coordinates and outcoords are the frame (x, y, camcol, filter) coordinates or vice-versa. """ if msg is not None: self.message = msg else: self.message = ("Unsolvable system. Coordinates not attributable " "to any CCD in the array. \n Initial coordinates: " "{0}. Retrieved coordinates: {1}. ") if args: self.message += "\n Args: " for i in range(2, len(args)+2): self.message += "{0} ".format(i) if args: self.message.format(incoords, outcoords, *args) else: self.message = self.message.format(incoords, outcoords) self.errorcoords = incoords self.outcoords = outcoords ArithmeticError.__init__(self, self.message)
[docs]def get_filter_int(filter): """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 """ return {"r":0, "i":1, "u":2, "z":3, "g":4}[filter]
[docs]def get_filter_from_int(filterint): """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 """ return ["r", "i", "u", "z", "g"][filterint-1]
[docs]def convert_ccd2frame(x, y): """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. """ res = [None, None, None, "nofilter"] solved_camcol = False solved_filter = False # whatever you have in your book is wrong, you messed something up in your # notes? Given a camcol and filter the annon funcs calculate the coordinates # in the frame coord sys. on the given single CCD at (camcol, filter) newx = lambda camcol: \ x - camcol * (ccd.W_CAMCOL + ccd.W_CAMCOL_SPACING) newy = lambda filter: \ y - filter * (ccd.H_FILTER + ccd.H_FILTER_SPACING) # to invert the solution we iterate over all camcols and only one camcol # will produce a value of x coordinate contained within the respective single # CCD. We store the calculated frame x coordinate and the respective camcol for i in range(0, 6): tmp = newx(i) if tmp >= 0 and tmp <= ccd.W_CAMCOL: res[0] = tmp res[2] = i+1 solved_camcol = True break # procedure is repeated for filters, only one filter will produce a valid # value of frame y coordinate, we remember the coord and the filter. for i in range(0, 5): tmp = newy(i) if tmp >= 0 and tmp <= ccd.H_FILTER: res[1] = tmp res[3] = get_filter_from_int(i+1) solved_filter = True break # it is possible no solutions are found if the CCD coordinates fall in the # gaps between CCD array columns and rows. We check: if solved_camcol and solved_filter: return res else: raise CoordinateConversionError((x,y), res)
[docs]def convert_frame2ccd(x, y, camcol, filter): """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}. """ # check filter type and resolve into integer if isinstance(filter, str) and filter in "riuzg": filter = get_filter_int(filter) elif isinstance(filter, int) and filter in (1,2,3,4,5): pass else: raise ValueError("Unrecognized filter: {0}".format(filter)) # check camcol is correct if camcol > 6 or camcol < 1: raise ValueError("Unrecognized camcol: {0}".format(filter)) newx = x + (camcol-1) * (ccd.W_CAMCOL_SPACING+ccd.W_CAMCOL) newy = y + filter*(ccd.H_FILTER + ccd.H_FILTER_SPACING) return [newx,newy]