001 /*
002 * $Id: MultiSpectralAggr.java,v 1.12 2012/02/19 17:35:41 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv.data.hydra;
032
033 import visad.FlatField;
034 import visad.SampledSet;
035 import visad.RealTuple;
036 import visad.SetType;
037 import visad.RealType;
038 import visad.RealTupleType;
039 import visad.VisADException;
040 import visad.CoordinateSystem;
041 import visad.FunctionType;
042 import visad.Real;
043 import visad.Set;
044 import visad.Linear1DSet;
045 import visad.Linear2DSet;
046 import visad.Gridded1DSet;
047 import visad.Gridded2DSet;
048 import visad.QuickSort;
049 import java.rmi.RemoteException;
050 import java.util.HashMap;
051 import java.util.ArrayList;
052 import java.awt.geom.Rectangle2D;
053
054 import visad.georef.MapProjection;
055 import visad.CachingCoordinateSystem;
056 import ucar.visad.ProjectionCoordinateSystem;
057
058 public class MultiSpectralAggr extends MultiSpectralData {
059
060 Gridded1DSet aggrDomain = null;
061
062 MultiSpectralData[] adapters = null;
063
064 int[] sort_indexes = null;
065
066 float[] aggrValues = null;
067
068 float[] aggrSamples = null;
069
070 int numAdapters;
071
072 int numBands;
073
074 int[] offset;
075
076 public MultiSpectralAggr(MultiSpectralData[] adapters)
077 throws Exception {
078 super(adapters[0].swathAdapter, null);
079 this.adapters = adapters;
080 paramName = adapters[0].getParameter();
081
082 numAdapters = adapters.length;
083 int[] numBandsAdapter = new int[numAdapters];
084 offset = new int[numAdapters];
085 SampledSet[] spectrumDomains = new SampledSet[numAdapters];
086
087 if (adapters[0].spectrumAdapter.hasBandNames()) {
088 hasBandNames = true;
089 bandNameList = new ArrayList<String>();
090 bandNameMap = new HashMap<String, Float>();
091 for (int k=0; k<numAdapters; k++) {
092 bandNameList.addAll(adapters[k].spectrumAdapter.getBandNames());
093 bandNameMap.putAll(adapters[k].spectrumAdapter.getBandNameMap());
094 }
095 }
096
097 numBands = 0;
098 for (int k=0; k<numAdapters; k++) {
099 SampledSet set = adapters[k].spectrumAdapter.getDomainSet();
100 spectrumDomains[k] = set;
101 numBandsAdapter[k] = set.getLength();
102 offset[k] = numBands;
103 numBands += numBandsAdapter[k];
104 }
105
106 aggrSamples = new float[numBands];
107 aggrValues = new float[numBands];
108
109 for (int k=0; k<numAdapters; k++) {
110 float[][] samples = spectrumDomains[k].getSamples(false);
111 System.arraycopy(samples[0], 0, aggrSamples, offset[k], samples[0].length);
112 }
113
114 sort_indexes = QuickSort.sort(aggrSamples);
115 SpectrumAdapter specAdapt = adapters[0].spectrumAdapter;
116 aggrDomain = new Gridded1DSet(specAdapt.getDomainSet().getType(),
117 new float[][] {aggrSamples}, aggrSamples.length);
118
119 init_wavenumber = getWavenumberFromChannelIndex(0);
120 }
121
122 public FlatField getSpectrum(int[] coords) throws Exception {
123 FlatField spectrum = null;
124 for (int k=0; k<numAdapters; k++) {
125 spectrum = adapters[k].getSpectrum(coords);
126 if (spectrum == null) {
127 return null;
128 }
129 float[][] values = spectrum.getFloats(false);
130 System.arraycopy(values[0], 0, aggrValues, offset[k], values[0].length);
131 }
132
133 for (int t=0; t<numBands; t++) {
134 aggrValues[t] = aggrValues[sort_indexes[t]];
135 }
136
137 spectrum = new FlatField((FunctionType)spectrum.getType(), aggrDomain);
138 spectrum.setSamples(new float[][] {aggrValues});
139
140 return spectrum;
141 }
142
143 public FlatField getSpectrum(RealTuple location) throws Exception {
144 FlatField spectrum = null;
145 for (int k=0; k<numAdapters; k++) {
146 spectrum = adapters[k].getSpectrum(location);
147 if (spectrum == null) {
148 return null;
149 }
150 float[][] values = spectrum.getFloats(false);
151 System.arraycopy(values[0], 0, aggrValues, offset[k], values[0].length);
152 }
153
154 for (int t=0; t<numBands; t++) {
155 aggrValues[t] = aggrValues[sort_indexes[t]];
156 }
157
158 spectrum = new FlatField((FunctionType)spectrum.getType(), aggrDomain);
159 spectrum.setSamples(new float[][] {aggrValues});
160
161 return spectrum;
162 }
163
164 public FlatField getImage(HashMap subset) throws Exception {
165 int channelIndex = (int) ((double[])subset.get(SpectrumAdapter.channelIndex_name))[0];
166
167 int idx = sort_indexes[channelIndex];
168
169 int swathAdapterIndex = numAdapters-1;
170 for (int k=0; k<numAdapters-1;k++) {
171 if (idx >= offset[k] && idx < offset[k+1]) swathAdapterIndex = k;
172 }
173 float channel = aggrSamples[channelIndex];
174 FlatField image = adapters[swathAdapterIndex].getImage(channel, subset);
175 cs = ((RealTupleType) ((FunctionType)image.getType()).getDomain()).getCoordinateSystem();
176 for (int k=0; k<numAdapters;k++) {
177 if (k != swathAdapterIndex) adapters[k].setCoordinateSystem(cs);
178 }
179 return image;
180 }
181
182 public FlatField getImage(float channel, HashMap subset) throws Exception {
183 int channelIndex = aggrDomain.valueToIndex(new float[][] {{channel}})[0];
184
185 int idx = sort_indexes[channelIndex];
186
187 int swathAdapterIndex = numAdapters-1;
188 for (int k=0; k<numAdapters-1;k++) {
189 if (idx >= offset[k] && idx < offset[k+1]) swathAdapterIndex = k;
190 }
191 channel = aggrSamples[channelIndex];
192 FlatField image = adapters[swathAdapterIndex].getImage(channel, subset);
193 cs = ((RealTupleType) ((FunctionType)image.getType()).getDomain()).getCoordinateSystem();
194 for (int k=0; k<numAdapters;k++) {
195 if (k != swathAdapterIndex) adapters[k].setCoordinateSystem(cs);
196 }
197 return image;
198 }
199
200 public int getChannelIndexFromWavenumber(float channel) throws VisADException, RemoteException {
201 int idx = (aggrDomain.valueToIndex(new float[][] {{channel}}))[0];
202 return idx;
203 }
204
205 public float getWavenumberFromChannelIndex(int index) throws Exception {
206 return (aggrDomain.indexToValue(new int[] {index}))[0][0];
207 }
208
209 public HashMap getDefaultSubset() {
210 HashMap subset = adapters[0].getDefaultSubset();
211 double chanIdx = 0;
212 try {
213 chanIdx = getChannelIndexFromWavenumber(init_wavenumber);
214 }
215 catch (Exception e) {
216 System.out.println("couldn't get chanIdx, using zero");
217 }
218 subset.put(SpectrumAdapter.channelIndex_name, new double[] {chanIdx, chanIdx, 1});
219 return subset;
220 }
221
222 }