Ejemplo n.º 1
0
/** @author Trey Roby */
public class ImagePlotCreator {

  private static final Logger.LoggerImpl _log = Logger.getLogger();
  private static final String OBS_DATE = "Obs date";
  private static final String MID_OBS = "Mid obs";

  static ImagePlotInfo[] makeAllNoBand(
      String workingCtxStr, PlotState stateAry[], FileReadInfo[] readAry, ZoomChoice zoomChoice)
      throws FailedRequestException, FitsException, GeomException, IOException {
    // never use this method with three color plots

    ImagePlotInfo piAry[] = new ImagePlotInfo[readAry.length];
    FileReadInfo readInfo;
    Map<Band, WebFitsData> wfDataMap = new LinkedHashMap<Band, WebFitsData>(5);
    for (int i = 0; (i < readAry.length); i++) {
      readInfo = readAry[i];
      WebPlotRequest req = stateAry[i].getPrimaryWebPlotRequest();
      if (readAry.length > 3) {
        PlotServUtils.updateProgress(
            req,
            ProgressStat.PType.CREATING,
            PlotServUtils.CREATING_MSG + ": " + (i + 1) + " of " + readAry.length);
      } else {
        PlotServUtils.updateProgress(req, ProgressStat.PType.CREATING, PlotServUtils.CREATING_MSG);
      }
      ActiveFitsReadGroup frGroup = new ActiveFitsReadGroup();
      frGroup.setFitsRead(readInfo.getBand(), readInfo.getFitsRead());
      ImagePlot plot =
          createImagePlot(
              stateAry[i],
              frGroup,
              readInfo.getBand(),
              readInfo.getDataDesc(),
              zoomChoice,
              readAry.length > 1);
      WebFitsData wfData =
          makeWebFitsData(plot, frGroup, readInfo.getBand(), readInfo.getOriginalFile());
      wfDataMap.put(Band.NO_BAND, wfData);
      Map<Band, ModFileWriter> fileWriterMap = new LinkedHashMap<Band, ModFileWriter>(1);
      if (readInfo.getModFileWriter() != null)
        fileWriterMap.put(Band.NO_BAND, readInfo.getModFileWriter());
      piAry[i] =
          new ImagePlotInfo(
              stateAry[i], plot, frGroup, readInfo.getDataDesc(), wfDataMap, fileWriterMap);
      VisContext.shouldContinue(workingCtxStr);
    }

    return piAry;
  }

  static ImagePlotInfo makeOneImagePerBand(
      String workingCtxStr,
      PlotState state,
      Map<Band, FileReadInfo[]> readInfoMap,
      ZoomChoice zoomChoice)
      throws FailedRequestException, FitsException, GeomException, IOException {

    ImagePlotInfo retval;
    ImagePlot plot = null;
    boolean first = true;
    Map<Band, WebFitsData> wfDataMap = new LinkedHashMap<Band, WebFitsData>(5);
    Map<Band, ModFileWriter> fileWriterMap = new LinkedHashMap<Band, ModFileWriter>(5);
    ActiveFitsReadGroup frGroup = new ActiveFitsReadGroup();
    for (Map.Entry<Band, FileReadInfo[]> entry : readInfoMap.entrySet()) {
      Band band = entry.getKey();
      FileReadInfo readInfoAry[] = entry.getValue();
      FileReadInfo readInfo = readInfoAry[state.getImageIdx(band)];
      frGroup.setFitsRead(band, readInfo.getFitsRead());
      if (first) {
        plot =
            createImagePlot(
                state, frGroup, readInfo.getBand(), readInfo.getDataDesc(), zoomChoice, false);
        if (state.isThreeColor()) {
          plot.setThreeColorBand(
              state.isBandVisible(readInfo.getBand()) ? readInfo.getFitsRead() : null,
              readInfo.getBand(),
              frGroup);
        }
        if (readInfo.getModFileWriter() != null) {
          fileWriterMap.put(band, readInfo.getModFileWriter());
        }
        first = false;
      } else {
        ModFileWriter mfw = createBand(state, plot, readInfo, frGroup);
        if (mfw != null) {
          fileWriterMap.put(band, mfw);
        } else if (readInfo.getModFileWriter() != null) {
          fileWriterMap.put(band, readInfo.getModFileWriter());
        }
      }
      WebFitsData wfData =
          makeWebFitsData(plot, frGroup, readInfo.getBand(), readInfo.getOriginalFile());
      wfDataMap.put(band, wfData);
      VisContext.shouldContinue(workingCtxStr);
    }
    String desc = make3ColorDataDesc(readInfoMap);
    retval = new ImagePlotInfo(state, plot, frGroup, desc, wfDataMap, fileWriterMap);

    if (first)
      _log.error("something is wrong, plot not setup correctly - no color bands specified");
    return retval;
  }

  /**
   * Create the ImagePlot. If this is the first time the plot has been created the compute the
   * appropriate zoom, otherwise using the zoom level in the PlotState object. Using the FitsRead in
   * the PlotData object. Record the zoom level in the PlotData object.
   *
   * @param state plot state
   * @param frGroup fits read group
   * @param plotDesc plot description
   * @return the image plot object
   * @throws nom.tam.fits.FitsException if creating plot fails
   */
  static ImagePlot createImagePlot(
      PlotState state,
      ActiveFitsReadGroup frGroup,
      Band band,
      String plotDesc,
      ZoomChoice zoomChoice,
      boolean isMultiImage)
      throws FitsException {

    RangeValues rv = state.getPrimaryRangeValues();
    if (rv == null) {
      rv = FitsRead.getDefaultFutureStretch();
      state.setRangeValues(rv, state.firstBand());
    }

    float zoomLevel = zoomChoice.getZoomLevel();

    ImagePlot plot =
        PlotServUtils.makeImagePlot(
            frGroup, zoomLevel, state.isThreeColor(), band, state.getColorTableId(), rv);

    if (state.isNewPlot()) { // new plot requires computing the zoom level

      zoomLevel = computeZoomLevel(plot, zoomChoice);
      plot.getPlotGroup().setZoomTo(zoomLevel);
      state.setZoomLevel(zoomLevel);
    }

    state.setZoomLevel(zoomLevel);
    initPlotTitle(state, plot, frGroup, plotDesc, isMultiImage);
    return plot;
  }

  public static ModFileWriter createBand(
      PlotState state, ImagePlot plot, FileReadInfo readInfo, ActiveFitsReadGroup frGroup)
      throws FitsException, IOException, GeomException {
    ModFileWriter retval = null;
    Band band = readInfo.getBand();

    plot.setThreeColorBand(
        state.isBandVisible(readInfo.getBand()) ? readInfo.getFitsRead() : null,
        readInfo.getBand(),
        frGroup);
    HistogramOps histOps = plot.getHistogramOps(band, frGroup);
    FitsRead tmpFR = histOps.getFitsRead();
    if (tmpFR != readInfo.getFitsRead()
        && readInfo.getWorkingFile()
            != null) { // testing to see it the fits read got geomed when the band was added
      state.setImageIdx(0, band);
      retval =
          new ModFileWriter.GeomFileWriter(
              readInfo.getWorkingFile(), 0, tmpFR, readInfo.getBand(), false);
      FitsCacher.addFitsReadToCache(retval.getTargetFile(), new FitsRead[] {tmpFR});
    }

    RangeValues rv = state.getRangeValues(readInfo.getBand());
    if (rv == null) {
      rv = FitsRead.getDefaultFutureStretch();
      state.setRangeValues(rv, readInfo.getBand());
    }
    histOps.recomputeStretch(rv, true);
    return retval;
  }

  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;
    }
  }

  //    private static String getServiceDateDesc(WebPlotRequest.ServiceType sType, FitsRead fr) {
  //        String preFix;
  //        String header= "none";
  //        preFix= OBS_DATE;
  //        switch (sType) {
  //            case TWOMASS:
  //                header= "ORDATE";
  //                break;
  //            case DSS:
  //                header= "DATE-OBS";
  //                break;
  //            case WISE:
  //                preFix= MID_OBS;
  //                header= "MIDOBS";
  //                break;
  //            case SDSS:
  //                header= "DATE-OBS";
  //                break;
  //            case IRIS:
  //                header= "DATEIRIS";
  //                break;
  //        }
  //        return preFix + ": " + PlotServUtils.getDateValueFromServiceFits(header, fr);
  //    }

  //    private static String getDateValue(String addDateTitleStr, FitsRead fr) {
  //        String retval = "";
  //        if (addDateTitleStr!=null && addDateTitleStr.contains(";")) {
  //            String dateAry[]= addDateTitleStr.split(";");
  //            retval = dateAry[1] + ": " + PlotServUtils.getDateValueFromServiceFits(dateAry[0],
  // fr);
  //        }
  //        return retval;
  //    }

  private static String make3ColorDataDesc(Map<Band, FileReadInfo[]> readInfoMap) {

    StringBuffer desc = new StringBuffer(100);
    desc.append("3 Color: ");
    for (Map.Entry<Band, FileReadInfo[]> entry : readInfoMap.entrySet()) {
      desc.append(readInfoMap.get(entry.getKey())[0].getDataDesc());
    }
    return desc.toString();
  }

  static float computeZoomLevel(ImagePlot plot, ZoomChoice zoomChoice) {
    int width = plot.getImageDataWidth();
    int height = plot.getImageDataHeight();
    float retval = zoomChoice.getZoomLevel();
    if (zoomChoice.isSmartZoom()) {
      retval = computeSmartZoom(width, height, zoomChoice.getZoomType());
    } else if (zoomChoice.getZoomType() == ZoomType.TO_WIDTH) {
      retval = (float) zoomChoice.getWidth() / (float) width;
      if (zoomChoice.hasMaxZoomLevel()) {
        if (retval > zoomChoice.getMaxZoomLevel()) retval = zoomChoice.getMaxZoomLevel();
      }
    } else if (zoomChoice.getZoomType() == ZoomType.FULL_SCREEN) {
      retval =
          VisUtil.getEstimatedFullZoomFactor(
              VisUtil.FullType.WIDTH_HEIGHT,
              width,
              height,
              zoomChoice.getWidth(),
              zoomChoice.getHeight());
      if (zoomChoice.hasMaxZoomLevel()) {
        if (retval > zoomChoice.getMaxZoomLevel()) retval = zoomChoice.getMaxZoomLevel();
      }
    } else if (zoomChoice.getZoomType() == ZoomType.ARCSEC_PER_SCREEN_PIX) {
      retval = (float) plot.getPixelScale() / zoomChoice.getArcsecPerScreenPix();
    }
    return retval;
  }

  static float computeSmartZoom(int width, int height, ZoomType zoomType) {
    float zoomLevel;
    if (width > 6200 || height > 6200) zoomLevel = 1F / 32F;
    else if (width > 2800 || height > 2800) zoomLevel = 1F / 16F;
    else if (width > 2000 || height > 2000) zoomLevel = 1F / 8F;
    else if (width > 1200 || height > 1200) zoomLevel = 1F / 4F;
    else if (width > 500 || height > 500) zoomLevel = 1F / 2F;
    else if (width < 100 && height < 100) zoomLevel = 4F;
    else if (width < 30 && height < 30) zoomLevel = 4F;
    else zoomLevel = 1;

    return zoomLevel;
  }

  public static WebFitsData makeWebFitsData(
      ImagePlot plot, ActiveFitsReadGroup frGroup, Band band, File f) {
    long fileLength = (f != null && f.canRead()) ? f.length() : 0;
    HistogramOps ops = plot.getHistogramOps(band, frGroup);
    return new WebFitsData(
        ops.getDataMin(), ops.getDataMax(), fileLength, plot.getFluxUnits(band, frGroup));
  }
}
Ejemplo n.º 2
0
/** @author tatianag */
@SearchProcessorImpl(
    id = "LSSTCatalogQuery",
    params = {
      @ParamDoc(name = "RequestedDataSet", desc = "catalog table to query"),
      @ParamDoc(name = "UserTargetWorldPt", desc = "the target point, a serialized WorldPt object"),
      @ParamDoc(name = "radius", desc = "radius in degrees for cone search"),
      @ParamDoc(name = "size", desc = "size in degrees for box search"),
      @ParamDoc(
          name = CatalogRequest.SELECTED_COLUMNS,
          desc = "a comma separated list of columns to return, empty gives the default list"),
      @ParamDoc(
          name = CatalogRequest.CONSTRAINTS,
          desc = "a where fragment of the column constrains")
    })
public class QueryLSSTCatalog extends IpacTablePartProcessor {
  private static final Logger.LoggerImpl _log = Logger.getLogger();

  private static String QSERV_URI = AppProperties.getProperty("lsst.qserv.uri");
  private static String QSERV_USER = AppProperties.getProperty("lsst.qserv.user");
  private static String QSERV_PASS = AppProperties.getProperty("lsst.qserv.pass");

  private static final String RA_COL = "ra";
  private static final String DEC_COL = "decl";

  @Override
  protected File loadDataFile(TableServerRequest request) throws IOException, DataAccessException {

    File file = createFile(request);

    WorldPt pt = request.getWorldPtParam(ServerParams.USER_TARGET_WORLD_PT);
    pt = VisUtil.convertToJ2000(pt);
    doGetData(file, request.getParams(), pt);
    return file;
  }

  // qserv_areaspec_circle does not work at the moment, only qserv_areaspec_box works
  void doGetData(File oFile, List<Param> params, WorldPt wpt) throws DataAccessException {
    DbInstance dbinstance =
        new DbInstance(
            false, // pooled
            "null", // datasourcePath
            QSERV_URI, // dbUrl
            QSERV_USER,
            StringUtils.isEmpty(QSERV_PASS) ? null : QSERV_PASS,
            "com.mysql.jdbc.Driver",
            "lsstdb");
    DataSource ds = JdbcFactory.getDataSource(dbinstance);

    String searchMethod = null;
    String catTable = null;
    String selectedColumns = null;
    String[] constraints = null;
    for (Param p : params) {
      String pname = p.getName();
      if (pname.equals(CatalogRequest.SEARCH_METHOD)) {
        searchMethod = p.getValue();
      } else if (pname.equals(ServerParams.REQUESTED_DATA_SET)) {
        catTable = p.getValue();
      } else if (pname.equals(CatalogRequest.SELECTED_COLUMNS)) {
        selectedColumns = p.getValue();
      } else if (pname.equals(CatalogRequest.CONSTRAINTS)) {
        String val = p.getValue();
        if (!StringUtils.isEmpty(val)) {
          _log.briefDebug("CONSTRAINTS: " + val);
          constraints = val.split(",");
        }
      }
    }

    String update = getSelectedColumnsUpdate(selectedColumns);
    if (update != null) selectedColumns = update;

    String pname;
    String sql;
    if (searchMethod != null && searchMethod.equals(CatalogRequest.Method.CONE.getDesc())) {
      double radius = 0.0;
      for (Param p : params) {
        pname = p.getName();
        if (pname.equals(CatalogRequest.RADIUS)) {
          radius = Double.parseDouble(p.getValue());
        }
      }
      // qserv_areaspec_circle(ra, dec, radius)
      // sql="select * from "+catTable+" where qserv_areaspec_circle("+wpt.getLon()+",
      // "+wpt.getLat()+", "+radius+")";
      // Per Serge, the above query only can not be applied to unpartitioned table
      sql =
          "select "
              + selectedColumns
              + " from "
              + catTable
              + " where scisql_s2PtInCircle(ra, decl, "
              + wpt.getLon()
              + ", "
              + wpt.getLat()
              + ", "
              + radius
              + ")=1";
    } else if (searchMethod != null && searchMethod.equals(CatalogRequest.Method.BOX.getDesc())) {
      double size = 0.0;
      for (Param p : params) {
        pname = p.getName();
        if (pname.equals(CatalogRequest.SIZE)) {
          size = Double.parseDouble(p.getValue());
        }
      }
      double halfsize = size / 2.0;
      double lon1 = wpt.getLon() - halfsize;
      if (lon1 < 0) lon1 += 360;
      double lon2 = wpt.getLon() + halfsize;
      if (lon2 > 360) lon1 -= 360;
      double lat1 = wpt.getLat() - halfsize;
      if (lat1 < -90) lat1 = -180 - lat1;
      double lat2 = wpt.getLat() + halfsize;
      if (lat2 > 90) lat2 = 180 - lat2;

      // qserv_areaspec_box(raA, decA, raB, decB)
      // sql="select * from "+catTable+" where qserv_areaspec_box("+lon1+", "+lat1+", "+lon2+",
      // "+lat2+")";
      // Per Serge, the above query only can not be applied to unpartitioned table
      sql =
          "select * from "
              + catTable
              + " where scisql_s2PtInBox(ra, decl, "
              + lon1
              + ", "
              + lat1
              + ", "
              + lon2
              + ", "
              + lat2
              + ")=1";

    } else {
      throw new RuntimeException(searchMethod + " search is not Implemented");
    }

    // add additional constraints
    if (constraints != null) {
      for (String constr : constraints) {
        sql += " and " + constr;
      }
    }

    // workaround for https://jira.lsstcorp.org/browse/DM-1841
    sql += " LIMIT 3000";

    Connection conn = null;
    Statement stmt = null;
    try {
      conn = DataSourceUtils.getConnection(ds);
      long cTime = System.currentTimeMillis();
      stmt = conn.createStatement();
      _log.briefDebug("Executing SQL query: " + sql);
      // ResultSet rs = stmt.executeQuery(sql);
      IpacTableExtractor.query(null, ds, oFile, 10000, sql);
      _log.briefDebug("SELECT took " + (System.currentTimeMillis() - cTime) + "ms");
    } catch (Exception e) {
      _log.error(e);
      throw new DataAccessException("Query failed: " + e.getMessage());
    } finally {
      if (stmt != null) {
        try {
          closeStatement(stmt);
        } catch (Exception e1) {
        }
      }
      if (conn != null) {
        DataSourceUtils.releaseConnection(conn, ds);
      }
    }
  }

  @Override
  public void prepareTableMeta(TableMeta meta, List<DataType> columns, ServerRequest request) {
    super.prepareTableMeta(meta, columns, request);

    TableMeta.LonLatColumns llc = new TableMeta.LonLatColumns(RA_COL, DEC_COL); // J2000 default
    meta.setLonLatColumnAttr(MetaConst.CATALOG_COORD_COLS, llc);
    meta.setCenterCoordColumns(llc);

    String title = request.getParam(ServerParams.REQUESTED_DATA_SET);
    title = (title == null) ? "LSST" : "LSST " + title;
    meta.setAttribute(MetaConst.CATALOG_OVERLAY_TYPE, title);
    meta.setAttribute(MetaConst.DATA_PRIMARY, "False");

    setColumnTips(meta, request);
  }

  private static String getSelectedColumnsUpdate(String selectedColumns) {
    String update = null;
    if (StringUtils.isEmpty(selectedColumns)) {
      return "*";
    } else {
      boolean hasRa = false, hasDec = false;
      String[] cols = selectedColumns.split(",");
      for (String col : cols) {
        if (col.equalsIgnoreCase(RA_COL)) {
          hasRa = true;
          if (hasDec) break;
        } else if (col.equalsIgnoreCase(DEC_COL)) {
          hasDec = true;
          if (hasRa) break;
        }
      }
      if (!hasRa) {
        update = selectedColumns + ",ra";
      }
      if (!hasDec) {
        update = (update == null ? selectedColumns : update) + ",decl";
      }
      return update;
    }
  }

  static void closeStatement(Statement stmt) {
    if (stmt != null) {
      try {
        stmt.close();
      } catch (Throwable th) {
        // log and ignore
        _log.warn(th, "Failed to close statement: " + th.getMessage());
      }
    }
  }

  protected void setColumnTips(TableMeta meta, ServerRequest request) {

    TableServerRequest req = new TableServerRequest("LSSTCatalogDD");
    req.setPageSize(1000);
    req.setParam(CatalogRequest.CATALOG, request.getParam(ServerParams.REQUESTED_DATA_SET));

    SearchManager sm = new SearchManager();
    DataGroupPart dgp = new DataGroupPart();

    try {
      dgp = sm.getDataGroup(req);
    } catch (Exception e) {
    }

    DataGroup dg = dgp.getData();
    if (dg != null) {
      for (int i = 0; i < dg.size(); i++) {
        DataObject dObj = dg.get(i);
        String tipStr = "";

        String descStr = (String) dObj.getDataElement("description");
        if (!StringUtils.isEmpty(descStr) && !descStr.equalsIgnoreCase("null")) {
          tipStr += descStr;
        }

        String unitStr = (String) dObj.getDataElement("unit");
        if (!StringUtils.isEmpty(unitStr) && !unitStr.equalsIgnoreCase("null")) {
          if (tipStr.length() > 0) {
            tipStr += " ";
          }
          tipStr += "(" + unitStr + ")";
        }

        String nameStr = (String) dObj.getDataElement("name");
        meta.setAttribute(makeAttribKey(DESC_TAG, nameStr.toLowerCase()), tipStr);
      }
    }
  }

  public static void main(String[] args) {
    DbInstance dbinstance =
        new DbInstance(
            false, // pooled
            "null", // datasourcePath
            "<REPLACE_WITH_DB_URL>", // dbUrl
            "qsmaster",
            null,
            "com.mysql.jdbc.Driver",
            "lsstdb");
    DataSource ds = JdbcFactory.getDataSource(dbinstance);

    String sql = "select * from DeepSource where qserv_areaspec_box(0.4, 1.05, 0.5, 1.15)";

    Connection conn = null;
    try {
      conn = DataSourceUtils.getConnection(ds);
      long cTime = System.currentTimeMillis();

      Statement stmt = null;
      try {
        stmt = conn.createStatement();
        _log.briefDebug("Executing SQL query: " + sql);
        // ResultSet rs = stmt.executeQuery(sql);
        // _log.briefDebug ("SELECT took "+(System.currentTimeMillis()-cTime)+"ms");
        File file = new File("/tmp/lsstTest.tbl");
        IpacTableExtractor.query(null, ds, file, 10000, sql);
        _log.briefDebug("SELECT took " + (System.currentTimeMillis() - cTime) + "ms");
      } catch (Exception e) {
        System.out.println("Exception " + e.getMessage());
      } finally {
        closeStatement(stmt);
      }

    } catch (Exception e) {
      System.out.println("Exception " + e.getMessage());
      e.printStackTrace();
    } finally {
      if (conn != null) {
        DataSourceUtils.releaseConnection(conn, ds);
      }
    }
  }
}