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 }