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 }