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    }