001    /*
002     * $Id: MultiDimensionAdapter.java,v 1.19 2012/02/19 17:35:40 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.VisADException;
035    import visad.RealType;
036    import visad.SetType;
037    import visad.FunctionType;
038    import visad.Set;
039    import java.rmi.RemoteException;
040    import java.util.HashMap;
041    import java.util.Iterator;
042    
043    public abstract class MultiDimensionAdapter {
044    
045       MultiDimensionReader reader = null;
046       HashMap metadata = null;
047       String arrayName = null;
048       String[] array_dim_names = null;
049       int[] array_dim_lengths  = null;
050       int array_rank;
051       Class arrayType;
052    
053       HashMap<String, String> dimNameMap = new HashMap<String, String>();
054    
055       RealType rangeType;
056    
057       RangeProcessor rangeProcessor = null;
058    
059       public MultiDimensionAdapter() {
060       }
061    
062       public MultiDimensionAdapter(MultiDimensionReader reader, HashMap metadata) {
063         this.reader = reader;
064         this.metadata = metadata;
065         this.init();
066       }
067    
068       public abstract HashMap getDefaultSubset();
069    
070       public abstract Set makeDomain(Object subset) throws Exception;
071    
072       private void init() {
073         this.arrayName = (String) metadata.get("array_name");
074    
075         String[] suppliedDimNames = (String[]) metadata.get("array_dimension_names");
076         if (suppliedDimNames != null) {
077           array_dim_names = suppliedDimNames;
078         }
079         else {
080           array_dim_names = reader.getDimensionNames(arrayName);
081         }
082    
083         array_dim_lengths = reader.getDimensionLengths(arrayName);
084         array_rank = array_dim_lengths.length;
085         arrayType = reader.getArrayType(arrayName);
086    
087         for (int i=0; i<array_rank; i++) {
088           dimNameMap.put(array_dim_names[i], array_dim_names[i]);
089         }
090    
091         Iterator iter = metadata.keySet().iterator();
092         while (iter.hasNext()) {
093           String key = (String) iter.next();
094           Object val = metadata.get(key);
095           if (!(val instanceof String)) continue;
096           String name = (String) val; 
097           for (int kk=0; kk<array_rank; kk++) {
098             if (array_dim_names[kk].equals(name)) {
099               dimNameMap.put(array_dim_names[kk], key);
100             }
101           }
102         }
103    
104       }
105    
106       public Subset getIndexes(HashMap select) {
107         Subset subset = new Subset(array_rank);
108         int[] start = subset.getStart();
109         int[] count = subset.getCount();
110         int[] stride = subset.getStride();
111    
112         Iterator iter = select.keySet().iterator();
113         while (iter.hasNext()) {
114           String key = (String) iter.next();
115           String name = (String) metadata.get(key);
116    
117           if (name == null) name = key;
118    
119           for (int kk=0; kk<array_rank; kk++) {
120             if (array_dim_names[kk].equals(name)) {
121               double[] coords = (double[]) select.get(key);
122    
123               if (array_dim_lengths[kk] == 1) {
124                 start[kk] = 0;
125                 count[kk] = 1;
126                 stride[kk] = 1;
127               }
128               else {
129                 start[kk] = (int) coords[0];
130                 count[kk] = (int) ((coords[1] - coords[0])/coords[2] + 1f);
131                 stride[kk] = (int) coords[2];
132               }
133    
134             }
135           }
136         }
137         return subset;
138       }
139    
140       public FlatField getData(Object subset) throws Exception {
141         Set domainSet = makeDomain(subset);
142         return makeFlatField(domainSet, subset);
143       }
144    
145       private FlatField makeFlatField(Set domainSet, float[][] range) throws VisADException, RemoteException {
146         FlatField f_field = makeFlatField(domainSet);
147         f_field.setSamples(range, false);
148         return f_field;
149       }
150    
151       private FlatField makeFlatField(Set domainSet, double[][] range) throws VisADException, RemoteException {
152         FlatField f_field = makeFlatField(domainSet);
153         f_field.setSamples(range, false);
154         return f_field;
155       }
156    
157       private FlatField makeFlatField(Set domainSet) throws VisADException, RemoteException {
158         FlatField f_field = new FlatField(new FunctionType(((SetType)domainSet.getType()).getDomain(), rangeType), domainSet);
159         return f_field;
160       }
161    
162       public FlatField makeFlatField(Set domainSet, Object subset) throws Exception {
163         FlatField f_field = null;
164    
165         Object range = readArray(subset);
166    
167         if (range instanceof float[]) {
168           float[] new_range = processRange((float[]) range, subset);
169           f_field = makeFlatField(domainSet, new float[][] {new_range});
170         }
171         else if (range instanceof double[]) {
172           double[] new_range = processRange((double[]) range, subset);
173           f_field = makeFlatField(domainSet, new double[][] {new_range});
174         }
175         else if (range instanceof short[]) {
176           float[] float_range = processRange((short[])range, subset);
177           f_field = makeFlatField(domainSet, new float[][] {float_range});
178         }
179         else if (range instanceof byte[]) {
180           float[] float_range = processRange((byte[])range, subset);
181           f_field = makeFlatField(domainSet, new float[][] {float_range});
182         }
183    
184         return f_field;
185       }
186    
187       public RangeProcessor getRangeProcessor() {
188         return rangeProcessor;
189       }
190    
191       public void setRangeProcessor(RangeProcessor rangeProcessor) {
192         this.rangeProcessor = rangeProcessor;
193       }
194    
195       public float[] processRange(short[] range, Object subset) {
196         if (rangeProcessor == null) {
197           float[] f_range = new float[range.length];
198           for (int i=0; i<range.length;i++) f_range[i] = (float) range[i]; 
199           return f_range;
200         }
201         else { 
202           return rangeProcessor.processRange(range, (HashMap)subset);
203         }
204       }
205    
206       public float[] processRange(byte[] range, Object subset) {
207         if (rangeProcessor == null) {
208           float[] f_range = new float[range.length];
209           for (int i=0; i<range.length;i++) f_range[i] = (float) range[i];
210           return f_range;
211         }
212         else {
213           return rangeProcessor.processRange(range, (HashMap)subset);
214         }
215       }
216    
217       public float[] processRange(float[] range, Object subset) {
218         if (rangeProcessor == null) {
219           return range;
220         }
221         else {
222           return rangeProcessor.processRange(range, (HashMap)subset);
223         }
224       }
225    
226       public double[] processRange(double[] range, Object subset) {
227         if (rangeProcessor == null) {
228           return range;
229         }
230         else {
231           return rangeProcessor.processRange(range, (HashMap)subset);
232         }
233       }
234    
235    
236       public Object readArray(Object subset) throws Exception {
237         Subset select = getIndexes((HashMap)subset);
238         int[] start = select.getStart();
239         int[] count = select.getCount();
240         int[] stride = select.getStride();
241    
242         return reader.getArray(arrayName, start, count, stride);
243       }
244    
245       public MultiDimensionReader getReader() {
246         return reader;
247       }
248    
249       public Object getMetadata() {
250         return metadata;
251       }
252    
253       String getArrayName() {
254         return arrayName;
255       }
256    
257       public RealType getRangeType() {
258         return rangeType;
259       }
260       
261       public HashMap getSubsetFromLonLatRect(HashMap subset, double minLat, double maxLat,
262                                                              double minLon, double maxLon) {
263         return subset;
264       }
265    
266       public HashMap getSubsetFromLonLatRect(double minLat, double maxLat,
267                                              double minLon, double maxLon) {
268         return null;
269       }
270    
271       public HashMap getSubsetFromLonLatRect(double minLat, double maxLat,
272                                              double minLon, double maxLon,
273                                              int xStride, int yStride, int zStride) {
274         return null;
275       }
276    
277    }