001/*
002 * $Id: MultiSpectralAggr.java,v 1.11 2011/03/24 16:06:33 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2011
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
031package edu.wisc.ssec.mcidasv.data.hydra;
032
033import visad.FlatField;
034import visad.SampledSet;
035import visad.RealTuple;
036import visad.SetType;
037import visad.RealType;
038import visad.RealTupleType;
039import visad.VisADException;
040import visad.CoordinateSystem;
041import visad.FunctionType;
042import visad.Real;
043import visad.Set;
044import visad.Linear1DSet;
045import visad.Linear2DSet;
046import visad.Gridded1DSet;
047import visad.Gridded2DSet;
048import visad.QuickSort;
049import java.rmi.RemoteException;
050import java.util.HashMap;
051import java.util.ArrayList;
052import java.awt.geom.Rectangle2D;
053
054import visad.georef.MapProjection;
055import visad.CachingCoordinateSystem;
056import ucar.visad.ProjectionCoordinateSystem;
057
058public 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}