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 }