private void extractCoordinateSystem() throws TransformationException { // To get the coordinate system we look at the CTYPEn, EQUINOX, RADESYSm String lonType = h.getStringValue("CTYPE" + lonAxis).substring(0, 4); String latType = h.getStringValue("CTYPE" + latAxis).substring(0, 4); String coordSym = null; CoordinateSystem coords; if (lonType.equals("RA--") && latType.equals("DEC-")) { coordSym = frame() + equinox(); } else { if (lonType.charAt(0) != latType.charAt(0)) { throw new TransformationException( "Inconsistent axes definitions:" + lonType + "," + latType); } if (lonType.equals("GLON")) { coordSym = "G"; } else if (lonType.equals("ELON")) { coordSym = "E" + equinox(); } else if (lonType.equals("HLON")) { coordSym = "H" + equinox(); } } coords = CoordinateSystem.factory(coordSym); this.csys = coords; add(coords.getSphereDistorter()); add(coords.getRotater()); }
/** Handle the NEAT special projection */ private void doNeatWCS() throws TransformationException { // The NEAT transformation from the standard spherical system // includes: // Transformation to J2000 spherical coordinates (a null operation) // A tangent plane projection to the standard plane // A scaler transformation to corrected pixel coordinates. // A distorter to distorted pixel coordinates // A scaler transformation of distorted coordinates to actual pixels CoordinateSystem csys = CoordinateSystem.factory("J2000"); this.csys = csys; // The RA0/DEC0 pair are the actual center of the projection. double cv1 = toRadians(h.getDoubleValue("RA0")); double cv2 = toRadians(h.getDoubleValue("DEC0")); wcsKeys.put("CRVAL1", toDegrees(cv1)); wcsKeys.put("CRVAL2", toDegrees(cv2)); Projection proj = new Projection("Tan", new double[] {cv1, cv2}); this.proj = proj; double cd1 = toRadians(h.getDoubleValue("CDELT1")); double cd2 = toRadians(h.getDoubleValue("CDELT2")); wcsKeys.put("CDELT1", toDegrees(cd1)); wcsKeys.put("CDELT2", toDegrees(cd2)); wcsScale = abs(cd1); double cp1 = h.getDoubleValue("CRPIX1"); double cp2 = h.getDoubleValue("CRPIX2"); wcsKeys.put("CPRIX1", cp1); wcsKeys.put("CRPIX2", cp2); wcsKeys.put("CTYPE1", "RA---XTN"); wcsKeys.put("CTYPE2", "DEC--XTN"); Scaler s1 = new Scaler(0., 0., -1 / cd1, 0, 0, -1 / cd2); // Note that the the A0,A1,A2, B0,B1,B2 rotation // is relative to the original pixel values, so // we need to put this in the secondary scaler. // double x0 = h.getDoubleValue("X0"); double y0 = h.getDoubleValue("Y0"); Distorter dis = new skyview.geometry.distorter.Neat( h.getDoubleValue("RADIAL"), h.getDoubleValue("XRADIAL"), h.getDoubleValue("YRADIAL")); double a0 = h.getDoubleValue("A0"); double a1 = h.getDoubleValue("A1"); double a2 = h.getDoubleValue("A2"); double b0 = h.getDoubleValue("B0"); double b1 = h.getDoubleValue("B1"); double b2 = h.getDoubleValue("B2"); // The reference pixel is to be computed in the distorted frame. double[] cpix = new double[] {cp1, cp2}; double[] cout = new double[2]; dis.transform(cpix, cout); Scaler s2 = new Scaler( cout[0] - a0 - a1 * x0 - a2 * y0, cout[1] - b0 - b2 * x0 - b1 * y0, -(1 + a1), -a2, -b2, -(1 + b1)); wcsKeys.put("A0", a0); wcsKeys.put("A1", a1); wcsKeys.put("A2", a2); wcsKeys.put("B0", b0); wcsKeys.put("B1", b1); wcsKeys.put("B2", b2); this.distort = dis; add(csys.getSphereDistorter()); add(csys.getRotater()); add(proj.getRotater()); add(proj.getProjecter()); this.scale = s1; // Note that s1 is defined from the projection plane to the pixels coordinates, // so we don't need to invert it. // // But the second scaler, s2, used in the NEAT correction // is defined in the direction from pixels to sphere, so we // need to take its inverse. this.scale = this.scale.add(s2.inverse()); add(this.scale); add(dis); }
/** Handle a DSS projection */ private void doDSSWCS() throws TransformationException { double plateRA = h.getDoubleValue("PLTRAH") + h.getDoubleValue("PLTRAM") / 60 + h.getDoubleValue("PLTRAS") / 3600; plateRA = toRadians(15 * plateRA); wcsKeys.put("PLTRAH", h.getDoubleValue("PLTRAH")); wcsKeys.put("PLTRAM", h.getDoubleValue("PLTRAM")); wcsKeys.put("PLTRAS", h.getDoubleValue("PLTRAS")); double plateDec = h.getDoubleValue("PLTDECD") + h.getDoubleValue("PLTDECM") / 60 + h.getDoubleValue("PLTDECS") / 3600; plateDec = toRadians(plateDec); if (h.getStringValue("PLTDECSN").substring(0, 1).equals("-")) { plateDec = -plateDec; } wcsKeys.put("PLTDECD", h.getDoubleValue("PLTDECD")); wcsKeys.put("PLTDECM", h.getDoubleValue("PLTDECM")); wcsKeys.put("PLTDECS", h.getDoubleValue("PLTDECS")); wcsKeys.put("PLTDECSN", h.getStringValue("PLTDECSN")); double plateScale = h.getDoubleValue("PLTSCALE"); double xPixelSize = h.getDoubleValue("XPIXELSZ"); double yPixelSize = h.getDoubleValue("YPIXELSZ"); wcsKeys.put("PLTSCALE", plateScale); wcsKeys.put("XPIXELSZ", xPixelSize); wcsKeys.put("YPIXELSZ", yPixelSize); double[] xCoeff = new double[20]; double[] yCoeff = new double[20]; for (int i = 1; i <= 20; i += 1) { xCoeff[i - 1] = h.getDoubleValue("AMDX" + i); yCoeff[i - 1] = h.getDoubleValue("AMDY" + i); wcsKeys.put("AMDX" + i, xCoeff[i - 1]); wcsKeys.put("AMDY" + i, yCoeff[i - 1]); } double[] ppo = new double[6]; for (int i = 1; i <= 6; i += 1) { ppo[i - 1] = h.getDoubleValue("PPO" + i); wcsKeys.put("PPO" + i, ppo[i - 1]); } double plateCenterX = ppo[2]; double plateCenterY = ppo[5]; double cdelt1 = -plateScale / 1000 * xPixelSize / 3600; double cdelt2 = plateScale / 1000 * yPixelSize / 3600; wcsScale = abs(cdelt1); // This gives cdelts in degrees per pixel. // CNPIX pixels use a have the first pixel going from 1 - 2 so they are // off by 0.5 from FITS (which in turn is offset by 0.5 from the internal // scaling, but we handle that elsewhere). double crpix1 = plateCenterX / xPixelSize - h.getDoubleValue("CNPIX1", 0) - 0.5; double crpix2 = plateCenterY / yPixelSize - h.getDoubleValue("CNPIX2", 0) - 0.5; wcsKeys.put("CNPIX1", h.getDoubleValue("CNPIX1", 0)); wcsKeys.put("CNPIX2", h.getDoubleValue("CNPIX2", 0)); Projection proj = new Projection("Tan", new double[] {plateRA, plateDec}); this.proj = proj; CoordinateSystem coords = CoordinateSystem.factory("J2000"); this.csys = coords; cdelt1 = toRadians(cdelt1); cdelt2 = toRadians(cdelt2); Scaler s = new Scaler(-cdelt1 * crpix1, -cdelt2 * crpix2, cdelt1, 0, 0, cdelt2); // Got the transformers ready. Add them in properly. add(coords.getSphereDistorter()); add(coords.getRotater()); add(proj.getRotater()); add(proj.getProjecter()); this.distort = new skyview.geometry.distorter.DSS( plateRA, plateDec, xPixelSize, yPixelSize, plateScale, ppo, xCoeff, yCoeff); add(this.distort); this.scale = s.inverse(); add(this.scale); }