Пример #1
0
  @Test
  public void testreadWriteHdu() throws Exception {
    byte[] undefinedData = new byte[1000];
    for (int index = 0; index < undefinedData.length; index++) {
      undefinedData[index] = (byte) index;
    }
    UndefinedData data = UndefinedHDU.encapsulate(undefinedData);
    Header header = new Header();
    header.pointToData(data);
    UndefinedHDU hdu = new UndefinedHDU(header, data);

    hdu.getHeader().deleteKey("EXTEND");

    BufferedFile stream = new BufferedFile("target/rewriteHduTest.bin", "rw");
    hdu.write(stream);
    stream.close();

    stream = new BufferedFile("target/rewriteHduTest.bin", "rw");
    data = UndefinedHDU.encapsulate(new byte[0]);
    hdu = new UndefinedHDU(new Header(data), data);
    hdu.read(stream);
    hdu.addValue("TESTER", "WRITE", null);
    hdu.rewrite();
    hdu.reset();
    hdu.read(stream);
    hdu.getHeader().getStringValue("TESTER");

    byte[] rereadUndefinedData = (byte[]) hdu.getData().getData();
    Assert.assertArrayEquals(undefinedData, rereadUndefinedData);
  }
Пример #2
0
  /** Create the WCS using the definition given in the FITS header. */
  public WCS(Header h) throws TransformationException {

    wcsKeys = new HashMap<String, Object>();

    this.h = h;
    headerNaxis = new int[2];
    if (checkDSS()) {
      headerNaxis[0] = h.getIntValue("NAXIS1");
      headerNaxis[1] = h.getIntValue("NAXIS2");
      if (headerNaxis[0] == 0) {
        headerNaxis[0] = h.getIntValue("XPIXELS");
        headerNaxis[1] = h.getIntValue("YPIXELS");
      }
      doDSSWCS();
      stdWCS = false;

    } else if (checkNeat()) {
      headerNaxis[0] = h.getIntValue("NAXIS1");
      headerNaxis[1] = h.getIntValue("NAXIS2");
      doNeatWCS();
      stdWCS = false;

    } else { // More or less standard FITS WCS

      getAxes();
      if (lonAxis == -1 || latAxis == -1) {
        throw new TransformationException("Unable to find coordinate axes");
      }
      headerNaxis[0] = h.getIntValue("NAXIS" + lonAxis);
      headerNaxis[1] = h.getIntValue("NAXIS" + latAxis);
      extractCoordinateSystem();
      extractProjection();
      extractScaler();
    }
  }
Пример #3
0
  @Test
  public void testFitsUndefinedHdu4() throws Exception {
    Fits fits1 = makeAsciiTable();
    fits1.read();
    byte[] undefinedData = new byte[1000];
    for (int index = 0; index < undefinedData.length; index++) {
      undefinedData[index] = (byte) index;
    }
    Data data = UndefinedHDU.encapsulate(undefinedData);
    Header header = new Header();
    header.pointToData(data);

    fits1.addHDU(FitsFactory.hduFactory(header, data));
    BufferedDataOutputStream os =
        new BufferedDataOutputStream(new FileOutputStream("target/UndefindedHDU4.fits"));
    fits1.write(os);
    os.close();

    Fits fits2 = new Fits("target/UndefindedHDU4.fits");
    BasicHDU<?>[] hdus = fits2.read();

    byte[] rereadUndefinedData =
        (byte[]) ((UndefinedData) hdus[hdus.length - 1].getData()).getData();
    Assert.assertArrayEquals(undefinedData, rereadUndefinedData);

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    hdus[hdus.length - 1].info(new PrintStream(out));
    String undefinedInfo = new String(out.toByteArray());

    Assert.assertTrue(undefinedInfo.indexOf("Apparent size:1000") >= 0);
  }
Пример #4
0
  static void initPlotTitle(
      PlotState state,
      ImagePlot plot,
      ActiveFitsReadGroup frGroup,
      String dataDesc,
      boolean isMultiImage) {
    WebPlotRequest req = state.getPrimaryWebPlotRequest();
    WebPlotRequest.TitleOptions titleOps = req.getTitleOptions();
    String headerKey = req.getHeaderKeyForTitle();
    if ((isMultiImage
            && (titleOps == WebPlotRequest.TitleOptions.NONE
                || titleOps == WebPlotRequest.TitleOptions.FILE_NAME))
        || (titleOps == WebPlotRequest.TitleOptions.HEADER_KEY && StringUtils.isEmpty(headerKey))) {
      titleOps = WebPlotRequest.TitleOptions.HEADER_KEY;
      headerKey = "EXTNAME";
    }
    String s = req.getPlotDescAppend();
    plot.setPlotDesc("");
    Header header = frGroup.getFitsRead(state.firstBand()).getHeader();

    switch (titleOps) {
      case NONE:
        plot.setPlotDesc("");
        break;
      case PLOT_DESC:
        String base = req.getTitle() == null ? "" : req.getTitle();
        plot.setPlotDesc(base + dataDesc);
        break;
      case FILE_NAME:
        break;
      case HEADER_KEY:
        HeaderCard card = header.findCard(headerKey);
        if (card == null && state.getCubeCnt(state.firstBand()) > 0) {
          card = header.findCard("PLANE" + state.getImageIdx(state.firstBand()));
        }
        String hTitle = card != null ? card.getValue() : "";
        plot.setPlotDesc(hTitle);
        break;
      case PLOT_DESC_PLUS:
        plot.setPlotDesc(req.getTitle() + (s != null ? " " + s : ""));
        break;
      case SERVICE_OBS_DATE:
        if (req.getRequestType() == RequestType.SERVICE) {
          //                    String desc= req.getServiceType()== WebPlotRequest.ServiceType.WISE
          // ? MID_OBS : OBS_DATE;
          String title =
              req.getTitle()
                  + ": "
                  +
                  //                                  desc + ": " +
                  PlotServUtils.getDateValueFromServiceFits(req.getServiceType(), header);
          plot.setPlotDesc(title);
        }
        break;
    }
  }
Пример #5
0
 @Test
 public void testHduFromHeader() throws Exception {
   Header header = new Header();
   header.addValue("SIMPLE", true, "");
   header.addValue("BITPIX", 8, "");
   header.addValue("NAXIS", 2, "");
   header.addValue("NAXIS1", 4, "");
   header.addValue("NAXIS3", 4, "");
   ImageHDU hdu = (ImageHDU) Fits.makeHDU(header);
   Assert.assertNotNull(hdu);
 }
Пример #6
0
  private double equinox() {

    double equin = h.getDoubleValue("EQUINOX", NaN);

    if (isNaN(equin)) {
      equin = h.getDoubleValue("EPOCH", NaN);
    }
    if (isNaN(equin)) {
      equin = 2000;
    }
    wcsKeys.put("EQUINOX", 2000);
    return equin;
  }
Пример #7
0
  @Test
  public void testBigDataSegments() throws Exception {
    ImageData data = new ImageData(new float[4][4]);

    Header manufactureHeader = ImageHDU.manufactureHeader(data);
    manufactureHeader.card(Standard.END).comment("");
    manufactureHeader.findCard(Standard.NAXIS1).setValue(25000);
    manufactureHeader.findCard(Standard.NAXIS2).setValue(25000);

    long value = manufactureHeader.getDataSize();
    int intValue = (int) manufactureHeader.getDataSize();
    assertEquals(2500001280L, value);
    Assert.assertTrue(intValue != value);
  }
Пример #8
0
  public void copyToHeader(Header h) throws nom.tam.fits.HeaderCardException {

    String[] srt = wcsKeys.keySet().toArray(new String[0]);
    java.util.Arrays.sort(srt);
    for (String key : srt) {
      Object o = wcsKeys.get(key);
      if (o instanceof Integer) {
        h.addValue(key, ((Integer) o).intValue(), "Copied WCS eleemnt");
      } else if (o instanceof Double) {
        h.addValue(key, ((Double) o).doubleValue(), "Copied WCS element");
      } else if (o instanceof String) {
        h.addValue(key, (String) o, "Copied WCS element");
      }
    }
  }
Пример #9
0
  public String getHeaderString() {
    Header hdr = hdu.getHeader();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream ps = new PrintStream(baos);
    hdr.dumpHeader(ps);
    String hdrString = baos.toString();
    try {
      baos.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    ps.close();

    return hdrString;
  }
Пример #10
0
  /** Get the scaling between the projection plane and pixel coordinates */
  private void extractScaler() throws TransformationException {

    // There are three ways that scaling information may be provided:
    //    CDELTn, CRPIXn, and CROTAn
    //    CDm_n, CRPIXn
    //    PCm_n, CDELTn, CRPIXn
    // We look for them in this sequence.
    //

    double crpix1 = h.getDoubleValue("CRPIX" + lonAxis, NaN);
    double crpix2 = h.getDoubleValue("CRPIX" + latAxis, NaN);
    wcsKeys.put("CRPIX1", crpix1);
    wcsKeys.put("CRPIX2", crpix2);
    if (isNaN(crpix1) || isNaN(crpix2)) {
      throw new TransformationException("CRPIXn not found in header");
    }

    // Note that in FITS files, the center of the first pixel is
    // assumed to be at coordinates 1,1.  Thus the corner of the image
    // is at pixels coordinates 1/2, 1/2.
    crpix1 -= 0.5;
    crpix2 -= 0.5;

    if (extractScaler1(crpix1, crpix2)) {
      return;
    }
    if (extractScaler2(crpix1, crpix2)) {
      return;
    }

    // No scaling information found.
    throw new TransformationException("No scaling information found in FITS header");
  }
Пример #11
0
  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());
  }
Пример #12
0
  /** Is this a DSS projection? */
  private boolean checkDSS() throws TransformationException {

    String origin = h.getStringValue("ORIGIN");
    if (origin == null || h.getStringValue("CTYPE1") != null) {
      return false;
    }
    wcsKeys.put("ORIGIN", origin);

    // If we have a local solution use it unless told
    // to prefer the DSS solution.
    if (h.getStringValue("CTYPE1") != null && !preferDSS) {
      return false;
    }

    if (h.getDoubleValue("XPIXELSZ", -1) == -1) {
      return false;
    }

    return origin.startsWith("CASB") || origin.startsWith("STScI");
  }
Пример #13
0
  /** Get the scaling when it is described as a matrix */
  private boolean extractScaler2(double crpix1, double crpix2) throws TransformationException {

    // Look for the CD matrix...
    //
    double m11 = h.getDoubleValue("CD" + lonAxis + "_" + lonAxis, NaN);
    double m12 = h.getDoubleValue("CD" + lonAxis + "_" + latAxis, NaN);
    double m21 = h.getDoubleValue("CD" + latAxis + "_" + lonAxis, NaN);
    double m22 = h.getDoubleValue("CD" + latAxis + "_" + latAxis, NaN);

    boolean matrix = !isNaN(m11 + m12 + m21 + m22);
    if (!matrix) {
      return false;
    }
    wcsKeys.put("CD1_1", m11);
    wcsKeys.put("CD1_2", m12);
    wcsKeys.put("CD2_1", m21);
    wcsKeys.put("CD2_2", m22);

    m11 = toRadians(m11);
    m12 = toRadians(m12);
    m21 = toRadians(m21);
    m22 = toRadians(m22);

    // we have
    //   t = a11 (x-x0) + a12 (y-y0); u = a21(x-x0) + a22(y-y0)
    //       t = a11x + a12y - a11 x0 - a12 y0;
    //
    Scaler s =
        new Scaler(-m11 * crpix1 - m12 * crpix2, -m21 * crpix1 - m22 * crpix2, m11, m12, m21, m22);

    s = s.inverse();

    // Are longitude and latitude in unusual order?
    if (lonAxis > latAxis) {
      s.interchangeAxes();
    }
    this.scale = s;
    add(s);
    setWCSScale(s);
    return true;
  }
Пример #14
0
  /** Update the display to show the FITS headers of the spectrum */
  public void updateDisplay() {
    Header header = null;
    if (specData != null) {
      header = specData.getHeaders();
    }

    //  Stop with null table if no spectrum or no headers.
    if (specData == null || header == null) {
      table.setModel(new DefaultTableModel());
      return;
    }

    String[] columnNames = {"Keyword", "Value", "Comment"};
    int numKeywords = header.getNumberOfCards();
    String[][] values = new String[numKeywords][3];
    Iterator it = header.iterator();
    int n = 0;
    while (it.hasNext()) {
      HeaderCard card = (HeaderCard) (it.next());
      String key = card.getKey();
      String value = card.getValue();
      String comment = card.getComment();
      //  A blank keyword is really a comment line.
      if ("".equals(key)) {
        value = comment;
        comment = "";
      }
      values[n][0] = key;
      values[n][1] = value;
      values[n++][2] = comment;
    }
    table.setModel(new DefaultTableModel(values, columnNames));

    //  Set default widths, matched to FITS format.
    TableColumn column = table.getColumnModel().getColumn(0);
    column.setPreferredWidth(100);
    column = table.getColumnModel().getColumn(1);
    column.setPreferredWidth(300);
    column = table.getColumnModel().getColumn(2);
    column.setPreferredWidth(450);
  }
Пример #15
0
  /**
   * Find which axes are being used for coordinates. Normally this will just be 1 and 2, but
   * occasionally we may be surprised.
   */
  private void getAxes() {

    int naxes = h.getIntValue("NAXIS");

    // The first axes match are assumed to be correct.
    for (int i = 1; i <= naxes; i += 1) {
      String axis = h.getStringValue("CTYPE" + i);
      if (axis != null && axis.length() >= 4) {
        axis = axis.substring(0, 4);
      } else {
        continue;
      }

      if (lonAxis == -1) {
        if (axis.equals("RA--")
            || axis.equals("GLON")
            || axis.equals("ELON")
            || axis.equals("HLON")) {
          lonAxis = i;
        }
      }
      if (latAxis == -1) {
        if (axis.equals("DEC-")
            || axis.equals("GLAT")
            || axis.equals("ELAT")
            || axis.equals("HLAT")) {
          latAxis = i;
        }
      }
    }
    if (lonAxis > -1) {
      wcsKeys.put("CTYPE1", h.getStringValue("CTYPE" + lonAxis));
    }
    if (latAxis > -1) {
      wcsKeys.put("CTYPE2", h.getStringValue("CTYPE" + latAxis));
    }
  }
Пример #16
0
 private String frame() {
   String sys = h.getStringValue("RADESYS");
   if (sys != null) {
     wcsKeys.put("RADESYS", sys);
   }
   if (sys == null) {
     double equin = equinox();
     if (equin >= 1984) {
       return "J";
     } else {
       return "B";
     }
   }
   if (sys.length() > 3 && sys.substring(0, 3).equals("FK4")) {
     return "B";
   } else {
     return "J";
   }
 }
Пример #17
0
  @Test
  public void testFitsUndefinedHdu3() throws Exception {
    Fits fits1 = makeAsciiTable();
    fits1.read();
    byte[] undefinedData = new byte[1000];
    for (int index = 0; index < undefinedData.length; index++) {
      undefinedData[index] = (byte) index;
    }
    Data data = UndefinedHDU.encapsulate(undefinedData);
    Header header = new Header(data);

    Cursor<String, HeaderCard> iter = header.iterator();

    String[] headers = new String[header.getNumberOfCards() - 1];
    int index = 0;
    while (iter.hasNext()) {
      HeaderCard headerCard = iter.next();
      // the EXTEND key will be deleted later on because the header is no
      // primary header so don't use it
      if (!headerCard.getKey().equals("EXTEND")) {
        headers[index++] = headerCard.toString();
      }
    }
    Header newHeader = new Header(headers);
    for (index = 0; index < headers.length; index++) {
      Assert.assertEquals(header.getCard(index), newHeader.getCard(index));
    }

    fits1.addHDU(FitsFactory.hduFactory(newHeader, data));
    BufferedDataOutputStream os =
        new BufferedDataOutputStream(new FileOutputStream("target/UndefindedHDU3.fits"));
    fits1.write(os);
    os.close();

    Fits fits2 = new Fits("target/UndefindedHDU3.fits");
    BasicHDU[] hdus = fits2.read();

    for (index = 0; index < headers.length; index++) {
      Assert.assertEquals(header.getCard(index), hdus[5].getHeader().getCard(index));
    }
  }
Пример #18
0
  @Test
  public void testFitsUndefinedHdu5() throws Exception {
    Header head = new Header();
    head.setXtension("UNKNOWN");
    head.setBitpix(BasicHDU.BITPIX_BYTE);
    head.setNaxes(1);
    head.addValue("NAXIS1", 1000, null);
    head.addValue("PCOUNT", 0, null);
    head.addValue("GCOUNT", 2, null);
    UndefinedHDU hdu = (UndefinedHDU) FitsFactory.hduFactory(head);
    byte[] data = (byte[]) hdu.getData().getData();
    Assert.assertEquals(2000, data.length);
    Arrays.fill(data, (byte) 1);
    BufferedFile buf = new BufferedFile("target/testFitsUndefinedHdu5", "rw");
    hdu.write(buf);
    buf.close();
    Arrays.fill(data, (byte) 2);

    buf = new BufferedFile("target/testFitsUndefinedHdu5", "rw");
    hdu.read(buf);
    data = (byte[]) hdu.getData().getData();
    buf.close();
    Assert.assertEquals((byte) 1, data[0]);
  }
Пример #19
0
  public String getWcsHeaderCardsString() {
    Header header = hdu.getHeader();
    Header filteredHeader = new Header();

    // now adjust WCS values:
    ArrayList<HeaderCard> cards = new ArrayList<HeaderCard>();
    cards.add(header.findCard("CTYPE1"));
    cards.add(header.findCard("CTYPE2"));
    cards.add(header.findCard("RADESYS"));
    cards.add(header.findCard("RADECSYS"));
    cards.add(header.findCard("CRVAL1"));
    cards.add(header.findCard("CRVAL2"));
    cards.add(header.findCard("CDELT1"));
    cards.add(header.findCard("CDELT2"));
    cards.add(header.findCard("EQUINOX"));
    cards.add(header.findCard("BUNIT"));
    cards.add(header.findCard("EPOCH"));
    cards.add(header.findCard("CD1_1"));
    cards.add(header.findCard("CD1_2"));
    cards.add(header.findCard("CD2_1"));
    cards.add(header.findCard("CD2_2"));
    cards.add(header.findCard("CRPIX1"));
    cards.add(header.findCard("CRPIX2"));
    cards.add(header.findCard("END"));

    cards.forEach(
        (card) -> {
          if (card != null) {
            try {
              filteredHeader.addLine(card);
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
        });
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream ps = new PrintStream(baos);
    filteredHeader.dumpHeader(ps);
    String wcsHdrString = baos.toString();
    try {
      baos.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    ps.close();

    return wcsHdrString;
  }
Пример #20
0
  /**
   * Write FITS WCS keywords given key values. Only relatively simple WCSs are handled here. We
   * assume we are dealing with axes 1 and 2.
   *
   * @param h The header to be updated.
   * @param s A Scaler giving the transformation between standard projection coordinates and
   *     pixel/device coordinates.
   * @param projString A three character string giving the projection used. Supported projections
   *     are: "Tan", "Sin", "Ait", "Car", "Zea".
   * @param coordString A string giving the coordinate system used. The first character gives the
   *     general frame. For most frames the remainder of the string gives the equinox of the
   *     coordinate system. E.g., J2000, B1950, Galactic, "E2000", "H2020.10375".
   */
  public void updateHeader(
      Header h, Scaler s, double[] crval, String projString, String coordString) throws Exception {

    if (proj.isFixedProjection()) {
      h.addValue("CRVAL1", toDegrees(proj.getReferencePoint()[0]), "Fixed reference center");
      h.addValue("CRVAL2", toDegrees(proj.getReferencePoint()[1]), "Fixed reference center");
    } else {
      h.addValue("CRVAL1", crval[0], "Reference longitude");
      h.addValue("CRVAL2", crval[1], "Reference latitude");
    }

    coordString = coordString.toUpperCase();
    String[] prefixes = new String[2];
    char c = coordString.charAt(0);
    if (c == 'J' || c == 'I') {
      h.addValue("RADESYS", "FK5", "Coordinate system");
      prefixes[0] = "RA--";
      prefixes[1] = "DEC-";
    } else if (c == 'B') {
      h.addValue("RADESYS", "FK4", "Coordinate system");
      prefixes[0] = "RA--";
      prefixes[1] = "DEC-";
    } else {
      prefixes[0] = c + "LON";
      prefixes[1] = c + "LAT";
    }

    if (c != 'G' && c != 'I') {
      try {
        double equinox = Double.parseDouble(coordString.substring(1));
        h.addValue("EQUINOX", equinox, "Epoch of the equinox");
      } catch (Exception e) {
        // Couldn't parse out the equinox
      }
    }
    if (c == 'I') {
      h.addValue("EQUINOX", 2000, "ICRS coordinates");
    }

    String upProj = projString.toUpperCase();

    h.addValue("CTYPE1", prefixes[0] + "-" + upProj, "Coordinates -- projection");
    h.addValue("CTYPE2", prefixes[1] + "-" + upProj, "Coordinates -- projection");

    // Note that the scaler transforms from the standard projection
    // coordinates to the pixel coordinates.
    //     P = P0 + M X  where X is the standard coordinates and P is the
    // pixel coordinates.  So the reference pixels are just the constants
    // in the scaler.
    // Remember that FITS pixels are offset by 0.5 from 0 offset pixels.

    h.addValue("CRPIX1", s.x0 + 0.5, "X reference pixel");
    h.addValue("CRPIX2", s.y0 + 0.5, "Y reference pixel");

    // Remember that the FITS values are of the form
    //    X = M(P-P0)
    // so we'll need to invert the scaler.
    //
    // Do we need a matrix?
    if (abs(s.a01) < 1.e-14 && abs(s.a10) < 1.e-14) {
      // No cross terms, so we'll just use CDELTs
      h.addValue("CDELT1", toDegrees(1 / s.a00), "X scale");
      h.addValue("CDELT2", toDegrees(1 / s.a11), "Y scale");
    } else {
      // We have cross terms.  It's simplest
      // just to use the CD matrix and not worry about
      // normalization.  First invert the matrix to get
      // the transformation in the direction that FITS uses.
      Scaler rev = s.inverse();
      h.addValue("CD1_1", toDegrees(rev.a00), "Matrix element");
      h.addValue("CD1_2", toDegrees(rev.a01), "Matrix element");
      h.addValue("CD2_1", toDegrees(rev.a10), "Matrix element");
      h.addValue("CD2_2", toDegrees(rev.a11), "Matrix element");
    }
  }
Пример #21
0
  /** 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);
  }
Пример #22
0
 /** Is this a NEAT special projection? */
 private boolean checkNeat() {
   return h.getStringValue("CTYPE1").equals("RA---XTN");
 }
Пример #23
0
  /** 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);
  }
Пример #24
0
  private void extractProjection() throws TransformationException {

    Projection proj = null;
    Scaler ncpScale = null;

    String lonType = h.getStringValue("CTYPE" + lonAxis).substring(5, 8);
    String latType = h.getStringValue("CTYPE" + latAxis).substring(5, 8);
    if (!lonType.equals(latType)) {
      throw new TransformationException(
          "Inconsistent projection in FITS header: " + lonType + "," + latType);
    }

    if (lonType.equals("AIT")) {
      proj = new Projection("Ait");

    } else if (lonType.equals("CAR")) {
      proj = new Projection("Car");
      // Allow non-central latitudes for the Cartesian projection.
      try {
        double lon = h.getDoubleValue("CRVAL" + lonAxis);
        if (lon != 0) {
          proj.setReference(toRadians(lon), 0);
        }
      } catch (Exception e) {
        System.err.println("Unable to read reference longitude in Cartesian projection");
      }

    } else if (lonType.equals("CSC")) {
      proj = new Projection("Csc");

    } else if (lonType.equals("SFL") || lonType.equals("GLS")) {
      proj = new Projection("Sfl");

    } else if (lonType.equals("TOA")) {
      proj = new Projection("Toa");

    } else {

      double crval1 = h.getDoubleValue("CRVAL" + lonAxis, NaN);
      double crval2 = h.getDoubleValue("CRVAL" + latAxis, NaN);

      if (isNaN(crval1 + crval2)) {
        throw new TransformationException("Unable to find reference coordinates in FITS header");
      }

      wcsKeys.put("CRVAL1", crval1);
      wcsKeys.put("CRVAL2", crval2);

      if (lonType.equals("TAN")
          || lonType.equals("SIN")
          || lonType.equals("ZEA")
          || lonType.equals("ARC")
          || lonType.equals("STG")) {

        String type = lonType.substring(0, 1) + lonType.substring(1, 3).toLowerCase();
        proj = new Projection(type, new double[] {toRadians(crval1), toRadians(crval2)});

        double lonpole = h.getDoubleValue("LONPOLE", NaN);
        if (!isNaN(lonpole)) {
          wcsKeys.put("LONPOLE", lonpole);
        }
        //  ---- Following is probably erroneous -----
        // The WCS standard indicates that the default LONPOLE for
        // a projection is 180 when the CRVAL latitude is less than
        // the native latitude of the projection (90 degrees for the projections
        // handled here) and 0 otherwise.  This means that for a projection
        // around the pole the default lonpole is 0.  Some data (the SFD surveys)
        // seem to require that we do a rotation of 180 degrees to accommodate
        // this.  However we do not implement this unless the LONPOLE is
        // explicitly given since this seems non-intuitive to me and I suspect
        // that a user who is not careful enough to specify a LONPOLE in this
        // situation probably doesn't understand what is going on anyway.
        // ----- We now assume that our standard processing of
        // ----- zenithal projections handles lonpole of 180 and that
        // ----- this is the default for all zenithal images.
        // ----- Previously we assumed that we were using lonPole=0 at
        // ----- at the poles, but we weren't....
        //

        if (!isNaN(lonpole)) {
          double lonDefault = 180;
          if (lonpole != lonDefault) {

            Rotater r = proj.getRotater();

            Rotater lon = new Rotater("Z", toRadians(lonpole - lonDefault), 0, 0);
            if (r != null) {
              proj.setRotater(r.add(lon));
            } else {
              proj.setRotater(lon);
            }
          }
        }

      } else if (lonType.equals("NCP")) {

        // Sin projection with projection centered at pole.
        double[] xproj = new double[] {toRadians(crval1), PI / 2};
        if (crval2 < 0) {
          xproj[1] = -xproj[1];
        }

        double poleOffset = sin(xproj[1] - toRadians(crval2));
        // Have we handled South pole here?

        proj = new Projection("Sin", xproj);

        // NCP scales the Y-axis to accommodate the distortion of the SIN projection away
        // from the pole.
        ncpScale = new Scaler(0, poleOffset, 1, 0, 0, 1);
        ncpScale = ncpScale.add(new Scaler(0., 0., 1, 0, 0, 1 / sin(toRadians(crval2))));

      } else {
        throw new TransformationException("Unsupported projection type:" + lonType);
      }
    }

    this.proj = proj;
    if (ncpScale != null) {
      this.scale = ncpScale;
    }
    add(proj.getRotater());
    add(proj.getProjecter());
    add(ncpScale); // Ignored if null
  }
Пример #25
0
  /** Get the scaling when CDELT is specified */
  private boolean extractScaler1(double crpix1, double crpix2) throws TransformationException {

    boolean matrix = false;

    double cdelt1 = h.getDoubleValue("CDELT" + lonAxis, NaN);
    double cdelt2 = h.getDoubleValue("CDELT" + latAxis, NaN);
    wcsKeys.put("CDELT1", cdelt1);
    wcsKeys.put("CDELT2", cdelt2);
    if (isNaN(cdelt1) || isNaN(cdelt2)) {
      return false;
    }

    // We use 1 indexing to match better with the FITS files.
    double m11, m12, m21, m22;

    // We've got minimal information...  We might have more.
    double crota = h.getDoubleValue("CROTA" + latAxis, NaN);
    if (!isNaN(crota) && crota != 0) {
      wcsKeys.put("CROTA2", crota);
      crota = toRadians(crota);

      m11 = cos(crota);
      m12 = sin(crota);
      m21 = -sin(crota);
      m22 = cos(crota);
      matrix = true;

    } else {

      m11 = h.getDoubleValue("PC" + lonAxis + "_" + lonAxis, NaN);
      m12 = h.getDoubleValue("PC" + lonAxis + "_" + latAxis, NaN);
      m21 = h.getDoubleValue("PC" + latAxis + "_" + lonAxis, NaN);
      m22 = h.getDoubleValue("PC" + latAxis + "_" + latAxis, NaN);
      matrix = !isNaN(m11 + m12 + m21 + m22);
      if (matrix) {
        wcsKeys.put("PC1_1", m11);
        wcsKeys.put("PC1_2", m12);
        wcsKeys.put("PC2_1", m21);
        wcsKeys.put("PC2_2", m22);
      }
    }

    // Note that Scaler is defined with parameters t = x0 + a00 x + a01 y; u = y0 + a10 x + a11 y
    // which is different from what we have here...
    //    t = scalex (x-x0),  u = scaley (y-y0)
    //    t = scalex x - scalex x0; u = scaley y - scaley y0
    // or
    //    t = scalex [a11 (x-x0) + a12 (y-y0)], u = scaley [a21 (x-x0) + a22 (y-y0)] ->
    //       t = scalex a11 x - scalex a11 x0 + scalex a12 y + scalex a12 y0         ->
    //       t = - scalex (a11 x0 + a12 y0) + scalex a11 x + scalex a12 y (and similarly for u)

    Scaler s;
    cdelt1 = toRadians(cdelt1);
    cdelt2 = toRadians(cdelt2);
    if (!matrix) {
      s = new Scaler(-cdelt1 * crpix1, -cdelt2 * crpix2, cdelt1, 0, 0, cdelt2);
    } else {
      s =
          new Scaler(
              -cdelt1 * (m11 * crpix1 + m12 * crpix2),
              -cdelt2 * (m21 * crpix1 + m22 * crpix2),
              cdelt1 * m11,
              cdelt1 * m12,
              cdelt2 * m21,
              cdelt2 * m22);
    }

    // Note that this scaler transforms from pixel coordinates to standard projection
    // plane coordinates.  We want the inverse transformation as the scaler.
    s = s.inverse();

    // Are lon and lat in unusual order?
    if (lonAxis > latAxis) {
      s.interchangeAxes();
    }

    this.scale = s;
    add(s);
    setWCSScale(s);

    return true;
  }
Пример #26
0
 protected void customisePrimaryHeader(Header hdr) throws HeaderCardException {
   hdr.addValue("VOTMETA", true, "Table metadata in VOTable format");
 }
  public Header getHeader() throws HeaderCardException {

    /* Work out the dimensions in columns and bytes of the table. */
    int rowLength = 0;
    int nUseCol = 0;
    int ncol = table.getColumnCount();
    for (int icol = 0; icol < ncol; icol++) {
      ColumnWriter writer = colWriters[icol];
      if (writer != null) {
        nUseCol++;
        rowLength += writer.getLength();
      }
    }

    /* Prepare a FITS header block. */
    Header hdr = new Header();

    /* Add HDU layout metadata. */
    hdr.addValue("XTENSION", "BINTABLE", "binary table extension");
    hdr.addValue("BITPIX", 8, "8-bit bytes");
    hdr.addValue("NAXIS", 2, "2-dimensional table");
    hdr.addValue("NAXIS1", rowLength, "width of table in bytes");
    hdr.addValue("NAXIS2", rowCount, "number of rows in table");
    hdr.addValue("PCOUNT", 0, "size of special data area");
    hdr.addValue("GCOUNT", 1, "one data group");
    hdr.addValue("TFIELDS", nUseCol, "number of columns");

    /* Add EXTNAME record containing table name. */
    String tname = table.getName();
    if (tname != null && tname.trim().length() > 0) {
      FitsConstants.addTrimmedValue(hdr, "EXTNAME", tname, "table name");
    }

    /* Add HDU metadata describing columns. */
    int jcol = 0;
    for (int icol = 0; icol < ncol; icol++) {
      ColumnWriter colwriter = colWriters[icol];
      if (colwriter != null) {
        jcol++;
        String forcol = " for column " + jcol;
        ColumnInfo colinfo = colInfos[icol];

        /* Name. */
        String name = colinfo.getName();
        if (name != null && name.trim().length() > 0) {
          FitsConstants.addTrimmedValue(hdr, "TTYPE" + jcol, name, "label" + forcol);
        }

        /* Format. */
        String form = colwriter.getFormat();
        hdr.addValue("TFORM" + jcol, form, "format" + forcol);

        /* Units. */
        String unit = colinfo.getUnitString();
        if (unit != null && unit.trim().length() > 0) {
          FitsConstants.addTrimmedValue(hdr, "TUNIT" + jcol, unit, "units" + forcol);
        }

        /* Blank. */
        Number bad = colwriter.getBadNumber();
        if (bad != null) {
          hdr.addValue("TNULL" + jcol, bad.longValue(), "blank value" + forcol);
        }

        /* Shape. */
        int[] dims = colwriter.getDims();
        if (dims != null && dims.length > 1) {
          StringBuffer sbuf = new StringBuffer();
          for (int i = 0; i < dims.length; i++) {
            sbuf.append(i == 0 ? '(' : ',');
            sbuf.append(dims[i]);
          }
          sbuf.append(')');
          hdr.addValue("TDIM" + jcol, sbuf.toString(), "dimensions" + forcol);
        }

        /* Scaling. */
        double zero = colwriter.getZero();
        double scale = colwriter.getScale();
        if (zero != 0.0) {
          hdr.addValue("TZERO" + jcol, zero, "base" + forcol);
        }
        if (scale != 1.0) {
          hdr.addValue("TSCALE" + jcol, scale, "factor" + forcol);
        }

        /* Comment (non-standard). */
        String comm = colinfo.getDescription();
        if (comm != null && comm.trim().length() > 0) {
          try {
            hdr.addValue("TCOMM" + jcol, comm, null);
          } catch (HeaderCardException e) {
            // never mind.
          }
        }

        /* UCD (non-standard). */
        String ucd = colinfo.getUCD();
        if (ucd != null && ucd.trim().length() > 0 && ucd.length() < 68) {
          try {
            hdr.addValue("TUCD" + jcol, ucd, null);
          } catch (HeaderCardException e) {
            // never mind.
          }
        }

        /* Utype (non-standard). */
        String utype = colinfo.getUtype();
        if (utype != null && utype.trim().length() > 0 && utype.trim().length() < 68) {
          try {
            hdr.addValue("TUTYP" + jcol, utype, null);
          } catch (HeaderCardException e) {
            // never mind.
          }
        }
      }
    }
    return hdr;
  }