def transform_coords(self, catalog=None, x=None, y=None): """ Use the solution to transform the pixel coordinates """ from astropyp.catalog import Catalog ungroup = False if catalog is None: try: len(x) except TypeError: x = [x] y = [y] ungroup = True catalog = table.Table([x, y], names=('x', 'y')) if not isinstance(catalog, Catalog): cat = Catalog(catalog) else: cat = catalog x_tbl = get_transform_tbl(cat.x, cat.y, self.order, 'A') x_tbl['Intercept'] = 1 x = 0 for column, value in self.x_tx.items(): x += x_tbl[column] * value y_tbl = get_transform_tbl(cat.y, cat.x, self.order, 'B') y_tbl['Intercept'] = 1 y = 0 for column, value in self.y_tx.items(): y += y_tbl[column] * value if ungroup: x = x[0] y = y[0] return x, y
def pix2world(self, x, y): """ Convert pixel coordinates to wcs using an astropyp astrometric solution. Parameters ---------- x,y: array-like Pixel coordinates of the sources Result ------ ra, dec """ ra_tbl = get_transform_tbl(x - self.crpix[0], y - self.crpix[1], self.order, 'A') dec_tbl = get_transform_tbl(y - self.crpix[1], x - self.crpix[0], self.order, 'B') ra_tbl['Intercept'] = 1 dec_tbl['Intercept'] = 1 ra = 0 dec = 0 for column, value in self.x2ra.items(): ra += ra_tbl[column] * value for column, value in self.y2dec.items(): dec += dec_tbl[column] * value return ra + self.crval[0], dec + self.crval[1]
def world2pix(self, ra, dec): """ Convert pixel coordinates to wcs using an astropyp astrometric solution. Parameters ---------- x,y: array-like Pixel coordinates of the sources Result ------ ra, dec """ x_tbl = get_transform_tbl(ra - self.crval[0], dec - self.crval[1], self.order, 'Ap') y_tbl = get_transform_tbl(dec - self.crval[1], ra - self.crval[0], self.order, 'Bp') x_tbl['Intercept'] = 1 y_tbl['Intercept'] = 1 x = 0 y = 0 for column, value in self.ra2x.items(): x += x_tbl[column] * value for column, value in self.dec2y.items(): y += y_tbl[column] * value return x + self.crpix[0], y + self.crpix[1]
def _get_solution(coord1, coord2, ref_coord, order, param_name, prefix='A', fit_package='statsmodels', weights=None): """ Given a set of source coordinates and the reference coordinate, get the coefficients for the astrometric (or inverse) solution Parameters ---------- coord1, coord2: array-like Arrays of source coordinates ref_coord: array-like Array of reference coordinates order: int Order of the solution polynomial param_name: string The name of the parameter we are solving for (for example: 'x','y','ra','dec') prefix: string The prefix of the coefficient name fitpackage: string, optional Name of the fit package to use. Currently only the default 'statsmodels' is available. """ if fit_package == 'statsmodels': try: import statsmodels.formula.api as smf except: raise Exception("'statsmodels' package required for this type of " "astrometric solution") tbl = get_transform_tbl(coord1, coord2, order, prefix) formula = build_formula(param_name, tbl) tbl[param_name] = ref_coord if weights is None: result = smf.OLS.from_formula(formula=formula, data=tbl).fit() else: result = smf.WLS.from_formula(formula=formula, data=tbl, weights=weights).fit() result = { 'params': _statsmodels_to_result(result.params), 'statsmodels': result } elif fit_package == 'lst_sq': result = _lst_sq_fit(coord1, coord2, ref_coord, order, weights, prefix) result = {'params': result} else: raise ValueError("fit_package must be either statsmodels' or" " 'lst_sq'") return result
def _get_solution(coord1, coord2, ref_coord, order, param_name, prefix='A', fit_package='statsmodels', weights=None): """ Given a set of source coordinates and the reference coordinate, get the coefficients for the astrometric (or inverse) solution Parameters ---------- coord1, coord2: array-like Arrays of source coordinates ref_coord: array-like Array of reference coordinates order: int Order of the solution polynomial param_name: string The name of the parameter we are solving for (for example: 'x','y','ra','dec') prefix: string The prefix of the coefficient name fitpackage: string, optional Name of the fit package to use. Currently only the default 'statsmodels' is available. """ if fit_package == 'statsmodels': try: import statsmodels.formula.api as smf except: raise Exception( "'statsmodels' package required for this type of " "astrometric solution") tbl = get_transform_tbl(coord1, coord2, order, prefix) formula = build_formula(param_name, tbl) tbl[param_name] = ref_coord if weights is None: result = smf.OLS.from_formula(formula=formula, data=tbl).fit() else: result = smf.WLS.from_formula(formula=formula, data=tbl, weights=weights).fit() result = { 'params': _statsmodels_to_result(result.params), 'statsmodels': result } elif fit_package == 'lst_sq': result = _lst_sq_fit(coord1, coord2, ref_coord, order, weights, prefix) result = {'params': result} else: raise ValueError("fit_package must be either statsmodels' or" " 'lst_sq'") return result
def _lst_sq_fit(coord1, coord2, ref_coord, order, weights=None, prefix='A'): from astropyp.astrometry import get_transform_tbl A = get_transform_tbl(coord1, coord2, order, prefix) columns = ['Intercept'] + A.columns.keys() tbl_dtype = A[A.columns.keys()[0]].dtype A['Intercept'] = np.ones((len(A)), dtype=tbl_dtype) A = A[columns] A = A.as_array().view(tbl_dtype).reshape((len(A), len(A.columns))) y = ref_coord if weights is not None: w = np.vstack([weights for n in range(A.shape[1])]).T A = A * w y = y * weights result = np.linalg.lstsq(A, y)[0] solution = OrderedDict([ (columns[n], result[n]) for n in range(len(columns))]) return solution
def _lst_sq_fit(coord1, coord2, ref_coord, order, weights=None, prefix='A'): from astropyp.astrometry import get_transform_tbl A = get_transform_tbl(coord1, coord2, order, prefix) columns = ['Intercept'] + A.columns.keys() tbl_dtype = A[A.columns.keys()[0]].dtype A['Intercept'] = np.ones((len(A)), dtype=tbl_dtype) A = A[columns] A = A.as_array().view(tbl_dtype).reshape((len(A), len(A.columns))) y = ref_coord if weights is not None: w = np.vstack([weights for n in range(A.shape[1])]).T A = A * w y = y * weights result = np.linalg.lstsq(A, y)[0] solution = OrderedDict([(columns[n], result[n]) for n in range(len(columns))]) return solution