Esempio n. 1
0
    /**
     * Constructor.
     *
     * @param inTable saved table as read
     */
    public CodecTable(StarTable inTable) {

      /* Sort out table parameters. */
      codecParamMap_ = new HashMap<String, DescribedValue>();
      List<DescribedValue> dataParamList = new ArrayList<DescribedValue>();
      for (Iterator it = inTable.getParameters().iterator(); it.hasNext(); ) {
        DescribedValue param = (DescribedValue) it.next();
        String utype = param.getInfo().getUtype();
        if (isCodecUtype(utype)) {
          codecParamMap_.put(utype, param);
        } else {
          dataParamList.add(param);
        }
      }

      /* Sort out table columns. */
      codecIcolMap_ = new HashMap<String, Integer>();
      IntList dataIcolList = new IntList();
      for (int icol = 0; icol < inTable.getColumnCount(); icol++) {
        ColumnInfo info = inTable.getColumnInfo(icol);
        String utype = info.getUtype();
        if (isCodecUtype(utype)) {
          codecIcolMap_.put(utype, icol);
        } else {
          dataIcolList.add(icol);
        }
      }
      int[] dataColMap = dataIcolList.toIntArray();

      /* Construct a table containing only the data items. */
      dataTable_ = new MetaCopyStarTable(new ColumnPermutedStarTable(inTable, dataColMap, true));
      dataTable_.getParameters().clear();
      dataTable_.getParameters().addAll(dataParamList);
    }
Esempio n. 2
0
  /**
   * Constructs the DataLink Parameters from an URL string containing a VOTable with DataLink
   * information The VOTABLE must contain only Datalink info! ????? or?
   *
   * @throws IOException
   */
  public DataLinkParams(String dataLinksrc) throws IOException {
    id_source = null;
    request = null;
    accessURL = null;
    contentType = null;
    service = new ArrayList<DataLinkService>();
    DataLinkService thisService = new DataLinkService();

    URL dataLinkURL = new URL(dataLinksrc);
    DataSource datsrc = new URLDataSource(dataLinkURL);

    StarTable starTable =
        new VOTableBuilder().makeStarTable(datsrc, true, StoragePolicy.getDefaultPolicy());

    int ncol = starTable.getColumnCount();

    for (int k = 0; k < ncol; k++) {
      ColumnInfo colInfo = starTable.getColumnInfo(k);

      //   String utype = colInfo.getUtype();
      String name = colInfo.getName();
      if (name != null) thisService.addParam(name, (String) starTable.getCell(0, k));

      //  if ( utype != null ) {
      //     utype = utype.toLowerCase();
      //     if ( utype.endsWith( "datalink.accessurl" ) ) {
      //        thisService.addParam("accessURL", (String) starTable.getCell(0, k));
      //     }
      //     if ( utype.endsWith( "datalink.contenttype" ) ) {
      //         thisService.addParam("contentType", (String) starTable.getCell(0, k));
      // }
    }
    service.add(thisService);
  }
  public void writeData(DataOutput strm) throws IOException {

    /* Work out the length of each row in bytes. */
    int rowBytes = 0;
    int ncol = table.getColumnCount();
    for (int icol = 0; icol < ncol; icol++) {
      ColumnWriter writer = colWriters[icol];
      if (writer != null) {
        rowBytes += writer.getLength();
      }
    }

    /* Write the data cells, delegating the item in each column to
     * the writer that knows how to handle it. */
    long nWritten = 0L;
    RowSequence rseq = table.getRowSequence();
    try {
      while (rseq.next()) {
        Object[] row = rseq.getRow();
        for (int icol = 0; icol < ncol; icol++) {
          ColumnWriter writer = colWriters[icol];
          if (writer != null) {
            writer.writeValue(strm, row[icol]);
          }
        }
        nWritten += rowBytes;
      }
    } finally {
      rseq.close();
    }

    /* Write padding. */
    int extra = (int) (nWritten % (long) 2880);
    if (extra > 0) {
      strm.write(new byte[2880 - extra]);
    }
  }
Esempio n. 4
0
  /**
   * @param ra - in degrees
   * @param dec - in degrees
   * @param angularWidthAlongRAAxis - width along RA axis
   * @param angularWidthAlongDecAxis - width along DEC axis
   * @param otherConstraints - map of UCDKey -> Value. Only images whose column UCDs match the
   *     values are selected
   * @return array of fits image urls
   * @throws Exception -
   */
  public String[] fetchFitsImages(
      double ra,
      double dec,
      double angularWidthAlongRAAxis,
      double angularWidthAlongDecAxis,
      Map<String, Object> otherConstraints)
      throws MalformedURLException, SAXException, IOException, NoValidResultsResourceFoundException,
          SiaQueryFailedException {
    // TODO: Need to take a call on the otherConstraints argument

    String modurl = url + "&FORMAT=image/fits";
    modurl += "&POS=" + ra + "," + dec;
    modurl += "&SIZE=" + angularWidthAlongRAAxis + "," + angularWidthAlongDecAxis;

    URL siaUrl = new URL(modurl);
    logger.info("Connecting to SIA URL: " + siaUrl);

    String interestedImageFormat = "image/fits";
    ArrayList<String> imageUrls = new ArrayList<String>();

    VOElement votable = new VOElementFactory().makeVOElement(siaUrl);
    NodeList resources = votable.getElementsByTagName("RESOURCE");

    // check for a "results" resource with of sia votable resu
    int resInd = 0;
    for (; resInd < resources.getLength(); resInd++) {
      VOElement resource = (VOElement) resources.item(resInd);
      if (SIAP_RESOURCE_TYPE_VALUE_RESULTS.equals(resource.getAttribute("type"))) {
        break;
      }
    }

    if (resInd == resources.getLength()) {
      throw new NoValidResultsResourceFoundException();
    } else {
      String queryStatus = null;
      String queryStatusDescription = null;

      // check query status
      VOElement resource = (VOElement) resources.item(resInd);
      NodeList infos = resource.getElementsByTagName("INFO");
      for (int infoInd = 0; infoInd < infos.getLength(); infoInd++) {
        VOElement info = (VOElement) infos.item(infoInd);
        String name = info.getAttribute("name");
        if (name.equals(QUERY_STATUS)) {
          queryStatus = info.getAttribute("value");
          queryStatusDescription = info.getNodeValue();
        }
      }

      // if query successful.equalsIgnoreCase()
      if (!queryStatus.equals(QUERY_STATUS_VALUE_OK)) {
        throw new SiaQueryFailedException(queryStatusDescription);
      }

      // handle the table
      VOElement[] tables = resource.getChildrenByName("TABLE");
      if (tables.length > 0) {
        // take the first table and look for URLs in it.
        TableElement tableElement = (TableElement) tables[0];

        // create star-table
        StarTable table = new VOStarTable(tableElement);

        // ideally its mandatory to have RA_UCD, DEC_UCD, NAXES_UCD,
        // NAXIS_UCD, FORMAT_UCD, SCALE_UCD in each row but we will not
        // check for those as of now.

        int formatColIndex = -1;
        int urlColIndex = -1;
        int otherConstraintsSize = (otherConstraints != null) ? otherConstraints.size() : 0;
        HashMap<String, Integer> otherConstraintsIndices = new HashMap<String, Integer>();

        for (int colInd = 0; colInd < table.getColumnCount(); colInd++) {
          ColumnInfo colInfo = table.getColumnInfo(colInd);
          if (colInfo.getUCD().equalsIgnoreCase(FORMAT_UCD)) {
            formatColIndex = colInd;
          } else if (colInfo.getUCD().equalsIgnoreCase(ACCESS_REF_UCD)) {
            urlColIndex = colInd;
          }
          if (otherConstraintsSize > 0) {
            Iterator<String> keyIte = otherConstraints.keySet().iterator();
            while (keyIte.hasNext()) {
              String key = keyIte.next();
              if (key.equalsIgnoreCase(colInfo.getUCD())) {
                otherConstraintsIndices.put(key, colInd);
              }
            }
          }
        }

        for (int rowInd = 0; rowInd < table.getRowCount(); rowInd++) {
          Object[] cells = table.getRow(rowInd);
          // looking for only FITS images or JPG images .. ..
          if (interestedImageFormat.equalsIgnoreCase((String) cells[formatColIndex])) {
            Iterator<String> keyIte = otherConstraintsIndices.keySet().iterator();
            boolean allConstraintsPassed = true;
            while (keyIte.hasNext()) {
              String key = keyIte.next();
              int keyInd = otherConstraintsIndices.get(key);
              if (!cells[keyInd].equals(otherConstraints.get(key))) {
                allConstraintsPassed = false;
                break;
              }
            }

            if (allConstraintsPassed) {
              imageUrls.add((String) cells[urlColIndex]);
            }
          }
        }
      }
      return imageUrls.toArray(new String[] {});
    }
  }
  /**
   * Configures this serializer for use with a given table and column writer factory. Should be
   * called before this object is ready for use; in a constructor would be a good place. Calls
   * {@link #createColumnWriter}.
   *
   * @param table table to be written
   */
  final void init(StarTable table) throws IOException {
    if (this.table != null) {
      throw new IllegalStateException("Table already initialised");
    }
    this.table = table;

    /* Get table dimensions (though we may need to calculate the row
     * count directly later. */
    int ncol = table.getColumnCount();
    long nrow = table.getRowCount();

    /* Store column infos. */
    colInfos = Tables.getColumnInfos(table);

    /* Work out column shapes, and check if any are unknown (variable
     * last dimension). */
    boolean hasVarShapes = false;
    boolean checkForNullableInts = false;
    int[][] shapes = new int[ncol][];
    int[] maxChars = new int[ncol];
    int[] maxElements = new int[ncol];
    long[] totalElements = new long[ncol];
    boolean[] useCols = new boolean[ncol];
    boolean[] varShapes = new boolean[ncol];
    boolean[] varChars = new boolean[ncol];
    boolean[] varElementChars = new boolean[ncol];
    boolean[] mayHaveNullableInts = new boolean[ncol];
    Arrays.fill(useCols, true);
    boolean[] hasNulls = new boolean[ncol];
    for (int icol = 0; icol < ncol; icol++) {
      ColumnInfo colinfo = colInfos[icol];
      Class clazz = colinfo.getContentClass();
      if (clazz.isArray()) {
        shapes[icol] = (int[]) colinfo.getShape().clone();
        int[] shape = shapes[icol];
        if (shape[shape.length - 1] < 0) {
          varShapes[icol] = true;
          hasVarShapes = true;
        } else {
          int nel = shape.length > 0 ? 1 : 0;
          for (int id = 0; id < shape.length; id++) {
            nel *= shape[id];
          }
          assert nel >= 0;
          maxElements[icol] = nel;
        }
        if (clazz.getComponentType().equals(String.class)) {
          maxChars[icol] = colinfo.getElementSize();
          if (maxChars[icol] <= 0) {
            varElementChars[icol] = true;
            hasVarShapes = true;
          }
        }
      } else if (clazz.equals(String.class)) {
        maxChars[icol] = colinfo.getElementSize();
        if (maxChars[icol] <= 0) {
          varChars[icol] = true;
          hasVarShapes = true;
        }
      } else if (colinfo.isNullable()
          && (clazz == Byte.class
              || clazz == Short.class
              || clazz == Integer.class
              || clazz == Long.class)) {
        mayHaveNullableInts[icol] = true;

        /* Only set the flag which forces a first pass if we need
         * to work out whether nulls actually exist.  If the
         * aux datum giving a null value exists we will use it in
         * any case, so finding out whether there are in fact null
         * values by scanning the data is not necessary. */
        if (colinfo.getAuxDatumValue(Tables.NULL_VALUE_INFO, Number.class) != null) {
          hasNulls[icol] = true;
        } else {
          checkForNullableInts = true;
        }
      }
    }

    /* If necessary, make a first pass through the table data to
     * find out the maximum size of variable length fields and the length
     * of the table. */
    if (hasVarShapes || checkForNullableInts || nrow < 0) {
      StringBuffer sbuf = new StringBuffer("First pass needed: ");
      if (hasVarShapes) {
        sbuf.append("(variable array shapes) ");
      }
      if (checkForNullableInts) {
        sbuf.append("(nullable ints) ");
      }
      if (nrow < 0) {
        sbuf.append("(unknown row count) ");
      }
      logger.config(sbuf.toString());
      nrow = 0L;

      /* Get the maximum dimensions. */
      RowSequence rseq = table.getRowSequence();
      try {
        while (rseq.next()) {
          nrow++;
          for (int icol = 0; icol < ncol; icol++) {
            if (useCols[icol]
                && (varShapes[icol]
                    || varChars[icol]
                    || varElementChars[icol]
                    || (mayHaveNullableInts[icol] && !hasNulls[icol]))) {
              Object cell = rseq.getCell(icol);
              if (cell == null) {
                if (mayHaveNullableInts[icol]) {
                  hasNulls[icol] = true;
                }
              } else {
                if (varChars[icol]) {
                  int leng = ((String) cell).length();
                  maxChars[icol] = Math.max(maxChars[icol], leng);
                } else if (varElementChars[icol]) {
                  String[] svals = (String[]) cell;
                  for (int i = 0; i < svals.length; i++) {
                    maxChars[icol] = Math.max(maxChars[icol], svals[i].length());
                  }
                }
                if (varShapes[icol]) {
                  int nel = Array.getLength(cell);
                  maxElements[icol] = Math.max(maxElements[icol], nel);
                  totalElements[icol] += nel;
                }
              }
            }
          }
        }
      } finally {
        rseq.close();
      }

      /* In the case of variable string lengths and no non-null data
       * in any of the cells, maxChars could still be set negative.
       * Fix that here. */
      for (int icol = 0; icol < ncol; icol++) {
        if (maxChars[icol] < 0) {
          maxChars[icol] = 0;
        }
      }

      /* Furthermore, zero length strings are probably a bad idea
       * for FITS output.  Make sure that all output strings have
       * a length of at least 1. */
      for (int icol = 0; icol < ncol; icol++) {
        if (maxChars[icol] == 0) {
          maxChars[icol] = 1;
        }
      }

      /* Work out the actual shapes for columns which have variable ones,
       * based on the shapes that we encountered in the rows. */
      if (hasVarShapes) {
        for (int icol = 0; icol < ncol; icol++) {
          if (useCols[icol]) {
            if (varShapes[icol]) {
              int[] shape = shapes[icol];
              int ndim = shape.length;
              assert shape[ndim - 1] <= 0;
              int nel = 1;
              for (int i = 0; i < ndim - 1; i++) {
                nel *= shape[i];
              }
              shape[ndim - 1] = Math.max(1, (maxElements[icol] + nel - 1) / nel);
            }
          }
        }
      }
    }

    /* Store the row count, which we must have got by now. */
    assert nrow >= 0;
    rowCount = nrow;

    /* We now have all the information we need about the table.
     * Construct and store a custom writer for each column which
     * knows about the characteristics of the column and how to
     * write values to the stream.  For columns which can't be
     * written in FITS format store a null in the writers array
     * and log a message. */
    colWriters = new ColumnWriter[ncol];
    int rbytes = 0;
    for (int icol = 0; icol < ncol; icol++) {
      if (useCols[icol]) {
        ColumnInfo cinfo = colInfos[icol];
        ColumnWriter writer =
            createColumnWriter(
                cinfo,
                shapes[icol],
                varShapes[icol],
                maxChars[icol],
                maxElements[icol],
                totalElements[icol],
                mayHaveNullableInts[icol] && hasNulls[icol]);
        if (writer == null) {
          logger.warning(
              "Ignoring column " + cinfo.getName() + " - don't know how to write to FITS");
        }
        colWriters[icol] = writer;
      }
    }
  }
  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;
  }