001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 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 029package edu.wisc.ssec.mcidasv.data.hydra; 030 031import visad.FlatField; 032import visad.SampledSet; 033import visad.RealTuple; 034import visad.SetType; 035import visad.RealType; 036import visad.RealTupleType; 037import visad.VisADException; 038import visad.CoordinateSystem; 039import visad.FunctionType; 040import visad.Real; 041import visad.Set; 042import visad.Linear1DSet; 043import visad.Linear2DSet; 044import visad.Gridded1DSet; 045import visad.Gridded2DSet; 046import visad.QuickSort; 047import java.rmi.RemoteException; 048import java.util.HashMap; 049import java.util.ArrayList; 050import java.awt.geom.Rectangle2D; 051import java.util.Map; 052 053import visad.georef.MapProjection; 054import visad.CachingCoordinateSystem; 055import ucar.visad.ProjectionCoordinateSystem; 056 057public class MultiSpectralAggr extends MultiSpectralData { 058 059 Gridded1DSet aggrDomain = null; 060 061 MultiSpectralData[] adapters = null; 062 063 int[] sort_indexes = null; 064 065 float[] aggrValues = null; 066 067 float[] aggrSamples = null; 068 069 int numAdapters; 070 071 int numBands; 072 073 int[] offset; 074 075 public MultiSpectralAggr(MultiSpectralData[] adapters) 076 throws Exception { 077 super(adapters[0].swathAdapter, null); 078 this.adapters = adapters; 079 paramName = adapters[0].getParameter(); 080 081 numAdapters = adapters.length; 082 int[] numBandsAdapter = new int[numAdapters]; 083 offset = new int[numAdapters]; 084 SampledSet[] spectrumDomains = new SampledSet[numAdapters]; 085 086 if (adapters[0].spectrumAdapter.hasBandNames()) { 087 hasBandNames = true; 088 bandNameList = new ArrayList<>(); 089 bandNameMap = new HashMap<>(); 090 for (int k=0; k<numAdapters; k++) { 091 bandNameList.addAll(adapters[k].spectrumAdapter.getBandNames()); 092 bandNameMap.putAll(adapters[k].spectrumAdapter.getBandNameMap()); 093 } 094 } 095 096 numBands = 0; 097 for (int k=0; k<numAdapters; k++) { 098 SampledSet set = adapters[k].spectrumAdapter.getDomainSet(); 099 spectrumDomains[k] = set; 100 numBandsAdapter[k] = set.getLength(); 101 offset[k] = numBands; 102 numBands += numBandsAdapter[k]; 103 } 104 105 aggrSamples = new float[numBands]; 106 aggrValues = new float[numBands]; 107 108 for (int k=0; k<numAdapters; k++) { 109 float[][] samples = spectrumDomains[k].getSamples(false); 110 System.arraycopy(samples[0], 0, aggrSamples, offset[k], samples[0].length); 111 } 112 113 sort_indexes = QuickSort.sort(aggrSamples); 114 SpectrumAdapter specAdapt = adapters[0].spectrumAdapter; 115 aggrDomain = new Gridded1DSet(specAdapt.getDomainSet().getType(), 116 new float[][] {aggrSamples}, aggrSamples.length); 117 118 init_wavenumber = getWavenumberFromChannelIndex(0); 119 } 120 121 public FlatField getSpectrum(int[] coords) throws Exception { 122 FlatField spectrum = null; 123 for (int k=0; k<numAdapters; k++) { 124 spectrum = adapters[k].getSpectrum(coords); 125 if (spectrum == null) { 126 return null; 127 } 128 float[][] values = spectrum.getFloats(false); 129 System.arraycopy(values[0], 0, aggrValues, offset[k], values[0].length); 130 } 131 132 for (int t=0; t<numBands; t++) { 133 aggrValues[t] = aggrValues[sort_indexes[t]]; 134 } 135 136 spectrum = new FlatField((FunctionType)spectrum.getType(), aggrDomain); 137 spectrum.setSamples(new float[][] {aggrValues}); 138 139 return spectrum; 140 } 141 142 public FlatField getSpectrum(RealTuple location) throws Exception { 143 FlatField spectrum = null; 144 for (int k=0; k<numAdapters; k++) { 145 spectrum = adapters[k].getSpectrum(location); 146 if (spectrum == null) { 147 return null; 148 } 149 float[][] values = spectrum.getFloats(false); 150 System.arraycopy(values[0], 0, aggrValues, offset[k], values[0].length); 151 } 152 153 for (int t=0; t<numBands; t++) { 154 aggrValues[t] = aggrValues[sort_indexes[t]]; 155 } 156 157 spectrum = new FlatField((FunctionType)spectrum.getType(), aggrDomain); 158 spectrum.setSamples(new float[][] {aggrValues}); 159 160 return spectrum; 161 } 162 163 public FlatField getImage(Map<String, double[]> subset) throws Exception { 164 int channelIndex = (int) ((double[])subset.get(SpectrumAdapter.channelIndex_name))[0]; 165 166 int idx = sort_indexes[channelIndex]; 167 168 int swathAdapterIndex = numAdapters-1; 169 for (int k=0; k<numAdapters-1;k++) { 170 if (idx >= offset[k] && idx < offset[k+1]) swathAdapterIndex = k; 171 } 172 float channel = aggrSamples[channelIndex]; 173 FlatField image = adapters[swathAdapterIndex].getImage(channel, subset); 174 cs = ((RealTupleType) ((FunctionType)image.getType()).getDomain()).getCoordinateSystem(); 175 for (int k=0; k<numAdapters;k++) { 176 if (k != swathAdapterIndex) adapters[k].setCoordinateSystem(cs); 177 } 178 return image; 179 } 180 181 public FlatField getImage(float channel, Map<String, double[]> subset) throws Exception { 182 int channelIndex = aggrDomain.valueToIndex(new float[][] {{channel}})[0]; 183 184 int idx = sort_indexes[channelIndex]; 185 186 int swathAdapterIndex = numAdapters-1; 187 for (int k=0; k<numAdapters-1;k++) { 188 if (idx >= offset[k] && idx < offset[k+1]) swathAdapterIndex = k; 189 } 190 channel = aggrSamples[channelIndex]; 191 FlatField image = adapters[swathAdapterIndex].getImage(channel, subset); 192 cs = ((RealTupleType) ((FunctionType)image.getType()).getDomain()).getCoordinateSystem(); 193 for (int k=0; k<numAdapters;k++) { 194 if (k != swathAdapterIndex) adapters[k].setCoordinateSystem(cs); 195 } 196 return image; 197 } 198 199 public int getChannelIndexFromWavenumber(float channel) throws VisADException, RemoteException { 200 int idx = (aggrDomain.valueToIndex(new float[][] {{channel}}))[0]; 201 return idx; 202 } 203 204 public float getWavenumberFromChannelIndex(int index) throws Exception { 205 return (aggrDomain.indexToValue(new int[] {index}))[0][0]; 206 } 207 208 public Map<String, double[]> getDefaultSubset() { 209 Map<String, double[]> subset = adapters[0].getDefaultSubset(); 210 double chanIdx = 0; 211 try { 212 chanIdx = getChannelIndexFromWavenumber(init_wavenumber); 213 } 214 catch (Exception e) { 215 System.out.println("couldn't get chanIdx, using zero"); 216 } 217 subset.put(SpectrumAdapter.channelIndex_name, new double[] {chanIdx, chanIdx, 1}); 218 return subset; 219 } 220 221}