/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.beam.smos.visat; import org.esa.beam.dataio.smos.L1cScienceSmosFile; import org.esa.beam.dataio.smos.L1cSmosFile; import org.esa.beam.dataio.smos.SmosConstants; import org.esa.beam.framework.ui.product.ProductSceneView; import org.esa.beam.smos.SmosUtils; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.DeviationRenderer; import org.jfree.data.xy.YIntervalSeries; import org.jfree.data.xy.YIntervalSeriesCollection; import org.jfree.ui.RectangleInsets; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; public class GridPointBtDataChartToolView extends GridPointBtDataToolView { public static final String ID = GridPointBtDataChartToolView.class.getName(); private JFreeChart chart; private YIntervalSeriesCollection coPolDataset; private YIntervalSeriesCollection crossPolDataset; private XYPlot plot; private JCheckBox[] modeCheckers; @Override protected JComponent createGridPointComponent() { coPolDataset = new YIntervalSeriesCollection(); crossPolDataset = new YIntervalSeriesCollection(); chart = ChartFactory.createXYLineChart(null, null, null, coPolDataset, PlotOrientation.VERTICAL, true, // Legend? true, false); plot = chart.getXYPlot(); plot.setNoDataMessage("No data"); plot.setAxisOffset(new RectangleInsets(5, 5, 5, 5)); final NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setLabel("Incidence Angle (deg)"); xAxis.setRange(0, 70); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); final NumberAxis yAxis = (NumberAxis) plot.getRangeAxis(); yAxis.setLabel("Co-Pol BT(K)"); yAxis.setRange(50, 350); final NumberAxis yAxis2 = new NumberAxis("Cross-Pol BT(K)"); yAxis2.setRange(-25, 25); plot.setRangeAxis(1, yAxis2); plot.setDataset(1, crossPolDataset); plot.mapDatasetToRangeAxis(1, 1); DeviationRenderer coPolRenderer = new DeviationRenderer(true, false); coPolRenderer.setSeriesFillPaint(0, new Color(255, 127, 127)); coPolRenderer.setSeriesFillPaint(1, new Color(127, 127, 255)); DeviationRenderer crossPolRenderer = new DeviationRenderer(true, false); crossPolRenderer.setSeriesFillPaint(0, new Color(127, 255, 127)); crossPolRenderer.setSeriesFillPaint(1, new Color(255, 255, 127)); plot.setRenderer(0, coPolRenderer); plot.setRenderer(1, crossPolRenderer); return new ChartPanel(chart); } @Override protected void updateClientComponent(ProductSceneView smosView) { L1cSmosFile l1cSmosFile = getL1cSmosFile(); if (l1cSmosFile != null && l1cSmosFile instanceof L1cScienceSmosFile) { final L1cScienceSmosFile smosFile = (L1cScienceSmosFile) l1cSmosFile; modeCheckers[0].setEnabled(true); modeCheckers[1].setEnabled(true); modeCheckers[2].setEnabled(SmosUtils.isFullPolScienceFormat(smosFile.getDataFormat().getName())); } } @Override protected JComponent createGridPointComponentOptionsComponent() { modeCheckers = new JCheckBox[]{ new JCheckBox("X", true), new JCheckBox("Y", true), new JCheckBox("XY", true), }; final JPanel optionsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 2, 2)); for (JCheckBox modeChecker : modeCheckers) { modeChecker.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateGridPointBtDataComponent(); } }); optionsPanel.add(modeChecker); } return optionsPanel; } @Override protected void updateGridPointBtDataComponent(GridPointBtDataset ds) { coPolDataset.removeAllSeries(); crossPolDataset.removeAllSeries(); int ix = ds.getColumnIndex("Incidence_Angle"); int iq = ds.getColumnIndex("Flags"); int id = ds.getColumnIndex("Pixel_Radiometric_Accuracy"); // todo: calculate and display H/V/HV BT values instead of X/Y/XY (rq-200100121) if (ix != -1 && iq != -1 && id != -1) { int iy1 = ds.getColumnIndex("BT_Value"); if (iy1 != -1) { YIntervalSeries series1 = new YIntervalSeries("X"); YIntervalSeries series2 = new YIntervalSeries("Y"); boolean m1 = modeCheckers[0].isSelected(); boolean m2 = modeCheckers[1].isSelected(); final Number[][] data = ds.getData(); for (final Number[] dataList : data) { int polMode = dataList[iq].intValue() & SmosConstants.L1C_POL_MODE_FLAGS_MASK; double x = dataList[ix].doubleValue(); double y = dataList[iy1].doubleValue(); double dev = dataList[id].doubleValue(); if (m1 && polMode == SmosConstants.L1C_POL_MODE_X) { series1.add(x, y, y - dev, y + dev); } else if (m2 && polMode == SmosConstants.L1C_POL_MODE_Y) { series2.add(x, y, y - dev, y + dev); } } coPolDataset.addSeries(series1); coPolDataset.addSeries(series2); } else { int iy2; iy1 = ds.getColumnIndex("BT_Value_Real"); iy2 = ds.getColumnIndex("BT_Value_Imag"); if (iy1 != -1 && iy2 != -1) { YIntervalSeries series1 = new YIntervalSeries("X"); YIntervalSeries series2 = new YIntervalSeries("Y"); YIntervalSeries series3 = new YIntervalSeries("XY_Real"); YIntervalSeries series4 = new YIntervalSeries("XY_Imag"); boolean m1 = modeCheckers[0].isSelected(); boolean m2 = modeCheckers[1].isSelected(); boolean m3 = modeCheckers[2].isSelected(); final Number[][] data = ds.getData(); for (final Number[] dataList : data) { int polMode = dataList[iq].intValue() & SmosConstants.L1C_POL_MODE_FLAGS_MASK; double dev = dataList[id].doubleValue(); double x = dataList[ix].doubleValue(); double y1 = dataList[iy1].doubleValue(); if (m1 && polMode == SmosConstants.L1C_POL_MODE_X) { series1.add(x, y1, y1 - dev, y1 + dev); } else if (m2 && polMode == SmosConstants.L1C_POL_MODE_Y) { series2.add(x, y1, y1 - dev, y1 + dev); } else if (m3 && (polMode == SmosConstants.L1C_POL_MODE_XY1 || polMode == SmosConstants.L1C_POL_MODE_XY2)) { double y2 = dataList[iy2].doubleValue(); series3.add(x, y1, y1 - dev, y1 + dev); series4.add(x, y2, y2 - dev, y2 + dev); } } coPolDataset.addSeries(series1); coPolDataset.addSeries(series2); crossPolDataset.addSeries(series3); crossPolDataset.addSeries(series4); } } } else { plot.setNoDataMessage("Not a SMOS D1C/F1C pixel."); } chart.fireChartChanged(); } @Override protected void updateGridPointBtDataComponent(IOException e) { coPolDataset.removeAllSeries(); crossPolDataset.removeAllSeries(); plot.setNoDataMessage("I/O error"); } @Override protected void clearGridPointBtDataComponent() { coPolDataset.removeAllSeries(); crossPolDataset.removeAllSeries(); plot.setNoDataMessage("No data"); } }