/** @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)); } }
/** @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); } } } }