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