/// <summary> /// Get WCS at any pixel in the image /// </summary> /// <param name="crpix1">pixel coord 1 (double)</param> /// <param name="crpix2">pixel coord 2 (double)</param> /// <returns>WCS</returns> public WCS Wcs(double crpix1, double crpix2) { SdssCoord[] corner; center = CoordsAtPix(crpix1, crpix2); corner = CornerCoords(); double mu, nu, ra, dec; // build linear eqns and solve for affine transform double mumu = 0, nunu = 0, munu = 0, ramu = 0, ranu = 0, decmu = 0, decnu = 0; for (int i = 0; i < corner.Length; i++) { mu = corner[i].mu - center.mu; nu = corner[i].nu - center.nu; ra = corner[i].ra - center.ra; dec = corner[i].dec - center.dec; // increment mumu += mu * mu; munu += mu * nu; nunu += nu * nu; ramu += ra * mu; ranu += ra * nu; decmu += dec * mu; decnu += dec * nu; } double p, q, s, r; SolveSym2D(mumu, munu, nunu, ramu, ranu, out p, out q); SolveSym2D(mumu, munu, nunu, decmu, decnu, out s, out r); WCS wcs = new WCS(); wcs.EPOCH = "J2000"; wcs.CTYPE2 = "DEC--TAN"; wcs.CTYPE1 = "RA---TAN"; wcs.CUNIT1 = "deg"; wcs.CUNIT2 = "deg"; wcs.NAXIS1 = this.npix1; wcs.NAXIS2 = this.npix2; wcs.CRPIX1 = crpix1 + 0.5; // different SDSS vs FITS convention (Steve Kent) wcs.CRPIX2 = crpix2 + 0.5; // -"- wcs.CRVAL1 = center.ra; wcs.CRVAL2 = center.dec; wcs.CD1_1 = p * b + q * e; wcs.CD1_2 = s * b + r * e; wcs.CD2_1 = p * c + q * f; wcs.CD2_2 = s * c + r * f; // john's suggestions for a fix double scale = Math.Cos(center.dec * Math.PI / 180); wcs.CD1_1 *= scale; wcs.CD1_2 *= scale; return(wcs); }
/// <summary> /// Get the corners of the frame /// </summary> /// <returns>list of corner coords (SdssCoord[])</returns> public SdssCoord[] CornerCoords() { SdssCoord[] corner = new SdssCoord[4]; int n = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { corner[n++] = CoordsAtMuNu(a + i * (npix1 * c + npix2 * b), d + j * (npix1 * f + npix2 * e)); } } return(corner); }